Skip to content

Pre Release

Pre Release #174

Workflow file for this run

#
# 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