# Workflow to build binaries and release them. # Triggered by the schedule or manual dispatch, which might include # `@`. # # 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' runs-on: ${{ matrix.config.os }} strategy: fail-fast: false matrix: config: - name: windows os: windows-latest 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" "-DLLVM_USE_CRT_RELEASE=MT" 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 env: MACOSX_DEPLOYMENT_TARGET=10.9 cmake: >- "-DCMAKE_C_COMPILER=clang" "-DCMAKE_CXX_COMPILER=clang++" "-DLLVM_ENABLE_ZLIB=FORCE_ON" "-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64" # BoringSSL doesn't support universal binaries when building with ASM. grpc_cmake: >- "-DOPENSSL_NO_ASM=ON" - name: linux os: ubuntu-18.04 preinstall: sudo apt-get install ninja-build libz-dev libc-ares-dev cflags: -O3 -gline-tables-only -DNDEBUG -include $GITHUB_WORKSPACE/.github/workflows/lib_compat.h cmake: >- "-DCMAKE_C_COMPILER=clang" "-DCMAKE_CXX_COMPILER=clang++" "-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" 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" "-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" "-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: 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}'