Skip to content

feat: Homebrew bottle生成とFormula更新 #41

feat: Homebrew bottle生成とFormula更新

feat: Homebrew bottle生成とFormula更新 #41

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run (skip actual release)'
type: boolean
default: false
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
BINARY_NAME: git-sc
jobs:
prepare-release:
name: Prepare Release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.bump.outputs.version }}
tag: ${{ steps.bump.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump version
id: bump
run: |
# Use 2-digit year (YY) for Windows MSI compatibility (major version must be <= 255)
YEAR=$(date +%y)
MONTH=$(date +%-m)
CURRENT=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
echo "Current version: ${CURRENT}"
if echo "${CURRENT}" | grep -qE '^[0-9]{2,4}\.[0-9]{1,2}\.[0-9]+$'; then
OLD_YEAR=$(echo "${CURRENT}" | cut -d. -f1)
OLD_MONTH=$(echo "${CURRENT}" | cut -d. -f2)
OLD_COUNTER=$(echo "${CURRENT}" | cut -d. -f3)
# Handle both 2-digit and 4-digit year formats
OLD_YEAR_2DIGIT=$(echo "${OLD_YEAR}" | sed 's/^20//')
if [ "${OLD_YEAR_2DIGIT}" = "${YEAR}" ] && [ "${OLD_MONTH}" = "${MONTH}" ]; then
NEW_COUNTER=$((OLD_COUNTER + 1))
else
NEW_COUNTER=100
fi
else
NEW_COUNTER=100
fi
NEW_VERSION="${YEAR}.${MONTH}.${NEW_COUNTER}"
echo "New version: ${NEW_VERSION}"
# Only replace the first occurrence (package version, not dependency versions)
sed -i "0,/^version = \"[^\"]*\"/s//version = \"${NEW_VERSION}\"/" Cargo.toml
if [ -f "Cargo.lock" ]; then
cargo generate-lockfile 2>/dev/null || true
fi
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
echo "tag=v${NEW_VERSION}" >> $GITHUB_OUTPUT
- name: Commit and tag
if: ${{ !inputs.dry_run }}
run: |
git add Cargo.toml
[ -f "Cargo.lock" ] && git add Cargo.lock || true
git commit -m "Release ${{ steps.bump.outputs.tag }}"
git tag -a "${{ steps.bump.outputs.tag }}" -m "Release ${{ steps.bump.outputs.tag }}"
git push origin HEAD "${{ steps.bump.outputs.tag }}"
- name: Dry run info
if: ${{ inputs.dry_run }}
run: |
echo "🧪 Dry run mode - skipping commit and tag"
echo "Would release: ${{ steps.bump.outputs.tag }}"
build:
name: Build (${{ matrix.target }})
needs: prepare-release
if: ${{ !inputs.dry_run }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: git-sc
asset_name: git-sc-x86_64-unknown-linux-gnu.tar.gz
cross: false
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
artifact_name: git-sc
asset_name: git-sc-aarch64-unknown-linux-gnu.tar.gz
cross: true
- os: macos-latest
target: x86_64-apple-darwin
artifact_name: git-sc
asset_name: git-sc-x86_64-apple-darwin.tar.gz
cross: false
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: git-sc
asset_name: git-sc-aarch64-apple-darwin.tar.gz
cross: false
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: git-sc.exe
asset_name: git-sc-x86_64-pc-windows-msvc.zip
cross: false
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.prepare-release.outputs.tag }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools
if: matrix.cross
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Build with cross
if: matrix.cross
run: |
cargo install cross --git https://github.com/cross-rs/cross
cross build --release --target ${{ matrix.target }}
- name: Build
if: "!matrix.cross"
run: cargo build --release --target ${{ matrix.target }}
- name: Package (Unix)
if: runner.os != 'Windows'
run: |
cd target/${{ matrix.target }}/release
tar czvf ../../../${{ matrix.asset_name }} ${{ matrix.artifact_name }}
cd ../../..
- name: Package (Windows)
if: runner.os == 'Windows'
run: |
cd target/${{ matrix.target }}/release
7z a ../../../${{ matrix.asset_name }} ${{ matrix.artifact_name }}
cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: ${{ matrix.asset_name }}
release:
name: Create Release
needs: [prepare-release, build]
if: ${{ !inputs.dry_run }}
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release files
run: |
mkdir -p release
find artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" \) -exec mv {} release/ \;
ls -la release/
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare-release.outputs.tag }}
name: ${{ needs.prepare-release.outputs.tag }}
body: |
## git-sc ${{ needs.prepare-release.outputs.version }}
AI-powered smart commit message generator for coding agents
### Installation
#### Homebrew (macOS/Linux)
```bash
brew install owayo/git-sc/git-sc
```
#### Manual Download
Download the appropriate binary for your platform and add it to your PATH.
#### macOS (Apple Silicon)
```bash
curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/git-sc-aarch64-apple-darwin.tar.gz | tar xz
sudo mv git-sc /usr/local/bin/
```
#### macOS (Intel)
```bash
curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/git-sc-x86_64-apple-darwin.tar.gz | tar xz
sudo mv git-sc /usr/local/bin/
```
#### Linux (x86_64)
```bash
curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/git-sc-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv git-sc /usr/local/bin/
```
#### Linux (ARM64)
```bash
curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/git-sc-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv git-sc /usr/local/bin/
```
#### Windows
Download `git-sc-x86_64-pc-windows-msvc.zip`, extract, and add to PATH.
files: release/*
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update-homebrew:
name: Update Homebrew Tap
needs: [prepare-release, release]
if: ${{ !inputs.dry_run }}
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App Token
id: app-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
repositories: '["homebrew-git-sc"]'
- name: Create Homebrew bottles and calculate SHA256
id: bottles
run: |
VERSION="${{ needs.prepare-release.outputs.version }}"
TAG="${{ needs.prepare-release.outputs.tag }}"
# Download source archive for formula URL
curl -sL "https://github.com/${{ github.repository }}/archive/refs/tags/${TAG}.tar.gz" -o source.tar.gz
SHA256_SOURCE=$(sha256sum source.tar.gz | cut -d' ' -f1)
echo "sha256_source=${SHA256_SOURCE}" >> $GITHUB_OUTPUT
# Download release binaries
curl -sL "https://github.com/${{ github.repository }}/releases/download/${TAG}/git-sc-aarch64-apple-darwin.tar.gz" -o mac_arm64.tar.gz
curl -sL "https://github.com/${{ github.repository }}/releases/download/${TAG}/git-sc-x86_64-apple-darwin.tar.gz" -o mac_x86_64.tar.gz
curl -sL "https://github.com/${{ github.repository }}/releases/download/${TAG}/git-sc-x86_64-unknown-linux-gnu.tar.gz" -o linux_x86_64.tar.gz
# Create Homebrew bottle tarball from release binary
create_bottle() {
local src_tarball=$1
local bottle_tag=$2
rm -rf bottle_staging
mkdir -p "bottle_staging/git-sc/${VERSION}/bin"
# Extract binary from release tarball into bottle structure
tar xzf "${src_tarball}" -C "bottle_staging/git-sc/${VERSION}/bin/"
chmod +x "bottle_staging/git-sc/${VERSION}/bin/git-sc"
# Create bottle tarball
local bottle_name="git-sc--${VERSION}.${bottle_tag}.bottle.tar.gz"
tar czvf "${bottle_name}" -C bottle_staging git-sc
# Return SHA256
sha256sum "${bottle_name}" | cut -d' ' -f1
}
SHA256_BOTTLE_ARM64_SONOMA=$(create_bottle mac_arm64.tar.gz arm64_sonoma)
SHA256_BOTTLE_SONOMA=$(create_bottle mac_x86_64.tar.gz sonoma)
SHA256_BOTTLE_X86_64_LINUX=$(create_bottle linux_x86_64.tar.gz x86_64_linux)
echo "sha256_bottle_arm64_sonoma=${SHA256_BOTTLE_ARM64_SONOMA}" >> $GITHUB_OUTPUT
echo "sha256_bottle_sonoma=${SHA256_BOTTLE_SONOMA}" >> $GITHUB_OUTPUT
echo "sha256_bottle_x86_64_linux=${SHA256_BOTTLE_X86_64_LINUX}" >> $GITHUB_OUTPUT
- name: Upload bottles to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ needs.prepare-release.outputs.version }}"
TAG="${{ needs.prepare-release.outputs.tag }}"
gh release upload "${TAG}" \
"git-sc--${VERSION}.arm64_sonoma.bottle.tar.gz" \
"git-sc--${VERSION}.sonoma.bottle.tar.gz" \
"git-sc--${VERSION}.x86_64_linux.bottle.tar.gz" \
--clobber \
--repo "${{ github.repository }}"
- name: Update Homebrew Formula
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
VERSION="${{ needs.prepare-release.outputs.version }}"
TAG="${{ needs.prepare-release.outputs.tag }}"
SHA256_SOURCE="${{ steps.bottles.outputs.sha256_source }}"
SHA256_BOTTLE_ARM64_SONOMA="${{ steps.bottles.outputs.sha256_bottle_arm64_sonoma }}"
SHA256_BOTTLE_SONOMA="${{ steps.bottles.outputs.sha256_bottle_sonoma }}"
SHA256_BOTTLE_X86_64_LINUX="${{ steps.bottles.outputs.sha256_bottle_x86_64_linux }}"
# Clone homebrew tap
git clone "https://x-access-token:${GH_TOKEN}@github.com/owayo/homebrew-git-sc.git"
cd homebrew-git-sc
# Create Formula directory if not exists
mkdir -p Formula
# Create/update formula with bottle support
cat > Formula/git-sc.rb << 'FORMULA'
class GitSc < Formula

Check failure on line 336 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

You have an error in your yaml syntax on line 336
desc "AI-powered smart commit message generator for coding agents"
homepage "https://github.com/owayo/git-smart-commit"
url "URL_SOURCE_PLACEHOLDER"
sha256 "SHA256_SOURCE_PLACEHOLDER"
license "MIT"
bottle do
root_url "ROOT_URL_PLACEHOLDER"
sha256 cellar: :any_skip_relocation, arm64_sonoma: "SHA256_BOTTLE_ARM64_SONOMA_PLACEHOLDER"
sha256 cellar: :any_skip_relocation, sonoma: "SHA256_BOTTLE_SONOMA_PLACEHOLDER"
sha256 cellar: :any_skip_relocation, x86_64_linux: "SHA256_BOTTLE_X86_64_LINUX_PLACEHOLDER"
end
depends_on "rust" => :build
def install
system "cargo", "install", *std_cargo_args
end
test do
system "#{bin}/git-sc", "--version"
end
end
FORMULA
# Replace placeholders with actual values
sed -i "s|URL_SOURCE_PLACEHOLDER|https://github.com/owayo/git-smart-commit/archive/refs/tags/${TAG}.tar.gz|g" Formula/git-sc.rb
sed -i "s|SHA256_SOURCE_PLACEHOLDER|${SHA256_SOURCE}|g" Formula/git-sc.rb
sed -i "s|ROOT_URL_PLACEHOLDER|https://github.com/owayo/git-smart-commit/releases/download/${TAG}|g" Formula/git-sc.rb
sed -i "s|SHA256_BOTTLE_ARM64_SONOMA_PLACEHOLDER|${SHA256_BOTTLE_ARM64_SONOMA}|g" Formula/git-sc.rb
sed -i "s|SHA256_BOTTLE_SONOMA_PLACEHOLDER|${SHA256_BOTTLE_SONOMA}|g" Formula/git-sc.rb
sed -i "s|SHA256_BOTTLE_X86_64_LINUX_PLACEHOLDER|${SHA256_BOTTLE_X86_64_LINUX}|g" Formula/git-sc.rb
# Commit and push
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/git-sc.rb
git commit -m "Update git-sc to ${TAG}"
git push
release-summary:
name: Release Summary
needs: [prepare-release, release, update-homebrew]
if: ${{ !inputs.dry_run }}
runs-on: ubuntu-latest
steps:
- name: Summary
run: |
echo "🚀 Released ${{ needs.prepare-release.outputs.tag }}"
echo ""
echo "Assets uploaded:"
echo " - git-sc-x86_64-unknown-linux-gnu.tar.gz"
echo " - git-sc-aarch64-unknown-linux-gnu.tar.gz"
echo " - git-sc-x86_64-apple-darwin.tar.gz"
echo " - git-sc-aarch64-apple-darwin.tar.gz"
echo " - git-sc-x86_64-pc-windows-msvc.zip"
echo ""
echo "🍺 Homebrew tap updated: owayo/homebrew-git-sc"