chore: release v0.2.1 #16
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: 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: Ensure CARGO_HOME and PATH | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| echo "CARGO_HOME=$HOME/.cargo" >> "$GITHUB_ENV" | |
| echo "RUSTUP_HOME=$HOME/.rustup" >> "$GITHUB_ENV" | |
| echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" | |
| - name: Install musl tools (Linux MUSL) | |
| if: matrix.musl == 'true' | |
| shell: bash | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Install cross linkers (Linux ARM gnu) | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| 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: Build | |
| shell: bash | |
| run: | | |
| set -eux | |
| cargo build --release --target ${{ matrix.target }} | |
| - name: Strip (non-Windows) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -eux | |
| BIN="target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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') | |
| shell: bash | |
| 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' | |
| shell: bash | |
| 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/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Generate CHANGELOG from commits with "(closed #N)" | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| CURRENT_TAG="${GITHUB_REF_NAME}" | |
| PREV_TAG="$(git describe --tags --abbrev=0 "${CURRENT_TAG}^" 2>/dev/null || true)" | |
| if [ -n "$PREV_TAG" ]; then | |
| RANGE="${PREV_TAG}..${CURRENT_TAG}" | |
| else | |
| RANGE="${CURRENT_TAG}" | |
| fi | |
| mkdir -p dist | |
| { | |
| echo "# Changelog" | |
| echo | |
| echo "## ${CURRENT_TAG}" | |
| echo | |
| git log ${RANGE} --pretty='%h%x09%s' --no-merges \ | |
| | awk -F'\t' '$2 ~ /\(closed #[0-9]+\)$/ { print "* " $2 " (" $1 ")"}' | |
| echo | |
| } > dist/CHANGELOG.md | |
| cat dist/CHANGELOG.md | |
| - name: Checksums | |
| shell: bash | |
| 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 | |
| body_path: dist/CHANGELOG.md | |
| files: | | |
| dist/* |