Skip to content

feat: run maintenance pass (#13) #7

feat: run maintenance pass (#13)

feat: run maintenance pass (#13) #7

Workflow file for this run

name: Auto Release
on:
push:
branches: [main]
permissions:
contents: write
jobs:
version:
name: Determine Version
runs-on: ubuntu-latest
# Skip version bump commits to avoid infinite loops
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
outputs:
tag: ${{ steps.version.outputs.next }}
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install Just
uses: extractions/setup-just@v2
- name: Determine next version
id: version
run: |
latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "latest=$latest_tag" >> "$GITHUB_OUTPUT"
version="${latest_tag#v}"
IFS='.' read -r major minor patch <<< "$version"
commits=$(git log "$latest_tag"..HEAD --pretty=format:"%s" 2>/dev/null || git log --pretty=format:"%s")
if echo "$commits" | grep -qE "^feat(\(.+\))?!:|^fix(\(.+\))?!:|^refactor(\(.+\))?!:|BREAKING CHANGE"; then
major=$((major + 1))
minor=0
patch=0
elif echo "$commits" | grep -qE "^feat(\(.+\))?:"; then
minor=$((minor + 1))
patch=0
else
patch=$((patch + 1))
fi
next="v${major}.${minor}.${patch}"
echo "next=$next" >> "$GITHUB_OUTPUT"
echo "version=${major}.${minor}.${patch}" >> "$GITHUB_OUTPUT"
echo "Next version: $next (from $latest_tag)"
- name: Update versions
run: |
bun install --frozen-lockfile
just set-version ${{ steps.version.outputs.version }}
- name: Verify
run: |
just typecheck
just test
- name: Commit and tag
env:
TAG: ${{ steps.version.outputs.next }}
VERSION: ${{ steps.version.outputs.version }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add package.json src/cli/index.ts skills/*/SKILL.md .claude-plugin/plugin.json
git commit -m "chore(release): bump version to v$VERSION"
git tag -a "$TAG" -m "Release $TAG"
git push origin main --follow-tags
build:
name: Build ${{ matrix.target }}
needs: version
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: linux-x64
os: ubuntu-latest
artifact: upkeep-linux-x64
- target: linux-arm64
os: ubuntu-latest
artifact: upkeep-linux-arm64
- target: darwin-arm64
os: macos-latest
artifact: upkeep-darwin-arm64
- target: darwin-x64
os: macos-latest
artifact: upkeep-darwin-x64
- target: windows-x64
os: windows-latest
artifact: upkeep-windows-x64.exe
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.version.outputs.tag }}
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build binary
run: bun run build:${{ matrix.target }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: dist/${{ matrix.artifact }}
if-no-files-found: error
release:
name: Create Release
needs: [version, build]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.version.outputs.tag }}
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Package release archives
env:
VERSION: ${{ needs.version.outputs.version }}
run: |
mkdir -p release
# Tar+gzip each Unix binary as `upkeep` inside the archive, named
# upkeep_<version>_<os>_<arch>.tar.gz with Homebrew-style arch tokens.
archive() {
src="$1"; os="$2"; arch="$3"
cp "$src" upkeep
chmod +x upkeep
tar -czf "release/upkeep_${VERSION}_${os}_${arch}.tar.gz" upkeep
rm upkeep
}
archive artifacts/upkeep-linux-x64/upkeep-linux-x64 linux amd64
archive artifacts/upkeep-linux-arm64/upkeep-linux-arm64 linux arm64
archive artifacts/upkeep-darwin-x64/upkeep-darwin-x64 darwin amd64
archive artifacts/upkeep-darwin-arm64/upkeep-darwin-arm64 darwin arm64
# Windows ships as a raw .exe — Homebrew does not consume it.
cp artifacts/upkeep-windows-x64.exe/upkeep-windows-x64.exe \
"release/upkeep_${VERSION}_windows_amd64.exe"
# checksums.txt lists the sha256 of each tarball; the Homebrew tap
# downloads this to render per-platform url + sha256.
( cd release && sha256sum upkeep_"${VERSION}"_*.tar.gz > checksums.txt )
ls -la release/
cat release/checksums.txt
- name: Generate changelog
uses: orhun/git-cliff-action@v4
id: changelog
with:
config: cliff.toml
args: --latest --strip header
env:
OUTPUT: CHANGELOG.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.version.outputs.tag }}
files: |
release/*.tar.gz
release/*.exe
release/checksums.txt
body: ${{ steps.changelog.outputs.content }}
draft: false
prerelease: false