Skip to content

Build Fat Binaries v0.5.6 #14

Build Fat Binaries v0.5.6

Build Fat Binaries v0.5.6 #14

name: Build Fat Binaries
run-name: Build Fat Binaries ${{ github.event_name == 'push' && github.ref_name || format('v{0}', inputs.version || 'manual') }}
on:
workflow_dispatch:
inputs:
version:
description: "CLI version from cz_cli/version.py"
required: false
type: string
push:
tags:
- "v*"
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
python-version: "3.11"
target: linux-x86_64
- os: windows-latest
python-version: "3.11"
target: windows-x86_64
- os: macos-14
python-version: "3.11"
target: macos-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install build dependencies
shell: bash
run: |
python -m pip install --upgrade pip
pip install -e . pyinstaller
- name: Build standalone binary (onedir)
shell: bash
run: |
# Use the same build script that local `make build-fat` uses
bash scripts/build_fat_multi_platform.sh
- name: Ad-hoc codesign (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
DIR="cz_cli/skills/cz-cli/scripts/${{ matrix.target }}"
# Sign all Mach-O binaries (dylib, so, and the main executable)
find "$DIR" -type f \( -name '*.so' -o -name '*.dylib' \) -exec codesign --force --sign - {} +
chmod +x "$DIR/cz-cli"
codesign --force --sign - "$DIR/cz-cli"
- name: Ensure executable (Linux)
if: runner.os == 'Linux'
shell: bash
run: chmod +x cz_cli/skills/cz-cli/scripts/${{ matrix.target }}/cz-cli
- name: Package as zip
shell: bash
run: |
TARGET="${{ matrix.target }}"
SCRIPTS_DIR="cz_cli/skills/cz-cli/scripts/${TARGET}"
if [ ! -d "$SCRIPTS_DIR" ]; then
echo "Build output not found at $SCRIPTS_DIR"
exit 1
fi
# Include setup script in the zip
if [[ "${{ runner.os }}" == "Windows" ]]; then
cp scripts/setup.bat "$SCRIPTS_DIR/setup.bat"
else
cp scripts/setup.sh "$SCRIPTS_DIR/setup.sh"
chmod +x "$SCRIPTS_DIR/setup.sh"
fi
mkdir -p dist
DIST_ABS="$(cd dist && pwd)"
cd "$SCRIPTS_DIR"
if [[ "${{ runner.os }}" == "Windows" ]]; then
7z a -tzip "${DIST_ABS}/cz-cli-${TARGET}.zip" .
else
zip -r "${DIST_ABS}/cz-cli-${TARGET}.zip" .
fi
ls -lh "${DIST_ABS}/cz-cli-${TARGET}.zip"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: dist/cz-cli-${{ matrix.target }}.zip
package-skills:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirement.txt
- name: Package skills
run: |
mkdir -p dist/skills-staging
# Copy cz_cli skills
if [ -d "cz_cli/skills" ]; then
cp -r cz_cli/skills/* dist/skills-staging/
fi
# Copy cz_mcp skills if available
CZ_MCP_SKILLS=$(python -c "
import importlib.util, pathlib
spec = importlib.util.find_spec('cz_mcp')
if spec and spec.submodule_search_locations:
for loc in spec.submodule_search_locations:
p = pathlib.Path(loc) / 'skills'
if p.exists():
print(p); break
" 2>/dev/null || true)
if [ -n "$CZ_MCP_SKILLS" ] && [ -d "$CZ_MCP_SKILLS" ]; then
for skill_dir in "$CZ_MCP_SKILLS"/*/; do
skill_name=$(basename "$skill_dir")
if [ ! -d "dist/skills-staging/$skill_name" ]; then
cp -r "$skill_dir" "dist/skills-staging/$skill_name"
fi
done
fi
# Clean up non-skill artifacts
find dist/skills-staging -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find dist/skills-staging -path "*/scripts/macos-*" -exec rm -rf {} + 2>/dev/null || true
find dist/skills-staging -path "*/scripts/linux-*" -exec rm -rf {} + 2>/dev/null || true
find dist/skills-staging -path "*/scripts/windows-*" -exec rm -rf {} + 2>/dev/null || true
# Create tarball
cd dist/skills-staging && tar -czf ../skills.tar.gz . && cd ../..
- name: Upload skills artifact
uses: actions/upload-artifact@v4
with:
name: skills
path: dist/skills.tar.gz
release:
if: startsWith(github.ref, 'refs/tags/')
needs: [build, package-skills]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout (for install.sh)
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
- name: Create GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: ${{ github.ref_name }}
draft: false
prerelease: false
generate_release_notes: true
files: |
dist/linux-x86_64/cz-cli-linux-x86_64.zip
dist/windows-x86_64/cz-cli-windows-x86_64.zip
dist/macos-arm64/cz-cli-macos-arm64.zip
dist/skills/skills.tar.gz
scripts/install.sh