2019-08-13 10:26:50 +08:00
|
|
|
name: CI
|
|
|
|
|
2019-08-13 11:00:51 +08:00
|
|
|
on:
|
2020-08-26 19:27:42 +08:00
|
|
|
pull_request:
|
2020-08-23 03:35:14 +08:00
|
|
|
types: [synchronize, opened, reopened, labeled, unlabeled]
|
2019-08-13 10:26:50 +08:00
|
|
|
|
2020-08-25 10:17:40 +08:00
|
|
|
env:
|
|
|
|
HOMEBREW_DEVELOPER: 1
|
|
|
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
|
|
|
|
2019-08-13 10:26:50 +08:00
|
|
|
jobs:
|
2020-08-13 05:47:11 +08:00
|
|
|
generate-matrix:
|
|
|
|
outputs:
|
|
|
|
matrix: ${{ steps.generate-matrix.outputs.matrix }}
|
2020-08-28 06:55:56 +08:00
|
|
|
runs-on: ubuntu-latest
|
2020-08-13 05:47:11 +08:00
|
|
|
steps:
|
2020-08-25 10:17:40 +08:00
|
|
|
- name: Set up Homebrew
|
|
|
|
id: set-up-homebrew
|
|
|
|
uses: Homebrew/actions/setup-homebrew@master
|
|
|
|
with:
|
|
|
|
test-bot: false
|
|
|
|
|
2020-08-13 05:47:11 +08:00
|
|
|
- name: Check out Pull Request
|
2020-08-25 10:17:40 +08:00
|
|
|
uses: actions/checkout@v2
|
|
|
|
with:
|
|
|
|
fetch-depth: 0
|
|
|
|
persist-credentials: false
|
|
|
|
|
2020-08-13 05:47:11 +08:00
|
|
|
- name: Generate CI matrix
|
|
|
|
id: generate-matrix
|
2020-08-28 06:55:56 +08:00
|
|
|
run: |
|
|
|
|
if ${{ contains(github.event.pull_request.labels.*.name, 'syntax-only') }}; then
|
|
|
|
flags=(--syntax-only)
|
|
|
|
else
|
|
|
|
flags=()
|
|
|
|
fi
|
|
|
|
|
|
|
|
brew ruby -- "$(brew --repository homebrew/cask)/cmd/lib/generate-matrix.rb" "${flags[@]}"
|
2020-08-13 05:47:11 +08:00
|
|
|
|
|
|
|
test:
|
2020-08-28 06:55:56 +08:00
|
|
|
name: ${{ matrix.name }}
|
2020-08-13 05:47:11 +08:00
|
|
|
needs: generate-matrix
|
|
|
|
runs-on: macos-latest
|
|
|
|
strategy:
|
2020-08-28 06:55:56 +08:00
|
|
|
matrix:
|
|
|
|
include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
2020-08-13 05:47:11 +08:00
|
|
|
steps:
|
2020-08-25 10:17:40 +08:00
|
|
|
- name: Set up Homebrew
|
|
|
|
id: set-up-homebrew
|
|
|
|
uses: Homebrew/actions/setup-homebrew@master
|
|
|
|
with:
|
|
|
|
test-bot: false
|
2020-08-13 05:47:11 +08:00
|
|
|
|
|
|
|
- name: Check out Pull Request
|
2020-08-25 10:17:40 +08:00
|
|
|
uses: actions/checkout@v2
|
|
|
|
with:
|
|
|
|
fetch-depth: 0
|
|
|
|
persist-credentials: false
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-08-11 10:27:12 +08:00
|
|
|
- name: Clean up CI machine
|
|
|
|
run: |
|
|
|
|
if ! brew cask ls visual-studio &>/dev/null; then
|
|
|
|
if ! rm -r '/Applications/Visual Studio.app'; then
|
|
|
|
echo '::warning::Workaround for Visual Studio is no longer needed.'
|
|
|
|
fi
|
|
|
|
fi
|
2019-08-13 17:02:53 +08:00
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
if brew tap-info adoptopenjdk/openjdk; then
|
|
|
|
brew untap adoptopenjdk/openjdk
|
|
|
|
else
|
|
|
|
echo '::warning::Untapping adoptopenjdk/openjdk is no longer necessary.'
|
|
|
|
fi
|
|
|
|
|
2020-07-30 15:20:47 +08:00
|
|
|
- name: Cache Homebrew Gems
|
|
|
|
uses: actions/cache@v2
|
|
|
|
with:
|
2020-08-25 10:17:40 +08:00
|
|
|
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
|
|
|
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
|
|
|
restore-keys: ${{ runner.os }}-rubygems-
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-07-30 15:20:47 +08:00
|
|
|
- name: Install Homebrew Gems
|
|
|
|
run: brew install-bundler-gems
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Run brew cask style ${{ matrix.cask.token }}
|
2020-07-30 15:20:47 +08:00
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
if ${{ !matrix.cask }}; then
|
|
|
|
brew cask style
|
|
|
|
exit $?
|
|
|
|
fi
|
2019-08-14 12:47:01 +08:00
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
brew cask style '${{ matrix.cask.path }}' || brew ruby <<'EOF'
|
|
|
|
path = Pathname('${{ matrix.cask.path }}')
|
2020-08-13 05:47:11 +08:00
|
|
|
json = Cask::Cmd::Style.rubocop(path.expand_path, json: true)
|
|
|
|
|
|
|
|
json.fetch("files").each do |file|
|
|
|
|
file.fetch("offenses").each do |o|
|
|
|
|
line = o.fetch("location").fetch("start_line")
|
|
|
|
column = o.fetch("location").fetch("start_column")
|
|
|
|
message = Tty.strip_ansi(o.fetch("message"))
|
|
|
|
.gsub(/\r/, '%0D')
|
|
|
|
.gsub(/\n/, '%0A')
|
|
|
|
.gsub(/]/, '%5D')
|
|
|
|
.gsub(/;/, '%3B')
|
|
|
|
|
|
|
|
puts "::error file=#{path},line=#{line},col=#{column}::#{message}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
exit 1
|
|
|
|
EOF
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Run brew cask audit ${{ matrix.cask.token }}
|
|
|
|
run: |
|
|
|
|
if ${{ !matrix.cask }}; then
|
|
|
|
brew cask audit
|
|
|
|
exit $?
|
|
|
|
fi
|
|
|
|
|
|
|
|
brew cask audit ${{ join(matrix.audit_args, ' ') }} '${{ matrix.cask.path }}'
|
2020-08-15 10:13:57 +08:00
|
|
|
env:
|
2020-08-26 19:27:42 +08:00
|
|
|
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
2020-08-13 05:47:11 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Gather cask information
|
|
|
|
id: info
|
2020-07-27 21:55:41 +08:00
|
|
|
run: |
|
2020-08-13 05:47:11 +08:00
|
|
|
brew ruby <<'EOF'
|
2020-08-22 04:06:56 +08:00
|
|
|
require 'cask/cask_loader'
|
|
|
|
require 'cask/installer'
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
cask = Cask::CaskLoader.load('${{ matrix.cask.path }}')
|
|
|
|
|
|
|
|
was_installed = cask.installed?
|
|
|
|
manual_installer = cask.artifacts.any? { |artifact|
|
|
|
|
artifact.is_a?(Cask::Artifact::Installer::ManualInstaller)
|
|
|
|
}
|
|
|
|
|
|
|
|
macos_requirement_satisfied = if macos_requirement = cask.depends_on.macos
|
|
|
|
macos_requirement.satisfied?
|
|
|
|
else
|
|
|
|
true
|
|
|
|
end
|
2020-07-27 21:55:41 +08:00
|
|
|
|
2020-08-22 06:11:32 +08:00
|
|
|
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? }
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-08-22 04:06:56 +08:00
|
|
|
installer = Cask::Installer.new(cask)
|
|
|
|
cask_and_formula_dependencies = installer.missing_cask_and_formula_dependencies
|
2020-08-13 05:47:11 +08:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
puts "::set-output name=was_installed::#{JSON.generate(was_installed)}"
|
|
|
|
puts "::set-output name=manual_installer::#{JSON.generate(manual_installer)}"
|
|
|
|
puts "::set-output name=macos_requirement_satisfied::#{JSON.generate(macos_requirement_satisfied)}"
|
2020-08-22 04:06:56 +08:00
|
|
|
puts "::set-output name=cask_conflicts::#{JSON.generate(cask_conflicts)}"
|
2020-08-13 05:47:11 +08:00
|
|
|
puts "::set-output name=cask_dependencies::#{JSON.generate(cask_dependencies)}"
|
2020-08-22 04:06:56 +08:00
|
|
|
puts "::set-output name=formula_conflicts::#{JSON.generate(formula_conflicts)}"
|
2020-08-13 05:47:11 +08:00
|
|
|
puts "::set-output name=formula_dependencies::#{JSON.generate(formula_dependencies)}"
|
|
|
|
EOF
|
2020-08-28 06:55:56 +08:00
|
|
|
if: matrix.cask
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-08-22 04:06:56 +08:00
|
|
|
- name: Uninstall conflicting formulae
|
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew uninstall ${{ join(fromJSON(steps.info.outputs.formula_conflicts), ' ') }}
|
|
|
|
if: steps.info.outcome == 'success' && join(fromJSON(steps.info.outputs.formula_conflicts)) != ''
|
2020-08-22 04:06:56 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
|
|
|
- name: Uninstall conflicting casks
|
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew cask uninstall ${{ join(fromJSON(steps.info.outputs.cask_conflicts), ' ') }}
|
|
|
|
if: steps.info.outcome == 'success' && join(fromJSON(steps.info.outputs.cask_conflicts)) != ''
|
2020-08-22 04:06:56 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Run brew cask zap ${{ matrix.cask.token }}
|
2020-08-13 05:47:11 +08:00
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew cask zap '${{ matrix.cask.path }}'
|
|
|
|
if: steps.info.outcome == 'success' && fromJSON(steps.info.outputs.was_installed)
|
2020-08-13 05:47:11 +08:00
|
|
|
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'
|
|
|
|
puts "::set-output name=before::#{JSON.generate(Check.all)}"
|
|
|
|
EOF
|
2020-08-28 06:55:56 +08:00
|
|
|
if: success() && steps.info.outcome == 'success'
|
2020-08-13 05:47:11 +08:00
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Run brew cask install ${{ matrix.cask.token }}
|
2020-08-13 05:47:11 +08:00
|
|
|
id: install
|
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew cask install '${{ matrix.cask.path }}'
|
|
|
|
if: success() && steps.info.outcome == 'success' && fromJSON(steps.info.outputs.macos_requirement_satisfied)
|
2020-08-13 05:47:11 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
- name: Run brew cask uninstall ${{ matrix.cask.token }}
|
|
|
|
run: brew cask uninstall '${{ matrix.cask.path }}'
|
|
|
|
if: success() && steps.install.outcome == 'success' && !fromJSON(steps.info.outputs.manual_installer)
|
2020-08-13 05:47:11 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
|
|
|
- name: Uninstall formula dependencies
|
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew uninstall ${{ join(fromJSON(steps.info.outputs.formula_dependencies), ' ') }}
|
|
|
|
if: success() && steps.install.outcome == 'success' && join(fromJSON(steps.info.outputs.formula_dependencies)) != ''
|
2020-08-13 05:47:11 +08:00
|
|
|
timeout-minutes: 30
|
|
|
|
|
|
|
|
- name: Uninstall cask dependencies
|
|
|
|
run: |
|
2020-08-28 06:55:56 +08:00
|
|
|
brew cask uninstall ${{ join(fromJSON(steps.info.outputs.cask_dependencies), ' ') }}
|
|
|
|
if: success() && steps.install.outcome == 'success' && join(fromJSON(steps.info.outputs.cask_dependencies)) != ''
|
2020-08-13 05:47:11 +08:00
|
|
|
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'
|
|
|
|
before = JSON.parse(<<~'EOS').transform_keys(&:to_sym)
|
|
|
|
${{ steps.snapshot.outputs.before }}
|
|
|
|
EOS
|
|
|
|
after = Check.all
|
|
|
|
|
|
|
|
errors = Check.errors(before, after)
|
|
|
|
|
|
|
|
errors.each do |error|
|
|
|
|
onoe error
|
|
|
|
end
|
|
|
|
|
|
|
|
error = errors.map { |e|
|
|
|
|
Tty.strip_ansi(e)
|
|
|
|
.gsub(/\r/, '%0D')
|
|
|
|
.gsub(/\n/, '%0A')
|
|
|
|
.gsub(/]/, '%5D')
|
|
|
|
.gsub(/;/, '%3B')
|
|
|
|
}.join("\n\n")
|
|
|
|
|
2020-08-28 06:55:56 +08:00
|
|
|
puts "::error file=${{ matrix.cask.path }}::#{error}"
|
2020-08-13 05:47:11 +08:00
|
|
|
|
|
|
|
exit 1 if errors.any?
|
|
|
|
EOF
|
2020-08-28 06:55:56 +08:00
|
|
|
if: success() && steps.snapshot.outcome == 'success'
|
|
|
|
conclusion:
|
|
|
|
name: conclusion
|
|
|
|
needs: test
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
if: always()
|
|
|
|
steps:
|
|
|
|
- name: Result
|
|
|
|
run: ${{ needs.test.result == 'success' }}
|