Skip to content

✨ Prefer XDG-style config path on macOS #289

✨ Prefer XDG-style config path on macOS

✨ Prefer XDG-style config path on macOS #289

Workflow file for this run

name: CI/CD
on:
push:
branches:
- main
tags:
- "v*.*.*"
pull_request:
branches:
- main
workflow_dispatch:
inputs:
tag:
description: "Tag to build/release (e.g., v1.2.3)"
required: false
release_run_id:
description: "Run ID of the release workflow (for artifact download)"
required: false
jobs:
# ── CI (lint, test) ──────────────────────────────────────────
ci:
uses: hyperb1iss/shared-workflows/.github/workflows/rust-ci.yml@main
with:
change-detection: false
cargo-deny: false
nextest: false
permissions:
contents: read
pull-requests: read
secrets: inherit
# ── Docker Build & Test ──────────────────────────────────────
docker-build-and-test:
name: 🐳 Docker Build & Test
runs-on: ubuntu-latest
needs: ci
env:
IMAGE_NAME: git-iris-test
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: docker/setup-buildx-action@v3
- name: Build Docker image
working-directory: ./docker
run: ./build.sh $IMAGE_NAME
- name: Test Docker image
working-directory: ./docker
run: CI=true ./test-image.sh $IMAGE_NAME
# ── Build Artifacts ──────────────────────────────────────────
build-artifacts:
name: 📦 Build Artifacts (${{ matrix.build }})
if: startsWith(github.ref, 'refs/tags/')
needs: ci
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- build: linux-amd64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
binary_name: git-iris
- build: linux-arm64
os: ubuntu-24.04-arm
target: aarch64-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:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
workspaces: ". -> target/${{ matrix.target }}/release"
cache-on-failure: true
- name: Build release binary
run: cargo build --verbose --locked --release --target ${{ matrix.target }}
- 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 (.deb, .rpm) ──────────────────────────────
build-packages:
name: 📦 Build Packages
if: startsWith(github.ref, 'refs/tags/')
needs: ci
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- build: linux-amd64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
arch_suffix: amd64
rpm_arch: x86_64
rust_flags: "-C target-cpu=x86-64"
outputs:
version: ${{ steps.get_version.outputs.VERSION }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get version
id: get_version
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup cross-compilation (ARM64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install cargo-deb
run: cargo install cargo-deb
- name: Build .deb package
env:
RUSTFLAGS: ${{ matrix.rust_flags }}
run: cargo deb --target ${{ matrix.target }}
- uses: actions/upload-artifact@v4
with:
name: git-iris-deb-${{ matrix.arch_suffix }}
path: ./target/${{ matrix.target }}/debian/git-iris_${{ steps.get_version.outputs.VERSION }}-1_${{ matrix.arch_suffix }}.deb
if-no-files-found: error
retention-days: 1
- name: Install cargo-generate-rpm
run: cargo install cargo-generate-rpm
- name: Build release binary for RPM
env:
RUSTFLAGS: ${{ matrix.rust_flags }}
run: cargo build --release --target ${{ matrix.target }}
- name: Build .rpm package
env:
RUSTFLAGS: ${{ matrix.rust_flags }}
run: cargo generate-rpm --target ${{ matrix.target }}
- uses: actions/upload-artifact@v4
with:
name: git-iris-rpm-${{ matrix.arch_suffix }}
path: ./target/${{ matrix.target }}/generate-rpm/git-iris-${{ steps.get_version.outputs.VERSION }}-1.${{ matrix.rpm_arch }}.rpm
if-no-files-found: error
retention-days: 1
- name: Upload man page
if: matrix.build == 'linux-amd64'
uses: actions/upload-artifact@v4
with:
name: git-iris-man
path: ./git-iris.1
if-no-files-found: error
retention-days: 1
# ── Docker Publish ───────────────────────────────────────────
docker-publish:
if: startsWith(github.ref, 'refs/tags/')
needs: [ci, docker-build-and-test, build-packages]
uses: hyperb1iss/shared-workflows/.github/workflows/docker-publish.yml@main
with:
image-name: hyperb1iss/git-iris
dockerfile: ./docker/Dockerfile
permissions:
contents: read
packages: write
secrets: inherit
# ── Publish to crates.io ─────────────────────────────────────
cargo-publish:
if: startsWith(github.ref, 'refs/tags/')
needs: [build-artifacts, build-packages]
uses: hyperb1iss/shared-workflows/.github/workflows/rust-publish.yml@main
permissions:
contents: read
id-token: write
secrets: inherit
# ── Create GitHub Release ────────────────────────────────────
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:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: git-iris-*
- name: Prepare release assets
run: |
mkdir -p release-assets
for dir in ./artifacts/git-iris-*/; do
artifact_name=$(basename "$dir")
if [ -f "$dir/git-iris" ]; then
cp "$dir/git-iris" "./release-assets/${artifact_name}"
elif [ -f "$dir/git-iris.exe" ]; then
cp "$dir/git-iris.exe" "./release-assets/${artifact_name}.exe"
fi
done
# Copy non-binary artifacts (deb, rpm, man page) as-is
find ./artifacts -type f \( -name "*.deb" -o -name "*.rpm" -o -name "*.1" \) -exec cp {} ./release-assets/ \;
ls -la ./release-assets
- name: Get previous tag
id: prev_tag
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
echo "tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT
- name: Prepare git-iris binary
run: |
chmod +x ./artifacts/git-iris-linux-amd64/git-iris
./artifacts/git-iris-linux-amd64/git-iris --version
- name: Download release notes from release workflow
id: download_notes
if: ${{ inputs.release_run_id != '' }}
uses: actions/download-artifact@v4
with:
name: release-notes
run-id: ${{ inputs.release_run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: Generate release notes (fallback)
if: steps.download_notes.outcome != 'success' && steps.prev_tag.outputs.tag != ''
uses: ./
with:
command: release-notes
from: ${{ steps.prev_tag.outputs.tag }}
to: ${{ github.ref_name }}
version-name: ${{ github.ref_name }}
provider: anthropic
model: claude-opus-4-5-20251101
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
output-file: RELEASE_NOTES.md
binary-path: ./artifacts/git-iris-linux-amd64/git-iris
- name: Fallback release notes (no tags)
if: steps.prev_tag.outputs.tag == ''
run: |
echo "# Release ${{ github.ref_name }}" > RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
echo "See [commit history](https://github.com/hyperb1iss/git-iris/commits/${{ github.ref_name }}) for changes." >> RELEASE_NOTES.md
- 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
# ── Update Major Version Tag ─────────────────────────────────
update-major-tag:
name: 🏷️ Update Major Version Tag
if: startsWith(github.ref, 'refs/tags/v')
needs: create-release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Update major version tag
run: |
FULL_TAG="${GITHUB_REF_NAME}"
MAJOR_TAG=$(echo "$FULL_TAG" | sed -E 's/^(v[0-9]+).*/\1/')
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -fa "$MAJOR_TAG" -m "Update $MAJOR_TAG to $FULL_TAG"
git push origin "$MAJOR_TAG" --force
# ── Update Homebrew Tap ──────────────────────────────────────
update-homebrew:
name: 🍺 Update Homebrew Tap
if: startsWith(github.ref, 'refs/tags/v')
needs: create-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
repository: hyperb1iss/homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-tap
- name: Calculate SHA256 checksums
id: sha
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
MACOS_ARM64=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/releases/download/${GITHUB_REF_NAME}/git-iris-macos-arm64" | shasum -a 256 | cut -d' ' -f1)
LINUX_ARM64=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/releases/download/${GITHUB_REF_NAME}/git-iris-linux-arm64" | shasum -a 256 | cut -d' ' -f1)
LINUX_AMD64=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/releases/download/${GITHUB_REF_NAME}/git-iris-linux-amd64" | shasum -a 256 | cut -d' ' -f1)
SOURCE=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/archive/refs/tags/${GITHUB_REF_NAME}.tar.gz" | shasum -a 256 | cut -d' ' -f1)
echo "macos_arm64=$MACOS_ARM64" >> $GITHUB_OUTPUT
echo "linux_arm64=$LINUX_ARM64" >> $GITHUB_OUTPUT
echo "linux_amd64=$LINUX_AMD64" >> $GITHUB_OUTPUT
echo "source=$SOURCE" >> $GITHUB_OUTPUT
- name: Generate formula
run: |
cat > homebrew-tap/Formula/git-iris.rb << 'EOF'
# typed: false
# frozen_string_literal: true
class GitIris < Formula
desc "An intelligent agent that understands your code and crafts perfect Git artifacts"
homepage "https://github.com/hyperb1iss/git-iris"
license "Apache-2.0"
version "${{ steps.sha.outputs.version }}"
on_macos do
on_arm do
url "https://github.com/hyperb1iss/git-iris/releases/download/v#{version}/git-iris-macos-arm64"
sha256 "${{ steps.sha.outputs.macos_arm64 }}"
end
on_intel do
url "https://github.com/hyperb1iss/git-iris/archive/refs/tags/v#{version}.tar.gz"
sha256 "${{ steps.sha.outputs.source }}"
depends_on "rust" => :build
end
end
on_linux do
on_arm do
url "https://github.com/hyperb1iss/git-iris/releases/download/v#{version}/git-iris-linux-arm64"
sha256 "${{ steps.sha.outputs.linux_arm64 }}"
end
on_intel do
url "https://github.com/hyperb1iss/git-iris/releases/download/v#{version}/git-iris-linux-amd64"
sha256 "${{ steps.sha.outputs.linux_amd64 }}"
end
end
def install
if build.with?("rust")
system "cargo", "install", *std_cargo_args
else
bin.install Dir["git-iris*"].first => "git-iris"
end
end
test do
assert_match "git-iris #{version}", shell_output("#{bin}/git-iris --version")
end
end
EOF
- name: Push to tap
run: |
cd homebrew-tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/git-iris.rb
git commit -m "git-iris ${{ steps.sha.outputs.version }}"
git push
# ── Update AUR Package ──────────────────────────────────────
update-aur:
name: 📦 Update AUR Package
if: startsWith(github.ref, 'refs/tags/v')
needs: create-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Generate PKGBUILD
run: |
VERSION="${GITHUB_REF_NAME#v}"
SHA_X86_64=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/releases/download/${GITHUB_REF_NAME}/git-iris-linux-amd64" | sha256sum | cut -d' ' -f1)
SHA_AARCH64=$(curl -fsSL "https://github.com/hyperb1iss/git-iris/releases/download/${GITHUB_REF_NAME}/git-iris-linux-arm64" | sha256sum | cut -d' ' -f1)
cat > PKGBUILD << EOF
# Maintainer: Stefanie Jane <stef@hyperbliss.tech>
pkgname=git-iris-bin
pkgver=${VERSION}
pkgrel=1
pkgdesc="An intelligent agent that understands your code and crafts perfect Git artifacts"
arch=('x86_64' 'aarch64')
url="https://github.com/hyperb1iss/git-iris"
license=('Apache-2.0')
provides=('git-iris')
conflicts=('git-iris')
depends=('gcc-libs' 'openssl')
source_x86_64=("\${pkgname}-\${pkgver}-x86_64::https://github.com/hyperb1iss/git-iris/releases/download/v\${pkgver}/git-iris-linux-amd64")
source_aarch64=("\${pkgname}-\${pkgver}-aarch64::https://github.com/hyperb1iss/git-iris/releases/download/v\${pkgver}/git-iris-linux-arm64")
sha256sums_x86_64=('${SHA_X86_64}')
sha256sums_aarch64=('${SHA_AARCH64}')
package() {
install -Dm755 "\${srcdir}/\${pkgname}-\${pkgver}-\${CARCH}" "\${pkgdir}/usr/bin/git-iris"
}
EOF
- name: Publish to AUR
uses: KSXGitHub/github-actions-deploy-aur@v4.1.2
with:
pkgname: git-iris-bin
pkgbuild: ./PKGBUILD
commit_username: Stefanie Jane
commit_email: stef@hyperbliss.tech
ssh_private_key: ${{ secrets.AUR_SSH_KEY }}
commit_message: "Update to ${{ github.ref_name }}"