diff --git a/.github/workflows/rainix-tag-release.yaml b/.github/workflows/rainix-tag-release.yaml index 7406607..a3a9375 100644 --- a/.github/workflows/rainix-tag-release.yaml +++ b/.github/workflows/rainix-tag-release.yaml @@ -56,9 +56,10 @@ on: default: sol-v snapshot-generate-cmd: description: >- - Command that regenerates the deploy-pin snapshot from the (deterministic) bytecode into src/generated//, DEPLOY_TAG and any pointer libs, then formats. Run after [package].version is set to the release version, so the generated tag matches it. e.g. `forge script ./script/BuildPointers.sol && forge fmt`. - required: true + Command that cuts the release: it regenerates the rolling `src/generated/candidate/` pins from the current source and freezes a copy of them as `src/generated//`, in that order and in one call, then formats. `BuildScript.cutRelease()` is that call, so the default is the whole of it for a deploy repo whose `script/Build.sol` extends `BuildScript` and such a repo passes nothing. Run after `[package].version` is set to the release version, so the tag the freeze derives from it is the one being released. + required: false type: string + default: 'forge script ./script/Build.sol --sig "cutRelease()" && forge fmt' test-cmd: description: >- Pre-publish verification gate. Run against the regenerated snapshot; for a deploy repo this is the fork suite that reads the live chain and asserts it matches the fresh pins, so a release that snapshots addresses the chain does not actually carry fails loud BEFORE publishing. Default `forge test`. @@ -196,11 +197,24 @@ jobs: echo "::error::foundry.toml has no [package] version line to set to ${VERSION}" >&2 exit 1 } - - name: Regenerate the deploy-pin snapshot - # Deterministic: the pins are computed from bytecode (address = f(bytecode) - # under CREATE2), so this needs no chain access and produces the exact - # src/generated// the release publishes and commits. - run: nix develop github:rainlanguage/rainix/${{ env.RAINIX_SHA }}#sol-shell -c bash -c '${{ inputs.snapshot-generate-cmd }}' + - name: Cut the release snapshot + # One call regenerates the rolling src/generated/candidate/ pins and + # freezes a copy of them as src/generated//, so there is no point + # between the two at which the record and the pins the release publishes + # can disagree. Deterministic: the pins are computed from bytecode + # (address = f(bytecode) under CREATE2), so this needs no chain access and + # produces the exact snapshot the release publishes and commits. The + # ordering, the version read, the append-only refusal and the guards + # around them all live in that call — LibRainDeploySnapshot.freeze, via + # BuildScript.cutRelease(). + env: + # Via env, not interpolated into the script body: a workflow input + # spliced into `run:` text is a template-injection surface. The + # expansion is one word, which bash then reads as the script. + SNAPSHOT_GENERATE_CMD: ${{ inputs.snapshot-generate-cmd }} + # `set -euo pipefail` so a command written as `a; b` cannot hide a's + # failure behind b's success. + run: nix develop github:rainlanguage/rainix/${{ env.RAINIX_SHA }}#sol-shell -c bash -c "set -euo pipefail; $SNAPSHOT_GENERATE_CMD" - name: Commit the release snapshot # Commit BEFORE the append-only gate and Soldeer push so both operate on a # clean, inspectable tree. The commit is what lands on main below.