Build Fat Binaries v0.5.5 #11
Workflow file for this run
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: 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 |