Skip to content

rainix-tag-release: make deploy releases push-free (works under branch protection) #338

Description

@thedavidmeister

rainix-tag-release must not push to the consumer branch (deploy repos can't rely on unprotected main)

rainix-autopublish was made push-free in #335/#336, but rainix-tag-release (deploy repos) still does git push origin HEAD:$MAIN in its "Commit the snapshot back to main" step. On a branch-protected main that push is rejected (GH006), so the release fails after publishing — the same failure class datacontract hit. Today it only works because deploy repo mains happen to be unprotected, which is not something to rely on.

Why this is NOT a straight copy of the library fix

The library fix wrote nothing to main because the only pushed content was a cosmetic version line. Deploy repos push real, depended-on content: the frozen src/generated/<version>/ deploy-pin snapshot. Two readers consume it FROM main:

  1. The daily drift sweep — the workflow comment states main carries the current release's pins "so the daily drift sweep has live constants to check."
  2. The repo's own snapshot tests — e.g. ExtrospectDeploySnapshotTest's frozen-record walk reads src/generated/ from the working tree; fs_permissions grants it.

So "just stop pushing" breaks both. The fix has to move the snapshot to main by a protection-compatible path, or redirect those readers.

Current flow (for reference)

Human runs the manual on-chain deploy, then pushes sol-v<x.y.z> on the main tip. The workflow: resolve version from the tag → set foundry.toml version → regenerate+freeze the snapshot (deterministic from bytecode, no chain access) → commit → append-only gate → verify live chain matches the fresh pins → publish to Soldeer → push the release commit to main → GitHub release. Note the tag was made on the PRE-release commit, so today the tag does not even point at the released snapshot.

Options (need a ruling on the release-flow change)

A — Reviewed PR before the tag (recommended). Release becomes: deploy on-chain → open a PR that regenerates+commits the snapshot + version bump → PR CI runs the append-only gate + chain-match verification → human merges (normal protected-merge) → tag sol-v<x.y.z> on the merged commit → workflow only publishes to Soldeer + creates the GitHub release, ZERO branch writes. main gets the snapshot via the reviewed PR (protection-compatible); drift sweep + tests unchanged; the tag points at the actual released content (fixes today's divergence); deploy pins (addresses consumers trust) get human review BEFORE they publish. Cost: release is two steps (merge, then tag) instead of one.

B — Workflow opens a PR instead of pushing. Keep the one-step trigger (human tags, workflow does everything) but replace git push origin HEAD:$MAIN with "push a branch + open a PR"; publish + tag + release still happen immediately from the runner tree. main's snapshot lands when the PR merges. Cost: main (and therefore the drift sweep) lags the publish until a human merges; pins publish unreviewed as they do today.

C — Tag-only, redirect the readers. Workflow tags the release commit and pushes only the tag ref (no branch write); rework the drift sweep and the snapshot tests to read src/generated/<version>/ from the tag/Soldeer zip instead of main. Cost: largest — touches the drift sweep (rain-org-health) and every deploy repo's snapshot tests; main stops accumulating the snapshot history.

Recommendation: A — it is the only option that both keeps every current reader working and reviews deploy pins before they ship, and it mirrors the library principle (content reaches main via reviewed PR; the release workflow is read-only publish + tag). B is the smaller change if the two-step release is unacceptable.

Scope

  • rainix-tag-release.yaml + any helper it calls.
  • The append-only-snapshot and chain-verify steps move to run on the PR (option A) or stay in the workflow (B).
  • RAINIX_SHA advance + the two-commit pattern as usual.
  • Consumer deploy repos: release-process doc update (the new flow). No foundry.toml [external.package] sweep — deploy repos keep their version line by the existing ruling.

Context

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions