Build release binaries #251
This file contains 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
# Workflow to build binaries and release them. | |
# Triggered by the schedule or manual dispatch, which might include | |
# `<owner/llvm-project>@<full-sha>`. | |
# | |
# Because the build takes more than an hour, our GITHUB_TOKEN credentials may | |
# expire. A token `secrets.RELEASE_TOKEN` must exist with public_repo scope. | |
name: Build release binaries | |
on: | |
# Run weekly on sunday at 21:37 UTC (arbitrary) | |
schedule: | |
- cron: '37 21 * * SUN' | |
workflow_dispatch: | |
inputs: | |
commit: | |
description: 'Commit to build from' | |
required: true | |
repo: | |
description: 'Repository to build from' | |
required: true | |
default: 'llvm/llvm-project' | |
release_name: | |
description: 'Release name' | |
required: true | |
tag: | |
description: 'Tag name' | |
required: true | |
description: | |
description: 'Release description' | |
required: true | |
jobs: | |
schedule_environment: | |
name: Create default build environment | |
runs-on: ubuntu-latest | |
if: ${{ github.event_name == 'schedule' }} | |
steps: | |
- name: Install deps | |
run: | | |
sudo apt-get install jq | |
- name: Clone scripts | |
uses: actions/checkout@v2 | |
# Choose the commit to build a release from. | |
# | |
# We want to avoid unbuildable revisions: choose the last green from CI. | |
# FIXME: The criteria should be some consistent set of buildbots passing. | |
# Use clangd/actions/pick after | |
# https://github.com/ramasilveyra/last-successful-gh-commit/issues/2 has | |
# been addressed. | |
- name: Get commit hash for LLVM head | |
run: > | |
COMMIT=$(curl --fail --show-error | |
"https://api.github.com/repos/llvm/llvm-project/commits/main" | | |
jq ".sha" -r) | |
echo "LLVM_COMMIT=$COMMIT" >> $GITHUB_ENV | |
- name: Compute release info | |
run: | | |
echo "RELEASE_COMMIT_SHORT=$(printf '%.12s' ${{ env.LLVM_COMMIT }})" >> $GITHUB_ENV | |
echo "RELEASE_DATE=$(date -u +%Y%m%d)" >> $GITHUB_ENV | |
echo "LLVM_REPO=llvm/llvm-project" >> commit.env | |
echo "LLVM_COMMIT=${{ env.LLVM_COMMIT }}" >> commit.env | |
- name: Use date as the tag name | |
run: > | |
echo "TAG_NAME=snapshot_${{ env.RELEASE_DATE }}" >> commit.env | |
- name: Use date and release commit as release name | |
run: > | |
echo "RELEASE_NAME=${{ env.RELEASE_DATE }} @${{ env.RELEASE_COMMIT_SHORT }}" >> commit.env | |
- name: Generate default release description | |
run: > | |
echo "RELEASE_DESCRIPTION=Unstable snapshot of clangd on ${{ env.RELEASE_DATE }}." >> commit.env | |
- name: Upload result | |
uses: actions/upload-artifact@v2 | |
with: | |
name: env | |
path: commit.env | |
workflow_dispatch_environment: | |
name: Use inputs to create build environment | |
runs-on: ubuntu-latest | |
if: ${{ github.event_name == 'workflow_dispatch' }} | |
steps: | |
- name: Use repo and commit from the inputs | |
run: | | |
echo "LLVM_REPO=${{ github.event.inputs.repo }}" >> commit.env | |
echo "LLVM_COMMIT=${{ github.event.inputs.commit }}" >> commit.env | |
echo "TAG_NAME=${{ github.event.inputs.tag }}" >> commit.env | |
echo "RELEASE_NAME=${{ github.event.inputs.release_name }}" >> commit.env | |
echo "RELEASE_DESCRIPTION=${{ github.event.inputs.description }}" >> commit.env | |
- name: Upload result | |
uses: actions/upload-artifact@v2 | |
with: | |
name: env | |
path: commit.env | |
create_release: | |
name: Create release | |
runs-on: ubuntu-latest | |
needs: [schedule_environment, workflow_dispatch_environment] | |
# Use always() and manually check results here since GitHub Actions do not | |
# support conditionally skipping jobs and there is no way to "exit with | |
# success" from a job. | |
if: always() && (needs.schedule_environment.result == 'success' || needs.workflow_dispatch_environment.result == 'success') | |
steps: | |
- name: Fetch environment variables | |
uses: actions/download-artifact@v1 | |
with: | |
name: | |
env | |
- name: Set environment variables | |
run: | | |
cat env/commit.env >> $GITHUB_ENV | |
- name: Create release | |
uses: actions/create-release@master | |
id: create_release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: ${{ env.TAG_NAME }} | |
release_name: ${{ env.RELEASE_NAME }} | |
body: | | |
${{ env.RELEASE_DESCRIPTION }} | |
Built from ${{ env.LLVM_REPO }}@${{ env.LLVM_COMMIT }}. | |
prerelease: true | |
draft: true | |
- name: Preserve release info | |
run: | | |
echo "UPLOAD_URL=${{ steps.create_release.outputs.upload_url }}" >> release.env | |
echo "TAG_NAME=${{ env.TAG_NAME }}" >> release.env | |
echo "RELEASE_ID=${{ steps.create_release.outputs.id }}" >> release.env | |
- name: Upload result | |
uses: actions/upload-artifact@v2 | |
with: | |
name: release | |
path: release.env | |
# Build clangd using CMake/Ninja. | |
# | |
# This step is a template that runs on each OS, build config varies slightly. | |
# Uploading releases needs a per-job token that expires after an hour. | |
build: | |
name: Build ${{ matrix.config.name }} | |
needs: create_release | |
if: always() && needs.create_release.result == 'success' | |
strategy: | |
fail-fast: false | |
matrix: | |
config: | |
- name: windows | |
os: windows-2019 | |
preinstall: choco install ninja nasm | |
vcvars: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat | |
cflags: /O2 /DNDEBUG | |
cmake: >- | |
"-DCMAKE_C_COMPILER=cl" | |
"-DCMAKE_CXX_COMPILER=cl" | |
"-DLLVM_ENABLE_ZLIB=OFF" | |
"-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded" | |
grpc_cmake: >- | |
"-DgRPC_MSVC_STATIC_RUNTIME=ON" | |
binary_extension: ".exe" | |
- name: mac | |
os: macos-latest | |
preinstall: brew install ninja zlib p7zip | |
cflags: -O3 -gline-tables-only -DNDEBUG | |
cmake: >- | |
"-DCMAKE_C_COMPILER=clang" | |
"-DCMAKE_CXX_COMPILER=clang++" | |
"-DLLVM_ENABLE_ZLIB=FORCE_ON" | |
"-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64" | |
"-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9" | |
# BoringSSL doesn't support universal binaries when building with ASM. | |
grpc_cmake: >- | |
"-DOPENSSL_NO_ASM=ON" | |
- name: linux | |
os: ubuntu-latest | |
container: ubuntu:18.04 | |
preinstall: >- | |
apt-get update && | |
apt-get install -y ninja-build libz-dev libc-ares-dev wget clang-9 | |
software-properties-common p7zip-full curl && | |
add-apt-repository ppa:git-core/ppa && | |
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - && | |
apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' && | |
apt-get update && | |
apt-get install -y git cmake | |
cflags: -O3 -gline-tables-only -DNDEBUG -include $GITHUB_WORKSPACE/.github/workflows/lib_compat.h | |
cmake: >- | |
"-DCMAKE_C_COMPILER=clang-9" | |
"-DCMAKE_CXX_COMPILER=clang++-9" | |
"-DCMAKE_EXE_LINKER_FLAGS_RELEASE=-static-libgcc -Wl,--compress-debug-sections=zlib" | |
"-DLLVM_STATIC_LINK_CXX_STDLIB=ON" | |
"-DLLVM_ENABLE_ZLIB=FORCE_ON" | |
"-DCMAKE_PROJECT_INCLUDE=$GITHUB_WORKSPACE/.github/workflows/linux-static-deps.cmake" | |
# Using c-ares as a module prevents dynamic linking of unneeded | |
# libraries. All other gRPC dependencies can be built from sources. | |
grpc_cmake: >- | |
"-DgRPC_CARES_PROVIDER=package" | |
runs-on: ${{ matrix.config.os }} | |
container: ${{ matrix.config.container }} | |
steps: | |
- name: Clone scripts | |
uses: actions/checkout@v2 | |
with: { ref: master } | |
- name: Install tools | |
run: ${{ matrix.config.preinstall }} | |
# Visual Studio tools require a bunch of environment variables to be set. | |
# Run vcvars64.bat and re-export the current environment to the workflow. | |
# (It'd be nice to only export the variables that *changed*, oh well). | |
- name: Visual Studio environment | |
if: matrix.config.name == 'windows' | |
shell: powershell | |
run: | | |
cmd /c "`"${{ matrix.config.vcvars }}`">NUL && set" | Foreach-Object { | |
$name, $value = $_ -split '=', 2 | |
if ($value) { | |
echo "$($name)=$($value)" >> $env:GITHUB_ENV | |
} | |
} | |
- name: Clone gRPC | |
uses: actions/checkout@v2 | |
with: | |
repository: grpc/grpc | |
path: grpc | |
# We use the same version of gRPC for LLVM's clangd-ubuntu-tsan | |
# buildbot. | |
# https://github.com/llvm/llvm-zorg/blob/main/buildbot/google/docker/buildbot-clangd-ubuntu-clang/Dockerfile | |
ref: v1.36.3 | |
submodules: recursive | |
- name: Build gRPC | |
run: > | |
mkdir $HOME/grpc-installation | |
mkdir grpc-build | |
cmake -G Ninja -S grpc -B grpc-build | |
"-DgRPC_INSTALL=ON" | |
"-DCMAKE_INSTALL_PREFIX=$HOME/grpc-installation" | |
"-DCMAKE_BUILD_TYPE=Release" | |
"-DCMAKE_C_FLAGS_RELEASE=${{ matrix.config.cflags }}" | |
"-DCMAKE_CXX_FLAGS_RELEASE=${{ matrix.config.cflags }}" | |
${{ matrix.config.grpc_cmake }} ${{ matrix.config.cmake }} | |
ninja -C grpc-build install | |
- name: Fetch target commit | |
uses: actions/download-artifact@v1 | |
with: | |
name: | |
env | |
- name: Fetch release info | |
uses: actions/download-artifact@v1 | |
with: | |
name: | |
release | |
- name: Put release info into env | |
run: | | |
cat env/commit.env >> $GITHUB_ENV | |
cat release/release.env >> $GITHUB_ENV | |
shell: bash | |
# Use environment variables set above to create a directory. This needs | |
# to be a separate step because they are not in the context yet when | |
# being set. | |
- name: Set build directory | |
run: | | |
echo "CLANGD_DIR=clangd_${{ env.TAG_NAME }}" >> $GITHUB_ENV | |
shell: bash | |
- name: Clone LLVM | |
uses: actions/checkout@v2 | |
with: | |
repository: ${{ env.LLVM_REPO }} | |
path: llvm-project | |
ref: ${{ env.LLVM_COMMIT }} | |
- name: CMake | |
run: > | |
mkdir ${{ env.CLANGD_DIR }} | |
cp llvm-project/llvm/LICENSE.TXT ${{ env.CLANGD_DIR }} | |
cmake -G Ninja -S llvm-project/llvm -B ${{ env.CLANGD_DIR }} | |
"-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;openmp" | |
"-DLLVM_ENABLE_ASSERTIONS=OFF" | |
"-DLLVM_ENABLE_BACKTRACES=ON" | |
"-DLLVM_ENABLE_TERMINFO=OFF" | |
"-DCMAKE_BUILD_TYPE=Release" | |
"-DCLANG_PLUGIN_SUPPORT=OFF" | |
"-DLLVM_ENABLE_PLUGINS=OFF" | |
"-DCMAKE_C_FLAGS_RELEASE=${{ matrix.config.cflags }}" | |
"-DCMAKE_CXX_FLAGS_RELEASE=${{ matrix.config.cflags }}" | |
"-DCLANGD_ENABLE_REMOTE=ON" | |
"-DLLVM_ENABLE_ZSTD=OFF" | |
"-DGRPC_INSTALL_PATH=$HOME/grpc-installation" | |
${{ matrix.config.cmake }} | |
- name: Ninja | |
run: > | |
ninja -C ${{ env.CLANGD_DIR }} clangd clangd-indexer clangd-index-server | |
clangd-index-server-monitor | |
- name: Install OpenMP headers | |
shell: bash | |
run: > | |
cp ${{ env.CLANGD_DIR }}/projects/openmp/runtime/src/omp{,-tools}.h ${{ env.CLANGD_DIR }}/lib/clang/*/include | |
|| true # Don't let the non-existing omp headers block the release. | |
- name: Archive clangd | |
run: > | |
7z a clangd.zip | |
${{ env.CLANGD_DIR }}/LICENSE.TXT | |
${{ env.CLANGD_DIR }}/bin/clangd${{ matrix.config.binary_extension }} | |
${{ env.CLANGD_DIR }}/lib/clang | |
- name: Archive indexing-tools | |
run: > | |
7z a indexing-tools.zip | |
${{ env.CLANGD_DIR }}/LICENSE.TXT | |
${{ env.CLANGD_DIR }}/bin/clangd-indexer${{ matrix.config.binary_extension }} | |
${{ env.CLANGD_DIR }}/bin/clangd-index-server${{ matrix.config.binary_extension }} | |
${{ env.CLANGD_DIR }}/bin/clangd-index-server-monitor${{ matrix.config.binary_extension }} | |
${{ env.CLANGD_DIR }}/lib/clang | |
- name: Upload clangd asset | |
uses: actions/upload-release-asset@v1.0.1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
with: | |
upload_url: ${{ env.UPLOAD_URL }} | |
asset_name: clangd-${{ matrix.config.name }}-${{ env.TAG_NAME }}.zip | |
asset_path: clangd.zip | |
asset_content_type: application/zip | |
- name: Upload indexing-tools asset | |
uses: actions/upload-release-asset@v1.0.1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
with: | |
upload_url: ${{ env.UPLOAD_URL }} | |
asset_name: clangd_indexing_tools-${{ matrix.config.name }}-${{ env.TAG_NAME }}.zip | |
asset_path: indexing-tools.zip | |
asset_content_type: application/zip | |
- name: Check binary compatibility | |
if: matrix.config.name == 'linux' | |
run: .github/workflows/lib_compat_test.py --lib=GLIBC_2.18 "$CLANGD_DIR/bin/clangd" | |
# Create the release, and upload the artifacts to it. | |
finalize: | |
runs-on: ubuntu-latest | |
needs: build | |
if: always() && needs.build.result == 'success' | |
steps: | |
- name: Fetch release info | |
uses: actions/download-artifact@v1 | |
with: | |
name: | |
release | |
- name: Update the env variables | |
run: > | |
cat release/release.env >> $GITHUB_ENV | |
- name: Publish release | |
run: > | |
curl -XPATCH | |
"-HAuthorization: Bearer ${{ secrets.RELEASE_TOKEN }}" | |
"https://api.github.com/repos/${{ github.repository }}/releases/${{ env.RELEASE_ID }}" | |
"-d" '{"draft": false}' |