brew/.github/workflows/tests.yml
Mike McQuaid 3a3572449a
workflows/tests: run brew style on all taps at once.
It's nicer and faster to not split these up and avoids needing to
repeatedly rerun this workflow in order to get all the results.
2025-08-22 10:55:50 +01:00

525 lines
17 KiB
YAML

name: CI
on:
push:
branches:
- main
- master
pull_request:
merge_group:
permissions:
contents: read
env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_ENV_HINTS: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_VERIFY_ATTESTATIONS: 1
defaults:
run:
shell: bash -xeuo pipefail {0}
concurrency:
group: "${{ github.ref }}"
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
syntax:
if: github.repository_owner == 'Homebrew'
runs-on: ubuntu-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: false
cask: false
test-bot: false
- name: Cache Bundler RubyGems
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
key: ${{ runner.os }}-rubygems-syntax-${{ steps.set-up-homebrew.outputs.gems-hash }}
restore-keys: ${{ runner.os }}-rubygems-syntax-
- name: Install Bundler RubyGems
run: brew install-bundler-gems --groups=style,typecheck
- name: Install shellcheck and shfmt
run: brew install shellcheck shfmt
- name: Cache style cache
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ~/.cache/Homebrew/style
key: syntax-style-cache-${{ github.sha }}
restore-keys: syntax-style-cache-
- run: brew style
- run: brew typecheck
- name: Check RuboCop filepaths
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/Library/Homebrew
run: |
public_apis="$(git grep -l "@api public" -- :^sorbet/ :^vendor/ | sort)"
rubocop_docs="$(yq '.Style/Documentation.Include[]' .rubocop.yml | sort)"
if [[ "${public_apis}" != "${rubocop_docs}" ]]; then
echo "All public Homebrew APIs should be included in the \`Style/Documentation\` RuboCop."
echo "Add/remove the following paths from \`Library/Homebrew/.rubocop.yml\` as appropriate:"
echo "${public_apis} ${rubocop_docs}" | tr ' ' '\n' | sort | uniq -u
exit 1
fi
tap-syntax:
name: tap syntax
needs: syntax
if: github.repository_owner == 'Homebrew'
runs-on: macos-15
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: true
cask: true
test-bot: true
- name: Cache Bundler RubyGems
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
key: ${{ runner.os }}-rubygems-tap-syntax-${{ steps.set-up-homebrew.outputs.gems-hash }}
restore-keys: ${{ runner.os }}-rubygems-tap-syntax-
- name: Install Bundler RubyGems
run: brew install-bundler-gems --groups=style
- name: Cache style cache
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ~/.cache/Homebrew/style
key: tap-syntax-style-cache-${{ github.sha }}
restore-keys: tap-syntax-style-cache-
- name: Run brew style on homebrew-core
run: brew style homebrew/core
- name: Set up all Homebrew taps
run: |
brew tap homebrew/command-not-found
brew tap homebrew/portable-ruby
# brew style doesn't like world writable directories
sudo chmod -R g-w,o-w "$(brew --repo)/Library/Taps"
- name: Run brew style on official taps
run: |
brew style homebrew/test-bot \
homebrew/command-not-found \
homebrew/portable-ruby \
homebrew/cask
formula-audit:
name: formula audit
needs: syntax
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
runs-on: ubuntu-latest
container:
image: ghcr.io/homebrew/brew:main
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: true
cask: false
test-bot: false
- name: Run brew readall on homebrew/core
run: brew readall --os=all --arch=all --aliases homebrew/core
- name: Run brew audit --skip-style on homebrew/core
run: brew audit --skip-style --except=version --tap=homebrew/core
- name: Generate formula API
run: brew generate-formula-api --dry-run
cask-audit:
name: cask audit
needs: syntax
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
runs-on: macos-15
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: true
cask: true
test-bot: false
- name: Run brew readall on all casks
run: brew readall --os=all --arch=all homebrew/cask
- name: Run brew audit --skip-style on homebrew/cask
run: |
brew audit --skip-style --except=version --tap=homebrew/cask
- name: Generate cask API
run: brew generate-cask-api --dry-run
vendored-gems:
name: vendored gems
needs: syntax
runs-on: ubuntu-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: false
cask: false
test-bot: false
- name: Configure Git user
uses: Homebrew/actions/git-user-config@main
with:
username: BrewTestBot
# Can't cache this because we need to check that it doesn't fail the
# "uncommitted RubyGems" step with a cold cache.
- name: Install Bundler RubyGems
run: brew install-bundler-gems --groups=all
- name: Check for uncommitted RubyGems
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
run: git diff --stat --exit-code Library/Homebrew/vendor/bundle/ruby
update-test:
name: ${{ matrix.name }}
runs-on: ${{ matrix.runs-on }}
needs: syntax
if: github.event_name != 'push'
strategy:
matrix:
include:
- name: update-test (Linux)
runs-on: ubuntu-latest
- name: update-test (macOS)
runs-on: macos-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: false
cask: false
test-bot: false
- name: Run brew update-tests
run: |
brew update-test
brew update-test --to-tag
brew update-test --commit=HEAD
tests:
if: github.event_name != 'push'
name: ${{ matrix.name }}
needs: syntax
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
include:
- name: tests (online)
test-flags: --online --coverage
runs-on: ubuntu-latest
- name: tests (generic OS)
test-flags: --generic --coverage
runs-on: ubuntu-latest
- name: tests (Linux)
test-flags: --coverage
runs-on: ubuntu-24.04
- name: tests (macOS)
test-flags: --coverage
runs-on: macos-15
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
# We only test needs_homebrew_core tests on macOS because
# homebrew/core is not available by default on GitHub-hosted Ubuntu
# runners, and it's expensive to tap it.
core: ${{ runner.os == 'macOS' }}
cask: false
test-bot: false
- name: Cache Bundler RubyGems
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
key: ${{ matrix.runs-on }}-tests-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
restore-keys: ${{ matrix.runs-on }}-tests-rubygems-
- run: brew config
- name: Install Bundler RubyGems
run: brew install-bundler-gems --groups=all
- name: Create parallel test log directory
run: mkdir tests
- name: Cache parallel tests log
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: tests
key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-${{ github.sha }}
restore-keys: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-
- name: Install brew tests --online dependencies
if: matrix.name == 'tests (online)'
run: brew install subversion curl
- name: Install brew tests macOS dependencies
if: runner.os != 'Linux'
run: |
# Workaround GitHub Actions Python issues
brew unlink python && brew link --overwrite python
brew install subversion
# brew tests doesn't like world writable directories
- name: Cleanup permissions
if: runner.os == 'Linux'
run: sudo chmod -R g-w,o-w /home/linuxbrew/.linuxbrew/Homebrew
- name: Run brew tests
if: github.event_name == 'pull_request' || matrix.name != 'tests (online)'
run: |
# Retry multiple times to detect and submit flakiness to CodeCov (because rspec-retry is disabled).
if [[ -n "${CODECOV_TOKEN-}" ]]
then
brew tests ${{ matrix.test-flags }} ||
brew tests ${{ matrix.test-flags }}
else
brew tests ${{ matrix.test-flags }}
fi
env:
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# These cannot be queried at the macOS level on GitHub Actions.
HOMEBREW_LANGUAGES: en-GB
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Get RSpec JUnit XML filenames
id: junit_xml
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
run: |
mkdir -p Library/Homebrew/test/junit
filenames=$(find Library/Homebrew/test/junit -name 'rspec*.xml' -print | tr '\n' ',')
echo "filenames=${filenames%,}" >> "$GITHUB_OUTPUT"
- uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
with:
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
files: ${{ steps.junit_xml.outputs.filenames }}
disable_search: true
token: ${{ secrets.CODECOV_TOKEN }}
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
files: Library/Homebrew/test/coverage/coverage.xml
disable_search: true
token: ${{ secrets.CODECOV_TOKEN }}
test-bot:
name: ${{ matrix.name }}
needs: syntax
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
runs-on: ${{ matrix.runs-on }}
container: ${{ matrix.container }}
strategy:
matrix:
include:
- name: test-bot (Linux arm64)
runs-on: ubuntu-24.04-arm
container: ghcr.io/homebrew/ubuntu24.04:latest
- name: test-bot (Linux x86_64)
runs-on: ubuntu-latest
container: ghcr.io/homebrew/ubuntu22.04:main
# Use Debian Old Stable for testing Homebrew's glibc support.
- name: test-bot (Linux Homebrew glibc)
runs-on: ubuntu-latest
container: debian:oldstable
- name: test-bot (macOS x86_64)
runs-on: macos-13
- name: test-bot (macOS arm64)
runs-on: macos-15
env:
HOMEBREW_TEST_BOT_ANALYTICS: 1
HOMEBREW_ENFORCE_SBOM: 1
HOMEBREW_DOWNLOAD_CONCURRENCY: auto
steps:
- name: Install Homebrew and Homebrew's dependencies
# All other images are built from our Homebrew Dockerfile.
# This is the only one that needs to be set up manually.
if: matrix.container == 'debian:oldstable'
run: |
# Slimmed down version from the Homebrew Dockerfile
apt-get update
apt-get install -y --no-install-recommends \
bzip2 \
ca-certificates \
curl \
file \
g++ \
git-core \
less \
locales \
make \
netbase \
patch \
procps \
sudo \
uuid-runtime \
tzdata
# Install Homebrew
mkdir -p /home/linuxbrew/.linuxbrew/bin
# Don't do shallow clone or it's unshallowed by "Set up Homebrew"
git clone https://github.com/Homebrew/brew.git /home/linuxbrew/.linuxbrew/Homebrew
cd /home/linuxbrew/.linuxbrew/bin
ln -s ../Homebrew/bin/brew brew
echo "/home/linuxbrew/.linuxbrew/bin" >>"$GITHUB_PATH"
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: false
cask: false
test-bot: true
- run: brew test-bot --only-cleanup-before
- name: Setup environment variables
run: |
# Set enviroment variables to bypass `brew doctor` failures on Tier >=2 configurations
if [[ "${MATRIX_NAME}" == "test-bot (Linux arm64)" ]]; then
echo "HOMEBREW_ARM64_TESTING=1" >> "$GITHUB_ENV"
elif [[ "${MATRIX_NAME}" == "test-bot (Linux Homebrew glibc)" ]]; then
echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
fi
env:
MATRIX_NAME: ${{ matrix.name }}
- run: brew test-bot --only-setup
- run: brew install gnu-tar
- run: brew test-bot --only-formulae --only-json-tab --test-default-formula
bundle-and-services:
name: ${{ matrix.name }}
needs: syntax
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
include:
- name: bundle and services (Linux)
runs-on: ubuntu-latest
- name: bundle and services (macOS)
runs-on: macos-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
core: false
cask: false
test-bot: false
- run: brew test-bot --only-cleanup-before
- name: Run brew bundle and brew services integration tests
run: |
cat <<EOS >> Brewfile
brew "git"
brew "memcached", restart_service: true
brew "postgresql@15", restart_service: true
cask "1password"
cask "1password-cli"
cask "google-chrome"
# VSCode cask is not available on Linux.
vscode "github.copilot" if OS.mac?
EOS
brew bundle check && exit 1
brew bundle check --verbose && exit 1
brew bundle list
brew bundle --verbose
brew bundle --upgrade-formulae=memcached,postgresql@15
brew bundle upgrade
brew bundle env | grep PATH | grep git
brew bundle env --install
brew bundle exec --services true
brew bundle dump --force --describe
brew services list
brew services info memcached postgresql@15
brew services info --json memcached postgresql@15
brew services cleanup
brew bundle cleanup --force
analytics:
name: ${{ matrix.name }}
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
include:
- name: analytics (Linux)
runs-on: ubuntu-latest
- name: analytics (macOS)
runs-on: macos-latest
needs: syntax
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version-file: ${{ steps.set-up-homebrew.outputs.repository-path }}/Library/Homebrew/formula-analytics/.python-version
- name: Cache Homebrew Bundler RubyGems
id: cache
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
restore-keys: ${{ runner.os }}-rubygems-
- name: Install Homebrew Bundler RubyGems
if: steps.cache.outputs.cache-hit != 'true'
run: brew install-bundler-gems
- run: brew formula-analytics --setup
- run: brew formula-analytics --install --json --days-ago=2
if: github.event.pull_request.head.repo.fork == false && (github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dependabot[bot]')
env:
HOMEBREW_INFLUXDB_TOKEN: ${{ secrets.HOMEBREW_INFLUXDB_READ_TOKEN }}
- run: brew generate-analytics-api
if: github.event.pull_request.head.repo.fork == false && (github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dependabot[bot]')
env:
HOMEBREW_INFLUXDB_TOKEN: ${{ secrets.HOMEBREW_INFLUXDB_READ_TOKEN }}