name: Release on: push: tags: - "v*" workflow_dispatch: env: CARGO_TERM_COLOR: always jobs: # ── Read version from Cargo.toml ───────────────────────────────────────────── prepare: name: Prepare release tag runs-on: ubuntu-latest outputs: tag: ${{ steps.tag.outputs.tag }} steps: - uses: actions/checkout@v4 - name: Extract version id: tag run: | VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/') echo "tag=v${VERSION}" >> $GITHUB_OUTPUT echo "Release tag: v${VERSION}" # ── Linux stable targets ───────────────────────────────────────────────────── build-linux: name: Build ${{ matrix.name }} needs: prepare runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - target: x86_64-unknown-linux-musl name: linux-amd64 - target: aarch64-unknown-linux-musl name: linux-arm64 steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Cache uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.target }} - name: Install cross run: | curl -sSL \ https://github.com/cross-rs/cross/releases/latest/download/cross-x86_64-unknown-linux-gnu.tar.gz \ | tar xz -C /usr/local/bin cross - name: Build run: cross build --release --target ${{ matrix.target }} - name: Stage binary run: cp target/${{ matrix.target }}/release/leakguard leakguard-${{ matrix.name }} - name: Upload artifact uses: actions/upload-artifact@v4 with: name: leakguard-${{ matrix.name }} path: leakguard-${{ matrix.name }} # ── Windows (native MSVC runner) ───────────────────────────────────────────── build-windows: name: Build windows-amd64 needs: prepare runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: targets: x86_64-pc-windows-msvc - name: Cache uses: Swatinem/rust-cache@v2 - name: Build run: cargo build --release --target x86_64-pc-windows-msvc - name: Stage binary run: cp target/x86_64-pc-windows-msvc/release/leakguard.exe leakguard-windows-amd64.exe - name: Upload artifact uses: actions/upload-artifact@v4 with: name: leakguard-windows-amd64 path: leakguard-windows-amd64.exe # ── macOS ARM64 ─────────────────────────────────────────────────────────────── build-macos: name: Build macos-arm64 needs: prepare runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: targets: aarch64-apple-darwin - name: Cache uses: Swatinem/rust-cache@v2 - name: Build run: cargo build --release --target aarch64-apple-darwin - name: Stage binary run: cp target/aarch64-apple-darwin/release/leakguard leakguard-macos-arm64 - name: Upload artifact uses: actions/upload-artifact@v4 with: name: leakguard-macos-arm64 path: leakguard-macos-arm64 # ── Build Python Wheels ─────────────────────────────────────────────────────── build-wheels: name: Wheel (${{ matrix.target }}) needs: prepare runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu - os: ubuntu-latest target: aarch64-unknown-linux-gnu - os: windows-latest target: x86_64-pc-windows-msvc - os: macos-latest target: universal2-apple-darwin steps: - uses: actions/checkout@v4 - name: Build wheel uses: PyO3/maturin-action@v1 with: target: ${{ matrix.target }} args: --release --out dist manylinux: auto - name: Upload wheel uses: actions/upload-artifact@v4 with: name: wheels-${{ matrix.target }} path: dist/*.whl # ── Publish to PyPI ─────────────────────────────────────────────────────────── publish-pypi: name: Publish to PyPI needs: [prepare, build-wheels] runs-on: ubuntu-latest environment: pypi permissions: id-token: write # required for OIDC trusted publishing steps: - name: Download all wheels uses: actions/download-artifact@v4 with: pattern: wheels-* merge-multiple: true path: dist - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 # ── Create GitHub Release ──────────────────────────────────────────────────── release: name: Create Release needs: [prepare, build-linux, build-windows, build-macos] runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 - name: Download all artifacts uses: actions/download-artifact@v4 with: path: dist merge-multiple: true - name: Show binaries run: ls -lh dist/ - name: Create Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ needs.prepare.outputs.tag }} name: leakguard ${{ needs.prepare.outputs.tag }} generate_release_notes: true body: | ## Install ### via pip (recommended) ```bash pip install leakguard-secret-leaks leakguard check . ``` ### Manual download | Platform | File | |----------|------| | Linux x86_64 | `leakguard-linux-amd64` | | Linux ARM64 | `leakguard-linux-arm64` | | Windows x86_64 | `leakguard-windows-amd64.exe` | | macOS Apple Silicon | `leakguard-macos-arm64` | ```bash chmod +x leakguard-linux-amd64 sudo mv leakguard-linux-amd64 /usr/local/bin/leakguard ``` files: dist/*