Release #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: ["v*.*.*"] | |
| # Manual trigger: pick a version and (by default) do a dry run that builds | |
| # every artifact without publishing a GitHub Release. Uncheck "dry run" to cut | |
| # a real release (which also creates the tag). | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version to release, e.g. v1.2.3 (must match Cargo.toml)" | |
| required: true | |
| type: string | |
| dry_run: | |
| description: "Dry run: build artifacts but do not publish a release or tag" | |
| type: boolean | |
| default: true | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # Resolve the version + dry-run flag from whichever trigger fired, and refuse | |
| # to proceed unless the version matches the crate version in Cargo.toml (the | |
| # binary stamps its own version from Cargo.toml, so a mismatch ships a lie). | |
| setup: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.resolve.outputs.version }} | |
| dry_run: ${{ steps.resolve.outputs.dry_run }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: resolve | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| raw='${{ inputs.version }}' | |
| dry='${{ inputs.dry_run }}' | |
| else | |
| raw="$GITHUB_REF_NAME" | |
| dry="false" | |
| fi | |
| version="v${raw#v}" # normalize to a single leading 'v' | |
| crate="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"(.*)".*/\1/')" | |
| echo "version=$version crate=$crate dry_run=$dry" | |
| if ! echo "$version" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then | |
| echo "::error::version '$version' must look like vX.Y.Z"; exit 1 | |
| fi | |
| if [ "${version#v}" != "$crate" ]; then | |
| echo "::error::version $version does not match Cargo.toml version $crate"; exit 1 | |
| fi | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "dry_run=$dry" >> "$GITHUB_OUTPUT" | |
| # Slim release: the static `srcdump` binary, one per target. taiki-e runs in | |
| # dry-run mode purely as a cross-compiling builder; the actual release upload | |
| # happens later in `publish`. The built archive is passed to downstream jobs | |
| # as a workflow artifact. | |
| slim: | |
| name: slim ${{ matrix.target }} | |
| needs: setup | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: aarch64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: aarch64-apple-darwin | |
| os: macos-14 | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: taiki-e/upload-rust-binary-action@v1 | |
| with: | |
| bin: srcdump | |
| target: ${{ matrix.target }} | |
| archive: srcdump-$tag-$target | |
| ref: refs/tags/${{ needs.setup.outputs.version }} | |
| dry-run: true # always build-only here; `publish` does the upload | |
| - name: Collect the slim archive | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # taiki-e builds `srcdump-<version>-<target>.{tar.gz,zip}`; find it | |
| # wherever it landed and stage it for upload. | |
| mkdir -p out | |
| find . -type f -name "srcdump-${{ needs.setup.outputs.version }}-${{ matrix.target }}.*" \ | |
| -exec cp {} out/ \; | |
| ls -la out | |
| [ -n "$(ls -A out)" ] || { echo "::error::no slim archive was produced"; exit 1; } | |
| - name: Stash slim archive as a workflow artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: slim-${{ matrix.target }} | |
| if-no-files-found: error | |
| path: out/* | |
| # Full release: srcdump + uv + a self-contained, offline-installable | |
| # uv_angr.zip, built natively per-OS by scripts/build_release.py. The bundled | |
| # srcdump is the exact static (musl, where applicable) slim binary built | |
| # above, reused as-is for maximum compatibility — so this job needs no Rust | |
| # toolchain. | |
| full: | |
| name: full ${{ matrix.target }} | |
| needs: [setup, slim] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| slim: x86_64-unknown-linux-musl | |
| ext: tar.gz | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-24.04-arm | |
| slim: aarch64-unknown-linux-musl | |
| ext: tar.gz | |
| - target: aarch64-apple-darwin | |
| os: macos-14 | |
| slim: aarch64-apple-darwin | |
| ext: tar.gz | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| slim: x86_64-pc-windows-msvc | |
| ext: zip | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.x" | |
| - name: Install uv (with cache) | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| enable-cache: true | |
| - name: Fetch the slim srcdump for this platform | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: slim-${{ matrix.slim }} | |
| path: slim | |
| - name: Unpack the slim binary | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cd slim | |
| if [ "${{ matrix.ext }}" = "zip" ]; then | |
| unzip -o srcdump-*.zip | |
| else | |
| tar xzf srcdump-*.tar.gz | |
| fi | |
| - name: Build full release | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| bin=$(find slim -type f \( -name srcdump -o -name srcdump.exe \) | head -1) | |
| [ -n "$bin" ] || { echo "slim srcdump not found in artifact"; exit 1; } | |
| [ "${{ runner.os }}" = "Windows" ] || chmod +x "$bin" | |
| python scripts/build_release.py \ | |
| --full-only --srcdump "$bin" --archive-version "${{ needs.setup.outputs.version }}" | |
| - name: Stash full archive as a workflow artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: full-${{ matrix.target }} | |
| if-no-files-found: error | |
| path: dist/*-full.* | |
| # Publish: only for real (non-dry) runs. Gather every slim + full artifact and | |
| # create the GitHub Release (and its tag, for manual runs) with all of them. | |
| publish: | |
| needs: [setup, slim, full] | |
| if: needs.setup.outputs.dry_run != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: release | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: ls -la release | |
| - name: Build release notes with checksums | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| { | |
| echo "### SHA-256 checksums" | |
| echo | |
| echo '```' | |
| ( cd release && sha256sum * ) | |
| echo '```' | |
| } > notes.md | |
| cat notes.md | |
| - name: Create the GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.setup.outputs.version }} | |
| body_path: notes.md | |
| files: release/* | |
| fail_on_unmatched_files: true | |
| token: ${{ secrets.GITHUB_TOKEN }} |