feat: add build cache #61
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: workflow | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - "README.md" | |
| pull_request: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - "README.md" | |
| workflow_dispatch: | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install lint tools | |
| run: python -m pip install ruff | |
| - name: Run Ruff | |
| run: ruff check src | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install package | |
| run: python -m pip install -e . | |
| - name: Run tests | |
| run: make test | |
| build-python: | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install build tools | |
| run: python -m pip install --upgrade build twine | |
| - name: Build distributions | |
| run: python -m build | |
| - name: Check distributions | |
| run: python -m twine check dist/* | |
| - name: Upload Python distribution artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: python-dist | |
| path: | | |
| dist/*.whl | |
| dist/*.tar.gz | |
| build-binary: | |
| name: build-binary (${{ matrix.asset-name }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint, test] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| asset-name: hl-linux-x86_64 | |
| output-name: hl | |
| install-system-tools: sudo apt-get update && sudo apt-get install -y patchelf ccache | |
| - os: ubuntu-24.04-arm | |
| asset-name: hl-linux-arm64 | |
| output-name: hl | |
| install-system-tools: sudo apt-get update && sudo apt-get install -y patchelf ccache | |
| - os: macos-latest | |
| asset-name: hl-macos-arm64 | |
| output-name: hl | |
| install-system-tools: "" | |
| - os: macos-latest | |
| asset-name: hl-macos-x86_64 | |
| output-name: hl | |
| install-system-tools: "" | |
| - os: windows-latest | |
| asset-name: hl-windows-x86_64.exe | |
| output-name: hl.exe | |
| install-system-tools: "" | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| # Nuitka stores generated C compilation results below this directory. Persist | |
| # it between workflow runs so unchanged dependencies do not get rebuilt. | |
| - name: Restore Nuitka compilation cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: .nuitka-cache | |
| key: nuitka-${{ runner.os }}-${{ matrix.asset-name }}-py312-${{ hashFiles('pyproject.toml', '.github/workflows/workflow.yml') }} | |
| restore-keys: | | |
| nuitka-${{ runner.os }}-${{ matrix.asset-name }}-py312- | |
| - name: Install system build tools | |
| if: matrix.install-system-tools != '' | |
| shell: bash | |
| run: ${{ matrix.install-system-tools }} | |
| - name: Install macOS compiler cache | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: brew install ccache | |
| - name: Install Python build tools | |
| run: python -m pip install --upgrade pip nuitka zstandard | |
| - name: Build single binary | |
| env: | |
| NUITKA_CACHE_DIR: ${{ github.workspace }}/.nuitka-cache | |
| shell: bash | |
| run: | | |
| python -m pip install --upgrade -e . | |
| python tools/patch_parsimonious_for_nuitka.py | |
| PYTHONPATH=src python -m nuitka \ | |
| --onefile \ | |
| --standalone \ | |
| --assume-yes-for-downloads \ | |
| --output-filename=${{ matrix.output-name }} \ | |
| --nofollow-import-to=parsimonious.tests \ | |
| --include-package=hl_cli \ | |
| --include-package=hyperliquid \ | |
| --include-package=eth_account \ | |
| --include-package=eth_abi \ | |
| --include-package=eth_utils \ | |
| --include-package=eth_typing \ | |
| --include-package=parsimonious \ | |
| --include-package=rich \ | |
| hl_nuitka_entry.py | |
| mkdir -p dist | |
| cp "${{ matrix.output-name }}" "dist/${{ matrix.asset-name }}" | |
| - name: Upload release artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binary-${{ matrix.asset-name }} | |
| path: dist/${{ matrix.asset-name }} | |
| release: | |
| if: "github.event_name == 'push' && github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'release: v')" | |
| runs-on: ubuntu-latest | |
| needs: [build-python, build-binary] | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Create tag and GitHub release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message }} | |
| run: | | |
| set -euo pipefail | |
| TAG="${COMMIT_MESSAGE#release: }" | |
| case "$TAG" in | |
| v[0-9]*.[0-9]*.[0-9]*) ;; | |
| *) | |
| echo "Commit message must be like: release: v0.1.7" | |
| exit 1 | |
| ;; | |
| esac | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| if git rev-parse "$TAG" >/dev/null 2>&1; then | |
| echo "Tag $TAG already exists locally" | |
| else | |
| git tag "$TAG" "$GITHUB_SHA" | |
| fi | |
| if git ls-remote --tags origin "refs/tags/$TAG" | grep -q "$TAG"; then | |
| echo "Tag $TAG already exists on origin" | |
| else | |
| git push origin "refs/tags/$TAG" | |
| fi | |
| mapfile -t assets < <(find dist -maxdepth 1 -type f | sort) | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release edit "$TAG" --latest | |
| else | |
| gh release create "$TAG" "${assets[@]}" \ | |
| --title "$TAG" \ | |
| --generate-notes \ | |
| --latest | |
| fi | |
| publish: | |
| if: "github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'release: v'))" | |
| runs-on: ubuntu-latest | |
| needs: build-python | |
| environment: | |
| name: release | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: python-dist | |
| path: dist | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 |