[libcxx-commits] [libcxx] 9f21d34 - [libc++] Initial support for pre-commit CI with Buildkite

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 25 06:51:26 PDT 2020


Author: Louis Dionne
Date: 2020-09-25T09:51:10-04:00
New Revision: 9f21d341e83842c20f0cd09bb6b97617441ef55a

URL: https://github.com/llvm/llvm-project/commit/9f21d341e83842c20f0cd09bb6b97617441ef55a
DIFF: https://github.com/llvm/llvm-project/commit/9f21d341e83842c20f0cd09bb6b97617441ef55a.diff

LOG: [libc++] Initial support for pre-commit CI with Buildkite

This commit adds basic files and scripts that are used for the Buildkite
pre-commit CI setup. This was tested to mostly work on a fork of llvm-project,
however some adjustments will have to be made as we complete the real
setup.

Added: 
    libcxx/utils/ci/Dockerfile
    libcxx/utils/ci/buildkite-pipeline.yml
    libcxx/utils/ci/phabricator-report
    libcxx/utils/ci/run-buildbot.sh
    libcxx/utils/ci/secrets.env

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/libcxx/utils/ci/Dockerfile b/libcxx/utils/ci/Dockerfile
new file mode 100644
index 000000000000..a83936b47083
--- /dev/null
+++ b/libcxx/utils/ci/Dockerfile
@@ -0,0 +1,63 @@
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+
+#
+# This Dockerfile describes the base image used to run the various libc++
+# build bots. By default, the image runs the Buildkite Agent, however one
+# can also just start the image with a shell to debug CI failures.
+#
+# To start a Buildkite Agent, run it as:
+#   $ docker run --env-file secrets.env -it $(docker build -q .)
+#
+# The environment variables in `secrets.env` must be replaced by the actual
+# tokens for this to work. These should obviously never be checked in.
+#
+# To start a shell in the Docker image, use:
+#   $ docker run -it --volume "$(git rev-parse --show-toplevel):/llvm" --workdir "/llvm" $(docker build -q .) bash
+#
+# This will fire up the Docker container and mount the root of the monorepo
+# as /llvm in the container. Be careful, the state in /llvm is shared between
+# the container and the host machine.
+#
+
+FROM ubuntu:bionic
+
+RUN apt-get update
+RUN apt-get install -y bash curl
+
+# Install the most recently released LLVM
+RUN apt-get install -y lsb-release wget software-properties-common
+RUN bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
+RUN ln -s $(find /usr/bin -regex '.+/clang\+\+-[a-zA-Z0-9.]+') /usr/bin/clang++
+RUN ln -s $(find /usr/bin -regex '.+/clang-[a-zA-Z0-9.]+') /usr/bin/clang
+
+# Install a recent GCC
+RUN add-apt-repository ppa:ubuntu-toolchain-r/test
+RUN apt-get update && apt install -y gcc-10 g++-10
+RUN ln -s $(find /usr/bin -regex '.+/g\+\+-[a-zA-Z0-9.]+') /usr/bin/g++
+RUN ln -s $(find /usr/bin -regex '.+/gcc-[a-zA-Z0-9.]+') /usr/bin/gcc
+
+# Install a recent CMake
+RUN wget https://github.com/Kitware/CMake/releases/download/v3.18.2/cmake-3.18.2-Linux-x86_64.sh -O /tmp/install-cmake.sh
+RUN bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license
+RUN rm /tmp/install-cmake.sh
+
+# Install other tools used by the build or the test suite
+RUN apt-get install -y ninja-build python3 sphinx-doc
+
+# Install the Buildkite agent and dependencies
+RUN bash -c "$(curl -sL https://raw.githubusercontent.com/buildkite/agent/master/install.sh)"
+RUN apt-get install -y git
+ENV PATH="${PATH}:/root/.buildkite-agent/bin"
+
+# Install the Phabricator Python module to allow uploading results to Phabricator
+RUN apt-get install -y python3-pip
+RUN pip3 install phabricator
+
+# By default, start the Buildkite agent (this requires a token).
+CMD buildkite-agent start --tags "queue=libcxx-builders"

diff  --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
new file mode 100644
index 000000000000..605f103a3d95
--- /dev/null
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -0,0 +1,81 @@
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+
+#
+# This file describes the various pre-commit CI bots used to test libc++.
+#
+# This file should never contain logic -- all the logic must be offloaded
+# into scripts. This is critical to being able to reproduce CI issues outside
+# of the CI environment, which is important for debugging.
+#
+
+steps:
+  - label: "C++03"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-cxx03 | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "C++11"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-cxx11 | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "C++14"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-cxx14 | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "C++17"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-cxx17 | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "C++20"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-cxx2a | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "-fno-exceptions"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-noexceptions | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "32 bits"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-32bit | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "GCC/C++20"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-gcc | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "ASAN"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-asan | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "TSAN"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-tsan | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "UBSAN"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-ubsan | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "With LLVM's libunwind"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-with_llvm_unwinder | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"
+
+  - label: "Single-threaded"
+    command: "set -o pipefail && libcxx/utils/ci/run-buildbot.sh x86_64-ubuntu-singlethreaded | libcxx/utils/ci/phabricator-report"
+    agents:
+      queue: "libcxx-builders"

diff  --git a/libcxx/utils/ci/phabricator-report b/libcxx/utils/ci/phabricator-report
new file mode 100755
index 000000000000..14eac69c4c80
--- /dev/null
+++ b/libcxx/utils/ci/phabricator-report
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+
+import argparse
+import io
+import os
+import phabricator
+import re
+import subprocess
+import sys
+import time
+
+LLVM_REVIEWS_API = "https://reviews.llvm.org/api/"
+
+def main(argv):
+    parser = argparse.ArgumentParser(
+        description="""
+This script gathers information about a Buildkite build and updates the
+Phabricator review associated to the HEAD commit with those results.
+
+The intended usage of this script is to pipe the output of a command defined
+in a Buildkite pipeline into it. The script will echo everything to stdout,
+like tee, but will also update the Phabricator review associated to HEAD
+with the results of the build.
+
+The script is assumed to be running inside a Buildkite agent, and as such,
+it assumes the existence of several environment variables that are specific
+to Buildkite. It also assumes that it is running in a context where the HEAD
+commit contains the Phabricator ID of the review to update.
+""")
+    parser.add_argument('--token', type=str, required=True,
+        help="The Conduit token to use to authenticate with {}.".format(LLVM_REVIEWS_API))
+    args = parser.parse_args(argv)
+
+    for var in ('BUILDKITE_LABEL', 'BUILDKITE_JOB_ID', 'BUILDKITE_BUILD_URL', 'CONDUIT_TOKEN'):
+        if var not in os.environ:
+            raise RuntimeError(
+                'The {} environment variable must exist -- are you running '
+                'this script from a Buildkite agent?'.format(var))
+
+    # First, read all the log input and write it line-by-line to stdout.
+    # This is important so that we can follow progress in the Buildkite
+    # console. Since we're being piped into in real time, it's also the
+    # moment to time the duration of the job.
+    start = time.time()
+    log = io.StringIO()
+    while True:
+        line = sys.stdin.readline()
+        if line == '':
+            break
+        sys.stdout.write(line)
+        sys.stdout.flush() # flush every line to avoid buffering
+        log.write(line)
+    end = time.time()
+
+    # Then, extract information from the environment and post-process the logs.
+    log.seek(0)
+    log = log.read()
+    result = 'fail' if 'FAILED:' in log else 'pass'
+    resultObject = {
+        'name': '{BUILDKITE_LABEL} ({BUILDKITE_BUILD_URL}#{BUILDKITE_JOB_ID})'.format(**os.environ),
+        'result': result,
+        'duration': end - start,
+        'details': log
+    }
+
+    commitMessage = subprocess.check_output(['git', 'log', '--format=%B' , '-n', '1']).decode()
+    phabricatorID = re.search(r'^Phabricator-ID:\s+(.+)$', commitMessage, flags=re.MULTILINE)
+    if not phabricatorID:
+        raise RuntimeError('Could not find the Phabricator ID in the commit message. '
+                           'The commit message was:\n{}'.format(commitMessage))
+    else:
+        phabricatorID = phabricatorID.group(1)
+
+    token = os.environ['CONDUIT_TOKEN']
+    phab = phabricator.Phabricator(token=token, host=LLVM_REVIEWS_API)
+    phab.harbormaster.sendmessage(buildTargetPHID=phabricatorID, type=result, unit=[resultObject])
+
+if __name__ == '__main__':
+    main(sys.argv[1:])

diff  --git a/libcxx/utils/ci/run-buildbot.sh b/libcxx/utils/ci/run-buildbot.sh
new file mode 100755
index 000000000000..4dd1d485d4c5
--- /dev/null
+++ b/libcxx/utils/ci/run-buildbot.sh
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+
+set -ex
+
+BUILDER="${1}"
+
+args=()
+args+=("-DLLVM_ENABLE_PROJECTS=libcxx;libunwind;libcxxabi")
+args+=("-DLIBCXX_CXX_ABI=libcxxabi")
+
+case "${BUILDER}" in
+x86_64-ubuntu-cxx03)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported --param=std=c++03")
+;;
+x86_64-ubuntu-cxx11)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported --param=std=c++11")
+;;
+x86_64-ubuntu-cxx14)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported --param=std=c++14")
+;;
+x86_64-ubuntu-cxx17)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported --param=std=c++17")
+;;
+x86_64-ubuntu-cxx2a)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported --param=std=c++2a")
+;;
+x86_64-ubuntu-noexceptions)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+    args+=("-DLIBCXX_ENABLE_EXCEPTIONS=OFF")
+    args+=("-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF")
+;;
+x86_64-ubuntu-32bit)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+    args+=("-DLLVM_BUILD_32_BITS=ON")
+;;
+x86_64-ubuntu-gcc)
+    export CC=gcc
+    export CXX=g++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+;;
+x86_64-ubuntu-asan)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_USE_SANITIZER=Address")
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+;;
+x86_64-ubuntu-msan)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_USE_SANITIZER=MemoryWithOrigins")
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+;;
+x86_64-ubuntu-tsan)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_USE_SANITIZER=Thread")
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+;;
+x86_64-ubuntu-ubsan)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_USE_SANITIZER=Undefined")
+    args+=("-DLIBCXX_ABI_UNSTABLE=ON")
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+;;
+x86_64-ubuntu-with_llvm_unwinder)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+    args+=("-DLIBCXXABI_USE_LLVM_UNWINDER=ON")
+;;
+x86_64-ubuntu-singlethreaded)
+    export CC=clang
+    export CXX=clang++
+    args+=("-DLLVM_LIT_ARGS=-sv --show-unsupported")
+    args+=("-DLIBCXX_ENABLE_THREADS=OFF")
+    args+=("-DLIBCXXABI_ENABLE_THREADS=OFF")
+    args+=("-DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF")
+;;
+*)
+    echo "${BUILDER} is not a known configuration"
+    exit 1
+;;
+esac
+
+UMBRELLA_ROOT="$(git rev-parse --show-toplevel)"
+LLVM_ROOT="${UMBRELLA_ROOT}/llvm"
+BUILD_DIR="${UMBRELLA_ROOT}/build/${BUILDER}"
+
+echo "--- Generating CMake"
+rm -rf "${BUILD_DIR}"
+cmake -S "${LLVM_ROOT}" -B "${BUILD_DIR}" -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo "${args[@]}"
+
+echo "--- Building libc++ and libc++abi"
+ninja -C "${BUILD_DIR}" check-cxx-deps cxxabi
+
+echo "+++ Running the libc++ tests"
+ninja -C "${BUILD_DIR}" check-cxx
+
+echo "+++ Running the libc++abi tests"
+ninja -C "${BUILD_DIR}" check-cxxabi
+
+echo "+++ Running the libc++ benchmarks"
+ninja -C "${BUILD_DIR}" check-cxx-benchmarks

diff  --git a/libcxx/utils/ci/secrets.env b/libcxx/utils/ci/secrets.env
new file mode 100644
index 000000000000..782bdd94a5e9
--- /dev/null
+++ b/libcxx/utils/ci/secrets.env
@@ -0,0 +1,11 @@
+#
+# This file template shows which environment variables are required to run
+# libc++ CI nodes. The actual values of these tokens must obviously never be
+# checked in.
+#
+
+# Required to talk with the Phabricator API to update build results
+CONDUIT_TOKEN=<secret>
+
+# Required to register a new agent with Buildkite
+BUILDKITE_AGENT_TOKEN=<secret>


        


More information about the libcxx-commits mailing list