name: release # Builds the deployable runtime WASM blobs, publishes their authorize_upgrade # hashes, and signs the artifacts. A runtime upgrade on a fund-holding chain must be # verifiable: anyone can rebuild from this tag with the pinned toolchain (1.96.0, # rust-toolchain.toml) + the committed Cargo.lock and compare the blake2-256 hash to # what governance authorizes. # # NOTE: this is pinned-toolchain reproducibility (deterministic given the same # toolchain + lockfile + flags), not yet fully hermetic. srtool has no Rust 1.96 # image yet (latest is 1.93); a hermetic srtool/custom-container step will be added # when available. Tracked in the release-process issue. on: push: tags: - "v*" - "runtime-*" workflow_dispatch: inputs: ref: description: "Git ref to build (defaults to the triggering ref)" required: false permissions: contents: write # create the GitHub release id-token: write # build-provenance attestation attestations: write # build-provenance attestation concurrency: group: release-${{ github.ref }} cancel-in-progress: false env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: "0" jobs: build-runtime: # Pinned to one specific runner (not the whole substrate-build pool): these # builds aren't hermetic yet (pending srtool), and the self-hosted fleet # doesn't share a common absolute install path, so which runner picks up # the job changes the resulting WASM hash even for identical source. Fixing # the runner fixes the path, so the published hash is reproducible by # rebuilding at the same path on the same box until srtool lands. runs-on: [self-hosted, dks-runner-1] strategy: fail-fast: false matrix: # Mainnet relay + system teyrchains. The deployable on-chain artifacts. runtime: - pezkuwichain-runtime - asset-hub-pezkuwichain-runtime - people-pezkuwichain-runtime steps: - uses: actions/checkout@v7 with: ref: ${{ github.event.inputs.ref || github.ref }} - name: Toolchain & targets run: | rustup show rustup component add rust-src rustup target add wasm32v1-none wasm32-unknown-unknown - name: Build deployable runtime WASM (release, locked) run: cargo build --release --locked -p ${{ matrix.runtime }} - name: Locate WASM and compute upgrade hashes id: wasm run: | set -euo pipefail # The compact+compressed blob is the artifact that goes on-chain. # Some runtimes (the relay's build.rs, in particular) also emit a # `fast-runtime`-feature devnet variant (fast_runtime_binary.rs.*) in # the same wbuild dir for local/zombienet testing — never pick that # one up here. Fail loudly on anything else ambiguous rather than # silently taking whichever file a bare `find | head -1` returns # first (directory order is not guaranteed). wbuild_dir="target/release/wbuild/${{ matrix.runtime }}" mapfile -t candidates < <(find "$wbuild_dir" -maxdepth 1 \ -name '*.compact.compressed.wasm' ! -name 'fast_runtime_binary*') if [ "${#candidates[@]}" -eq 0 ]; then echo "::error::no compressed WASM found for ${{ matrix.runtime }}"; exit 1 fi if [ "${#candidates[@]}" -gt 1 ]; then echo "::error::ambiguous compressed WASM candidates for ${{ matrix.runtime }}: ${candidates[*]}"; exit 1 fi wasm="${candidates[0]}" out="artifacts"; mkdir -p "$out" base="${{ matrix.runtime }}" cp "$wasm" "$out/${base}.compact.compressed.wasm" # blake2-256 is the hash governance authorizes (authorize_upgrade / proposal hash). b2=$(b2sum -l 256 "$wasm" | cut -d' ' -f1) sha=$(sha256sum "$wasm" | cut -d' ' -f1) size=$(stat -c%s "$wasm") { echo "### ${base}" echo "" echo "| field | value |" echo "|---|---|" echo "| commit | \`${GITHUB_SHA}\` |" echo "| toolchain | \`$(rustc --version)\` |" echo "| size (bytes) | ${size} |" echo "| blake2-256 (authorize_upgrade) | \`0x${b2}\` |" echo "| sha256 | \`${sha}\` |" echo "" } > "$out/${base}.digest.md" echo "wasm=$out/${base}.compact.compressed.wasm" >> "$GITHUB_OUTPUT" echo "blake2_256=0x${b2}" >> "$GITHUB_OUTPUT" - name: Attest build provenance (SLSA) uses: actions/attest-build-provenance@v4 with: subject-path: ${{ steps.wasm.outputs.wasm }} - uses: actions/upload-artifact@v7 with: name: ${{ matrix.runtime }} path: artifacts/* if-no-files-found: error publish: needs: build-runtime runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v8 with: path: dl - name: Assemble release notes run: | set -e mkdir -p release find dl -name '*.compact.compressed.wasm' -exec cp {} release/ \; echo "# PezkuwiChain runtimes — ${GITHUB_REF_NAME}" > NOTES.md echo "" >> NOTES.md echo "Verify: rebuild this tag with the pinned toolchain (rust-toolchain.toml)" >> NOTES.md echo "and committed Cargo.lock, then compare the blake2-256 below to the hash" >> NOTES.md echo "authorized on-chain (\`system.authorizeUpgrade\`)." >> NOTES.md echo "" >> NOTES.md cat $(find dl -name '*.digest.md' | sort) >> NOTES.md - name: Publish GitHub release uses: softprops/action-gh-release@v3 with: body_path: NOTES.md files: release/* draft: true # human review before publishing a fund-critical artifact fail_on_unmatched_files: true