Skip to content

Decouple GitHub release publication from deployment approvals - #3149

Draft
UnArbosFive wants to merge 1 commit into
mainfrom
automatic-release-publication
Draft

Decouple GitHub release publication from deployment approvals#3149
UnArbosFive wants to merge 1 commit into
mainfrom
automatic-release-publication

Conversation

@UnArbosFive

Copy link
Copy Markdown
Contributor

Summary

  • Add a trusted control-plane detector for finalized mainnet runtime identity.
  • Add an independently gated reconciler that finalizes GitHub releases and updates the mainnet mirror after finalized-runtime and artifact verification.
  • Remove GitHub release/mirror mutation from the approval-gated watcher while preserving PyPI, crates.io, and production website approvals.
  • Make Docker, crates, and website publication independently retryable with immutable per-channel completion receipts.

Behavior

reconcile-mainnet-release.yml polls on the existing ten-minute cadence and is disabled unless both conditions hold:

  • the workflow ref is refs/heads/main; and
  • RELEASE_METADATA_AUTOMATION_ENABLED == 'true'.

The detector validates finalized runtime bytes, the exact lightweight v<spec> tag and main ancestry, and trusted release-train artifact provenance. Finalization is ordered as:

  1. verify the exact artifact;
  2. re-read finalized identity;
  3. update and read back the protected mainnet ref through the dedicated App token;
  4. re-read finalized identity;
  5. upload all five required runtime assets;
  6. promote the prerelease.

Already-final matching releases are verified without rewriting. Stale finalized identities stop before mutation.

The existing watcher retains its schedule, concurrency group, publish-sdk environment, crates and website mainnet environments, PyPI trusted publishing, crates.io publication, Vercel deployment, and automatic Docker dispatch behavior. Python state is isolated from non-Python channels. Docker, crates, and website receipts are immutable release assets named publication-<channel>.json; failed or partial channels remain retryable.

Verification

Offline checks run successfully:

PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s .github/scripts -p 'test_mainnet_release_state.py'
Ran 4 tests ... OK

PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s .github/scripts -p 'test_release_publication_state.py'
Ran 17 tests ... OK

Additional checks:

  • Both workflow files parse with PyYAML.
  • New Python scripts compile with py_compile.
  • git diff --check passes.
  • An offline fake-GitHub smoke harness executed the actual extracted publication command sequence and recorded verify -> mirror update/read-back -> asset upload -> final promotion; the already-final retry performed zero writes.
  • No live workflow, deployment, chain transaction, registry publication, or production website operation was performed.

Preserved authorization boundaries

This PR does not remove or change PyPI, crates.io, production-site, or Docker authorization behavior. It only removes the redundant generic mainnet approval from GitHub metadata finalization and mirror synchronization.

Activation contract — do not merge until ready

Provisioning and activation are intentionally not part of this PR. Before merging, a separately authorized cutover must:

  1. Create and install a dedicated GitHub App named subtensor-release-metadata on this repository only, with Contents read/write, mandatory Metadata read, and no webhooks.
  2. Add RELEASE_METADATA_APP_ID and RELEASE_METADATA_APP_PRIVATE_KEY to a new release-metadata environment restricted to main, with no reviewers or wait timer and no signing, registry, or Vercel credentials.
  3. Create the active mainnet-only mirror ruleset with the existing update/creation/deletion/non-fast-forward restrictions, retaining the DeployKey bypass and adding the dedicated App Integration bypass; only then remove mainnet from network-branch-mirrors (CI only).
  4. Set RELEASE_METADATA_AUTOMATION_ENABLED=true only after the above controls are in place.

There is deliberately no fallback to the shared mirror key, a PAT, or an unprotected environment. Keep the variable unset and do not merge/activate this PR until the provisioning and cutover are ready.

@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
subtensor Ready Ready Preview Sep 9, 2026 4:57pm UTC

Request Review

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🛡️ AI Review — Skeptic (security review)

VERDICT: SAFE

LOW contributor risk: repository admin with substantive merged history; young account noted, no listed Gittensor association. automatic-release-publication → main.

Reviewed all six changed files and the artifact-verification and publication paths. No AI review trust files changed; no prior Skeptic findings exist.

Checks passed: git diff --check 67dcf7f791dc495064c293f080a0702cb433e51e HEAD and git diff --check. git status --short was clean. actionlint was unavailable. No PR code, builds, or tests were executed.

Findings

No findings.

Conclusion

No malicious behavior or concrete security vulnerability found. Metadata automation requires explicit activation on main, validates release identity and artifact provenance, and preserves the package and website approval environments.


🔍 AI Review — Auditor (domain review)

VERDICT: 👎

Repository admin with substantial merged history; young account noted. Gittensor: UNKNOWN, with no trusted-list match.

The independent metadata reconciler preserves the documented authorization boundaries, but downstream publication has two regressions.

Compared the locally available implementation of #3059: This PR is the better candidate. Recommend closing #3059 after addressing the approval-blocking issue below. This PR provides broader reconciliation and receipt-based retry handling; #3059's supersession handling remains useful for downstream publishers.

Checks passed: git diff --check 67dcf7f791dc495064c293f080a0702cb433e51e HEAD, git diff --check, and git status --short (clean). actionlint was unavailable. No builds or tests were run; no files were modified.

Findings

Sev File Finding
HIGH .github/workflows/watch-mainnet-release.yml:503 Point the attestation action at the relocated distributions inline
HIGH .github/workflows/watch-mainnet-release.yml:588 Check completion receipts before entering approval-gated jobs inline

Conclusion

Fix the Python attestation path and check completion receipts before requesting environment approval. Both issues prevent the intended publication behavior.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

with:
pattern: core-dist-*
path: dist
path: release-src/dist

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Point the attestation action at the relocated distributions

At .github/workflows/watch-mainnet-release.yml:503, core distributions move to release-src/dist, and the SDK build now writes there too. However, the astral-sh/attest-action step at line 545 still uses its default dist/* input relative to the workspace root. The preceding steps' working-directory settings do not carry over to a uses step. Consequently, the release artifacts are not attested, breaking stable publication or its mandatory provenance verification. Configure the attestation action's artifact input to select release-src/dist/* and verify that attestations are created alongside the files consumed by uv publish.

Comment on lines +584 to +588
needs: check
if: >-
github.ref == 'refs/heads/main' &&
needs.check.result == 'success' &&
needs.check.outputs.eligible == 'true'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Check completion receipts before entering approval-gated jobs

At .github/workflows/watch-mainnet-release.yml:584-588, crates publication runs for every eligible finalized release, even when its receipt already exists; website publication has the same condition at lines 780-784. Receipt checks occur inside the mainnet environment jobs, so GitHub requires approval before discovering that both jobs should skip. After a successful publication, the next ten-minute poll therefore requests redundant approvals and holds the workflow-wide watch-mainnet-release concurrency lock. Leaving these no-op approvals pending blocks subsequent watcher runs, including Docker retries and publication for newer runtimes. Check receipts in an ungated detection job and use per-channel needed outputs in the job conditions, retaining the in-job recheck for races.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👎

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