mirror of
https://github.com/Sea-Haven-Industries/engineering-handbook.git
synced 2026-09-30 06:53:15 +00:00
Merge pull request #24 from Sea-Haven-Industries/docs/cicd-concurrency-convention
Some checks are pending
ci / ci / ci (push) Waiting to run
Some checks are pending
ci / ci / ci (push) Waiting to run
docs(cicd): document the concurrency convention used by the reusable workflows
This commit is contained in:
commit
f8f04bad41
1 changed files with 50 additions and 0 deletions
50
cicd.md
50
cicd.md
|
|
@ -98,6 +98,56 @@ Deploy workflows authenticate to AWS via OIDC (no long-lived credentials). Each
|
||||||
|
|
||||||
Always pass `node-version: "24"` to reusable workflows. Local dev uses Node 24 / npm 11 which generates lockfileVersion 3. The workflow defaults match this, but be explicit to avoid drift.
|
Always pass `node-version: "24"` to reusable workflows. Local dev uses Node 24 / npm 11 which generates lockfileVersion 3. The workflow defaults match this, but be explicit to avoid drift.
|
||||||
|
|
||||||
|
## Concurrency
|
||||||
|
|
||||||
|
Reusable workflows in the central `.github` repo declare their own `concurrency` group. Consumers do not have to add one.
|
||||||
|
|
||||||
|
### `cancel-in-progress`: false for deploys, true for CI
|
||||||
|
|
||||||
|
Deploy reusables set `cancel-in-progress: false`. Cancelling a deploy midway does not roll it back. It abandons the run wherever it happens to be, which can leave a CloudFormation stack mid-update, an Elastic Beanstalk environment mid-update, or a half-uploaded store build. A superseded deploy therefore queues behind the running one instead of killing it.
|
||||||
|
|
||||||
|
CI reusables set `cancel-in-progress: true`. A CI run produces no external side effects, so when a newer commit supersedes an older one there is nothing to protect and the older run should be abandoned.
|
||||||
|
|
||||||
|
### Groups are declared at job level
|
||||||
|
|
||||||
|
The `concurrency` block sits on the job, not at workflow top level. A single run can contain several jobs that must not share a group: a reusable with multiple jobs needs each one keyed separately, and a caller repo can invoke the same reusable from several jobs in one run. Where a reusable has more than one job, `${{ github.job }}` is part of the key so those jobs do not serialise against each other.
|
||||||
|
|
||||||
|
### Groups are scoped per repository
|
||||||
|
|
||||||
|
GitHub evaluates a concurrency group within the repository that owns the run, and for a reusable workflow that is the caller's repository. Two different repos calling the same reusable never contend. A group only has to be unique *inside* one repo, which is what the literal workflow-name prefix (`cd-sam-`, `cd-cdk-`, and so on) provides: it stops two different reusables in the same repo from colliding.
|
||||||
|
|
||||||
|
### The key must identify the deploy target
|
||||||
|
|
||||||
|
Every deploy group is keyed on the inputs that name what is being deployed, not just on the workflow. Keying on the workflow alone would serialise deploys that are genuinely independent — a repo that calls one reusable from several jobs, one per AWS account, would deploy those accounts one at a time for no reason.
|
||||||
|
|
||||||
|
The groups as implemented:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# cd-sam.yaml
|
||||||
|
group: cd-sam-${{ inputs.region }}-${{ inputs.stack-name }}
|
||||||
|
|
||||||
|
# cd-cdk.yaml
|
||||||
|
group: cd-cdk-${{ inputs.region }}-${{ inputs.stacks }}-${{ inputs.stack-name }}
|
||||||
|
|
||||||
|
# cd-dotnet-eb.yaml
|
||||||
|
group: cd-dotnet-eb-${{ inputs.eb-application }}-${{ inputs.eb-environment }}
|
||||||
|
|
||||||
|
# cd-mobile-ios.yaml
|
||||||
|
group: cd-mobile-ios-${{ inputs.working-directory }}-${{ inputs.fastlane-lane }}
|
||||||
|
```
|
||||||
|
|
||||||
|
`cd-cdk` keys on `stacks`, the stack *selector*, rather than on `stack-name` alone. `stack-name` is optional there, so a multi-account caller that passes only a selector would collapse every one of its jobs into a single group.
|
||||||
|
|
||||||
|
Every component of a key is an input that is either required or always defaults, so the group can never evaluate to a bare prefix: `region` defaults, `stacks` defaults to `--all`, and `working-directory` and `fastlane-lane` both default. A key built from an input that can be empty silently merges unrelated deploys into one group.
|
||||||
|
|
||||||
|
CI groups follow the same shape and add `${{ github.ref }}` so branches do not cancel each other:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ci-typescript-frontend.yaml
|
||||||
|
group: ci-typescript-frontend-${{ github.workflow }}-${{ github.ref }}-${{ inputs.working-directory }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
```
|
||||||
|
|
||||||
## Naming
|
## Naming
|
||||||
|
|
||||||
- All workflow files: kebab-case
|
- All workflow files: kebab-case
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue