feat: run maintenance pass (#13) #7
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
| 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 |