Rebuild bottles of pass #1434
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Dispatch rebottle (for all currently bottled OS versions) | |
run-name: Rebuild bottles of ${{ inputs.formula }} | |
on: | |
workflow_dispatch: | |
inputs: | |
formula: | |
description: Formula name | |
required: true | |
reason: | |
description: Reason for rebottling | |
required: true | |
timeout: | |
description: "Build timeout (in minutes, default: 60 minutes)" | |
type: number | |
default: 60 | |
required: false | |
issue: | |
description: Issue number, where comment on failure would be posted | |
type: number | |
required: false | |
upload: | |
description: "Upload built bottles? (default: false)" | |
type: boolean | |
default: false | |
required: false | |
fail-fast: | |
description: "Fail immediately on a single OS version failure? (default: true)" | |
type: boolean | |
default: true | |
required: false | |
defaults: | |
run: | |
shell: bash -xeuo pipefail {0} | |
# Intentionally the same as dispatch-build-bottle | |
concurrency: bottle-${{ github.event.inputs.formula }} | |
permissions: | |
contents: read | |
env: | |
HOMEBREW_DEVELOPER: 1 | |
HOMEBREW_GITHUB_ACTIONS: 1 | |
HOMEBREW_NO_AUTO_UPDATE: 1 | |
HOMEBREW_NO_INSTALL_FROM_API: 1 | |
HOMEBREW_NO_BUILD_ERROR_ISSUES: 1 | |
RUN_URL: ${{github.event.repository.html_url}}/actions/runs/${{github.run_id}} | |
DISPATCH_REBOTTLE_SENDER: ${{ github.event.sender.login }} | |
DISPATCH_REBOTTLE_FORMULA: ${{ inputs.formula }} | |
DISPATCH_REBOTTLE_TIMEOUT: ${{ inputs.timeout }} | |
DISPATCH_REBOTTLE_ISSUE: ${{ inputs.issue }} | |
DISPATCH_REBOTTLE_UPLOAD: ${{ inputs.upload }} | |
DISPATCH_REBOTTLE_REASON: ${{ inputs.reason }} | |
jobs: | |
setup: | |
runs-on: ubuntu-22.04 | |
container: | |
image: ghcr.io/homebrew/ubuntu22.04:master | |
outputs: | |
runners: ${{steps.determine-runners.outputs.runners}} | |
steps: | |
- name: Set up Homebrew | |
id: set-up-homebrew | |
uses: Homebrew/actions/setup-homebrew@master | |
with: | |
core: true | |
cask: false | |
test-bot: false | |
- name: Determine runners | |
id: determine-runners | |
run: brew determine-rebottle-runners "${DISPATCH_REBOTTLE_FORMULA}" "${DISPATCH_REBOTTLE_TIMEOUT}" | |
bottle: | |
permissions: | |
contents: read | |
needs: setup | |
strategy: | |
matrix: | |
include: ${{fromJson(needs.setup.outputs.runners)}} | |
fail-fast: ${{inputs.fail-fast}} | |
runs-on: ${{matrix.runner}} | |
container: ${{matrix.container}} | |
timeout-minutes: ${{fromJson(inputs.timeout)}} | |
defaults: | |
run: | |
shell: /bin/bash -xeuo pipefail {0} | |
working-directory: ${{matrix.workdir || github.workspace}} | |
env: | |
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} | |
BOTTLES_DIR: ${{ matrix.workdir || github.workspace }}/bottles | |
steps: | |
- name: ${{inputs.formula}} | |
id: print_details | |
run: | | |
echo sender="${DISPATCH_REBOTTLE_SENDER}" | |
echo formula="${DISPATCH_REBOTTLE_FORMULA}" | |
echo timeout="${DISPATCH_REBOTTLE_TIMEOUT}" | |
echo issue="${DISPATCH_REBOTTLE_ISSUE}" | |
echo upload="${DISPATCH_REBOTTLE_UPLOAD}" | |
echo reason="${DISPATCH_REBOTTLE_REASON}" | |
- name: Pre-test steps | |
uses: Homebrew/actions/pre-build@master | |
with: | |
bottles-directory: ${{ env.BOTTLES_DIR }} | |
- run: | | |
brew test-bot --only-formulae --only-json-tab --skip-online-checks \ | |
--skip-dependents \ | |
"${DISPATCH_REBOTTLE_FORMULA}" | |
working-directory: ${{ env.BOTTLES_DIR }} | |
env: | |
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.GITHUB_TOKEN}} | |
- name: Post-build steps | |
if: always() | |
uses: Homebrew/actions/post-build@master | |
with: | |
runner: ${{ matrix.runner }} | |
bottles-directory: ${{ env.BOTTLES_DIR }} | |
logs-directory: ${{ env.BOTTLES_DIR }}/logs | |
upload: | |
permissions: | |
issues: write # for Homebrew/actions/post-comment | |
contents: write # for Homebrew/actions/git-try-push | |
packages: write # for brew pr-upload | |
pull-requests: write # for gh pr | |
attestations: write # for actions/attest-build-provenance | |
id-token: write # for actions/attest-build-provenance | |
runs-on: ubuntu-22.04 | |
needs: bottle | |
if: inputs.upload | |
container: | |
image: ghcr.io/homebrew/ubuntu22.04:master | |
env: | |
HOMEBREW_SIMULATE_MACOS_ON_LINUX: 1 | |
GH_REPO: ${{github.repository}} | |
GH_NO_UPDATE_NOTIFIER: 1 | |
GH_PROMPT_DISABLED: 1 | |
BOTTLE_BRANCH: ${{github.actor}}/dispatch/${{inputs.formula}}/${{github.run_id}} | |
BOTTLES_DIR: ${{ github.workspace }}/bottles | |
steps: | |
- name: Set up Homebrew | |
id: set-up-homebrew | |
uses: Homebrew/actions/setup-homebrew@master | |
with: | |
core: true | |
cask: false | |
test-bot: false | |
- name: Download bottles from GitHub Actions | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: bottles_* | |
path: ${{ env.BOTTLES_DIR }} | |
merge-multiple: true | |
- name: Setup git | |
id: git-user-config | |
uses: Homebrew/actions/git-user-config@master | |
with: | |
username: ${{ (github.actor != 'github-actions[bot]' && github.actor) || 'BrewTestBot' }} | |
- name: Set up commit signing | |
uses: Homebrew/actions/setup-commit-signing@master | |
with: | |
signing_key: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY }} | |
- name: Generate build provenance | |
uses: actions/attest-build-provenance@v1 | |
with: | |
subject-path: ${{ env.BOTTLES_DIR }}/*.tar.gz | |
- name: Checkout branch for bottle commit | |
working-directory: ${{steps.set-up-homebrew.outputs.repository-path}} | |
run: git checkout -b "$BOTTLE_BRANCH" origin/master | |
- name: Upload bottles to GitHub Packages | |
id: upload | |
env: | |
HOMEBREW_GITHUB_PACKAGES_USER: brewtestbot | |
HOMEBREW_GITHUB_PACKAGES_TOKEN: ${{secrets.HOMEBREW_CORE_GITHUB_PACKAGES_TOKEN}} | |
HOMEBREW_GPG_PASSPHRASE: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY_PASSPHRASE }} | |
BREWTESTBOT_NAME_EMAIL: "BrewTestBot <[email protected]>" | |
HOMEBREW_CORE_PATH: ${{steps.set-up-homebrew.outputs.repository-path}} | |
working-directory: ${{ env.BOTTLES_DIR }} | |
run: | | |
brew pr-upload --verbose --committer="$BREWTESTBOT_NAME_EMAIL" --root-url="https://ghcr.io/v2/homebrew/core" --debug | |
echo "title=$(git -C "$HOMEBREW_CORE_PATH" log -1 --format='%s' "$BOTTLE_BRANCH")" >> "$GITHUB_OUTPUT" | |
echo "head_sha=$(git -C "$HOMEBREW_CORE_PATH" rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
- name: Push commits | |
uses: Homebrew/actions/git-try-push@master | |
with: | |
token: ${{secrets.GITHUB_TOKEN}} | |
directory: ${{steps.set-up-homebrew.outputs.repository-path}} | |
branch: ${{env.BOTTLE_BRANCH}} | |
env: | |
GIT_COMMITTER_NAME: BrewTestBot | |
GIT_COMMITTER_EMAIL: [email protected] | |
HOMEBREW_GPG_PASSPHRASE: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY_PASSPHRASE }} | |
- name: Open PR with bottle commit | |
id: create-pr | |
uses: Homebrew/actions/create-pull-request@master | |
with: | |
token: ${{secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN}} | |
base: ${{github.ref}} | |
head: ${{env.BOTTLE_BRANCH}} | |
title: ${{steps.upload.outputs.title}} | |
body: | | |
Created by [`dispatch-rebottle.yml`](${{env.RUN_URL}}) | |
----- | |
${{env.DISPATCH_REBOTTLE_REASON}} | |
labels: CI-published-bottle-commits | |
reviewers: ${{github.actor}} | |
- name: Enable automerge | |
env: | |
GH_TOKEN: ${{secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN}} | |
NODE_ID: ${{steps.create-pr.outputs.node_id}} | |
SHA: ${{steps.upload.outputs.head_sha}} | |
MUTATION: |- | |
mutation ($input: EnablePullRequestAutoMergeInput!) { | |
enablePullRequestAutoMerge(input: $input) { | |
clientMutationId | |
} | |
} | |
run: | | |
gh api graphql \ | |
--field "input[pullRequestId]=$NODE_ID" \ | |
--field "input[expectedHeadOid]=$SHA" \ | |
--raw-field query="$MUTATION" | |
- name: Approve PR | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
PR: ${{steps.create-pr.outputs.number}} | |
run: | | |
gh api \ | |
--method POST \ | |
--header "Accept: application/vnd.github+json" \ | |
--header "X-GitHub-Api-Version: 2022-11-28" \ | |
"/repos/$GITHUB_REPOSITORY/pulls/$PR/reviews" \ | |
--field "event=APPROVE" | |
- name: Wait until PR is merged | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
PR: ${{ steps.create-pr.outputs.number }} | |
run: | | |
# Hold the `concurrency` lock for up to another 10 minutes while the PR has not yet been merged. | |
sleep 300 | |
attempt=0 | |
max_attempts=5 | |
sleep_time=10 | |
while (( attempt < max_attempts )) | |
do | |
if jq --exit-status .merged_at | |
then | |
break | |
fi < <( # We could use `gh pr view`, but that uses 2 API calls. | |
gh api \ | |
--header "Accept: application/vnd.github+json" \ | |
--header "X-GitHub-Api-Version: 2022-11-28" \ | |
"/repos/$GITHUB_REPOSITORY/pulls/$PR" | |
) | |
sleep "$sleep_time" | |
sleep_time=$(( sleep_time * 2 )) | |
attempt=$(( attempt + 1 )) | |
done | |
comment: | |
permissions: | |
issues: write # for Homebrew/actions/post-comment | |
pull-requests: write # for Homebrew/actions/post-comment | |
needs: [bottle, upload] | |
if: failure() && inputs.issue > 0 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Post comment on failure | |
uses: Homebrew/actions/post-comment@master | |
with: | |
token: ${{secrets.GITHUB_TOKEN}} | |
issue: ${{inputs.issue}} | |
body: ":x: @${{github.actor}} bottle request for ${{inputs.formula}} [failed](${{env.RUN_URL}})." | |
bot_body: ":x: Bottle request for ${{inputs.formula}} [failed](${{env.RUN_URL}})." | |
bot: BrewTestBot |