name: Release Binaries on: workflow_dispatch: inputs: release-version: description: 'Release Version' required: false type: string upload: description: 'Upload binaries to the release page' required: true default: false type: boolean runs-on: description: "Runner to use for the build" required: true type: choice # We use ubuntu-22.04 rather than the latest version to make the built # binaries more portable (eg functional aginast older glibc). options: - ubuntu-22.04 - ubuntu-22.04-arm - macos-14 workflow_call: inputs: release-version: description: 'Release Version' required: false type: string upload: description: 'Upload binaries to the release page' required: true default: false type: boolean runs-on: description: "Runner to use for the build" required: true type: string secrets: LLVM_TOKEN_GENERATOR_CLIENT_ID: description: "Client ID for our GitHub App we use for generating access tokens." required: true LLVM_TOKEN_GENERATOR_PRIVATE_KEY: description: "Private key for our GitHub App we use for generating access tokens." required: true permissions: contents: read # Default everything to read-only jobs: prepare: name: Prepare to build binaries environment: deployment: false name: ${{ case( github.event_name == 'pull_request', null, 'release') }} runs-on: ${{ inputs.runs-on }} if: github.repository_owner == 'llvm' outputs: release-version: ${{ steps.vars.outputs.release-version }} ref: ${{ steps.vars.outputs.ref }} upload: ${{ steps.vars.outputs.upload }} target-cmake-flags: ${{ steps.vars.outputs.target-cmake-flags }} build-flang: ${{ steps.vars.outputs.build-flang }} release-binary-basename: ${{ steps.vars.outputs.release-binary-basename }} release-binary-filename: ${{ steps.vars.outputs.release-binary-filename }} build-runs-on: ${{ steps.vars.outputs.build-runs-on }} test-runs-on: ${{ steps.vars.outputs.build-runs-on }} attestation-name: ${{ steps.vars.outputs.attestation-name }} steps: - name: Checkout LLVM uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Check Permissions if: github.event_name != 'pull_request' uses: ./.github/workflows/require-release-manager with: LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }} LLVM_TOKEN_GENERATOR_PRIVATE_KEY: ${{ secrets.LLVM_TOKEN_GENERATOR_PRIVATE_KEY }} # The name of the Windows binaries uses the version from source, so we need # to fetch it here. - id: version-from-source if: runner.os == 'Windows' uses: ./.github/workflows/get-llvm-version - name: Collect Variables id: vars env: LLVM_VERSION_FROM_SOURCE: ${{ steps.version-from-source.outputs.full-no-suffix }} shell: bash # In order for the test-release.sh script to run correctly, the LLVM # source needs to be at the following location relative to the build dir: # | X.Y.Z-rcN | ./rcN/llvm-project # | X.Y.Z | ./final/llvm-project # # We also need to set divergent flags based on the release version: # | X.Y.Z-rcN | -rc N -test-asserts # | X.Y.Z | -final run: | trimmed=$(echo ${{ inputs.release-version }} | xargs) if [ -n "$trimmed" ]; then release_version="$trimmed" ref="llvmorg-$release_version" else if [ "$RUNNER_OS" = "Windows" ]; then release_version="$LLVM_VERSION_FROM_SOURCE" else release_version="${{ (github.event_name == 'pull_request' && format('PR{0}', github.event.pull_request.number)) || 'CI'}}-$GITHUB_SHA" fi ref="$GITHUB_SHA" fi if [ -n "${{ inputs.upload }}" ]; then upload="${{ inputs.upload }}" else upload="false" fi echo "release-version=$release_version">> $GITHUB_OUTPUT echo "ref=$ref" >> $GITHUB_OUTPUT echo "upload=$upload" >> $GITHUB_OUTPUT if [ "$RUNNER_OS" = "Windows" ]; then case $RUNNER_ARCH in "X64" ) tar_arch="x86_64" ;; "ARM64" ) tar_arch="aarch64" ;; esac release_binary_basename="clang+llvm-$release_version-$tar_arch-pc-windows-msvc" else release_binary_basename="LLVM-$release_version-$RUNNER_OS-$RUNNER_ARCH" fi echo "release-binary-basename=$release_binary_basename" >> $GITHUB_OUTPUT echo "release-binary-filename=$release_binary_basename.tar.xz" >> $GITHUB_OUTPUT target="$RUNNER_OS-$RUNNER_ARCH" # The macOS builds try to cross compile some libraries so we need to # add extra CMake args to disable them. # See https://github.com/llvm/llvm-project/issues/99767 if [ "$RUNNER_OS" = "macOS" ]; then target_cmake_flags="$target_cmake_flags -DBOOTSTRAP_BOOTSTRAP_COMPILER_RT_ENABLE_IOS=OFF" if [ "$RUNNER_ARCH" = "ARM64" ]; then arches=arm64 fi target_cmake_flags="$target_cmake_flags -DBOOTSTRAP_BOOTSTRAP_DARWIN_osx_ARCHS=$arches -DBOOTSTRAP_BOOTSTRAP_DARWIN_osx_BUILTIN_ARCHS=$arches" fi if [ "$RUNNER_OS" = "Windows" ]; then # The build times out on Windows, so we need to disable LTO. target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF" fi case "${{ inputs.runs-on }}" in ubuntu-22.04* | windows-2022) build_runs_on="depot-${{ inputs.runs-on }}-16" test_runs_on=$build_runs_on ;; windows-11-arm) if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "schedule" ]; then build_runs_on="${{ inputs.runs-on }}" else build_runs_on="windows-11-arm-16core" fi test_runs_on=$build_runs_on ;; macos-14) if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then build_runs_on="${{ inputs.runs-on }}" else build_runs_on="depot-macos-14" fi test_runs_on="${{ inputs.runs-on }}" ;; *) test_runs_on="${{ inputs.runs-on }}" build_runs_on=$test_runs_on ;; esac case "$build_runs_on" in # These runners cannot build the full release package faster than # the 6 hours timeout limit, so we need to use a configuration # that builds more quickly. macos-14) bootstrap_prefix="BOOTSTRAP" target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF -DLLVM_RELEASE_ENABLE_PGO=OFF" ;; *) bootstrap_prefix="BOOTSTRAP_BOOTSTRAP" ;; esac target_cmake_flags="$target_cmake_flags -D${bootstrap_prefix}_CPACK_PACKAGE_FILE_NAME=$release_binary_basename" echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT echo "build-runs-on=$build_runs_on" >> $GITHUB_OUTPUT echo "test-runs-on=$test_runs_on" >> $GITHUB_OUTPUT echo "attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-binary-attestation" >> $GITHUB_OUTPUT build-release-package: name: "Build Release Package" needs: prepare if: github.repository_owner == 'llvm' runs-on: ${{ needs.prepare.outputs.build-runs-on }} outputs: digest: ${{ steps.digest.outputs.digest }} artifact-id: ${{ steps.artifact-upload.outputs.artifact-id }} steps: # We need to hard code the python library path for Windows, so in order # to do that we need to specify a specific python version. It's also # good practice to do this on other OSes so the version of python doesn't # get changed unexpectedly. - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.11.9' # For some reason this is needed on Windows or else the build system can't find python3.lib. - name: Setup Python library path if: runner.os == 'Windows' run: | echo "LIB=$env:LIB;C:\hostedtoolcache\windows\Python\3.11.9\$($env:RUNNER_ARCH.ToLower())\libs" >> $env:GITHUB_ENV - name: Setup crlf if: runner.os == 'Windows' run: | git config --global core.autocrlf false - name: Checkout LLVM uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false ref: ${{ needs.prepare.outputs.ref }} - name: Set Build Prefix id: setup-stage shell: bash run: | build_prefix=`pwd` if [ "${{ runner.os }}" = "Linux" ]; then sudo chown $USER:$USER /mnt/ build_prefix=/mnt/ fi echo "build-prefix=$build_prefix" >> $GITHUB_OUTPUT - name: Configure Linux/MacOS id: build if: runner.os != 'Windows' shell: bash run: | # There were some issues on the ARM64 MacOS runners with trying to build x86 object, # so we need to set some extra cmake flags to disable this. cmake -G Ninja -S llvm -B ${{ steps.setup-stage.outputs.build-prefix }}/build \ ${{ needs.prepare.outputs.target-cmake-flags }} \ -C clang/cmake/caches/Release.cmake - name: Build Linux/MacOS if: runner.os != 'Windows' shell: bash run: | ninja -v -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-package release_dir=`find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname 'stage2-bins'` mv $release_dir/${{ needs.prepare.outputs.release-binary-filename }} . - name: Build Windows id: build-windows if: runner.os == 'Windows' env: LLVM_VERSION: ${{ needs.prepare.outputs.release-version }} run: | subst S: ${{ github.workspace }} cd S:\llvm\utils\release\ .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version $env:LLVM_VERSION --local-python --skip-checkout $installer = (Get-ChildItem -Recurse -Filter "*.exe" | Select-Object -First 1).fullName $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Select-Object -First 1).fullName # Move installer to top-level directory so it is easier to upload. mv $installer $env:GITHUB_WORKSPACE mv $tarball $env:GITHUB_WORKSPACE echo "windows-installer-filename=$(Split-Path -Path $installer -Leaf)" >> $env:GITHUB_OUTPUT - name: Generate sha256 digest for binaries id: digest shell: bash env: RELEASE_BINARY_FILENAME: ${{ needs.prepare.outputs.release-binary-filename }} # This will be empty on non-Windows builds. WINDOWS_INSTALLER_FILENAME: ${{ steps.build-windows.outputs.windows-installer-filename }} run: | if [ "$RUNNER_OS" = "macOS" ]; then # Mac runners don't have sha256sum. sha256sum="shasum -a 256" else sha256sum="sha256sum" fi echo "digest=$(cat $WINDOWS_INSTALLER_FILENAME $RELEASE_BINARY_FILENAME | $sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 id: artifact-upload with: name: ${{ runner.os }}-${{ runner.arch }}-release-binary # Due to path differences on Windows when running in bash vs running on node, # we need to search for files in the current workspace. # The steps.build-windows.* variables will be empty on Linux/MacOS. path: | ${{ needs.prepare.outputs.release-binary-filename }} ${{ steps.build-windows.outputs.windows-installer-filename }} - name: Run Tests # These almost always fail so don't let them fail the build and prevent the uploads. if : runner.os != 'Windows' continue-on-error: true run: | ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-check-all upload-release-binaries: name: "Upload Release Binaries" needs: - prepare - build-release-package if: >- github.event_name != 'pull_request' runs-on: ubuntu-24.04 permissions: contents: write # For release uploads id-token: write # For artifact attestations attestations: write # For artifact attestations steps: - name: Checkout Release Scripts uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false sparse-checkout: | .github/workflows/upload-release-artifact llvm/utils/release/github-upload-release.py llvm/utils/git/requirements.txt sparse-checkout-cone-mode: false - name: Upload Artifacts uses: ./.github/workflows/upload-release-artifact with: release-version: ${{ needs.prepare.outputs.release-version }} artifact-id: ${{ needs.build-release-package.outputs.artifact-id }} attestation-name: ${{ needs.prepare.outputs.attestation-name }} digest: ${{ needs.build-release-package.outputs.digest }} upload: ${{ needs.prepare.outputs.upload }} user-token: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}