Skip to content

Commit b1d4a5c

Browse files
committed
Prepare for the publish workflow
1 parent 17e8386 commit b1d4a5c

File tree

2 files changed

+110
-27
lines changed

2 files changed

+110
-27
lines changed

src/redis_release/models.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ class PackageState(BaseModel):
5757
release_handle: Optional[Dict[str, Any]] = None
5858
build_completed: bool = False
5959

60+
# Publish phase information
61+
publish_workflow: Optional[WorkflowRun] = None
62+
publish_completed: bool = False
63+
publish_info: Optional[Dict[str, Any]] = None
64+
6065

6166
class ReleaseState(BaseModel):
6267
"""Complete state of a release process."""
@@ -98,3 +103,31 @@ def has_build_failures(self) -> bool:
98103
and pkg.build_workflow.conclusion != WorkflowConclusion.SUCCESS
99104
for pkg in self.packages.values()
100105
)
106+
107+
def is_publish_phase_complete(self) -> bool:
108+
"""Check if all publish workflows are completed successfully."""
109+
if not self.packages:
110+
return False
111+
return all(
112+
pkg.publish_completed
113+
and pkg.publish_workflow
114+
and pkg.publish_workflow.conclusion == WorkflowConclusion.SUCCESS
115+
for pkg in self.packages.values()
116+
)
117+
118+
def is_publish_phase_finished(self) -> bool:
119+
"""Check if all publish workflows are finished (successfully or not)."""
120+
if not self.packages:
121+
return False
122+
return all(pkg.publish_completed for pkg in self.packages.values())
123+
124+
def has_publish_failures(self) -> bool:
125+
"""Check if any publish workflows failed or were cancelled."""
126+
if not self.packages:
127+
return False
128+
return any(
129+
pkg.publish_completed
130+
and pkg.publish_workflow
131+
and pkg.publish_workflow.conclusion != WorkflowConclusion.SUCCESS
132+
for pkg in self.packages.values()
133+
)

src/redis_release/orchestrator.py

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
ReleaseState,
1313
ReleaseType,
1414
WorkflowConclusion,
15+
WorkflowRun,
1516
)
1617
from .state_manager import StateManager
1718

@@ -216,36 +217,25 @@ def execute_release(
216217
)
217218
else:
218219
docker_state = state.packages.get(PackageType.DOCKER)
219-
if docker_state and docker_state.build_completed:
220-
if (
221-
docker_state.build_workflow
222-
and docker_state.build_workflow.conclusion
223-
):
224-
conclusion = docker_state.build_workflow.conclusion.value
225-
if conclusion == "success":
226-
console.print(
227-
"[green] Build phase already completed successfully[/green]"
228-
)
229-
console.print(
230-
"[dim] Skipping workflow execution - Docker build is done[/dim]"
231-
)
232-
else:
233-
console.print(
234-
f"[yellow] Build phase already completed with status: {conclusion}[/yellow]"
235-
)
236-
console.print(
237-
"[dim] Skipping workflow execution - use --force-rebuild to retry[/dim]"
238-
)
239-
else:
240-
console.print("[yellow] Build phase already completed[/yellow]")
241-
console.print(
242-
"[dim] Skipping workflow execution - use --force-rebuild to retry[/dim]"
243-
)
244-
else:
245-
console.print("[blue] No build phase needed[/blue]")
220+
self._print_completed_state_phase(
221+
phase_completed=docker_state.build_completed if docker_state else False,
222+
workflow=docker_state.build_workflow if docker_state else None,
223+
name="Build"
224+
)
246225

247226
state_manager.save_state(state)
248227

228+
# Execute publish phase if needed
229+
if self._should_run_publish_phase(state):
230+
console.print("[blue]Starting publish phase...[/blue]")
231+
if not self._execute_publish_phase(state, github_client):
232+
return ReleaseResult(
233+
success=False, message="Publish phase failed", state=state
234+
)
235+
236+
# Save state after publish phase
237+
state_manager.save_state(state)
238+
249239
if state.is_build_phase_complete():
250240
return ReleaseResult(
251241
success=True,
@@ -268,6 +258,47 @@ def _should_run_build_phase(self, state: ReleaseState) -> bool:
268258
docker_state = state.packages.get(PackageType.DOCKER)
269259
return not docker_state or not docker_state.build_completed
270260

261+
def _should_run_publish_phase(self, state: ReleaseState) -> bool:
262+
"""Check if publish phase should be executed."""
263+
# Only run publish phase if build phase is complete
264+
if not state.is_build_phase_complete():
265+
return False
266+
267+
# Only run publish phase for public releases
268+
return state.release_type == ReleaseType.PUBLIC
269+
270+
def _print_completed_state_phase(
271+
self,
272+
phase_completed: bool,
273+
workflow: Optional[WorkflowRun],
274+
name: str
275+
) -> None:
276+
"""Print the current phase state when phase is already completed."""
277+
if phase_completed:
278+
if workflow and workflow.conclusion:
279+
conclusion = workflow.conclusion.value
280+
if conclusion == "success":
281+
console.print(
282+
f"[green] {name} phase already completed successfully[/green]"
283+
)
284+
console.print(
285+
f"[dim] Skipping workflow execution - {name} is done[/dim]"
286+
)
287+
else:
288+
console.print(
289+
f"[yellow] {name} phase already completed with status: {conclusion}[/yellow]"
290+
)
291+
console.print(
292+
"[dim] Skipping workflow execution - use --force-rebuild to retry[/dim]"
293+
)
294+
else:
295+
console.print(f"[yellow] {name} phase already completed[/yellow]")
296+
console.print(
297+
"[dim] Skipping workflow execution - use --force-rebuild to retry[/dim]"
298+
)
299+
else:
300+
console.print(f"[blue] No {name.lower()} phase needed[/blue]")
301+
271302
def _execute_build_phase(
272303
self, state: ReleaseState, github_client: GitHubClient
273304
) -> bool:
@@ -367,6 +398,25 @@ def _execute_build_phase(
367398

368399
return True
369400

401+
def _execute_publish_phase(
402+
self, state: ReleaseState, github_client: GitHubClient
403+
) -> bool:
404+
"""Execute publish phase for all packages.
405+
406+
Returns:
407+
True if all publishes succeeded
408+
409+
Raises:
410+
RuntimeError: If release_handle doesn't exist in state
411+
"""
412+
docker_state = state.packages.get(PackageType.DOCKER)
413+
if not docker_state or not docker_state.release_handle:
414+
raise RuntimeError("release_handle doesn't exist in state - cannot proceed with publish phase")
415+
416+
# For now, just return True
417+
console.print("[green]Publish phase ready - release_handle found[/green]")
418+
return True
419+
370420
def get_release_status(
371421
self, tag: str, dry_run: bool = False
372422
) -> Optional[ReleaseState]:

0 commit comments

Comments
 (0)