Skip to content

Commit

Permalink
Improve building Homebrew*.pkg
Browse files Browse the repository at this point in the history
- split jobs into build/test/deploy
- test package on both macOS Intel and Apple Silicon
- cleanup some argument handling
- use `HOMEBREW_MACOS_OLDEST_SUPPORTED` naming to be consistent with
  `brew.sh`
- note in `brew.sh` that `Distribution.xml` also needs updated (and do
  so)
- various other little bits of style cleanup
  • Loading branch information
MikeMcQuaid committed Oct 4, 2023
1 parent d0eef12 commit c95a26b
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
name: Build Homebrew installer pkg
name: Installer Package
on:
push:
branches:
- '**'
tags-ignore:
- '**'
paths:
- .github/workflows/build-pkg.yml
- .github/workflows/installer-package.yml
- package/**/*
release:
types:
- published

env:
PKG_APPLE_DEVELOPER_TEAM_ID: ${{ secrets.PKG_APPLE_DEVELOPER_TEAM_ID }}
HOMEBREW_NO_ANALYTICS_THIS_RUN: 1
HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT: 1
jobs:
build:
if: github.repository_owner == 'Homebrew'
runs-on: macos-13
permissions:
# To write assets to GitHub release
contents: write
runs-on: macos-latest
outputs:
installer_path: "Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg"
env:
TEMPORARY_CERTIFICATE_FILE: 'homebrew_developer_id_installer_certificate.p12'
TEMPORARY_KEYCHAIN_FILE: 'homebrew_installer_signing.keychain-db'
# Set to the latest supported version of macOS
MIN_MACOS_VERSION: '12.0'
PKG_APPLE_DEVELOPER_TEAM_ID: ${{ secrets.PKG_APPLE_DEVELOPER_TEAM_ID }}
HOMEBREW_NO_ANALYTICS_THIS_RUN: 1
HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT: 1
# Set to the oldest supported version of macOS
HOMEBREW_MACOS_OLDEST_SUPPORTED: '12.0'
steps:
- name: Remove existing API cache (to force update)
run: rm -rvf ~/Library/Caches/Homebrew/api
Expand Down Expand Up @@ -58,7 +61,9 @@ jobs:
run: security import "${RUNNER_TEMP}/${TEMPORARY_CERTIFICATE_FILE}"
-k "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"
-P "${PKG_APPLE_SIGNING_CERTIFICATE_PASSWORD}"
-t cert -f pkcs12 -A
-t cert
-f pkcs12
-A

- name: Clean up temporary certificate file
if: ${{ always() }}
Expand All @@ -72,7 +77,7 @@ jobs:
persist-credentials: false

- name: Get Homebrew version from Git
id: print-version
id: homebrew-version
run: echo "version=$(git -C brew describe --tags --always)" >> "${GITHUB_OUTPUT}"

- name: Copy Homebrew API cache to brew subdirectory
Expand All @@ -86,23 +91,54 @@ jobs:
# binaries so it needs to be excluded from notarization.
run: pkgbuild --root brew
--scripts brew/package/scripts
--identifier "sh.brew.homebrew"
--version ${{ steps.print-version.outputs.version }}
--install-location "/opt/homebrew"
--identifier sh.brew.homebrew
--version "${{ steps.homebrew-version.outputs.version }}"
--install-location /opt/homebrew
--filter .DS_Store
--filter "(.*)/Library/Homebrew/test/support/fixtures/"
--min-os-version "${MIN_MACOS_VERSION}"
--sign "${PKG_APPLE_DEVELOPER_TEAM_ID}" Homebrew.pkg
--min-os-version "${HOMEBREW_MACOS_OLDEST_SUPPORTED}"
--sign "${PKG_APPLE_DEVELOPER_TEAM_ID}"
Homebrew.pkg

- name: Convert Homebrew license file to RTF
run: (printf "### " && cat brew/LICENSE.txt) |
pandoc --from markdown --standalone --output brew/package/resources/LICENSE.rtf

- name: Build Homebrew installer package
- name: Build Homebrew installer product package
run: productbuild --resources brew/package/resources
--distribution brew/package/Distribution.xml
--package-path Homebrew.pkg Homebrew-${{ steps.print-version.outputs.version }}.pkg
--package-path Homebrew.pkg
--sign "${PKG_APPLE_DEVELOPER_TEAM_ID}"
Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg

- name: Clean up temporary macOS keychain
if: ${{ always() }}
run: |
if [[ -f "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}" ]]
then
security delete-keychain "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"
fi
- name: Upload installer to GitHub Actions
uses: actions/upload-artifact@v3
with:
name: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
test:
needs: build
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
# Intel (free)
- runner: macos-latest
# Apple Silicon (paid)
- runner: macos-latest-xlarge
steps:
- name: Download installer from GitHub Actions
uses: actions/download-artifact@v3
with:
name: "${{ needs.build.outputs.installer_path }}"

- name: Remove existing Homebrew installations
run: |
Expand All @@ -114,7 +150,7 @@ jobs:
run: echo | sudo tee /var/log/install.log

- name: Install Homebrew from installer package
run: sudo installer -verbose -pkg Homebrew-${{ steps.print-version.outputs.version }}.pkg -target /
run: sudo installer -verbose -pkg "${{ needs.build.outputs.installer_path }}" -target /

- name: Output installer logs
if: ${{ always() }}
Expand All @@ -128,7 +164,7 @@ jobs:
run: echo | sudo tee /var/log/install.log

- name: Reinstall Homebrew from installer package
run: sudo installer -verbose -pkg Homebrew-${{ steps.print-version.outputs.version }}.pkg -target /
run: sudo installer -verbose -pkg "${{ needs.build.outputs.installer_path }}" -target /

- name: Output installer logs (again)
if: ${{ always() }}
Expand All @@ -138,37 +174,35 @@ jobs:

- run: brew doctor

upload:
needs: [build, test]
runs-on: macos-latest
permissions:
# To write assets to GitHub release
contents: write
steps:
- name: Download installer from GitHub Actions
uses: actions/download-artifact@v3
with:
name: "${{ needs.build.outputs.installer_path }}"

- name: Notarize Homebrew installer package
env:
PKG_APPLE_ID_EMAIL: ${{ secrets.PKG_APPLE_ID_EMAIL }}
PKG_APPLE_ID_APP_SPECIFIC_PASSWORD: ${{ secrets.PKG_APPLE_ID_APP_SPECIFIC_PASSWORD }}
run: xcrun notarytool submit Homebrew-${{ steps.print-version.outputs.version }}.pkg
run: xcrun notarytool submit "${{ needs.build.outputs.installer_path }}"
--team-id "${PKG_APPLE_DEVELOPER_TEAM_ID}"
--apple-id "${PKG_APPLE_ID_EMAIL}"
--password "${PKG_APPLE_ID_APP_SPECIFIC_PASSWORD}"
--wait

- name: Clean up temporary macOS keychain
if: ${{ always() }}
run: |
if [[ -f "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}" ]]
then
security delete-keychain "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"
fi
- name: Upload installer to GitHub Actions
uses: actions/upload-artifact@v3
with:
name: Homebrew ${{ steps.print-version.outputs.version }}
path: Homebrew-${{ steps.print-version.outputs.version }}.pkg

- name: Install gh
run: brew install gh

- name: Upload installer to GitHub release
if: startsWith(github.ref, 'refs/tags/')
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload --repo Homebrew/brew
"${GITHUB_REF//refs\/tags\//}"
Homebrew-${{ steps.print-version.outputs.version }}.pkg
"${GITHUB_REF//refs\/tags\//}"
"${{ needs.build.outputs.installer_path }}"
3 changes: 2 additions & 1 deletion Library/Homebrew/brew.sh
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ esac
HOMEBREW_MACOS_NEWEST_UNSUPPORTED="15"
# TODO: bump version when new macOS is released and update references in:
# - docs/Installation.md
# - MIN_MACOS_VERSION in .github/workflows/build-pkg.yml
# - HOMEBREW_MACOS_OLDEST_SUPPORTED in .github/workflows/installer-package.yml
# - `os-version min` in package/Distribution.xml
# - https://github.com/Homebrew/install/blob/HEAD/install.sh
HOMEBREW_MACOS_OLDEST_SUPPORTED="12"
HOMEBREW_MACOS_OLDEST_ALLOWED="10.11"
Expand Down
4 changes: 2 additions & 2 deletions package/Distribution.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<options customize="never" hostArchitectures="x86_64,arm64" rootVolumeOnly="true"/>
<volume-check>
<allowed-os-versions>
<os-version min="11.0.0"/>
<os-version min="12.0.0"/>
</allowed-os-versions>
</volume-check>
<choices-outline>
Expand All @@ -27,7 +27,7 @@
<license file="LICENSE.rtf"/>
<conclusion file="CONCLUSION.rtf" />
<allowed-os-versions>
<os-version min="11.0"/>
<os-version min="12.0.0"/>
</allowed-os-versions>

<script>
Expand Down
23 changes: 16 additions & 7 deletions package/scripts/postinstall
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# $2 Location of the Homebrew installation we may need to move into place
# $3 Target install location (unused)
# $4 System root directory (unused)
set -eu
set -euo pipefail

# disable analytics while installing
export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
Expand All @@ -26,24 +26,33 @@ cd "${homebrew_directory}"
git config --global --add safe.directory "${homebrew_directory}"
git reset --hard
git checkout --force master
git branch | grep -v '\*' | xargs -n 1 git branch --delete --force
git branch | grep -v '\*' | xargs -n 1 git branch --delete --force || true
git config --global --unset safe.directory "${homebrew_directory}"

# move to /usr/local if on x86_64
if [[ $(uname -m) == "x86_64" ]]
then
sudo mkdir -vp /usr/local/bin /usr/local/Homebrew
cp -a "${homebrew_directory}"/* "${homebrew_directory}/".??* "/usr/local/Homebrew/"
if [[ -f "/usr/local/bin/brew" && -d "/usr/local/Homebrew" ]]
then
cp -pRL "${homebrew_directory}/.git" "/usr/local/Homebrew/"
mv "${homebrew_directory}/cache_api" "/usr/local/Homebrew/"
git -C /usr/local/Homebrew reset --hard
git -C /usr/local/Homebrew checkout --force master
else
mkdir -vp /usr/local/bin
mv "${homebrew_directory}" "/usr/local/Homebrew/"

# create symlink to /usr/local/bin/brew
ln -svf "../Homebrew/bin/brew" "/usr/local/bin/brew"
# create symlink to /usr/local/bin/brew
ln -svf "../Homebrew/bin/brew" "/usr/local/bin/brew"
fi

rm -rf "${homebrew_directory}"
homebrew_directory="/usr/local/Homebrew"
cd /usr/local
fi

# create missing directories
sudo mkdir -vp Cellar Frameworks etc include lib opt sbin share var/homebrew/linked
mkdir -vp Cellar Frameworks etc include lib opt sbin share var/homebrew/linked

# set permissions
logged_in_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
Expand Down

0 comments on commit c95a26b

Please sign in to comment.