Skip to content

Add concurrency groups to workflow.yml to prevent racing publishes #321

@MariusStorhaug

Description

Module maintainers who push multiple commits in quick succession to a PR — or who label and immediately push — expect only the latest workflow run to proceed. If an earlier run reaches the Publish-Module or Publish-Site job before the newer run cancels it, conflicting releases or partial publishes can occur.

Request

Desired capability

A concurrency group on workflow.yml (and optionally on individual reusable workflows) that serializes or cancels-in-progress runs for the same branch/PR. This prevents two concurrent runs from racing through build → test → publish.

Current state

Only Release.yml defines a concurrency group:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

The remaining 15+ reusable workflows — including Publish-Module.yml, Build-Module.yml, Get-Settings.yml, and the *-ModuleLocal.yml family — have no concurrency control.

Acceptance criteria

  • workflow.yml includes a concurrency block scoped to workflow + ref
  • Rapid successive pushes cancel earlier in-progress runs rather than allowing them to race
  • The Publish-Module job never executes concurrently for the same branch
  • Existing Release.yml concurrency group remains unchanged or is aligned with the new pattern

Note

This aligns with Twelve-Factor App Factor VIII (Concurrency) — processes should be designed so that scaling out (or in this case, rapid re-triggering) does not produce conflicting side-effects.


Technical decisions

Scope: Add concurrency at the top level of workflow.yml only. Since workflow.yml is the orchestrator called via workflow_call, its concurrency group automatically governs all downstream reusable workflows within the same run. Individual reusable workflows do not need their own concurrency blocks.

Group key: ${{ github.workflow }}-${{ github.ref }} — matches the existing Release.yml pattern and scopes concurrency per workflow per branch/PR.

Cancel-in-progress: true — newer pushes should supersede older runs. This is safe because the workflow is idempotent: re-running build → test → publish with the latest code is always the correct outcome.


Implementation plan

  • Add concurrency block to workflow.yml after permissions: and before jobs:
  • Verify the group key pattern matches the existing Release.yml convention
  • Test with two rapid successive pushes to a PR to confirm the older run is cancelled

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions