name: CD
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
ACTIONS_RUNTIME_TOKEN: dummy
CARGO_TERM_COLOR: always
jobs:
artifact:
runs-on: ${{ matrix.os }}
continue-on-error: false
permissions:
contents: read
strategy:
matrix:
include:
- os: macos-latest
target: x86_64-apple-darwin
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: macos-latest
target: aarch64-apple-darwin
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with:
persist-credentials: false
- uses: Swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae with:
cache-on-failure: true
- name: Setup Rust
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 with:
toolchain: nightly
targets: ${{ matrix.target }}
- name: Add target std to the pinned toolchain
env:
TARGET: ${{ matrix.target }}
run: |
rustup show
rustup target add "$TARGET"
- name: Add x86_64-unknown-linux-musl target
if: matrix.target == 'x86_64-unknown-linux-musl'
run: |
rustup target add x86_64-unknown-linux-musl
sudo apt-get update && sudo apt-get install -y musl-tools
- name: Install Dependencies for musl Target
if: matrix.target == 'x86_64-unknown-linux-musl'
run: |
sudo apt-get update
sudo apt-get install -y musl-tools musl-dev perl make pkg-config libssl-dev
# Set up environment for musl compilation
echo "CC_x86_64_unknown_linux_musl=musl-gcc" >> $GITHUB_ENV
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc" >> $GITHUB_ENV
- name: Install Dependencies for Linux Target
if: matrix.target == 'x86_64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev
- name: Build for target
run: |
cargo build \
-Z unstable-options \
--profile release-with-debug \
--artifact-dir bin \
--target ${{ matrix.target }}
- name: Upload and compress artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: git-ai-${{ matrix.target }}
if-no-files-found: error
path: bin/git-*
release:
runs-on: ubuntu-latest
needs: artifact
permissions:
contents: write
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
- name: Setup Rust
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 with:
toolchain: nightly
- name: Configure git user name
env:
GH_ACTOR: ${{ github.actor }}
run: git config user.name "$GH_ACTOR"
- name: Configure git email
env:
GH_ACTOR: ${{ github.actor }}
run: git config user.email "${GH_ACTOR}@users.noreply.github.com"
- name: Determine version from Cargo.toml
id: app
run: echo "version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*\"([^\"]+)\".*/\1/')" >> "$GITHUB_OUTPUT"
- name: Check whether this version is already released
id: check
env:
APP_VERSION: ${{ steps.app.outputs.version }}
run: |
if git ls-remote --tags origin "refs/tags/v${APP_VERSION}" | grep -q .; then
echo "release=false" >> "$GITHUB_OUTPUT"
echo "v${APP_VERSION} already released; skipping publish."
else
echo "release=true" >> "$GITHUB_OUTPUT"
fi
- name: Publish to crates.io
if: steps.check.outputs.release == 'true' && github.ref == 'refs/heads/main'
run: cargo publish
- name: Verify packaging (dry run)
if: github.ref != 'refs/heads/main'
run: cargo publish --dry-run
- name: Tag and push the release tag
if: steps.check.outputs.release == 'true' && github.ref == 'refs/heads/main'
env:
APP_VERSION: ${{ steps.app.outputs.version }}
run: |
git tag "v${APP_VERSION}"
git push origin "v${APP_VERSION}"
- name: Download all artifacts
env:
RUN_ID: ${{ github.run_id }}
run: gh run download "$RUN_ID"
- name: Zip each downloaded directory
run: |
for dir in $(ls -d git-ai-*); do
tar -czf ${dir}.tar.gz ${dir}
done
- name: Uploads compressed artifacts
if: steps.check.outputs.release == 'true' && github.ref == 'refs/heads/main'
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 with:
tag_name: v${{ steps.app.outputs.version }}
fail_on_unmatched_files: true
files: git-ai-*.tar.gz