Skip to content

Reduce code duplication and fix README example #27

Reduce code duplication and fix README example

Reduce code duplication and fix README example #27

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
env:
CARGO_TERM_COLOR: always
jobs:
build:
name: Build (${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: Linux x86_64
target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- name: macOS ARM64
target: aarch64-apple-darwin
os: macos-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libncurses-dev
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Set version from tag
run: |
# Extract version from tag (e.g., v0.1.0 -> 0.1.0)
VERSION="${GITHUB_REF_NAME#v}"
echo "Setting version to $VERSION"
sed -i.bak "s/^version = .*/version = \"$VERSION\"/" Cargo.toml
rm -f Cargo.toml.bak
grep "^version" Cargo.toml
- name: Build
run: cargo build --release
- name: Run tests
run: cargo test --release -- --test-threads=1
- name: Package
shell: bash
run: |
cd target/release
tar czvf ../../bash-ast-${{ github.ref_name }}-${{ matrix.target }}.tar.gz bash-ast
cd ../..
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bash-ast-${{ matrix.target }}
path: bash-ast-${{ github.ref_name }}-${{ matrix.target }}.tar.gz
bottle:
name: Build Bottle (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-14 # ARM64 (M1/M2) - Sonoma
bottle_tag: arm64_sonoma
- os: macos-15 # ARM64 - Sequoia
bottle_tag: arm64_sequoia
steps:
- uses: actions/checkout@v4
- name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Tap and install formula for bottling
env:
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_INSTALL_FROM_API: 1
run: |
# Create a local tap with updated formula
TAP_DIR="$(brew --repository)/Library/Taps/cv/homebrew-taps"
mkdir -p "$TAP_DIR/Formula"
# Get tag info
TAG="${{ github.ref_name }}"
REVISION="${{ github.sha }}"
# Update formula with tag and revision
sed \
-e "s/VERSION_TAG_PLACEHOLDER/${TAG}/" \
-e "s/REVISION_PLACEHOLDER/${REVISION}/" \
Formula/bash-ast.rb > "$TAP_DIR/Formula/bash-ast.rb"
echo "Formula contents:"
cat "$TAP_DIR/Formula/bash-ast.rb"
# Build bottle
brew install --build-bottle cv/taps/bash-ast
- name: Create bottle
run: |
cd $(mktemp -d)
brew bottle --no-rebuild --json cv/taps/bash-ast
# Rename bottle to standard format
# Homebrew creates: bash-ast--VERSION.BOTTLE_TAG.bottle.tar.gz
# We want: bash-ast-VERSION.BOTTLE_TAG.bottle.tar.gz
for f in bash-ast--*.bottle.tar.gz; do
newname="${f/bash-ast--/bash-ast-}"
mv "$f" "$newname" 2>/dev/null || true
done
# Also rename in JSON
for f in bash-ast--*.bottle.json; do
newname="${f/bash-ast--/bash-ast-}"
mv "$f" "$newname" 2>/dev/null || true
done
ls -la
# Move to workspace
mv bash-ast-*.bottle.* ${{ github.workspace }}/
- name: Upload bottle artifact
uses: actions/upload-artifact@v4
with:
name: bottle-${{ matrix.bottle_tag }}
path: |
bash-ast-*.bottle.tar.gz
bash-ast-*.bottle.json
release:
name: Create Release
needs: [build, bottle]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
artifacts/*.tar.gz
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
homebrew:
name: Update Homebrew Formula
needs: [release, bottle]
runs-on: ubuntu-latest
# Skip for prereleases
if: ${{ !contains(github.ref_name, '-') }}
steps:
- name: Checkout bash-ast
uses: actions/checkout@v4
- name: Download bottle artifacts
uses: actions/download-artifact@v4
with:
pattern: bottle-*
path: bottles
merge-multiple: true
- name: List bottles
run: ls -la bottles/
- name: Generate bottle block
id: bottle
run: |
TAG="${{ github.ref_name }}"
VERSION="${TAG#v}"
# Collect SHA256 hashes from JSON files
echo "Generating bottle block..."
BOTTLE_BLOCK=" bottle do"
BOTTLE_BLOCK+="\n root_url \"https://github.com/cv/bash-ast/releases/download/${TAG}\""
# Process each bottle JSON file
for json_file in bottles/*.bottle.json; do
if [ -f "$json_file" ]; then
echo "Processing $json_file"
cat "$json_file"
# Extract tag and sha256 from JSON
# The JSON structure is: {"cv/taps/bash-ast": {"formula": {...}, "bottle": {"tags": {"arm64_sonoma": {"sha256": "..."}}}}}
TAGS=$(jq -r '.["cv/taps/bash-ast"].bottle.tags | keys[]' "$json_file" 2>/dev/null || jq -r '.[].bottle.tags | keys[]' "$json_file")
for tag in $TAGS; do
SHA=$(jq -r ".\"cv/taps/bash-ast\".bottle.tags.\"$tag\".sha256 // .[].bottle.tags.\"$tag\".sha256" "$json_file")
echo " Tag: $tag, SHA: $SHA"
BOTTLE_BLOCK+="\n sha256 cellar: :any_skip_relocation, $tag: \"$SHA\""
done
fi
done
BOTTLE_BLOCK+="\n end"
echo "Generated bottle block:"
echo -e "$BOTTLE_BLOCK"
# Save to file for next step
echo -e "$BOTTLE_BLOCK" > bottle_block.txt
- name: Generate updated formula
run: |
TAG="${{ github.ref_name }}"
VERSION="${TAG#v}"
REVISION="${{ github.sha }}"
# Start with template
cp Formula/bash-ast.rb formula_updated.rb
# Update tag and revision
sed -i \
-e "s/VERSION_TAG_PLACEHOLDER/${TAG}/" \
-e "s/REVISION_PLACEHOLDER/${REVISION}/" \
formula_updated.rb
# Insert bottle block after license line
BOTTLE_BLOCK=$(cat bottle_block.txt)
# Use awk to insert bottle block after license line
awk -v bottle="$BOTTLE_BLOCK" '
/^ license/ {
print
print bottle
next
}
{ print }
' formula_updated.rb > formula_final.rb
echo "Final formula:"
cat formula_final.rb
mv formula_final.rb Formula/bash-ast.rb
- name: Checkout homebrew-taps
uses: actions/checkout@v4
with:
repository: cv/homebrew-taps
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-taps
- name: Update formula in tap
run: |
mkdir -p homebrew-taps/Formula
cp Formula/bash-ast.rb homebrew-taps/Formula/
cd homebrew-taps
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/bash-ast.rb
git diff --staged --quiet || git commit -m "bash-ast ${{ github.ref_name }}"
git push