Repository navigation
Define release-safe refs for consumer workflow wrappers and checked-out actions #238
Description
Problem
Consumer repositories currently synchronize thin workflow wrappers from resources/github-actions/*.yml, and those wrappers call reusable workflows from this repository using php-fast-forward/dev-tools/.github/workflows/<workflow>.yml@main.
Inside the reusable workflows, when local composite actions are needed, the workflow sparse-checks out .github/actions from php-fast-forward/dev-tools into .dev-tools-actions. In consumer runs that checkout currently resolves against main as well.
That means a consumer repository can run automation from the current development state of dev-tools, not necessarily from the latest published fast-forward/dev-tools release installed in that consumer. If main contains workflow or action changes that have not been released yet, consumers can see behavior that does not match the package version they depend on.
Why This Matters
This creates a subtle version skew across the ecosystem:
- the consumer's Composer dependency may be pinned to a released
fast-forward/dev-toolsversion; - the consumer's copied workflow wrapper may still point to reusable workflows on
@main; - the reusable workflow may checkout local action implementations from
main; - the action implementation may expect PHP classes, scripts, files, or command behavior that only exist on
main, not in the consumer's installed release.
The result can be hard-to-debug CI anomalies where the workflow logic and the package code are from different points in time.
Current Surfaces
Examples of the current pattern:
resources/github-actions/tests.ymlcallsphp-fast-forward/dev-tools/.github/workflows/tests.yml@main.resources/github-actions/changelog.ymlcallsphp-fast-forward/dev-tools/.github/workflows/changelog.yml@main.resources/github-actions/reports.yml,wiki.yml,wiki-maintenance.yml,review.yml,auto-assign.yml, andlabel-sync.ymlfollow the same wrapper model.- reusable workflows then checkout
.github/actionsinto.dev-tools-actions, commonly resolvingphp-fast-forward/dev-toolsatmainfor consumer repositories. - docs currently describe the sparse checkout model, but do not define a release/version contract for which ref should be used.
Proposed Direction
Define and implement a versioning policy for consumer-facing reusable workflows and the local action source they checkout.
This issue should evaluate at least these approaches:
-
Pin action checkout refs to the latest published release
- Reusable workflows could checkout
.github/actionsat the same released tag as the reusable workflow ref. - This reduces unreleased action drift, but we need a reliable way to know the intended ref from inside the workflow.
- Reusable workflows could checkout
-
Pin consumer wrappers to released tags instead of
@mainresources/github-actions/*.ymlcould be rendered with a concrete@vX.Y.Zref during release or sync.- Dependabot could then manage workflow updates in consumers similarly to dependency updates.
- Release automation would need to guarantee wrappers are updated consistently when a new DevTools release is prepared.
-
Keep wrappers on
@main, but pin only.github/actionscheckout- This reduces action-source drift while preserving central reusable workflow updates.
- It still leaves reusable workflow YAML on
main, so it may not fully solve version skew.
-
Expose a workflow input for
dev-tools-ref- Consumer wrappers could pass
dev-tools-refexplicitly. - Defaults could remain
mainfor development, but generated consumer wrappers could use a release tag. - This may be the most flexible route, but it requires touching every reusable workflow that checks out
.github/actions.
- Consumer wrappers could pass
-
Release-managed wrapper regeneration
- During release preparation, update
resources/github-actions/*.ymlto point at the release tag that is about to be published. - Ensure the packaged/synchronized workflow wrappers and docs explain how consumers receive updates.
- Evaluate whether Dependabot should be configured to raise PRs when these
uses: php-fast-forward/dev-tools/...@vX.Y.Zreferences lag behind.
- During release preparation, update
Implementation Strategy
Start with a design pass before changing every workflow:
- inventory every consumer wrapper under
resources/github-actions/and every reusable workflow under.github/workflows/that sparse-checks out.github/actions; - decide whether the authoritative ref should be
main, latest release tag, Composer package version, or an explicit wrapper input; - define how release automation updates the chosen ref;
- define how consumer repositories receive and update that ref through
dev-tools:syncand/or Dependabot; - update documentation so the release/version contract is explicit;
- only then apply the workflow changes consistently.
Requirements
- Consumer repositories MUST NOT unexpectedly execute unreleased
.github/actionsimplementations when their wrappers are intended to represent a released DevTools version. - The selected policy MUST be consistent across all packaged workflow wrappers, not only one workflow.
- Reusable workflows that checkout
.github/actionsMUST use a deterministic ref that matches the selected policy. - Release automation MUST keep generated wrappers, reusable workflow refs, and documentation aligned.
- The solution SHOULD preserve a convenient development path for this repository's own PRs, where workflows need to test in-branch changes before release.
- The solution SHOULD explain how Dependabot or another automation will update workflow refs in consumers if the final design uses versioned tags.
- The solution MUST avoid requiring consumers to manually edit every workflow after each DevTools release.
Open Questions
- Should consumer wrappers point at
@main, immutable release tags such as@v1.21.0, or a moving major/minor tag such as@v1? - If wrappers use release tags, should
dev-tools:syncrewrite them to the installed Composer package version or to the latest known upstream release? - Can Dependabot reliably update reusable workflow references that point to
php-fast-forward/dev-tools/.github/workflows/*.yml@vX.Y.Z? - Should
.github/actionscheckout use the same ref as the reusable workflow, or should it have an independent input/default? - How do we handle this repository's own workflows so PRs can still validate unreleased action changes before those actions are tagged?
- Should release preparation fail if packaged workflow wrappers still point to
@mainor to a stale release ref?
Non-goals
- Redesigning the workflow architecture unrelated to version/ref consistency.
- Removing reusable workflows or going back to copying full workflow implementations into every consumer.
- Solving arbitrary consumer workflow customization drift in the same change.
Acceptance Criteria
Functional Criteria
- The repository has a documented versioning policy for consumer workflow wrappers and
.github/actionscheckout refs. - All packaged consumer wrappers under
resources/github-actions/follow the chosen policy consistently. - All reusable workflows that checkout
.github/actionsuse the selected deterministic ref strategy. - Release preparation or validation detects stale or unintended workflow refs before publication.
- Consumer update behavior is documented, including whether updates happen through
dev-tools:sync, Dependabot, release automation, or a combination. - This repository can still validate unreleased workflow/action changes safely in its own PRs.
Regression Criteria
- Add workflow/static validation coverage or command-level tests that catch accidental
@mainusage where the selected policy forbids it. - Add documentation coverage for the chosen policy in the GitHub Actions or consumer sync docs.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
coisa commentedon Oct 21, 2026
Ownership reconciliation (2026-10-21)
#240 no longer targets a universal .github/github-actions repository. Keep this independent release-safe-ref requirement open and apply it per domain package: compatible runtime version, workflow/Action commit and skill source must be verified and recorded together by #384. #195 uses LLM Skills provenance instead of a second installer. Revalidate the unmerged #376 distribution candidate; future v2.0.0 template refs are not proof a release is available.
Consumers must not be migrated before tag/package/assets exist; keep exact previous refs for rollback and preserve required-check identities. Per-domain versioning must not force every package to release in lockstep or silently upgrade a consumer to latest.