name: Release
on:
push:
branches: [main]
env:
CARGO_TERM_COLOR: always
BINARY_NAME: pass-ssh-unpack
jobs:
check-version:
name: Check if release needed
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
version: ${{ steps.check.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for new version
id: check
run: |
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
TAG="v$VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists, skipping release"
echo "should_release=false" >> $GITHUB_OUTPUT
else
echo "Tag $TAG does not exist, proceeding with release"
echo "should_release=true" >> $GITHUB_OUTPUT
fi
create-tag:
name: Create tag
needs: check-version
if: needs.check-version.outputs.should_release == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Create and push tag
run: |
TAG="v${{ needs.check-version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
build:
name: Build ${{ matrix.name }}
needs: [check-version, create-tag]
if: needs.check-version.outputs.should_release == 'true'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
name: linux-x64
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
name: linux-arm64
cross: true
- target: x86_64-apple-darwin
os: macos-latest
archive: tar.gz
name: macos-x64
- target: aarch64-apple-darwin
os: macos-latest
archive: tar.gz
name: macos-arm64
- target: x86_64-pc-windows-msvc
os: windows-latest
archive: zip
name: windows-x64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross (Linux ARM64)
if: matrix.cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Build (cross)
if: matrix.cross
run: cross build --release --target ${{ matrix.target }}
- name: Build (native)
if: ${{ !matrix.cross }}
run: cargo build --release --target ${{ matrix.target }}
- name: Prepare artifacts (Unix)
if: matrix.os != 'windows-latest'
run: |
cd target/${{ matrix.target }}/release
tar -czvf ../../../${{ env.BINARY_NAME }}-${{ matrix.name }}.tar.gz ${{ env.BINARY_NAME }}
cd ../../..
shasum -a 256 ${{ env.BINARY_NAME }}-${{ matrix.name }}.tar.gz > ${{ env.BINARY_NAME }}-${{ matrix.name }}.tar.gz.sha256
- name: Prepare artifacts (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
cd target/${{ matrix.target }}/release
Compress-Archive -Path "${{ env.BINARY_NAME }}.exe" -DestinationPath "../../../${{ env.BINARY_NAME }}-${{ matrix.name }}.zip"
cd ../../..
$hash = (Get-FileHash -Algorithm SHA256 "${{ env.BINARY_NAME }}-${{ matrix.name }}.zip").Hash.ToLower()
"$hash ${{ env.BINARY_NAME }}-${{ matrix.name }}.zip" | Out-File -Encoding utf8 "${{ env.BINARY_NAME }}-${{ matrix.name }}.zip.sha256"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.BINARY_NAME }}-${{ matrix.name }}
path: |
${{ env.BINARY_NAME }}-${{ matrix.name }}.*
release:
name: Create Draft Release
needs: [check-version, build]
if: needs.check-version.outputs.should_release == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get merged PR info
id: pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Get the PR that was merged with this commit
PR_JSON=$(gh pr list --state merged --base main --json number,title,body --limit 1 --search "$(git rev-parse HEAD)")
if [ -z "$PR_JSON" ] || [ "$PR_JSON" = "[]" ]; then
# Fallback: get most recently merged PR to main
PR_JSON=$(gh pr list --state merged --base main --json number,title,body --limit 1)
fi
PR_TITLE=$(echo "$PR_JSON" | jq -r '.[0].title // empty')
PR_BODY=$(echo "$PR_JSON" | jq -r '.[0].body // empty')
# Use PR title or fallback to version
if [ -n "$PR_TITLE" ]; then
echo "title=$PR_TITLE" >> $GITHUB_OUTPUT
else
echo "title=v${{ needs.check-version.outputs.version }}" >> $GITHUB_OUTPUT
fi
# Write body to file to handle multiline content
if [ -n "$PR_BODY" ]; then
echo "$PR_BODY" > pr_body.md
else
echo "Release v${{ needs.check-version.outputs.version }}" > pr_body.md
fi
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Create draft release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.check-version.outputs.version }}
name: ${{ steps.pr.outputs.title }}
body_path: pr_body.md
draft: true
files: artifacts/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}