release #10
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*'] | |
| permissions: | |
| contents: write | |
| env: | |
| BIN_NAME: rivu | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| ext: tar.gz | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| ext: tar.gz | |
| musl: true | |
| - os: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| ext: tar.gz | |
| - os: ubuntu-latest | |
| target: armv7-unknown-linux-gnueabihf | |
| ext: tar.gz | |
| - os: ubuntu-latest | |
| target: aarch64-unknown-linux-musl | |
| ext: tar.gz | |
| zig: true | |
| - os: ubuntu-latest | |
| target: armv7-unknown-linux-musleabihf | |
| ext: tar.gz | |
| zig: true | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| ext: pkg | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| ext: pkg | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| ext: zip | |
| runs-on: ${{ matrix.os }} | |
| environment: ${{ startsWith(matrix.os, 'macos') && 'release' || '' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl tools (Linux MUSL) | |
| if: matrix.musl == 'true' | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Install cross linkers (Linux ARM gnu) | |
| if: runner.os == 'Linux' | |
| run: | | |
| set -euxo pipefail | |
| case "${{ matrix.target }}" in | |
| aarch64-unknown-linux-gnu) | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu | |
| mkdir -p .cargo | |
| { | |
| echo '[target.aarch64-unknown-linux-gnu]' | |
| echo 'linker = "aarch64-linux-gnu-gcc"' | |
| } >> .cargo/config.toml | |
| ;; | |
| armv7-unknown-linux-gnueabihf) | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf | |
| mkdir -p .cargo | |
| { | |
| echo '[target.armv7-unknown-linux-gnueabihf]' | |
| echo 'linker = "arm-linux-gnueabihf-gcc"' | |
| } >> .cargo/config.toml | |
| ;; | |
| esac | |
| - name: Install zig & cargo-zigbuild (for musl on ARM) | |
| if: matrix.zig == 'true' | |
| run: | | |
| set -eux | |
| sudo apt-get update | |
| sudo apt-get install -y zig | |
| cargo install cargo-zigbuild | |
| - name: Build | |
| run: | | |
| if [ "${{ matrix.zig || '' }}" = "true" ]; then | |
| cargo zigbuild --release --target ${{ matrix.target }} | |
| else | |
| cargo build --release --target ${{ matrix.target }} | |
| fi | |
| - name: Strip (non-Windows) | |
| if: runner.os != 'Windows' | |
| run: | | |
| set -eux | |
| BIN="target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" | |
| if [ "${{ matrix.zig || '' }}" = "true" ]; then | |
| echo "Skipping strip for zig/musl target ${{ matrix.target }}" | |
| exit 0 | |
| fi | |
| case "${{ matrix.target }}" in | |
| aarch64-unknown-linux-gnu) STRIP=aarch64-linux-gnu-strip ;; | |
| armv7-unknown-linux-gnueabihf) STRIP=arm-linux-gnueabihf-strip ;; | |
| x86_64-unknown-linux-musl|x86_64-unknown-linux-gnu) STRIP=strip ;; | |
| aarch64-apple-darwin|x86_64-apple-darwin) STRIP=strip ;; | |
| *) STRIP=strip ;; | |
| esac | |
| command -v "$STRIP" >/dev/null 2>&1 && "$STRIP" "$BIN" || true | |
| - name: Set up keychain and import Developer ID certs (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }} | |
| MACOS_CERT_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }} | |
| run: | | |
| KEYCHAIN=build.keychain | |
| security create-keychain -p "" "$KEYCHAIN" | |
| security default-keychain -s "$KEYCHAIN" | |
| security unlock-keychain -p "" "$KEYCHAIN" | |
| security set-keychain-settings -t 3600 -u "$KEYCHAIN" | |
| echo "$MACOS_CERT_P12" | base64 --decode > cert.p12 | |
| security import cert.p12 -k "$KEYCHAIN" -P "$MACOS_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/productbuild -T /usr/bin/pkgbuild | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" "$KEYCHAIN" | |
| rm -f cert.p12 | |
| - name: Codesign binary (macOS, Developer ID Application) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| MACOS_CERT_IDENTITY: ${{ secrets.MACOS_CERT_IDENTITY }} | |
| run: | | |
| BIN="target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" | |
| codesign --force --timestamp --options runtime --sign "$MACOS_CERT_IDENTITY" "$BIN" | |
| codesign -dv --verbose=2 "$BIN" | |
| - name: Build PKG payload root (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| run: | | |
| BIN="target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" | |
| mkdir -p pkgroot/usr/local/bin | |
| cp "$BIN" pkgroot/usr/local/bin/rivu | |
| chmod 755 pkgroot/usr/local/bin/rivu | |
| mkdir -p scripts | |
| cat > scripts/postinstall << 'EOF' | |
| #!/bin/sh | |
| set -e | |
| FILE="/etc/paths.d/rivu" | |
| if [ ! -f "$FILE" ]; then | |
| echo "/usr/local/bin" > "$FILE" | |
| fi | |
| exit 0 | |
| EOF | |
| chmod +x scripts/postinstall | |
| - name: Create signed component PKG (macOS, Developer ID Installer) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| MACOS_INSTALLER_CERT_IDENTITY: ${{ secrets.MACOS_INSTALLER_CERT_IDENTITY }} | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| PKG_ID="io.rivu.cli" | |
| OUT="rivu-${VERSION}-${{ matrix.target }}.pkg" | |
| pkgbuild \ | |
| --root pkgroot \ | |
| --install-location / \ | |
| --identifier "$PKG_ID" \ | |
| --version "$VERSION" \ | |
| --scripts scripts \ | |
| --ownership recommended \ | |
| --sign "$MACOS_INSTALLER_CERT_IDENTITY" \ | |
| "$OUT" | |
| mkdir -p dist && mv "$OUT" dist/ | |
| pkgutil --check-signature "dist/$OUT" | |
| - name: Notarize PKG (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} | |
| APPLE_API_KEY_P8: ${{ secrets.APPLE_API_KEY_P8 }} | |
| run: | | |
| echo "$APPLE_API_KEY_P8" > AuthKey.p8 | |
| PKG=$(ls dist/*.pkg) | |
| xcrun notarytool submit "$PKG" \ | |
| --key-id "$APPLE_API_KEY_ID" \ | |
| --issuer "$APPLE_API_ISSUER_ID" \ | |
| --key AuthKey.p8 \ | |
| --wait | |
| rm -f AuthKey.p8 | |
| - name: Staple PKG (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| run: | | |
| PKG=$(ls dist/*.pkg) | |
| xcrun stapler staple "$PKG" | |
| xcrun stapler validate "$PKG" | |
| - name: Build Uninstaller PKG (macOS, payload-free) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| MACOS_INSTALLER_CERT_IDENTITY: ${{ secrets.MACOS_INSTALLER_CERT_IDENTITY }} | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| IDENT="$MACOS_INSTALLER_CERT_IDENTITY" | |
| if [ -z "$IDENT" ]; then | |
| IDENT="$(security find-identity -p codesigning -v | awk -F\" '/Developer ID Installer/ {print $2; exit}')" | |
| fi | |
| if [ -z "$IDENT" ]; then | |
| echo "::error::No Developer ID Installer identity found." | |
| exit 1 | |
| fi | |
| mkdir -p scripts-uninstall | |
| cat > scripts-uninstall/postinstall <<'EOF' | |
| #!/bin/sh | |
| set -e | |
| /bin/rm -f /usr/local/bin/rivu | |
| /bin/rm -f /etc/paths.d/rivu | |
| /usr/sbin/pkgutil --forget io.rivu.cli || true | |
| exit 0 | |
| EOF | |
| chmod +x scripts-uninstall/postinstall | |
| UNPKG="rivu-uninstall-${VERSION}-${{ matrix.target }}.pkg" | |
| pkgbuild \ | |
| --nopayload \ | |
| --identifier "io.rivu.cli.uninstall" \ | |
| --version "$VERSION" \ | |
| --scripts scripts-uninstall \ | |
| --sign "$IDENT" \ | |
| "$UNPKG" | |
| mkdir -p dist && mv "$UNPKG" dist/ | |
| - name: Notarize Uninstaller PKG (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| env: | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} | |
| APPLE_API_KEY_P8: ${{ secrets.APPLE_API_KEY_P8 }} | |
| run: | | |
| set -euo pipefail | |
| echo "$APPLE_API_KEY_P8" > AuthKey.p8 | |
| UPKG=$(ls dist/*uninstall*.pkg) | |
| xcrun notarytool submit "$UPKG" \ | |
| --key-id "$APPLE_API_KEY_ID" \ | |
| --issuer "$APPLE_API_ISSUER_ID" \ | |
| --key AuthKey.p8 \ | |
| --wait | |
| rm -f AuthKey.p8 | |
| - name: Staple Uninstaller PKG (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| run: | | |
| set -euo pipefail | |
| UPKG=$(ls dist/*uninstall*.pkg) | |
| xcrun stapler staple "$UPKG" | |
| xcrun stapler validate "$UPKG" | |
| - name: Package (tar.gz) | |
| if: matrix.ext == 'tar.gz' | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| BIN="target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" | |
| PKG="${{ env.BIN_NAME }}-${VERSION}-${{ matrix.target }}.tar.gz" | |
| mkdir -p staging && cp "$BIN" staging/ | |
| tar -czf "$PKG" -C staging "${{ env.BIN_NAME }}" | |
| rm -rf staging | |
| mkdir -p dist && mv "$PKG" dist/ | |
| - name: Package (zip) | |
| if: matrix.ext == 'zip' | |
| shell: pwsh | |
| run: | | |
| $version = $env:GITHUB_REF_NAME.TrimStart('v') | |
| $bin = "target/${{ matrix.target }}/release/${{ env.BIN_NAME }}.exe" | |
| $pkg = "${{ env.BIN_NAME }}-$version-${{ matrix.target }}.zip" | |
| New-Item -ItemType Directory -Force -Path dist | Out-Null | |
| Compress-Archive -Path $bin -DestinationPath "dist/$pkg" | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: artifacts-${{ matrix.target }} | |
| path: dist/* | |
| release: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Checksums | |
| run: | | |
| cd dist | |
| sha256sum * > SHA256SUMS.txt || shasum -a 256 * > SHA256SUMS.txt | |
| cd - | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| draft: false | |
| files: | | |
| dist/* |