name: Release
on:
push:
branches: [main]
paths: [Cargo.toml]
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
CRATE_NAME: zackstrap
BIN_NAME: zackstrap
concurrency:
group: release
cancel-in-progress: false
jobs:
read-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.ver.outputs.version }}
tag: ${{ steps.ver.outputs.tag }}
tag_exists: ${{ steps.ver.outputs.tag_exists }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: ver
run: |
VERSION=$(grep '^version' Cargo.toml | head -1 | cut -d'"' -f2)
TAG="v${VERSION}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "tag_exists=true" >> "$GITHUB_OUTPUT"
else
echo "tag_exists=false" >> "$GITHUB_OUTPUT"
fi
echo "Version: ${VERSION}, Tag: ${TAG}"
verify:
needs: read-version
if: needs.read-version.outputs.tag_exists == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- uses: extractions/setup-just@v2
- run: just release-check
build:
needs: [read-version, verify]
if: needs.read-version.outputs.tag_exists == 'false'
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
cross: true
- target: x86_64-apple-darwin
os: macos-latest
- target: aarch64-apple-darwin
os: macos-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Install cross
if: matrix.cross
run: cargo install cross --locked
- name: Build
run: |
if [[ "${{ matrix.cross }}" == "true" ]]; then
cross build --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi
- name: Package
run: |
cd target/${{ matrix.target }}/release
tar czf "../../../${BIN_NAME}-${{ matrix.target }}.tar.gz" "${BIN_NAME}"
- uses: actions/upload-artifact@v4
with:
name: ${{ env.BIN_NAME }}-${{ matrix.target }}
path: ${{ env.BIN_NAME }}-${{ matrix.target }}.tar.gz
release:
needs: [read-version, build]
if: needs.read-version.outputs.tag_exists == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Generate checksums
run: |
cd artifacts
sha256sum *.tar.gz > SHA256SUMS.txt
cat SHA256SUMS.txt
- name: Create tag
run: |
git tag ${{ needs.read-version.outputs.tag }}
git push origin ${{ needs.read-version.outputs.tag }}
- uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.read-version.outputs.tag }}
generate_release_notes: true
files: |
artifacts/*.tar.gz
artifacts/SHA256SUMS.txt
publish-crate:
needs: [read-version, release]
if: needs.read-version.outputs.tag_exists == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Check if already published
id: check
run: |
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
"https://crates.io/api/v1/crates/${CRATE_NAME}/${{ needs.read-version.outputs.version }}")
if [[ "$STATUS" == "200" ]]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Version already on crates.io — skipping"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish
if: steps.check.outputs.skip == 'false'
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --allow-dirty