Skip to content

ci: pin the org's reusable workflows to a SHA - #15

Merged
BharathASL merged 1 commit into
mainfrom
ci/pin-org-reusable-workflows
Sep 9, 2026
Merged

ci: pin the org's reusable workflows to a SHA#15
BharathASL merged 1 commit into
mainfrom
ci/pin-org-reusable-workflows

Conversation

@BharathASL

Copy link
Copy Markdown
Contributor

Description

Pins this repository's reusable-workflow stubs to .github commit 2359bf4e8da8fbc78c19e09606468c5a0c3e47bd — the tip of that repository's main as of 2026-09-09 — in place of the mutable @main refs.

N6-CI-06 previously exempted the org's own reusable workflows from SHA pinning. Ninja6-MC/.github#38 reversed that exemption, pinned the three canonical stubs under templates/, and rewrote the normative text in .github/standards/ci.md. This applies the same change to the live workflows here.

The risk pinning addresses is mutability plus blast radius, not third-party code. dco.yml and standards.yml are required checks on every protected branch in the org, so one commit to .github's main changes what gates merges across every repository simultaneously — a failure this org has already had. Dependabot can keep a SHA-pinned reusable-workflow ref current; it can never propose an update for @main, because a branch is not a version.

No behaviour change on merge: 2359bf4e is the current tip of .github's main, so these workflows resolve to exactly the code they resolve to today.

Related Issues

Follows Ninja6-MC/.github#38, which made the rule change this implements. No issue in this repository.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation / Hygiene update

Checklist

  • My code follows the style of the surrounding code.
  • I have run this repository's tests locally and they pass. — not run; this change touches only .github/workflows/ and no source. The workflows themselves are verified by CI on this pull request.
  • I have added tests that prove my fix is effective or that my feature works. — not applicable to a workflow ref change.
  • I have updated documentation / CHANGELOG as appropriate. — the normative text lives in .github/standards/ci.md and was updated in ci(standards): pin the org's own reusable workflows under N6-CI-06 .github#38; nothing in this repository documents the ref.
  • My commits follow Conventional Commits.
  • Every commit is signed off (git commit -s), per section 5 of CONTRIBUTING.md.

Signed-off-by: Bharath Sendhurpandi <bharathasl74185@gmail.com>

@ninja6-agent ninja6-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. The pinned object is real and is what the trailing comment says it is, the references resolve, the gate keeps reporting under the same names, and this repository is fully converted with no half-applied state. The findings below are follow-ups elsewhere, not changes wanted here.

What I verified, and how

The pinned object exists and is what it claims. 2359bf4e8da8fbc78c19e09606468c5a0c3e47bd is a real commit in Ninja6-MC/.github, committed 2026-09-09, and is the merge commit of that repository's #38 — the change that reversed the @main exemption under N6-CI-06. It is also the current tip of main. That last point is worth stating rather than assuming: it means this pin changes nothing about which code runs today and only stops it changing tomorrow. A pin that quietly moves a required gate backwards to older logic is the expensive version of this change, and this is not that.

The reference format is valid for the context it is used in. The doubled .github segment survives on all three references — repository name once, directory once — and each ref is a 40-character lowercase hex SHA. The evidence is this pull request's own runs rather than inspection: dco / Check Sign-off and standards / Check Standards both reported and passed, which they could not do if the reference failed to resolve. That failure mode is worth naming, because it is the one this change could plausibly have caused and the one that hides: a bad reusable reference starts the run with zero jobs, so the check does not report at all, and a check that never reports is not a red tick — it is an absence.

The reported check names do not move. A called workflow reports as <job-id> / <job-name>, and neither changes here: only the @ref on the uses: line does. So nothing on a required-status list stops being reported (N6-CI-03, the rule most likely to be tripped by a workflow edit). Read off the run on this head rather than predicted.

This repository is completely converted. All three calls into the org's reusable workflows — dco.yml, scorecard.yml and standards.yml — are pinned by this commit, and a search across the repository finds no remaining Ninja6-MC/.github/...@main. There is no fourth caller left behind to surface on a later merge.

check-standards.py is not tripped by the change, and does not yet check it. Its N6-CI-01 test splits the uses: value on @ before comparing against the shared path, so pinning does not break the "calls the shared workflow" assertion. Its N6-CI-06 test still continues on any ref beginning Ninja6-MC/.github/. Both were read, not inferred. So the green Check Standards here is not evidence that the pin conforms — it is evidence that the rule's new half is not yet mechanically enforced, which is the sequencing standards/ci.md describes and defends.

The commit itself. Conventional Commits subject, Signed-off-by present and matching the author, authored under the address this organisation uses rather than the users.noreply artifact, and the diff is exactly the uses: lines with nothing carried along. The branch name describes the change.

Findings

All four sit in Ninja6-MC/.github rather than here, and none is a reason to hold this pull request. Two are gaps this change exposes rather than creates; two are documentation that has not caught up.

1. Nothing can bump this pin — significant

N6-CI-06 is explicit that pinning without an updater is the worse of the two states: a pin "goes stale in silence", and a repository that pins without dependabot.yml "has bought immutability and paid for it with invisibility". The rule's answer is Dependabot, and the case for extending the rule to the org's own workflows rests on it — standards/ci.md now says a pinned reference "is maintained by machinery every repository already runs".

That does not hold for this reference. Ninja6-MC/.github has no tags and no releases:

gh api repos/Ninja6-MC/.github/tags     -> []
gh api repos/Ninja6-MC/.github/releases -> []

Dependabot's github-actions updater resolves a candidate version for a SHA pin from the referenced repository's tags or releases. With neither, there is nothing to resolve and it will not open a pull request against this line — the same practical outcome as @main, arrived at from the other direction. The trailing comment admits it by omission: # main @ 2026-09-09 is a date, not the "human-readable version" N6-CI-06 asks for, because there is no version to name.

This does not make the change wrong. Immutability of the gate is worth having on its own terms, and this repository does carry .github/dependabot.yml with the github-actions ecosystem, so the rule's letter is satisfied. But its maintenance half is currently unstaffed, and that should be a decision rather than an assumption: either give Ninja6-MC/.github a tagged release line, so Dependabot has something to resolve and the trailing comment has something true to say, or accept that these twenty references move by hand and correct ci.md, which presently says the opposite.

2. Pinning standards.yml does not pin the standards check — significant

The pin fixes the workflow file. For dco.yml that is the entire gate: the sign-off script is inline in the reusable workflow, so this reference is now genuinely immutable and the blast-radius argument lands in full.

For standards.yml it is not. That reusable workflow checks out the register and scripts/check-standards.py at run time, from a ref it resolves for itself, preferring github.job_workflow_ref and falling back to refs/heads/main. On this pull request's own run it took the fallback:

JOB_WORKFLOW_REF:
job_workflow_ref is empty; falling back to main.
Register ref: refs/heads/main

So the code deciding whether a pull request may merge here is still read from main at the instant the job starts, and a bad commit to check-standards.py still reaches every caller at once. The workflow's own comment block already records that all three candidate context variables are empty or wrong in this context, and #38 rewrote the log line to stop claiming otherwise — but the consequence, that the mutability this change set out to close remains open for the more complex of the two gates, is not visible from this diff and deserves an issue on .github. It matters most at the moment the check-standards.py skip is removed, because that is when the register starts failing pull requests on rules the caller never reviewed.

3. The canonical templates pin an older commit than this does — minor

templates/dco-stub.yml, templates/standards-stub.yml and templates/scorecard-stub.yml pin 9e70c6b8134e62f33ad1f55096d47c00b8edaacc # main @ 2026-09-01. Every repository adopting the change pins 2359bf4. templates/README.md calls those files canonical and says to change them first and then propagate, which is the order that was followed — but the propagation landed on a newer commit than its source, so the canonical copy is now the stale one and a repository scaffolded tomorrow starts a generation behind the six that already exist.

Behaviourally it is nothing today: across 9e70c6b..2359bf4 the only workflow change is one log message in standards.yml, and dco.yml and scorecard.yml are byte-identical. It is still drift on day one, in the directory that exists to prevent drift, and it costs one commit to close.

4. standards/ci.md still hands out @main — minor

N6-CI-01 presents the DCO stub as normative text — "The whole file is:" — and that block still reads ...dco.yml@main. So does the worked example under N6-CI-02, and so do the header comments inside .github/workflows/dco.yml and .github/workflows/standards.yml, which show callers the stub to copy. N6-CI-06, further down the same file, now requires the opposite. A contributor following N6-CI-01 literally writes a reference N6-CI-06 forbids. README.md's worked example was corrected in #38; these four were not.

Conclusion

Approved and cleared. Nothing in this diff needs to change. Findings 1 and 2 are worth issues on Ninja6-MC/.github before the check-standards.py skip is removed, since that follow-up is the point at which the remaining gap stops being cheap to reverse; findings 3 and 4 are a commit each.

@BharathASL
BharathASL merged commit 7e03949 into main Sep 9, 2026
4 checks passed
@BharathASL
BharathASL deleted the ci/pin-org-reusable-workflows branch September 9, 2026 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant