feat(update): install-source-aware self-update subcommand (#7) #20
Workflow file for this run
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*.*.*"] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version to build (X.Y.Z), without the leading v. Used for dry-run dispatch." | |
| required: true | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write # create the GitHub Release | |
| id-token: write # OIDC token for npm Trusted Publishing (public npm) | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.target }} | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| CARGO_NET_GIT_FETCH_WITH_CLI: "true" | |
| # Tolerate the reserved Windows name tests/fixtures/contexts/CON.json when | |
| # git validates tree paths during checkout. Combined with the sparse | |
| # checkout below (which never materializes tests/ on disk), this lets the | |
| # win32 job clone. Honored by every git invocation, incl. actions/checkout. | |
| # No-op on Linux/macOS. | |
| GIT_CONFIG_COUNT: "1" | |
| GIT_CONFIG_KEY_0: core.protectNTFS | |
| GIT_CONFIG_VALUE_0: "false" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-24.04 | |
| musl: true | |
| - target: aarch64-unknown-linux-musl | |
| os: ubuntu-24.04-arm | |
| musl: true | |
| - target: aarch64-apple-darwin | |
| os: macos-14 | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| steps: | |
| # Sparse checkout: building the binary only needs the crate sources and the | |
| # root manifests. This also skips tests/fixtures, which contains an upstream | |
| # fixture named CON.json — a reserved device name that git cannot check out | |
| # on Windows (would fail the win32 job at checkout). | |
| - uses: actions/checkout@v4 | |
| with: | |
| sparse-checkout: | | |
| src | |
| benches | |
| - name: Authenticate cargo git fetch (private quire-rs) | |
| shell: bash | |
| run: git config --global url."https://x-access-token:${{ secrets.REGISTRY_TOKEN }}@github.com/".insteadOf "https://github.com/" | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl toolchain | |
| if: matrix.musl | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Cache cargo artifacts | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Build release binary | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Smoke test (--version) | |
| shell: bash | |
| run: | | |
| BIN=target/${{ matrix.target }}/release/quire | |
| [ "${{ runner.os }}" = "Windows" ] && BIN="$BIN.exe" | |
| "$BIN" --version | |
| - name: Stage binary | |
| shell: bash | |
| run: | | |
| mkdir -p "dist/${{ matrix.target }}" | |
| if [ "${{ runner.os }}" = "Windows" ]; then | |
| cp "target/${{ matrix.target }}/release/quire.exe" "dist/${{ matrix.target }}/quire.exe" | |
| else | |
| cp "target/${{ matrix.target }}/release/quire" "dist/${{ matrix.target }}/quire" | |
| fi | |
| - name: Upload binary artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bin-${{ matrix.target }} | |
| path: dist/${{ matrix.target }} | |
| if-no-files-found: error | |
| retention-days: 7 | |
| package: | |
| name: Package + publish | |
| needs: build | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Resolve version | |
| id: ver | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "version=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download all binaries | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| pattern: bin-* | |
| - name: Normalize binary artifact layout | |
| run: | | |
| mkdir -p normalized | |
| for artifact_dir in artifacts/bin-*; do | |
| target="${artifact_dir#artifacts/bin-}" | |
| mkdir -p "normalized/${target}" | |
| cp "${artifact_dir}"/quire* "normalized/${target}/" | |
| done | |
| rm -rf artifacts | |
| mv normalized artifacts | |
| - name: Build release tarballs + checksums | |
| run: | | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| mkdir -p release | |
| cd artifacts | |
| for target in */; do | |
| target="${target%/}" | |
| if [ -f "$target/quire.exe" ]; then | |
| (cd "$target" && zip -q "../../release/quire-${VERSION}-${target}.zip" quire.exe) | |
| else | |
| tar -czf "../release/quire-${VERSION}-${target}.tar.gz" -C "$target" quire | |
| fi | |
| done | |
| cd ../release | |
| sha256sum * > "SHA256SUMS.txt" | |
| ls -la | |
| - name: Create GitHub Release | |
| if: github.event_name == 'push' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release create "${GITHUB_REF_NAME}" release/* \ | |
| --title "${GITHUB_REF_NAME}" \ | |
| --notes "Automated release ${GITHUB_REF_NAME}. See CHANGELOG.md for details." \ | |
| --verify-tag | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" # OIDC Trusted Publishing requires Node >= 22.14 | |
| # OIDC Trusted Publishing needs npm >= 11.5.1. | |
| - name: Upgrade npm for Trusted Publishing | |
| run: npm install -g npm@latest | |
| # Public npm via OIDC: route @agent-ix at registry.npmjs.org with no auth | |
| # token. `npm publish` performs the tokenless OIDC token exchange (the | |
| # id-token: write permission above supplies the GitHub OIDC token). | |
| # Written to $HOME so every `npm publish` (run from each package dir) picks it up. | |
| # Public npm. Steady state is tokenless OIDC (id-token: write above). The | |
| # NPM_TOKEN fallback exists only to BOOTSTRAP: npm requires a package to | |
| # exist before a trusted publisher can be attached, and these 5 packages' | |
| # binaries can only be built by this CI matrix. Add NPM_TOKEN as a repo | |
| # secret for the first release, configure the trusted publishers on | |
| # npmjs.com, then DELETE the secret — every later release uses OIDC. | |
| # provenance=false: this repo is private, where provenance is unsupported. | |
| - name: Configure npm for public npm | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| if [ -n "$NPM_TOKEN" ]; then | |
| printf 'registry=https://registry.npmjs.org/\n@agent-ix:registry=https://registry.npmjs.org/\n//registry.npmjs.org/:_authToken=%s\nprovenance=false\n' "$NPM_TOKEN" > "$HOME/.npmrc" | |
| else | |
| printf 'registry=https://registry.npmjs.org/\n@agent-ix:registry=https://registry.npmjs.org/\nprovenance=false\n' > "$HOME/.npmrc" | |
| fi | |
| - name: Generate per-platform npm packages | |
| run: ARTIFACTS_DIR=artifacts node npm/build-packages.mjs "${{ steps.ver.outputs.version }}" | |
| - name: Publish to public npm | |
| if: github.event_name == 'push' | |
| run: | | |
| set -e | |
| # Platform packages first so the launcher's optionalDependencies resolve. | |
| for pkg in npm/dist/*/; do | |
| echo "publishing $pkg" | |
| (cd "$pkg" && npm publish) | |
| done | |
| echo "publishing launcher" | |
| (cd npm/quire-cli && npm publish) |