| 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: |
| RELEASE_TASKS_USER_TOKEN: |
| description: "Secret used to check user permissions." |
| required: false |
| |
| |
| permissions: |
| contents: read # Default everything to read-only |
| |
| jobs: |
| prepare: |
| name: Prepare to build binaries |
| 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 }} |
| |
| steps: |
| # It's good practice to use setup-python, but this is also required on macos-14 |
| # due to https://github.com/actions/runner-images/issues/10385 |
| - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 |
| with: |
| python-version: '3.14' |
| |
| - name: Checkout LLVM |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| |
| - name: Install Dependencies |
| shell: bash |
| run: | |
| pip install --require-hashes -r ./llvm/utils/git/requirements.txt |
| |
| - name: Check Permissions |
| if: github.event_name != 'pull_request' |
| env: |
| GITHUB_TOKEN: ${{ github.token }} |
| USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }} |
| shell: bash |
| run: | |
| ./llvm/utils/release/./github-upload-release.py --token "$GITHUB_TOKEN" --user "$GITHUB_ACTOR" --user-token "$USER_TOKEN" check-permissions |
| |
| # 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 |
| ;; |
| 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 |
| |
| 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@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 |
| with: |
| python-version: '3.10' |
| |
| # 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.10.11\x64\libs" >> $env:GITHUB_ENV |
| |
| - name: Setup crlf |
| if: runner.os == 'Windows' |
| run: | |
| git config --global core.autocrlf false |
| |
| - name: Checkout LLVM |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| with: |
| 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: | |
| echo "digest=$(cat $WINDOWS_INSTALLER_FILENAME $RELEASE_BINARY_FILENAME | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT |
| |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 |
| 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| with: |
| 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: |
| artifact-id: ${{ needs.build-release-package.outputs.artifact-id }} |
| attestation-name: ${{ runner.os }}-${{ runner.arch }}-release-binary-attestation |
| digest: ${{ needs.build-release-package.outputs.digest }} |
| upload: ${{ needs.prepare.outputs.upload }} |