Skip to content

scrolla 20

scrolla 20 #168900

Workflow file for this run

name: CI
on:
push:
branches:
- master
pull_request:
merge_group:
workflow_dispatch:
inputs:
casks:
description: List of casks to audit (comma-separated)
required: true
skip_install:
description: Skip installation of casks
required: false
default: true
type: boolean
new_cask:
description: Apply new cask audit
required: false
default: false
type: boolean
env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_INSTALL_FROM_API: 1
HOMEBREW_GITHUB_API_TOKEN: ${{ github.token }}
concurrency:
group: "${{ github.ref }}"
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
generate-matrix:
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
runs-on: macos-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
with:
core: false
cask: true
test-bot: false
- name: Check out Pull Request
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
persist-credentials: false
- name: Generate CI matrix
id: generate-matrix
env:
INPUT_CASKS: ${{ github.event.inputs.casks }}
PULL_REQUEST_URL: ${{ github.event.pull_request.url }}
run: |
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]
then
# shellcheck disable=SC2086 # $INPUT_CASKS is a space-separated list of cask tokens
brew generate-cask-ci-matrix ${{ github.event.inputs.skip_install && '--skip-install' }} ${{ github.event.inputs.new_cask && '--new' }} --casks $INPUT_CASKS
elif [[ "${GITHUB_EVENT_NAME}" == "push" ]]
then
brew generate-cask-ci-matrix --syntax-only
else
brew generate-cask-ci-matrix --url "$PULL_REQUEST_URL"
fi
test:
name: ${{ matrix.name }}
needs: generate-matrix
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
with:
core: false
cask: true
test-bot: true
- name: Enable debug mode
run: |
echo 'HOMEBREW_DEBUG=1' >> "${GITHUB_ENV}"
echo 'HOMEBREW_VERBOSE=1' >> "${GITHUB_ENV}"
if: runner.debug
- name: Check out Pull Request
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
persist-credentials: false
- name: Clean up CI machine
if: runner.os == 'macOS'
run: brew test-bot --cleanup --only-cleanup-before
- name: Cache Homebrew Gems
id: cache
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
key: ${{ matrix.runner }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
restore-keys: ${{ matrix.runner }}-rubygems-
- name: Cache style cache
if: runner.os == 'macOS'
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ~/Library/Caches/Homebrew/style
key: macos-style-cache-${{ github.sha }}
restore-keys: macos-style-cache-
- name: Run brew test-bot --only-tap-syntax
id: tap-syntax
run: brew test-bot --tap '${{ matrix.tap }}' --only-tap-syntax
if: always() && !matrix.cask
- name: Run brew fetch --cask ${{ matrix.cask.token }}
id: fetch
run: |
brew fetch --cask --retry --force ${{ join(matrix.fetch_args, ' ') }} '${{ matrix.cask.path }}'
timeout-minutes: 30
if: >
always() &&
contains(fromJSON('["success", "skipped"]'), steps.tap-syntax.outcome) &&
matrix.cask
- name: Run brew audit --cask${{ (matrix.cask && ' ') || ' --tap ' }}${{ matrix.cask.token || matrix.tap }}
id: audit
run: |
brew audit --cask ${{ join(matrix.audit_args, ' ') }}${{ (matrix.cask && ' ') || ' --tap ' }}'${{ matrix.cask.token || matrix.tap }}'
timeout-minutes: 30
if: >
always() &&
contains(fromJSON('["success", "skipped"]'), steps.tap-syntax.outcome) &&
(!matrix.cask || steps.fetch.outcome == 'success') &&
!matrix.skip_audit
- name: Gather cask information
id: info
run: |
brew ruby <<'EOF'
require 'cask/cask_loader'
require 'cask/installer'
cask = Cask::CaskLoader.load('${{ matrix.cask.path }}')
manual_installer = cask.artifacts.any? do |artifact|
if defined?(artifact.manual_install)
artifact.manual_install
end
end
macos_requirement_satisfied = if macos_requirement = cask.depends_on.macos
macos_requirement.satisfied?
else
true
end
cask_conflicts = cask.conflicts_with&.dig(:cask).to_a.select { |c| Cask::CaskLoader.load(c).installed? }
formula_conflicts = cask.conflicts_with&.dig(:formula).to_a.select { |f| Formula[f].any_version_installed? }
installer = Cask::Installer.new(cask)
cask_and_formula_dependencies = installer.missing_cask_and_formula_dependencies
cask_dependencies = cask_and_formula_dependencies.select { |d| d.is_a?(Cask::Cask) }.map(&:full_name)
formula_dependencies = cask_and_formula_dependencies.select { |d| d.is_a?(Formula) }.map(&:full_name)
File.open(ENV.fetch("GITHUB_OUTPUT"), "a") do |f|
f.puts "manual_installer=#{JSON.generate(manual_installer)}"
f.puts "macos_requirement_satisfied=#{JSON.generate(macos_requirement_satisfied)}"
f.puts "formula_dependencies=#{JSON.generate(formula_dependencies)}"
end
File.open(ENV.fetch("GITHUB_ENV"), "a") do |f|
f.puts "CASK_CONFLICTS=\"#{cask_conflicts&.join(" ")}\"" if cask_conflicts.present?
f.puts "CASK_DEPENDENCIES=\"#{cask_dependencies&.join(" ")}\"" if cask_dependencies.present?
f.puts "FORMULA_CONFLICTS=\"#{formula_conflicts&.join(" ")}\"" if formula_conflicts.present?
end
EOF
if: always() && steps.fetch.outcome == 'success' && matrix.cask
- name: Uninstall conflicting formulae
run: |
# shellcheck disable=SC2086
brew uninstall --formula $FORMULA_CONFLICTS
if: ${{ always() && steps.info.outcome == 'success' && env.FORMULA_CONFLICTS != '' }}
timeout-minutes: 30
- name: Uninstall conflicting casks
run: |
# shellcheck disable=SC2086
brew uninstall --cask $CASK_CONFLICTS
if: ${{ always() && steps.info.outcome == 'success' && env.CASK_CONFLICTS != '' }}
timeout-minutes: 30
- name: Run brew uninstall --cask --force --zap ${{ matrix.cask.token }}
run: |
brew uninstall --cask --force --zap '${{ matrix.cask.path }}'
if: always() && steps.info.outcome == 'success'
timeout-minutes: 30
- name: Take snapshot of installed and running apps and services
id: snapshot
run: |
brew ruby -r "$(brew --repository homebrew/cask)/cmd/lib/check.rb" <<'EOF'
File.open(ENV.fetch("GITHUB_ENV"), "a") do |f|
# We have to use a `HOMEBREW_` prefix so it will survive the
# environment variable filtering in `brew`.
f.puts "HOMEBREW_SNAPSHOT_BEFORE=#{JSON.generate(Check.all)}"
end
EOF
if: always() && steps.info.outcome == 'success'
- name: Run brew install --cask ${{ matrix.cask.token }}
id: install
run: brew install --cask '${{ matrix.cask.path }}'
if: >
always() && steps.info.outcome == 'success' &&
fromJSON(steps.info.outputs.macos_requirement_satisfied) &&
!matrix.skip_install
timeout-minutes: 30
- name: Run brew uninstall --cask ${{ matrix.cask.token }}
run: brew uninstall --cask '${{ matrix.cask.path }}'
if: always() && steps.install.outcome == 'success' && !fromJSON(steps.info.outputs.manual_installer)
timeout-minutes: 30
- name: Uninstall cask dependencies
run: |
# shellcheck disable=SC2086
brew uninstall --cask $CASK_DEPENDENCIES
if: ${{ always() && steps.install.outcome == 'success' && env.CASK_DEPENDENCIES != '' }}
timeout-minutes: 30
- name: Compare installed and running apps and services with snapshot
run: |
brew ruby -r "$(brew --repository homebrew/cask)/cmd/lib/check.rb" <<'EOF'
require "cask/cask_loader"
require "utils/github/actions"
before = JSON.parse(ENV.fetch("HOMEBREW_SNAPSHOT_BEFORE", "{}"))
.transform_keys(&:to_sym)
after = Check.all
cask = Cask::CaskLoader.load('${{ matrix.cask.path }}')
errors = Check.errors(before, after, cask: cask)
errors.each do |error|
onoe error
puts GitHub::Actions::Annotation.new(:error, error, file: '${{ matrix.cask.path }}')
end
exit 1 if errors.any?
EOF
if: always() && steps.snapshot.outcome == 'success'
conclusion:
name: conclusion
needs: test
runs-on: ubuntu-latest
if: always()
steps:
- name: Result
run: ${{ needs.test.result == 'success' }}