Skip to content
Merged
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
65 changes: 49 additions & 16 deletions e2e/scenarios/multi-repo/external-update-deploys-component.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Scenario: external deploy opts in to on_update.deploy and the receiver still
# records new external state, proving the additive on_update config is
# back-compatible with the live record path.
# Scenario: external deploy opts in to on_update.deploy and the receiver records
# new external state while the scoped deploy_cdk job runs live against a local
# reusable deploy workflow.
#
# Scope note: the scoped deploy job wiring (a deploy_<name> job, needs: update,
# if gated on needs.update.result == 'success' && inputs.deploy_name == '<name>',
# uses: the declared workflow, secrets: inherit) is asserted at the generator
# level in internal/generate/external_test.go. A live scoped deploy run needs a
# real reusable deploy workflow plus deploy credentials in the satellite repo,
# which is not reproducible in the gitea + act harness, so the actual deploy run
# is covered by the downstream fleet validation rather than forced here. This
# scenario keeps the live coverage focused on what the harness can prove: that
# adding on_update.deploy does not break the receiver's record path.
# The scenario proves three things end-to-end:
# 1. Adding on_update.deploy does not break the receiver's record path.
# 2. The generated deploy_cdk job fires when deploy_name == 'cdk' and
# calls the local reusable workflow via uses: ./.github/workflows/...
# 3. The local reusable workflow (committed to primary-backend before the
# dispatch) completes successfully so the overall run concludes success.
#
# Note: no actions/checkout inside the reusable workflow - act cannot resolve
# checkout for a reusable callback against the per-scenario gitea instance.

name: external-update-deploys-component
description: External deploy declares on_update.deploy; receiver still records new external state
description: External deploy declares on_update.deploy; receiver records state and scoped deploy job runs live

repos:
primary-backend:
Expand All @@ -33,7 +33,7 @@ repos:
workflow: example/cdk-infra/.github/workflows/deploy.yaml
on_update:
deploy:
workflow: example/cdk-infra/.github/workflows/deploy.yaml
workflow: .github/workflows/on-update-deploy-cdk.yaml
manifest:
state:
dev:
Expand Down Expand Up @@ -61,7 +61,39 @@ repos:
primary: primary-backend

steps:
# Step 1: Commit changes to satellite CDK repo
# Step 1: Commit the local reusable deploy workflow to primary-backend so that
# act can resolve it via uses: ./.github/workflows/on-update-deploy-cdk.yaml
# when the generated deploy_cdk job fires.
- name: seed-local-deploy-workflow
repo: primary-backend
action: commit
commit:
message: "chore: add on-update deploy workflow for cdk"
files:
.github/workflows/on-update-deploy-cdk.yaml: |
name: on-update-deploy-cdk
on:
workflow_call:
inputs:
environment:
required: false
type: string
sha:
required: false
type: string
version:
required: false
type: string
deploy_name:
required: false
type: string
jobs:
cdkdeploy:
runs-on: ubuntu-latest
steps:
- run: echo "on-update deploy ran deploy_name=${{ inputs.deploy_name }} sha=${{ inputs.sha }}"

# Step 2: Commit changes to satellite CDK repo
- name: update-cdk-stack
repo: cdk-infra
action: commit
Expand All @@ -77,7 +109,8 @@ steps:
}
}

# Step 2: Satellite notifies primary after deploy
# Step 3: Satellite notifies primary after deploy; external-update.yaml runs,
# records state, and the scoped deploy_cdk job calls the local reusable workflow.
- name: notify-primary
repo: cdk-infra
action: dispatch
Expand Down
1 change: 1 addition & 0 deletions internal/generate/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ func (g *ExternalUpdateGenerator) writeHeader(sb *strings.Builder) {

func (g *ExternalUpdateGenerator) writeWorkflowTrigger(sb *strings.Builder) {
sb.WriteString("name: External Update\n\n")
sb.WriteString("run-name: External Update ${{ inputs.deploy_name }} ${{ inputs.sha }}\n\n")
sb.WriteString("on:\n")
sb.WriteString(" workflow_dispatch:\n")
sb.WriteString(" inputs:\n")
Expand Down
26 changes: 26 additions & 0 deletions internal/generate/external_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1038,3 +1038,29 @@ func TestExternalUpdateGenerator_OnUpdateDeploy_LocalWorkflowPath(t *testing.T)
require.NoError(t, err)
assert.Contains(t, content, "uses: ./.github/workflows/deploy-cdk.yaml")
}

// TestExternalUpdateGenerator_EmitsRunName verifies that the generated
// external-update workflow includes a run-name line that embeds the
// deploy_name and sha inputs so individual runs are correlatable in the
// GitHub Actions UI.
func TestExternalUpdateGenerator_EmitsRunName(t *testing.T) {
cfg := &config.TrunkConfig{
TrunkBranch: "master",
Environments: []string{"dev", "test", "prod"},
External: []config.ExternalRepoConfig{
{
Repo: "example/cdk-infra",
Ref: "main",
Deploys: []config.ExternalDeployConfig{
{Name: "cdk", Workflow: "example/cdk-infra/.github/workflows/deploy.yaml"},
},
},
},
}

gen := NewExternalUpdateGenerator(cfg, "/tmp")
content, err := gen.Generate()
require.NoError(t, err)

assert.Contains(t, content, "run-name: External Update ${{ inputs.deploy_name }} ${{ inputs.sha }}")
}
Loading