Pre Release #174
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
| # | |
| # Copyright (c) 2024, Trail of Bits, Inc. | |
| # | |
| # This source code is licensed in accordance with the terms specified in | |
| # the LICENSE file found in the root directory of this source tree. | |
| # | |
| name: "Pre Release" | |
| on: | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: | |
| - completed | |
| branches: | |
| - "main" | |
| workflow_dispatch: | |
| inputs: | |
| release_notes: | |
| description: "Release notes" | |
| required: true | |
| type: string | |
| permissions: read-all | |
| jobs: | |
| build_prerelease: | |
| strategy: | |
| matrix: | |
| llvm-version: [22] | |
| image-version: [22.04] | |
| arch: [amd64, arm64] | |
| name: "Build Release and Doc" | |
| runs-on: ${{ matrix.arch == 'arm64' && format('ubuntu-{0}-arm', matrix.image-version) || format('ubuntu-{0}', matrix.image-version) }} | |
| if: ${{ (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') || github.event.workflow_run.conclusion == 'success' }} | |
| timeout-minutes: 60 | |
| # Build job only produces artifacts; `contents: write` is reserved for | |
| # the downstream `publish_release` and `deploy_doc` jobs that actually | |
| # touch the repository (release assets and gh-pages respectively). | |
| permissions: | |
| contents: read | |
| env: | |
| DEV_IMAGE: ghcr.io/lifting-bits/patchestry-ubuntu-${{ matrix.image-version }}-llvm-${{ matrix.llvm-version }}-dev:latest | |
| CMAKE_PREFIX_PATH: "/usr/lib/llvm-${{ matrix.llvm-version }}/lib/cmake/mlir/;/usr/lib/llvm-${{ matrix.llvm-version }}/lib/cmake/clang/" | |
| TOOLCHAIN: ${{ github.workspace }}/cmake/lld.toolchain.cmake | |
| LLVM_EXTERNAL_LIT: "/usr/local/bin/lit" | |
| steps: | |
| - name: Free up disk space | |
| uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: false | |
| swap-storage: true | |
| - name: Clone the Patchestry repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| fetch-depth: 1 | |
| - name: Pull dev container image | |
| run: docker pull $DEV_IMAGE | |
| - name: Create gitconfig for safe directories | |
| run: | | |
| cat > /tmp/.gitconfig << 'EOF' | |
| [safe] | |
| directory = /workspace | |
| directory = /workspace/vendor/glog/src | |
| directory = /workspace/vendor/gflags/src | |
| directory = /workspace/vendor/z3/src | |
| directory = /workspace/vendor/llvm-project/src | |
| EOF | |
| # CPACK_SYSTEM_NAME must be set at configure time. `include(CPack)` | |
| # bakes CPACK_PACKAGE_FILE_NAME into CPackConfig.cmake during configure, | |
| # so a later `cpack -D CPACK_SYSTEM_NAME=...` has no effect on the | |
| # tarball name and both arches collide on `patchestry-<ver>-Linux.tar.gz`. | |
| - name: Configure build | |
| run: | | |
| docker run --rm \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -v /tmp/.gitconfig:/root/.gitconfig:ro \ | |
| -w /workspace \ | |
| -e CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ | |
| -e LLVM_EXTERNAL_LIT="${LLVM_EXTERNAL_LIT}" \ | |
| -e CI=true \ | |
| $DEV_IMAGE \ | |
| cmake --preset ci \ | |
| -DLLVM_Z3_INSTALL_DIR=/usr/local \ | |
| -DCPACK_SYSTEM_NAME=Linux-${{ matrix.arch }} | |
| - name: Build release | |
| run: | | |
| docker run --rm \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -v /tmp/.gitconfig:/root/.gitconfig:ro \ | |
| -w /workspace \ | |
| -e CI=true \ | |
| $DEV_IMAGE \ | |
| cmake --build --preset ci-release -j $(nproc) | |
| # Docs are arch-independent; build on amd64 only to avoid duplicate work | |
| # and an artifact-name collision on the mkdocs-sites upload below. | |
| - name: Build Patchestry Doc | |
| if: matrix.arch == 'amd64' | |
| run: | | |
| docker run --rm \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -v /tmp/.gitconfig:/root/.gitconfig:ro \ | |
| -w /workspace \ | |
| $DEV_IMAGE \ | |
| cmake --build --preset ci-release --target mlir-doc | |
| - name: Build Patchestry Pages | |
| if: matrix.arch == 'amd64' | |
| run: | | |
| docker run --rm \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -v /tmp/.gitconfig:/root/.gitconfig:ro \ | |
| -w /workspace \ | |
| $DEV_IMAGE \ | |
| bash -c "sh ./www/setup.sh _site ./builds/ci/ && pip install mkdocs mkdocs-material && mkdocs build --config-file _site/mkdocs.yml --site-dir _site/site" | |
| - name: Package | |
| run: | | |
| docker run --rm \ | |
| -v ${{ github.workspace }}:/workspace \ | |
| -v /tmp/.gitconfig:/root/.gitconfig:ro \ | |
| -w /workspace \ | |
| $DEV_IMAGE \ | |
| cpack --preset ci | |
| # Upload both artifacts before any publish step can fail. The | |
| # downstream `publish_release` and `deploy_doc` jobs each consume one | |
| # of these, so keeping the uploads here (and running them on every | |
| # successful build) means a release-asset failure never blocks the | |
| # docs deploy, and a docs-deploy failure never blocks the release. | |
| - name: Upload Patchestry build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Patchestry-${{ matrix.arch }} | |
| path: ./builds/ci/package/* | |
| retention-days: 1 | |
| - name: Upload Patchestry sites | |
| if: matrix.arch == 'amd64' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mkdocs-sites | |
| path: _site | |
| if-no-files-found: error | |
| # Release publishing is split from `build_prerelease` so a publish | |
| # failure can't skip the `deploy_doc` job and vice versa. | |
| # | |
| # Only runs on manual `workflow_dispatch` — rolling builds on every | |
| # main push would accumulate releases quickly. Each publish creates a | |
| # fresh release tagged with the short commit SHA so every tag is | |
| # unique and immutability semantics never conflict (GitHub reserves | |
| # a tag name once used by an immutable release). | |
| publish_release: | |
| name: "Publish Pre-Release" | |
| needs: build_prerelease | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| # Deliberately not merging artifacts into one directory: if two uploads | |
| # ever ship tarballs with the same basename, the second would silently | |
| # overwrite the first. Per-artifact subdirs surface collisions. | |
| - name: Download Patchestry build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: Patchestry-* | |
| path: ./package | |
| - name: Verify both arch tarballs present | |
| run: | | |
| amd=$(ls ./package/Patchestry-amd64/patchestry-*-Linux-amd64.tar.gz 2>/dev/null | wc -l) | |
| arm=$(ls ./package/Patchestry-arm64/patchestry-*-Linux-arm64.tar.gz 2>/dev/null | wc -l) | |
| if [ "$amd" -ne 1 ] || [ "$arm" -ne 1 ]; then | |
| echo "::error::Expected 1 amd64 + 1 arm64 tarball, got amd=$amd arm=$arm" | |
| ls -laR ./package | |
| exit 1 | |
| fi | |
| - name: Publish Pre-Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| RELEASE_NOTES: ${{ inputs.release_notes }} | |
| run: | | |
| tag="${GITHUB_SHA:0:7}-${GITHUB_RUN_NUMBER}" | |
| gh release create "${tag}" \ | |
| --target "${GITHUB_SHA}" \ | |
| --prerelease \ | |
| --notes "${RELEASE_NOTES}" \ | |
| ./package/Patchestry-*/patchestry-*-Linux-*.tar.gz | |
| deploy_doc: | |
| needs: build_prerelease | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Clone the Patchestry repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Download Patchestry sites | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: mkdocs-sites | |
| path: _site | |
| # Deploy with the Docker-based action in a non-containerized job | |
| - name: Deploy Patchestry sites to gh-pages | |
| uses: mhausenblas/mkdocs-deploy-gh-pages@d77dd03172e96abbcdb081d8c948224762033653 # 1.26 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CONFIG_FILE: _site/mkdocs.yml |