🔧 Reorganize Cargo.toml structure and expand keywords #126
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
# This workflow handles continuous integration and deployment for the Git-Iris project. | |
# It runs tests and builds for all pushes, and creates releases for tagged pushes. | |
name: CI/CD | |
on: | |
push: | |
branches: | |
- main # Trigger on pushes to main branch | |
tags: | |
- "v*.*.*" # Trigger on version tags | |
pull_request: | |
branches: | |
- main # Trigger on pull requests to main branch | |
jobs: | |
# This job runs for all pushes and pull requests | |
build-and-test: | |
name: 🧪 Build & Test (${{ matrix.build }}) | |
runs-on: ${{ matrix.os }} | |
strategy: | |
matrix: | |
include: | |
- build: linux-amd64 | |
os: ubuntu-latest | |
target: x86_64-unknown-linux-gnu | |
cmd: cargo | |
steps: | |
- name: 📥 Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🦀 Install Rust | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
targets: ${{ matrix.target }} | |
- name: 📦 Rust cache | |
uses: Swatinem/rust-cache@v2 | |
with: | |
# Let action generate cache keys automatically | |
workspaces: ". -> target" | |
- name: 🔨 Build | |
run: | | |
echo "::group::Building Git-Iris (${{ matrix.build }})" | |
${{ matrix.cmd }} build --verbose --locked --target ${{ matrix.target }} | |
echo "::endgroup::" | |
- name: 🧪 Run tests | |
run: | | |
echo "::group::Running tests (${{ matrix.build }})" | |
${{ matrix.cmd }} test --verbose --locked --target ${{ matrix.target }} | |
echo "::endgroup::" | |
# Test Docker image building and functionality | |
docker-build-and-test: | |
name: 🐳 Docker Build & Test | |
runs-on: ubuntu-latest | |
needs: build-and-test | |
env: | |
IMAGE_NAME: git-iris-test | |
steps: | |
- name: 📥 Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🔍 Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: 🔨 Build Docker image | |
working-directory: ./docker | |
run: | | |
echo "::group::Building Docker image" | |
./build.sh $IMAGE_NAME | |
echo "::endgroup::" | |
- name: 🧪 Test Docker image | |
working-directory: ./docker | |
run: | | |
echo "::group::Testing Docker image" | |
# Run tests without auto-commit to avoid permission issues in CI | |
CI=true ./test-image.sh $IMAGE_NAME | |
echo "::endgroup::" | |
# The following jobs only run on tag pushes (i.e., releases) | |
build-artifacts: | |
name: 📦 Build Artifacts (${{ matrix.build }}) | |
if: startsWith(github.ref, 'refs/tags/') | |
needs: build-and-test | |
runs-on: ${{ matrix.os }} | |
strategy: | |
matrix: | |
include: | |
- build: linux-amd64 | |
os: ubuntu-latest | |
target: x86_64-unknown-linux-gnu | |
binary_name: git-iris | |
- build: windows-gnu | |
os: windows-latest | |
target: x86_64-pc-windows-gnu | |
binary_name: git-iris.exe | |
- build: macos-arm64 | |
os: macos-latest | |
target: aarch64-apple-darwin | |
binary_name: git-iris | |
steps: | |
- name: 📥 Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🦀 Install Rust | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
targets: ${{ matrix.target }} | |
- name: 📦 Rust cache | |
uses: Swatinem/rust-cache@v2 | |
with: | |
# Let action generate cache keys automatically | |
workspaces: ". -> target/${{ matrix.target }}/release" | |
# Additional cache suffix for release builds | |
cache-on-failure: true | |
- name: 🔨 Build release binary | |
run: | | |
echo "::group::Building release binary (${{ matrix.build }})" | |
cargo build --verbose --locked --release --target ${{ matrix.target }} | |
echo "::endgroup::" | |
- name: 📤 Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: git-iris-${{ matrix.build }} | |
path: ./target/${{ matrix.target }}/release/${{ matrix.binary_name }} | |
if-no-files-found: error | |
retention-days: 1 | |
build-packages: | |
name: 📦 Build Packages | |
if: startsWith(github.ref, 'refs/tags/') | |
needs: build-and-test | |
runs-on: ubuntu-latest | |
outputs: | |
version: ${{ steps.get_version.outputs.VERSION }} | |
steps: | |
- name: 📥 Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🏷️ Get version | |
id: get_version | |
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT | |
- name: 🦀 Install Rust | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
targets: x86_64-unknown-linux-gnu | |
- name: 📦 Rust cache | |
uses: Swatinem/rust-cache@v2 | |
with: | |
# Let action generate cache keys automatically | |
workspaces: "." | |
cache-on-failure: true | |
# Build DEB package | |
- name: 📦 Install cargo-deb | |
run: cargo install cargo-deb | |
- name: 🔨 Build .deb package | |
run: | | |
echo "::group::Building .deb package" | |
cargo deb | |
echo "::endgroup::" | |
- name: 📤 Upload DEB artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: git-iris-deb | |
path: ./target/debian/git-iris_${{ steps.get_version.outputs.VERSION }}-1_amd64.deb | |
if-no-files-found: error | |
retention-days: 1 | |
# Build RPM package | |
- name: 📦 Install cargo-generate-rpm | |
run: cargo install cargo-generate-rpm | |
- name: 🔨 Build Release Binary for RPM | |
run: cargo build --release | |
- name: 🔨 Build .rpm package | |
run: | | |
echo "::group::Building .rpm package" | |
cargo generate-rpm | |
echo "::endgroup::" | |
- name: 📤 Upload RPM artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: git-iris-rpm | |
path: ./target/generate-rpm/git-iris-${{ steps.get_version.outputs.VERSION }}-1.x86_64.rpm | |
if-no-files-found: error | |
retention-days: 1 | |
# Upload man page as artifact | |
- name: 📤 Upload man page artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: git-iris-man | |
path: ./git-iris.1 | |
if-no-files-found: error | |
retention-days: 1 | |
# Publish Docker image for releases | |
docker-publish: | |
name: 🐳 Publish Docker Image | |
if: startsWith(github.ref, 'refs/tags/') | |
needs: [build-and-test, docker-build-and-test, build-packages] | |
runs-on: ubuntu-latest | |
env: | |
REGISTRY: docker.io | |
IMAGE_NAME: hyperb1iss/git-iris | |
steps: | |
- name: 📥 Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🏷️ Get version | |
id: get_version | |
run: | | |
VERSION=${GITHUB_REF_NAME#v} | |
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
echo "Building Docker image for version $VERSION" | |
- name: 🔑 Login to DockerHub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_TOKEN }} | |
- name: 🔍 Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: 🔨 Build and push Docker image | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: ./docker/Dockerfile | |
push: true | |
tags: | | |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest | |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.get_version.outputs.VERSION }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
- name: 🎉 Docker image published | |
run: | | |
echo "✨ Successfully published Docker images:" | |
echo " • ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" | |
echo " • ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.get_version.outputs.VERSION }}" | |
# Add crates.io publishing | |
cargo-publish: | |
name: 📦 Publish to crates.io | |
if: startsWith(github.ref, 'refs/tags/') | |
needs: [build-artifacts, build-packages] | |
runs-on: ubuntu-latest | |
steps: | |
- name: 📥 Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 🦀 Install Rust | |
uses: dtolnay/rust-toolchain@stable | |
- name: 📦 Rust cache | |
uses: Swatinem/rust-cache@v2 | |
- name: 🔑 Setup crates.io token | |
run: cargo login ${{ secrets.CRATES_IO_TOKEN }} | |
- name: 📤 Publish to crates.io | |
run: | | |
echo "::group::Publishing to crates.io" | |
cargo publish | |
echo "::endgroup::" | |
- name: 🎉 crates.io publish successful | |
run: echo "✨ Successfully published to crates.io" | |
create-release: | |
name: 🚀 Create GitHub Release | |
if: startsWith(github.ref, 'refs/tags/') | |
needs: [build-artifacts, build-packages, docker-publish, cargo-publish] | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
steps: | |
- name: 📥 Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: 📥 Download all artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: ./artifacts | |
- name: 🔨 Prepare release assets | |
run: | | |
echo "::group::Preparing release assets" | |
mkdir -p release-assets | |
find ./artifacts -type f -exec cp {} ./release-assets/ \; | |
ls -la ./release-assets | |
echo "::endgroup::" | |
- name: 📝 Generate release notes with git-iris | |
env: | |
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
run: | | |
echo "::group::Generating release notes" | |
if [ -n "$OPENAI_API_KEY" ]; then | |
# Build git-iris locally to generate release notes | |
cargo build --release | |
# Get previous tag | |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") | |
if [ -n "$PREVIOUS_TAG" ]; then | |
# Generate release notes using git-iris | |
./target/release/git-iris release-notes --from "$PREVIOUS_TAG" --to "$GITHUB_REF_NAME" --print > RELEASE_NOTES.md | |
echo "✨ Generated release notes with git-iris" | |
else | |
echo "No previous tag found, using default release notes" | |
echo "# Release $GITHUB_REF_NAME" > RELEASE_NOTES.md | |
echo "See commit history for changes." >> RELEASE_NOTES.md | |
fi | |
else | |
echo "No OpenAI API key available, using default release notes" | |
echo "# Release $GITHUB_REF_NAME" > RELEASE_NOTES.md | |
echo "See commit history for changes." >> RELEASE_NOTES.md | |
fi | |
cat RELEASE_NOTES.md | |
echo "::endgroup::" | |
- name: 🚀 Create GitHub Release | |
uses: softprops/action-gh-release@v2 | |
with: | |
name: Release ${{ github.ref_name }} | |
draft: false | |
prerelease: false | |
files: | | |
./release-assets/* | |
body_path: RELEASE_NOTES.md |