perf(release): cache ccache and disable LTO to speed up Nuitka builds #6
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: Release | |
| # Builds standalone binaries for Linux / macOS / Windows and publishes them | |
| # as assets on the GitHub Release corresponding to the pushed tag. | |
| # | |
| # Trigger: | |
| # - Push a git tag matching v* (e.g. v0.1.0) → builds all targets and | |
| # creates/updates a Release named after the tag. | |
| # - workflow_dispatch → manual run for debugging; requires a tag input | |
| # that already exists on the repository. | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Existing tag to build and release (e.g. v0.1.0)' | |
| required: true | |
| permissions: | |
| contents: write | |
| env: | |
| PYTHON_VERSION: '3.11' | |
| DISABLE_BREAKING_CHANGES_WARNING: '1' | |
| jobs: | |
| # --------------------------------------------------------------------- | |
| # Version sanity check: setuptools-scm must resolve the tag to the | |
| # same PEP 440 version we expect from the tag name (v1.2.3 → 1.2.3). | |
| # --------------------------------------------------------------------- | |
| verify-version: | |
| name: Verify version | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ steps.resolve.outputs.tag }} | |
| version: ${{ steps.resolve.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.inputs.tag || github.ref }} | |
| fetch-depth: 0 # setuptools-scm needs full history + tags | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Resolve tag and version | |
| id: resolve | |
| shell: bash | |
| run: | | |
| TAG="${{ github.event.inputs.tag || github.ref_name }}" | |
| VERSION="${TAG#v}" | |
| python -m pip install --upgrade pip | |
| python -m pip install "setuptools-scm>=8" | |
| SCM_VERSION=$(python -m setuptools_scm) | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| if [ "$VERSION" != "$SCM_VERSION" ]; then | |
| echo "::error::Tag version ($VERSION) does not match setuptools-scm resolution ($SCM_VERSION). Make sure the tag points at the commit you want to release." | |
| exit 1 | |
| fi | |
| echo "Building version $VERSION from tag $TAG" | |
| # --------------------------------------------------------------------- | |
| # Matrix build: 5 targets | |
| # --------------------------------------------------------------------- | |
| build: | |
| name: Build ${{ matrix.target }} | |
| needs: verify-version | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux builds use ubuntu-22.04 (glibc 2.35) rather than a manylinux | |
| # container: manylinux ships a static CPython without libpython*.so, | |
| # which Nuitka cannot embed. The glibc-2.35 floor still covers | |
| # Ubuntu 22.04+, Debian 12+, RHEL 9+, and all current modern distros. | |
| - target: linux-amd64 | |
| runner: ubuntu-22.04 | |
| ext: '' | |
| archive: tar.gz | |
| - target: linux-arm64 | |
| runner: ubuntu-22.04-arm | |
| ext: '' | |
| archive: tar.gz | |
| - target: darwin-amd64 | |
| runner: macos-15-intel | |
| ext: '' | |
| archive: tar.gz | |
| - target: darwin-arm64 | |
| runner: macos-latest | |
| ext: '' | |
| archive: tar.gz | |
| - target: windows-amd64 | |
| runner: windows-latest | |
| ext: '.exe' | |
| archive: zip | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.verify-version.outputs.tag }} | |
| fetch-depth: 0 # setuptools-scm needs full history + tags | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install Nuitka build toolchain (Linux) | |
| if: startsWith(matrix.target, 'linux-') | |
| shell: bash | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y -qq patchelf ccache | |
| - name: Install ccache (macOS) | |
| if: startsWith(matrix.target, 'darwin-') | |
| shell: bash | |
| run: brew install ccache | |
| # Persist ccache across runs. Key hashes pyproject.toml + build-binary.sh | |
| # so a Nuitka pin bump or a build-script flag change buckets the cache | |
| # into a fresh partition. ccache itself is content-addressed, so stale | |
| # .o reuse is not a concern: if the generated C changes, it misses. | |
| # Skipped on Windows because Nuitka uses MSVC there and ccache does not | |
| # integrate with cl.exe. | |
| - name: Restore ccache | |
| if: ${{ !startsWith(matrix.target, 'windows-') }} | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/ccache | |
| ~/Library/Caches/ccache | |
| key: ccache-${{ matrix.target }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('pyproject.toml', 'scripts/build-binary.sh') }} | |
| restore-keys: | | |
| ccache-${{ matrix.target }}-py${{ env.PYTHON_VERSION }}- | |
| ccache-${{ matrix.target }}- | |
| - name: Configure ccache | |
| if: ${{ !startsWith(matrix.target, 'windows-') }} | |
| shell: bash | |
| run: | | |
| ccache --max-size=2G | |
| ccache --zero-stats | |
| - name: Install project + Nuitka | |
| shell: bash | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -e . | |
| python -m pip install "nuitka>=2.4" "zstandard>=0.22" | |
| - name: Build binary | |
| shell: bash | |
| run: | | |
| bash scripts/build-binary.sh | |
| ls -lh dist/ | |
| - name: Print ccache stats | |
| if: ${{ !startsWith(matrix.target, 'windows-') }} | |
| shell: bash | |
| run: ccache --show-stats | |
| - name: Smoke test binary | |
| shell: bash | |
| run: | | |
| BIN="./dist/agentrun${{ matrix.ext }}" | |
| "$BIN" --version | |
| "$BIN" --help >/dev/null | |
| "$BIN" config --help >/dev/null | |
| "$BIN" model --help >/dev/null | |
| "$BIN" sandbox --help >/dev/null | |
| "$BIN" skill --help >/dev/null | |
| "$BIN" super-agent --help >/dev/null | |
| "$BIN" tool --help >/dev/null | |
| echo "All 8 subcommand invocations OK on ${{ matrix.target }}" | |
| # --- Package (Unix) ----------------------------------------------- | |
| - name: Package tar.gz (Unix) | |
| if: matrix.archive == 'tar.gz' | |
| shell: bash | |
| run: | | |
| VERSION="${{ needs.verify-version.outputs.version }}" | |
| ASSET="agentrun-${VERSION}-${{ matrix.target }}.tar.gz" | |
| cd dist | |
| tar czf "../${ASSET}" "agentrun${{ matrix.ext }}" | |
| cd .. | |
| shasum -a 256 "${ASSET}" > "${ASSET}.sha256" | |
| echo "ASSET=${ASSET}" >> "$GITHUB_ENV" | |
| # --- Package (Windows) -------------------------------------------- | |
| - name: Package zip (Windows) | |
| if: matrix.archive == 'zip' | |
| shell: pwsh | |
| run: | | |
| $version = "${{ needs.verify-version.outputs.version }}" | |
| $asset = "agentrun-$version-${{ matrix.target }}.zip" | |
| Compress-Archive -Path "dist/agentrun${{ matrix.ext }}" -DestinationPath $asset -Force | |
| $hash = (Get-FileHash $asset -Algorithm SHA256).Hash.ToLower() | |
| "$hash $asset" | Out-File -Encoding ascii "$asset.sha256" | |
| echo "ASSET=$asset" >> $env:GITHUB_ENV | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: agentrun-${{ matrix.target }} | |
| path: | | |
| ${{ env.ASSET }} | |
| ${{ env.ASSET }}.sha256 | |
| retention-days: 7 | |
| if-no-files-found: error | |
| # --------------------------------------------------------------------- | |
| # Collect all artifacts and publish the Release | |
| # --------------------------------------------------------------------- | |
| release: | |
| name: Publish Release | |
| needs: [verify-version, build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: ls -lh dist/ | |
| - name: Create combined checksums file | |
| working-directory: dist | |
| run: | | |
| cat *.sha256 > SHA256SUMS | |
| echo "---" | |
| cat SHA256SUMS | |
| - name: Publish to GitHub Releases | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.verify-version.outputs.tag }} | |
| name: ${{ needs.verify-version.outputs.tag }} | |
| draft: false | |
| # PEP 440 pre-release markers: aN / bN / rcN / .devN. Tags must be in | |
| # canonical form (no '-'), so we match on these substrings instead. | |
| prerelease: ${{ contains(needs.verify-version.outputs.version, 'a') || contains(needs.verify-version.outputs.version, 'b') || contains(needs.verify-version.outputs.version, 'rc') || contains(needs.verify-version.outputs.version, 'dev') }} | |
| generate_release_notes: true | |
| files: | | |
| dist/agentrun-*.tar.gz | |
| dist/agentrun-*.zip | |
| dist/agentrun-*.sha256 | |
| dist/SHA256SUMS |