.github/workflows: use new test-bot features.

This commit is a fairly giant change to how our CI works. It:
- explains (in the name) the difference between `dispatch-build-bottle`
  and `dispatch-rebottle`
- allows a custom build timeout for `dispatch-build-bottle` and
  `dispatch-rebottle` (defaulting to an hour) to avoid the CI queue
  getting backed up by default
- does some general cleanup of the workflow files
- uses `--skip-dependents` for `dispatch-build-bottle` and
  `dispatch-rebottle`; we're not testing new changes in these cases so
  there's no sense doing the (sometimes incredibly slow) full dependency
  tree checks
- allows specifying whether `dispatch-rebottle` fails fast on the first
  matrix build or not. Given that we're almost always wanting to
  rebottle all macOS versions in this case: it defaults to true to save
  time on pointless builds
- runs `brew test-bot --only-formulae-detect` once in the `tap_syntax`
  job and uses these results in the remaining tests. This ensures that
  they are consistent, precalculated and more easily visible.
- move all `brew test-bot` label outputs into a single string with
  all the arguments to simplify adding more and DRY things up
- add support for new `CI-fail-fast`, `CI-long-timeout` labels to
  customise GitHub Actions behaviour and have quicker failures/timeouts
  by default to avoid the CI queue backing up
- add support for new `CI-skip-dependents`,
  `CI-build-dependents-from-source`, `CI-skip-recursive-dependents`
  labels for customising `brew test-bot` behaviour by passing the
  respective flags through. This will allow speeding up and slowing down
  builds using labels rather than hardcoded values in `brew test-bot`.
- Use separate `brew test-bot --only-dependents` step to fail faster if
  one of the original formulae has failed and to separate the output of
  dependents and original formulae builds
- autoformat `triage.yml`
- add support for `CI-long-timeout`, `CI-build-dependents-from-source`
  and `CI-skip-recursive-dependents` labels into `triage.yml`
master
Mike McQuaid 2021-07-08 14:17:21 +01:00
parent 0ba4519055
commit 4848257f4f
No known key found for this signature in database
GPG Key ID: 3338A31AFDB1D829
4 changed files with 167 additions and 93 deletions

View File

@ -1,4 +1,4 @@
name: Dispatch build bottle
name: Dispatch build bottle (for a single OS/version)
on:
workflow_dispatch:
@ -9,6 +9,10 @@ on:
formula:
description: Formula name
required: true
timeout:
description: "Build timeout (in minutes, default: 60 minutes)"
default: "60"
required: true
issue:
description: Issue number, where comment on failure would be posted
required: false
@ -29,7 +33,7 @@ env:
jobs:
bottle:
runs-on: ${{github.event.inputs.runner}}
timeout-minutes: 4320
timeout-minutes: ${{fromJson(github.event.inputs.timeout)}}
defaults:
run:
shell: /bin/bash -e {0}
@ -59,6 +63,8 @@ jobs:
- name: Run Docker container
if: runner.os == 'Linux'
env:
TAP_PATH: /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core
run: |
docker run \
--detach \
@ -72,11 +78,6 @@ jobs:
# Fix working directory permissions
docker exec --user root ${{github.sha}} chmod 777 /tmp/bottles
- name: Set up Homebrew in container
if: runner.os == 'Linux'
env:
TAP_PATH: /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core
run: |
docker exec --workdir "$TAP_PATH" ${{github.sha}} git remote set-url origin ${{github.event.repository.html_url}}
docker exec --workdir "$TAP_PATH" ${{github.sha}} git fetch origin ${{github.sha}} '+refs/heads/*:refs/remotes/origin/*'
docker exec --workdir "$TAP_PATH" ${{github.sha}} git remote set-head origin --auto
@ -98,21 +99,21 @@ jobs:
docker exec ${{github.sha}} brew test-bot --only-setup
fi
- name: Run brew test-bot --keep-old --only-json-tab
- name: Run brew test-bot --keep-old --only-json-tab --only-formulae --skip-dependents ${{github.event.inputs.formula}}
run: |
if [ "$RUNNER_OS" = 'macOS' ]; then
mkdir bottles
cd bottles
brew test-bot --keep-old --only-json-tab --only-formulae ${{github.event.inputs.formula}}
brew test-bot --keep-old --only-json-tab --only-formulae --skip-dependents ${{github.event.inputs.formula}}
else
docker exec ${{github.sha}} brew test-bot --keep-old --only-json-tab --only-formulae ${{github.event.inputs.formula}}
docker exec ${{github.sha}} brew test-bot --keep-old --only-json-tab --only-formulae --skip-dependents ${{github.event.inputs.formula}}
fi
- name: Copy bottles from container
if: always() && runner.os == 'Linux'
run: docker cp ${{github.sha}}:/tmp/bottles .
- name: Output brew test-bot --keep-old --only-json-tab failures
- name: Failures summary for brew test-bot --keep-old --only-json-tab --only-formulae --skip-dependents ${{github.event.inputs.formula}}
if: always()
run: |
cat bottles/steps_output.txt

View File

@ -1,4 +1,4 @@
name: Dispatch rebottle
name: Dispatch rebottle (for all macOS versions)
on:
workflow_dispatch:
@ -6,12 +6,20 @@ on:
formula:
description: Formula name
required: true
timeout:
description: "Build timeout (in minutes, default: 60 minutes)"
default: "60"
required: true
issue:
description: Issue number, where comment on failure would be posted
required: false
upload:
description: "Whether to upload built bottles or not (default: false)"
required: false
fail-fast:
description: "Whether to fail immediately on a single macOS version failure (default: true)"
default: "true"
required: false
env:
HOMEBREW_DEVELOPER: 1
@ -25,9 +33,9 @@ jobs:
strategy:
matrix:
version: ["11-arm64", "11", "10.15", "10.14"]
fail-fast: false
fail-fast: ${{fromJson(github.event.inputs.fail-fast)}}
runs-on: ${{ matrix.version }}
timeout-minutes: 4320
timeout-minutes: ${{fromJson(github.event.inputs.timeout)}}
env:
PATH: "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
GITHUB_ACTIONS_HOMEBREW_MACOS_SELF_HOSTED: 1
@ -50,15 +58,15 @@ jobs:
- run: brew test-bot --only-setup
- name: Run brew test-bot --only-json-tab --only-formulae
- name: Run brew test-bot --only-json-tab --only-formulae --skip-dependents
env:
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
mkdir bottles
cd bottles
brew test-bot --only-json-tab --only-formulae ${{github.event.inputs.formula}}
brew test-bot --only-json-tab --only-formulae --skip-dependents ${{github.event.inputs.formula}}
- name: Output brew test-bot --only-json-tab --only-formulae failures
- name: Failures summary for brew test-bot --only-json-tab --only-formulae --skip-dependents
if: always()
run: |
cat bottles/steps_output.txt

View File

@ -25,6 +25,10 @@ jobs:
image: ghcr.io/homebrew/ubuntu16.04:master
env:
HOMEBREW_SIMULATE_MACOS_ON_LINUX: 1
outputs:
testing_formulae: ${{ steps.formulae-detect.outputs.testing_formulae }}
added_formulae: ${{ steps.formulae-detect.outputs.added_formulae }}
deleted_formulae: ${{ steps.formulae-detect.outputs.deleted_formulae }}
steps:
- name: Set up Homebrew
id: set-up-homebrew
@ -32,18 +36,21 @@ jobs:
- run: brew test-bot --only-tap-syntax
check_labels:
- run: brew test-bot --only-formulae-detect
id: formulae-detect
setup_tests:
if: github.event_name == 'pull_request' && github.repository == 'Homebrew/homebrew-core'
runs-on: ubuntu-latest
needs: tap_syntax
outputs:
runners: ${{ steps.check-labels.outputs.runners }}
container: ${{ steps.check-labels.outputs.container }}
syntax-only: ${{ steps.check-labels.outputs.syntax-only }}
force-arm: ${{ steps.check-labels.outputs.force-arm }}
force-linux: ${{ steps.check-labels.outputs.force-linux }}
test-bot-fail-fast: ${{ steps.check-labels.outputs.test-bot-fail-fast }}
test-bot-skip-recursive-dependents: ${{ steps.check-labels.outputs.test-bot-skip-recursive-dependents }}
runners: ${{ steps.check-labels.outputs.runners }}
fail-fast: ${{ steps.check-labels.outputs.fail-fast }}
timeout-minutes: ${{ steps.check-labels.outputs.timeout-minutes }}
container: ${{ steps.check-labels.outputs.container }}
test-bot-formulae-args: ${{ steps.check-labels.outputs.test-bot-formulae-args }}
test-bot-dependents-args: ${{ steps.check-labels.outputs.test-bot-dependents-args }}
steps:
- name: Check for CI labels
id: check-labels
@ -59,74 +66,110 @@ jobs:
const label_names = labels.map(label => label.name)
if (label_names.includes('CI-syntax-only')) {
console.log('CI-syntax-only label found. Skipping tests.')
console.log('CI-syntax-only label found. Skipping tests job.')
core.setOutput('syntax-only', 'true')
} else {
console.log('No CI-syntax-only label found. Running tests.')
console.log('No CI-syntax-only label found. Running tests job.')
core.setOutput('syntax-only', 'false')
}
if (label_names.includes('CI-force-arm')) {
console.log('CI-force-arm label found. Running ARM builds.')
core.setOutput('force-arm', 'true')
} else {
console.log('No CI-force-arm label found. Not requiring ARM builds.')
core.setOutput('force-arm', 'false')
}
if (label_names.includes('CI-force-linux')) {
console.log('CI-force-linux label found. Running Linux builds.')
core.setOutput('force-linux', 'true')
} else {
console.log('No CI-force-linux label found. Not requiring Linux builds.')
core.setOutput('force-linux', 'false')
}
if (label_names.includes('CI-test-bot-fail-fast')) {
console.log('CI-test-bot-fail-fast label found. Passing --fail-fast to brew test-bot.')
core.setOutput('test-bot-fail-fast', '--fail-fast')
} else {
console.log('No CI-test-bot-fail-fast label found. Not passing --fail-fast to brew test-bot.')
core.setOutput('test-bot-fail-fast', '')
}
if (label_names.includes('CI-test-bot-skip-recursive-dependents')) {
console.log('CI-test-bot-skip-recursive-dependents label found. Passing --skip-recursive-dependents to brew test-bot.')
core.setOutput('test-bot-skip-recursive-dependents', '--skip-recursive-dependents')
} else {
console.log('No CI-test-bot-skip-recursive-dependents label found. Not passing --skip-recursive-dependents to brew test-bot.')
core.setOutput('test-bot-skip-recursive-dependents', '')
}
if (label_names.includes('CI-linux-wheezy')) {
console.log('CI-linux-wheezy label found. Running Linux wheezy builds.')
core.setOutput('container', 'homebrew/debian7:latest')
} else {
console.log('No CI-linux-wheezy label found. Not requiring Linux wheezy builds.')
core.setOutput('container', 'ghcr.io/homebrew/ubuntu16.04:master')
}
/* RUNNERS */
const runners = ["11-arm64", "11", "10.15", "10.14"]
if (label_names.includes('CI-linux-self-hosted')) {
runners.push('linux-self-hosted-1')
} else {
runners.push('ubuntu-latest')
}
core.setOutput('runners', JSON.stringify(runners))
if (label_names.includes('CI-no-fail-fast')) {
console.log('CI-no-fail-fast label found. Continuing tests despite failing matrix builds.')
core.setOutput('fail-fast', 'false')
} else {
console.log('No CI-no-fail-fast label found. Stopping tests on first failing matrix build.')
core.setOutput('fail-fast', 'true')
}
if (label_names.includes('CI-long-timeout')) {
console.log('CI-long-timeout label found. Setting long GitHub Actions timeout.')
core.setOutput('timeout-minutes', '4320')
} else {
console.log('No CI-long-timeout label found. Setting short GitHub Actions timeout.')
core.setOutput('timeout-minutes', '60')
}
if (label_names.includes('CI-linux-wheezy')) {
console.log('CI-linux-wheezy label found. Using Linux Debian 7 (Wheezy) container.')
core.setOutput('container', 'homebrew/debian7:latest')
} else {
console.log('No CI-linux-wheezy label found. Using default Homebrew (Ubuntu 16.04) container.')
core.setOutput('container', 'ghcr.io/homebrew/ubuntu16.04:master')
}
const test_bot_formulae_args = ["--only-formulae", "--junit", "--only-json-tab", "--skip-dependents"]
test_bot_formulae_args.push('--testing-formulae=${{needs.tap_syntax.outputs.testing_formulae}}')
test_bot_formulae_args.push('--added-formulae=${{needs.tap_syntax.outputs.added_formulae}}')
test_bot_formulae_args.push('--deleted-formulae=${{needs.tap_syntax.outputs.deleted_formulae}}')
const test_bot_dependents_args = ["--only-formulae-dependents", "--junit"]
test_bot_dependents_args.push('--testing-formulae=${{needs.tap_syntax.outputs.testing_formulae}}')
test_bot_dependents_args.push('--added-formulae=${{needs.tap_syntax.outputs.added_formulae}}')
test_bot_dependents_args.push('--deleted-formulae=${{needs.tap_syntax.outputs.deleted_formulae}}')
if (label_names.includes('CI-force-arm')) {
console.log('CI-force-arm label found. Not passing --skip-unbottled-arm to brew test-bot.')
} else {
console.log('No CI-force-arm label found. Passing --skip-unbottled-arm to brew test-bot.')
test_bot_formulae_args.push('--skip-unbottled-arm')
}
if (label_names.includes('CI-force-linux')) {
console.log('CI-force-linux label found. Not passing --skip-unbottled-linux to brew test-bot.')
} else {
console.log('No CI-force-linux label found. Passing --skip-unbottled-linux to brew test-bot.')
test_bot_formulae_args.push('--skip-unbottled-linux')
}
if (label_names.includes('CI-test-bot-fail-fast')) {
console.log('CI-test-bot-fail-fast label found. Passing --fail-fast to brew test-bot.')
test_bot_formulae_args.push('--fail-fast')
test_bot_dependents_args.push('--fail-fast')
} else {
console.log('No CI-test-bot-fail-fast label found. Not passing --fail-fast to brew test-bot.')
}
if (label_names.includes('CI-skip-dependents')) {
console.log('CI-skip-dependents label found. Passing --skip-dependents to brew test-bot.')
test_bot_formulae_args.push('--skip-dependents')
} else {
console.log('No CI-skip-dependents label found. Not passing --skip-dependents to brew test-bot.')
}
if (label_names.includes('CI-build-dependents-from-source')) {
console.log('CI-build-dependents-from-source label found. Passing --build-dependents-from-source to brew test-bot.')
test_bot_dependents_args.push('--build-dependents-from-source')
} else {
console.log('No CI-build-dependents-from-source label found. Not passing --build-dependents-from-source to brew test-bot.')
}
if (label_names.includes('CI-skip-recursive-dependents')) {
console.log('CI-skip-recursive-dependents label found. Passing --skip-recursive-dependents to brew test-bot.')
test_bot_dependents_args.push('--skip-recursive-dependents')
} else {
console.log('No CI-skip-recursive-dependents label found. Not passing --skip-recursive-dependents to brew test-bot.')
}
core.setOutput('test-bot-formulae-args', test_bot_formulae_args.join(" "))
core.setOutput('test-bot-dependents-args', test_bot_dependents_args.join(" "))
tests:
needs: check_labels
if: github.event_name == 'pull_request' && needs.check_labels.outputs.syntax-only == 'false'
needs: setup_tests
if: github.event_name == 'pull_request' && ${{fromJson(needs.setup_tests.outputs.syntax-only)}}
strategy:
matrix:
runner: ${{fromJson(needs.check_labels.outputs.runners)}}
fail-fast: false
runner: ${{fromJson(needs.setup_tests.outputs.runners)}}
fail-fast: ${{fromJson(needs.setup_tests.outputs.fail-fast)}}
runs-on: ${{matrix.runner}}
timeout-minutes: 4320
timeout-minutes: ${{fromJson(needs.setup_tests.outputs.timeout-minutes)}}
defaults:
run:
shell: /bin/bash -e {0}
@ -139,19 +182,15 @@ jobs:
if [ "$RUNNER_OS" = 'macOS' ]; then
echo 'PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin' >> $GITHUB_ENV
echo 'GITHUB_ACTIONS_HOMEBREW_MACOS_SELF_HOSTED=1' >> $GITHUB_ENV
if [ '${{needs.check_labels.outputs.force-arm}}' = 'false' ]; then
echo 'HOMEBREW_SKIP_UNBOTTLED_ARM_TESTS=1' >> $GITHUB_ENV
fi
else
# No PATH needed on Linux as set by Docker
echo 'HOMEBREW_FORCE_HOMEBREW_ON_LINUX=1' >> $GITHUB_ENV
if [ '${{needs.check_labels.outputs.force-linux}}' = 'false' ]; then
echo 'HOMEBREW_SKIP_UNBOTTLED_LINUX_TESTS=1' >> $GITHUB_ENV
fi
fi
- name: Run Docker container
- name: Set up Linux Homebrew Docker container
if: runner.os == 'Linux'
env:
TAP_PATH: /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core
run: |
docker run \
--detach \
@ -160,16 +199,11 @@ jobs:
--env-file <(env | egrep 'HOMEBREW|GITHUB') \
--workdir /tmp/bottles \
--pull always \
${{needs.check_labels.outputs.container}} \
${{needs.setup_tests.outputs.container}} \
sleep inf
# Fix working directory permissions
docker exec --user root ${{github.sha}} chmod 777 /tmp/bottles
- name: Set up Homebrew in container
if: runner.os == 'Linux'
env:
TAP_PATH: /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core
run: |
docker exec --workdir "$TAP_PATH" ${{github.sha}} git remote set-url origin ${{github.event.repository.html_url}}
docker exec --workdir "$TAP_PATH" ${{github.sha}} git fetch origin ${{github.sha}} '+refs/heads/*:refs/remotes/origin/*'
docker exec --workdir "$TAP_PATH" ${{github.sha}} git remote set-head origin --auto
@ -191,21 +225,40 @@ jobs:
docker exec ${{github.sha}} brew test-bot --only-setup
fi
- name: Run brew test-bot --only-json-tab --only-formulae ${{ needs.tap_syntax.outputs.test-bot-fail-fast }} ${{ needs.tap_syntax.outputs.test-bot-skip-recursive-dependents }}
- name: Run brew test-bot ${{ needs.setup_tests.outputs.test-bot-formulae-args }}
run: |
if [ "$RUNNER_OS" = 'macOS' ]; then
mkdir bottles
cd bottles
brew test-bot --only-json-tab --only-formulae ${{ needs.check_labels.outputs.test-bot-fail-fast }} ${{ needs.check_labels.outputs.test-bot-skip-recursive-dependents }}
brew test-bot ${{ needs.setup_tests.outputs.test-bot-formulae-args }}
else
docker exec ${{github.sha}} brew test-bot --only-json-tab --only-formulae ${{ needs.check_labels.outputs.test-bot-fail-fast }} ${{ needs.check_labels.outputs.test-bot-skip-recursive-dependents }}
docker exec ${{github.sha}} brew test-bot ${{ needs.setup_tests.outputs.test-bot-formulae-args }}
fi
- name: Copy bottles from container
- name: Copy results from container
if: always() && runner.os == 'Linux'
run: docker cp ${{github.sha}}:/tmp/bottles .
- name: Output brew test-bot --only-json-tab --only-formulae ${{ needs.check_labels.outputs.test-bot-fail-fast }} ${{ needs.check_labels.outputs.test-bot-skip-recursive-dependents }} failures
- name: Failures summary for brew test-bot ${{ needs.setup_tests.outputs.test-bot-formulae-args }}
if: always()
run: |
cat bottles/steps_output.txt
rm bottles/steps_output.txt
- name: Run brew test-bot ${{ needs.setup_tests.outputs.test-bot-dependents-args }}
run: |
if [ "$RUNNER_OS" = 'macOS' ]; then
cd bottles
brew test-bot ${{ needs.setup_tests.outputs.test-bot-dependents-args }}
else
docker exec ${{github.sha}} brew test-bot ${{ needs.setup_tests.outputs.test-bot-dependents-args }}
fi
- name: Copy results from container
if: always() && runner.os == 'Linux'
run: docker cp ${{github.sha}}:/tmp/bottles .
- name: Failures summary for brew test-bot ${{ needs.setup_tests.outputs.test-bot-dependents-args }}
if: always()
run: |
cat bottles/steps_output.txt

View File

@ -123,6 +123,18 @@ jobs:
"label": "swift",
"path": "Formula/.+",
"content": "system \"swift\", \"build\""
}, {
"label": "CI-long-timeout",
"path": "Formula/(boost|qt).rb",
"keep_if_no_match": true
}, {
"label": "CI-build-dependents-from-source",
"path": "Formula/(cabal-install|docbook-xsl|emscripten|erlang|ghc|go|ocaml|ocaml-findlib|ocaml-num|openjdk|rust).rb",
"keep_if_no_match": true
}, {
"label": "CI-skip-recursive-dependents",
"path": "Formula/(gettext|openssl).rb",
"keep_if_no_match": true
}, {
"label": "CI-linux-wheezy",
"path": "Formula/(zlib|patchelf|binutils).rb",