Skip to content

feat(release): move the major alias by release instead of by hand - #28

Merged
msalvatti merged 2 commits into
mainfrom
feat/release-process-for-the-major-alias
Aug 8, 2026
Merged

feat(release): move the major alias by release instead of by hand#28
msalvatti merged 2 commits into
mainfrom
feat/release-process-for-the-major-alias

Conversation

@msalvatti

Copy link
Copy Markdown
Member

Makes publishing a change here a deliberate act instead of a side effect of merging.

The problem

Callers reference @v1, and that ref is resolved when the caller runs. Whatever v1 points at is the CI of ~20 repositories.

The README already described the right model β€” "a deliberate v1.x release propagates to every repo" β€” but the operating instruction directly below it was:

git checkout main && git pull && git tag -f v1 && git push -f origin v1

Practice followed the instruction, not the model. v1 became a synonym for main: on 2026-08-07 this repository took eight commits, and each one reached every consuming repository on its next run, with no commit in those repositories for anyone to review.

What changes

release-major-alias.yml β€” on a pushed vN.Y.Z tag, moves vN onto it.

  • Refuses a tag that is not an ancestor of the default branch. Without that, tagging any commit β€” a branch, a fork's merge base β€” would redirect every consumer's CI while bypassing main's protections.
  • Reads the ref back after writing it, so a silent API failure cannot look like a successful release.
  • Creates the alias on the first release of a major, force-updates it after β€” moving forward to an unrelated commit is not a fast-forward.

AGENTS.md β€” the contract, for whoever works here next:

Ref What it is Who moves it
v1.4.2 Immutable release, protected by ruleset Created once, never touched
v1 Moving alias β€” what consumers reference Only the release workflow
main Where work lands, not what consumers run Pull requests

It also records why consumers use the alias rather than a pinned commit, and why third-party actions are the opposite case; and a checklist for changing a reusable workflow β€” including that a caller cannot add steps around a uses: job, which is how harden-runner was silently dropped from three repositories during the CodeQL conversion.

README.md β€” the force-push instruction is replaced by git tag v1.5.0 && git push origin v1.5.0, and the versioning section now says not to pin these references.

Not changed

v*.*.* is already immutable via the protect-release-tags ruleset (non_fast_forward + deletion). v1 stays writable because it has to move β€” the control is that only this workflow moves it, and the tag it moves onto is immutable.

After this merges

v1.0.0 gets cut at the merge commit, which makes the current state an actual release. The alias does not move as a result β€” it already points there.

Callers reference `@v1`, and that ref is resolved when the caller runs. So
whatever `v1` points at is the CI of roughly twenty repositories, and moving it
is a deploy.

The README already described the intended model β€” a deliberate v1.x release
propagating to every repo β€” but the operating instruction right below it was
`git tag -f v1 && git push -f origin v1`. Practice followed the instruction:
`v1` tracked `main`, and on 2026-08-07 eight merges became eight silent deploys
to every consumer, with no commit in those repositories to review.

This closes the gap the other way round, by making the instruction match the
model:

- `release-major-alias.yml` moves `vN` when a `vN.Y.Z` tag is pushed, and
  refuses a tag that is not an ancestor of the default branch β€” otherwise
  tagging any commit could redirect every consumer's CI. It reads the ref back
  after writing, so a silent failure cannot look like a release.
- AGENTS.md states the contract for whoever works here next, including why
  consumers use the alias rather than a pinned commit, and why third-party
  actions are the opposite case.
- The README instruction to force-push `v1` is replaced by the release command.

`v*.*.*` is already immutable by ruleset, so a caller pinning a version keeps
the same bytes forever.

Copilot AI 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.

Pull request overview

Introduces a controlled release mechanism for moving major aliases (e.g. v1) via an automated workflow triggered by immutable vX.Y.Z tags, and updates documentation to align operational practice with that model.

Changes:

  • Adds a release-major-alias.yml workflow to move vN aliases when vN.Y.Z tags are pushed, with safety checks and verification.
  • Adds AGENTS.md to document the alias/tag contract and release process for future maintainers/agents.
  • Updates README.md to remove force-push instructions and clarify versioning/release guidance.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
README.md Reformats tables and updates release/versioning instructions to match the β€œrelease moves alias” model.
AGENTS.md Adds an operational contract for tags/aliases and guidance for safe workflow changes.
.github/workflows/release-major-alias.yml New automation that moves the vN alias based on pushed vN.Y.Z tags, with branch-ancestry verification and read-back validation.

πŸ’‘ Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread README.md
Comment thread .github/workflows/release-major-alias.yml Outdated
msalvatti added a commit to bymaxone/nest-ai-tokens that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-auth that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-cache that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-config that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-core that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-logger that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-notification that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-queue that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-realtime that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
msalvatti added a commit to bymaxone/nest-storage that referenced this pull request Aug 8, 2026
Returns the `bymaxone/.github` references to the moving `@v1` alias.
**Third-party actions stay pinned to a commit** β€” that distinction is
the whole point.

## Why this is a revert

Pinning these was defensible in isolation: Scorecard flags a moving tag,
and GitHub's guidance recommends SHA-pinning without carving out
first-party repositories.

It was still wrong here, for a reason that only shows up at organization
scale:

- **It removes the reason the shared repository exists.** A CI fix is
supposed to land once and reach every repository. Pinned, it reaches
none of them until someone bumps each one.
- **Dependabot treats each reusable workflow path as a separate
dependency.** Ten libraries Γ— ~6 references is **~58 pull requests to
propagate one change**, throttled by `open-pull-requests-limit: 5` per
repository per week.
- **Those pull requests are merged in bulk.** So the review the pinning
was supposed to buy does not actually happen β€” the latency and the noise
are paid for, and the benefit is not collected.

## What replaces it as the control

The gap was never the pinning. It was that `v1` had become a synonym for
`main`: merging published immediately, and on 2026-08-07 eight commits
to the shared repository became eight silent deploys to every consumer.

[`bymaxone/.github#28`](bymaxone/.github#28)
closes that β€” `v1` now moves only when a `vN.Y.Z` tag is pushed, that
tag must be an ancestor of the default branch, and `v*.*.*` is immutable
by ruleset. Publishing is a deliberate act; the alias is what consumers
follow.

## Where pinning is still correct

Unchanged in this pull request, and verified as unchanged:

```
actions/checkout@3d3c42e…      github/codeql-action/*@f205ea1…
actions/setup-node@8207627…    ossf/scorecard-action@2d11466…
pnpm/action-setup@0ebf471…     step-security/harden-runner@bf7454d…
```

Those are outside the organization. That is where the supply-chain risk
lives, and none of them moved.

## Verification

Every touched file parses as YAML; the `uses:` count is unchanged per
file; the third-party pin count is asserted identical before and after;
and no `bymaxone/.github` reference is left on a commit.
Raised in review: the tag filter looked like a regex. Filter patterns here do
support `+` as a quantifier, so the precise pattern was expressible β€” but the
cost of being wrong about that subtlety is a release workflow that never fires
and never says so, which is the worst failure this file can have.

The trigger now errs toward firing (`v*`) and the job rejects what does not
belong. It skips rather than fails, because the alias `v1` also matches `v*`:
it is pushed by this workflow, and failing on it would paint every release red
for doing its job.

Also lists the workflow in the README table, so the release mechanism is
discoverable next to the reusables it publishes.
Copilot AI review requested due to automatic review settings August 8, 2026 10:32

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@msalvatti
msalvatti merged commit 15f15c1 into main Aug 8, 2026
5 checks passed
@msalvatti
msalvatti deleted the feat/release-process-for-the-major-alias branch August 8, 2026 12:08
msalvatti added a commit that referenced this pull request Aug 8, 2026
## Why

Every library whose per-push mutation run exceeds five minutes is moving
to an incremental Stryker run. That is the right trade for a gate on
every push, but it is a trade: an incremental run reuses stored
verdicts, and Stryker's own guidance is that reused verdicts for
**static** mutants can be stale. A score built on reuse is a fast
signal, not the truth β€” so the truth needs a cold run behind it.

That cold run already exists, written once in `nest-auth`. Nine
repositories are about to need it. Copying it would put a 130-line
decision β€” what counts as "the score can have moved", why the job is
pinned to the default branch, why a partial baseline must not be saved β€”
in nine places to drift apart.

## What it fixes that the copy could not

**The caller's workflow file is derived, not hardcoded.** The copy
compares against `gh run list --workflow mutation-full.yml`. A caller
that names its file anything else finds no previous run β€” *forever*, and
**green**, because "no previous run" fails open into running. The
failure mode is a weekly cold run that never skips and never says why.
This reads `github.workflow_ref` instead, so the name is whatever the
caller actually called it.

**The pathspec list is an input with a superset default.** Repositories
differ in which Jest and TypeScript config files they have. A pathspec
that does not exist in the caller matches nothing rather than erroring β€”
verified β€” so one default covers every layout, and a repository with an
unusual one can still override.

## What stays with the caller

The schedule (`on: schedule` cannot live in a reusable), the ceiling,
and the Stryker configuration. Those are genuinely per-repository: the
ceiling is calibrated to a measured cold duration, and the schedules are
staggered so a Monday morning does not start ten cold suites at once.

A caller becomes:

```yaml
name: Mutation (full)
on:
  schedule:
    - cron: '13 3 * * 1'
  workflow_dispatch:
permissions:
  contents: read
  actions: read
jobs:
  full:
    uses: bymaxone/.github/.github/workflows/mutation-full.yml@v1
    with:
      timeout-minutes: 90
```

## Verification

The file parses, declares `workflow_call`, exposes three inputs, and
pins all three third-party actions by SHA. The filename derivation was
checked against both `mutation-full.yml` and a deliberately different
name.

## Sequencing

This does not reach any library on merge. `v1` moves only when a
`vN.Y.Z` tag is pushed β€” the release gate added in #28 β€” and **no
`vN.Y.Z` tag exists yet**, so `v1` currently sits one commit behind
`main`. The callers cannot be opened until a release is cut, and cutting
the first one also exercises `release-major-alias.yml` for the first
time.
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.

2 participants