diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 1ba51ab..b00a149 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -3,21 +3,12 @@ env: NO_COLOR: "1" agents: - queue: "linux-small" + queue: "macos-medium" steps: - - label: ":git: Git 2.50.1" - key: "git-toolchain" - command: "bash .buildkite/scripts/build-modern-git.sh" - if: build.pull_request.id != null || build.env("TABELLIO_BUILD_CONTEXT") == "preflight" || build.branch == pipeline.default_branch - timeout_in_minutes: 15 - artifact_paths: - - ".artifacts/toolchain/git-2.50.1-linux-amd64.tar.gz" - - label: ":test_tube: Repository check" key: "repository-check" command: "bash .buildkite/scripts/tests.sh" - depends_on: "git-toolchain" if: build.pull_request.id != null || build.env("TABELLIO_BUILD_CONTEXT") == "preflight" || build.branch == pipeline.default_branch timeout_in_minutes: 10 artifact_paths: @@ -29,7 +20,6 @@ steps: - label: ":mag: Fallow changed-code" key: "fallow" command: "bash .buildkite/scripts/fallow.sh" - depends_on: "git-toolchain" if: build.pull_request.id != null || build.env("TABELLIO_BUILD_CONTEXT") == "preflight" || build.branch == pipeline.default_branch timeout_in_minutes: 10 artifact_paths: @@ -52,7 +42,6 @@ steps: - label: ":shield: Product validation" key: "product-validation" command: "bash .buildkite/scripts/product-validation.sh" - depends_on: "git-toolchain" if: build.pull_request.id != null || build.env("TABELLIO_BUILD_CONTEXT") == "preflight" || build.branch == pipeline.default_branch timeout_in_minutes: 50 artifact_paths: diff --git a/.buildkite/scripts/build-modern-git.sh b/.buildkite/scripts/build-modern-git.sh deleted file mode 100644 index 305896a..0000000 --- a/.buildkite/scripts/build-modern-git.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -version="2.50.1" -archive="git-${version}.tar.xz" -expected_sha256="7e3e6c36decbd8f1eedd14d42db6674be03671c2204864befa2a41756c5c8fc4" -workspace="$(mktemp -d)" -install_root="/tmp/intelip-tabellio-git-${version}" -artifact_dir=".artifacts/toolchain" -apt_lists="${workspace}/apt-lists" -apt_source_list="${workspace}/sources.list" -apt_source_parts="${workspace}/apt-sources.list.d" -apt_options=( - -o Dir::Etc::sourcelist="$apt_source_list" - -o Dir::Etc::sourceparts="$apt_source_parts" - -o Dir::State::lists="$apt_lists" - -o APT::Get::List-Cleanup="1" -) -packages=( - build-essential - ca-certificates - gettext - libcurl4-gnutls-dev - libexpat1-dev - libssl-dev - zlib1g-dev -) - -trap 'rm -rf "$workspace" "$install_root"' EXIT -rm -rf "$install_root" -mkdir -p "$install_root" - -missing_packages=() -for package in "${packages[@]}"; do - if ! dpkg-query -W -f='${Status}' "$package" 2>/dev/null | grep -qx "install ok installed"; then - missing_packages+=("$package") - fi -done - -if ((${#missing_packages[@]} > 0)); then - mkdir -p "${apt_lists}/partial" "$apt_source_parts" - chmod 755 "$workspace" "$apt_lists" "${apt_lists}/partial" "$apt_source_parts" - if [[ -f /etc/apt/sources.list ]]; then - awk ' - /^[[:space:]]*deb(-src)?[[:space:]]/ && - /(ubuntu\.com\/(ubuntu|ubuntu-ports)|debian\.org\/debian(-security|-ports)?)/ { print } - ' /etc/apt/sources.list > "$apt_source_list" - else - : > "$apt_source_list" - fi - for source_file in \ - /etc/apt/sources.list.d/ubuntu.sources \ - /etc/apt/sources.list.d/debian.sources \ - /etc/apt/sources.list.d/ubuntu.list \ - /etc/apt/sources.list.d/debian.list; do - [[ -f "$source_file" ]] || continue - cp -- "$source_file" "$apt_source_parts/" - done - sudo apt-get "${apt_options[@]}" update - sudo apt-get "${apt_options[@]}" install -y --no-install-recommends "${missing_packages[@]}" -fi - -curl --fail --location --silent --show-error \ - "https://www.kernel.org/pub/software/scm/git/${archive}" \ - --output "${workspace}/${archive}" - -printf '%s %s\n' "$expected_sha256" "${workspace}/${archive}" | sha256sum --check -tar -C "$workspace" -xf "${workspace}/${archive}" - -make -C "${workspace}/git-${version}" -j2 prefix="$install_root" all -make -C "${workspace}/git-${version}" prefix="$install_root" install - -mkdir -p "$artifact_dir" -tar -C "$install_root" -czf "${artifact_dir}/git-${version}-linux-amd64.tar.gz" . diff --git a/.buildkite/scripts/use-modern-git.sh b/.buildkite/scripts/use-modern-git.sh index 9f7d626..0bbb539 100644 --- a/.buildkite/scripts/use-modern-git.sh +++ b/.buildkite/scripts/use-modern-git.sh @@ -1,17 +1,28 @@ #!/usr/bin/env bash set -euo pipefail -version="2.50.1" -artifact=".artifacts/toolchain/git-${version}-linux-amd64.tar.gz" -install_root="/tmp/intelip-tabellio-git-${version}" +required_version="2.50.1" +actual_version="$(git version | awk '{print $3}')" -buildkite-agent artifact download "$artifact" . -rm -rf "$install_root" -mkdir -p "$install_root" -tar -C "$install_root" -xzf "$artifact" +if ! awk -v actual="$actual_version" -v required="$required_version" ' + BEGIN { + split(actual, actual_parts, ".") + split(required, required_parts, ".") + for (part_index = 1; part_index <= 3; part_index++) { + actual_part = actual_parts[part_index] + 0 + required_part = required_parts[part_index] + 0 + if (actual_part > required_part) { + exit 0 + } + if (actual_part < required_part) { + exit 1 + } + } + exit 0 + } +'; then + printf 'Git %s or newer is required; found %s.\n' "$required_version" "$actual_version" >&2 + exit 1 +fi -export PATH="${install_root}/bin:${PATH}" -export GIT_EXEC_PATH="${install_root}/libexec/git-core" -export GIT_TEMPLATE_DIR="${install_root}/share/git-core/templates" -export GITPERLLIB="${install_root}/share/perl5" git --version diff --git a/tests/buildkite-high-gates.test.mjs b/tests/buildkite-high-gates.test.mjs index 954ff33..b53db55 100644 --- a/tests/buildkite-high-gates.test.mjs +++ b/tests/buildkite-high-gates.test.mjs @@ -6,23 +6,26 @@ async function repositoryFile(path) { return readFile(new URL(`../${path}`, import.meta.url), "utf8"); } -test("Buildkite adds bounded pull-request quality gates without CI cutover", async () => { +test("Buildkite runs bounded pull-request quality gates on the included macOS queue", async () => { const [pipeline, productValidation, fallow, packageCheck, gitToolchain] = await Promise.all([ repositoryFile(".buildkite/pipeline.yml"), repositoryFile(".buildkite/scripts/product-validation.sh"), repositoryFile(".buildkite/scripts/fallow.sh"), repositoryFile(".buildkite/scripts/package.sh"), - repositoryFile(".buildkite/scripts/build-modern-git.sh"), + repositoryFile(".buildkite/scripts/use-modern-git.sh"), ]); + assert.match(pipeline, /queue: "macos-medium"/); assert.match(pipeline, /key: "repository-check"/); assert.match(pipeline, /key: "fallow"/); assert.match(pipeline, /key: "package"/); assert.match(pipeline, /key: "product-validation"/); + assert.doesNotMatch(pipeline, /linux-small/); + assert.doesNotMatch(pipeline, /git-toolchain/); assert.doesNotMatch(pipeline, /BUILDKITE_GITHUB_EVENT/); assert.equal( pipeline.match(/build\.pull_request\.id != null/g)?.length, - 5, + 4, ); assert.match( pipeline, @@ -60,17 +63,11 @@ test("Buildkite adds bounded pull-request quality gates without CI cutover", asy assert.match(fallow, /--gate new-only/); assert.match(packageCheck, /npm pack --dry-run --json/); assert.match(packageCheck, /forgejo\|change-request-provider/); - assert.match(gitToolchain, /dpkg-query/); - assert.match(gitToolchain, /Dir::Etc::sourcelist="\$apt_source_list"/); - assert.match(gitToolchain, /Dir::Etc::sourceparts="\$apt_source_parts"/); - assert.match(gitToolchain, /Dir::State::lists="\$apt_lists"/); - assert.match(gitToolchain, /ubuntu\\\.com/); - assert.match(gitToolchain, /debian\\\.org/); - assert.match(gitToolchain, /sources\.list\.d\/ubuntu\.sources/); - assert.match(gitToolchain, /sources\.list\.d\/debian\.sources/); - assert.doesNotMatch(gitToolchain, /sources\.list\.d\/\*/); - assert.equal(gitToolchain.match(/sudo apt-get "\$\{apt_options\[@\]\}"/g)?.length, 2); - assert.doesNotMatch(gitToolchain, /^\s*sudo apt-get update\s*$/m); + assert.match(gitToolchain, /required_version="2\.50\.1"/); + assert.match(gitToolchain, /git version/); + assert.match(gitToolchain, /awk -v actual=/); + assert.doesNotMatch(gitToolchain, /buildkite-agent artifact download/); + assert.doesNotMatch(gitToolchain, /apt-get/); }); function assertMatches(value, patterns) {