Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions cli/azd/internal/cmd/up_graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ func (u *UpGraphAction) Run(
DependsOn: []string{postDeployEventStep},
Tags: []string{"cmdhook"},
Action: func(ctx context.Context) error {
u.console.Message(ctx, "Running postdeploy hook...")
return runProjectCommandHook(
ctx, hookDeps, ext.HookTypePost, string(project.ProjectEventDeploy),
)
Expand All @@ -495,12 +496,23 @@ func (u *UpGraphAction) Run(
// in parallel with provisioning). This avoids conflicting with
// the provisioning progress display.
var (
tickerOnce sync.Once
stopTicker func()
tickerOnce sync.Once
stopTicker func()
deployProgressFinalized bool
)
if deployTracker != nil {
stopTicker = func() {} // no-op until started
}
finalizeDeployProgress := func() {
if stopTicker != nil {
stopTicker()
stopTicker = nil
}
if deployTracker != nil && deployTracker.HasActivity() && !deployProgressFinalized {
deployTracker.RenderFinal()
deployProgressFinalized = true
}
}

// startDeployTicker is called once (via tickerOnce) when the first publish or deploy
// step begins. It starts the progress table ticker and suppresses the console previewer
Expand Down Expand Up @@ -534,6 +546,11 @@ func (u *UpGraphAction) Run(
if baseOnStepStart != nil {
baseOnStepStart(stepName)
}
// Finalize deploy progress before postdeploy hooks execute so that
// hook output renders normally and does not look like a hang.
if shouldFinalizeDeployProgressBeforeStep(stepName) {
finalizeDeployProgress()
}
// Update deploy progress tracker for service steps.
// Packaging runs in parallel with provisioning, so only update the
// data model silently. Start the visual ticker when the first
Expand Down Expand Up @@ -579,13 +596,9 @@ func (u *UpGraphAction) Run(

result := exegraph.RunWithResult(ctx, g, opts)

// Stop the progress ticker and render a final summary table.
if stopTicker != nil {
stopTicker()
}
if deployTracker != nil && deployTracker.HasActivity() {
deployTracker.RenderFinal()
}
// Stop the progress ticker and render a final summary table if it has
// not already been finalized before the postdeploy hook.
finalizeDeployProgress()

// Clean up temporary package artifacts regardless of success/failure.
state.CleanupTempArtifacts()
Expand Down Expand Up @@ -710,6 +723,10 @@ func phaseDurations(steps []exegraph.StepTiming) (provision, deploy time.Duratio
return provision, deploy
}

func shouldFinalizeDeployProgressBeforeStep(stepName string) bool {
return stepName == "cmdhook-postdeploy"
}

// changedFlagNames returns the names of flags that were explicitly set on
// the FlagSet. Returns nil for a nil FlagSet so callers can pass through
// without a guard. Mirrors the changedFlags collection in
Expand Down
23 changes: 23 additions & 0 deletions cli/azd/internal/cmd/up_graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,26 @@ func TestPhaseTimingBreakdown(t *testing.T) {
})
}
}

func TestShouldFinalizeDeployProgressBeforeStep(t *testing.T) {
t.Parallel()

tests := []struct {
name string
stepName string
want bool
}{
{name: "postdeploy hook", stepName: "cmdhook-postdeploy", want: true},
{name: "predeploy hook", stepName: "cmdhook-predeploy", want: false},
{name: "deploy step", stepName: "deploy-web", want: false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := shouldFinalizeDeployProgressBeforeStep(tt.stepName); got != tt.want {
t.Fatalf("shouldFinalizeDeployProgressBeforeStep(%q)=%t, want %t", tt.stepName, got, tt.want)
}
})
}
}