Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS .pkg improvements #15751

Merged
merged 1 commit into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions .github/workflows/build-pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,29 @@ jobs:
build:
if: github.repository_owner == 'Homebrew'
runs-on: macos-13
permissions:
# To write assets to GitHub release
contents: write
env:
TEMPORARY_CERTIFICATE_FILE: 'homebrew_developer_id_installer_certificate.p12'
TEMPORARY_KEYCHAIN_FILE: 'homebrew_installer_signing.keychain-db'
MIN_MACOS_VERSION: '11.0'
PKG_APPLE_DEVELOPER_TEAM_ID: ${{ secrets.PKG_APPLE_DEVELOPER_TEAM_ID }}
steps:
- uses: actions/checkout@v3
- name: Checkout to brew subdirectory
uses: actions/checkout@v3
with:
path: brew
fetch-depth: 0
persist-credentials: false

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

- name: Install Pandoc
run: brew install pandoc

- name: Create and unlock temporary macOS keychain
env:
PKG_KEYCHAIN_PASSWORD: ${{ secrets.PKG_KEYCHAIN_PASSWORD }}
Expand All @@ -38,12 +47,16 @@ jobs:
- name: Create temporary certificate file
env:
PKG_APPLE_SIGNING_CERTIFICATE_BASE64: ${{ secrets.PKG_APPLE_SIGNING_CERTIFICATE_BASE64 }}
run: echo -n "${PKG_APPLE_SIGNING_CERTIFICATE_BASE64}" | base64 --decode --output="${RUNNER_TEMP}/${TEMPORARY_CERTIFICATE_FILE}"
run: echo -n "${PKG_APPLE_SIGNING_CERTIFICATE_BASE64}" |
base64 --decode --output="${RUNNER_TEMP}/${TEMPORARY_CERTIFICATE_FILE}"

- name: Import certificate file into macOS keychain
env:
PKG_APPLE_SIGNING_CERTIFICATE_PASSWORD: ${{ secrets.PKG_APPLE_SIGNING_CERTIFICATE_PASSWORD }}
run: security import "${RUNNER_TEMP}/${TEMPORARY_CERTIFICATE_FILE}" -k "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}" -t cert -f pkcs12 -P "${PKG_APPLE_SIGNING_CERTIFICATE_PASSWORD}" -A
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

- name: Clean up temporary certificate file
if: ${{ always() }}
Expand All @@ -52,25 +65,57 @@ jobs:
- name: Open macOS keychain
run: security list-keychain -d user -s "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"

- name: Build Homebrew installer package
env:
PKG_APPLE_DEVELOPER_TEAM_ID: ${{ secrets.PKG_APPLE_DEVELOPER_TEAM_ID }}
- name: Build Homebrew installer component package
# Note: `Library/Homebrew/test/support/fixtures/` contains unsigned
# 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 "/tmp/brew" --filter .DS_Store --filter "(.*)/Library/Homebrew/test/support/fixtures/" --min-os-version "${MIN_MACOS_VERSION}" --sign "${PKG_APPLE_DEVELOPER_TEAM_ID}" Homebrew-${{ steps.print-version.outputs.version }}.pkg
run: pkgbuild --root brew
--scripts brew/package/scripts
--identifier "sh.brew.homebrew"
--version ${{ steps.print-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

- 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
run: productbuild --resources brew/package/resources
--distribution brew/package/Distribution.xml
--package-path Homebrew.pkg Homebrew-${{ steps.print-version.outputs.version }}.pkg
--sign "${PKG_APPLE_DEVELOPER_TEAM_ID}"

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

- name: Clean up temporary macOS keychain
if: ${{ always() }}
run: test -f "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}" && security delete-keychain "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"
run: |
if [[ -f "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}" ]]
then
security delete-keychain "${RUNNER_TEMP}/${TEMPORARY_KEYCHAIN_FILE}"
fi

- uses: actions/upload-artifact@v3
- 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: Upload installer to GitHub release
if: startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload --repo Homebrew/brew
"${GITHUB_REF//refs\/tags\//}"
Homebrew-${{ steps.print-version.outputs.version }}.pkg
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@

# Unignore our packaging files
!/package
/package/resources/LICENSE.rtf

# Ignore generated documentation site
/docs/_site
Expand Down
47 changes: 47 additions & 0 deletions package/Distribution.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<installer-gui-script minSpecVersion="2">
<pkg-ref id="sh.brew.homebrew"/>
<options customize="never" hostArchitectures="x86_64,arm64" rootVolumeOnly="true"/>
<volume-check>
<allowed-os-versions>
<os-version min="11.0.0"/>
</allowed-os-versions>
</volume-check>
<choices-outline>
<line choice="default">
<line choice="sh.brew.homebrew"/>
</line>
</choices-outline>
<choice id="default"/>
<choice id="sh.brew.homebrew" visible="false">
<pkg-ref id="sh.brew.homebrew"/>
</choice>
<pkg-ref id="sh.brew.homebrew" onConclusion="none">Homebrew.pkg</pkg-ref>

<title>Homebrew</title>
<organization>sh.brew</organization>

<background file="Homebrew.png" alignment="bottomleft" scaling="proportional"/>
<background-darkAqua file="Homebrew.png" alignment="bottomleft" scaling="proportional"/>
<welcome file="WELCOME.rtf"/>
<license file="LICENSE.rtf"/>
<conclusion file="CONCLUSION.rtf" />
<allowed-os-versions>
<os-version min="11.0"/>
</allowed-os-versions>

<script>
function installation_check() {
if (system.files.fileExistsAtPath("/Library/Developer/CommandLineTools/usr/bin/git") ||
system.files.fileExistsAtPath("/Applications/Xcode.app/Contents/Developer/usr/bin/git")) {
return true;
} else {
my.result.title = "Xcode Command Line Tools (CLT) are missing";
my.result.message = "You must install the Xcode Command Line Tools (CLT) or Xcode before installing Homebrew. Install the CLT by running `xcode-select --install` from a Terminal.";
my.result.type = "Fatal";
return false;
}
}
</script>
<installation-check script="installation_check()" />
</installer-gui-script>
43 changes: 43 additions & 0 deletions package/resources/CONCLUSION.rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{\rtf1\ansi\ansicpg1252\cocoartf2709
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 Menlo-Regular;
}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid1\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid101\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}
{\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid201\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid202\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid3}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}}
\paperw11900\paperh16840\margl1440\margr1440\vieww13440\viewh7240\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0

\f0\b\fs24 \cf0 Homebrew has enabled anonymous aggregate formulae and cask analytics.
\f1\b0 \
\
Read the analytics documentation (and how to opt-out) here:\
\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
\ls1\ilvl0\cf0 {\listtext \uc0\u8259 }\ul https://docs.brew.sh/Analytics\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
\cf0 \ulnone No analytics data has been sent yet.\
\
Homebrew is run entirely by unpaid volunteers. Please consider donating:\
\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
\ls2\ilvl0\cf0 {\listtext \uc0\u8259 }\ul https://github.com/Homebrew/brew#donations\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
\cf0 \ulc0 \
\ulnone Next steps:\ul \
\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
\ls3\ilvl0\cf0 \ulnone {\listtext \uc0\u8259 }To add Homebrew to your
\f2 PATH
\f1 run
\f2 brew shellenv
\f1 in your shell profile (e.g.
\f2 ~/.bash_profile
\f1 or
\f2 ~/.zprofile
\f1 )\
{\listtext \uc0\u8259 }Run
\f2 brew help
\f1 to get started\
{\listtext \uc0\u8259 }Further documentation:\
\pard\tx940\tx1440\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li1440\fi-1440\pardirnatural\partightenfactor0
\ls3\ilvl1\cf0 {\listtext \uc0\u8259 }\ul https://docs.brew.sh}
Binary file added package/resources/Homebrew.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions package/resources/WELCOME.rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{\rtf1\ansi\ansicpg1252\cocoartf2709
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Menlo-Regular;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid1\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
\paperw11900\paperh16840\margl1440\margr1440\vieww13440\viewh7240\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0

\f0\fs24 \cf0 This package will install to:\
\pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
\ls1\ilvl0
\f1 \cf0 {\listtext \uc0\u8259 }/opt/homebrew
\f0 on Apple Silicon\
\ls1\ilvl0
\f1 {\listtext \uc0\u8259 }/usr/local/bin/brew
\f0 and
\f1 /usr/local/Homebrew
\f0 on Intel}
83 changes: 40 additions & 43 deletions package/scripts/postinstall
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
#!/bin/bash
# $1 Full path to the installer - unused
# $2 Location of the temporary brew install we're moving into place
# $3 Target install location - unused
# $4 System root directory - unused
set -e

# verify the files exist
tmp_brew="$2"
if [[ ! -d "${tmp_brew:?}" ]]
# $1 Full path to the installer (unused)
# $2 Location of the Homebrew installation we may need to move into place
# $3 Target install location (unused)
# $4 System root directory (unused)
set -xeu

# disable analytics while installing
export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1

# verify the installation exists
# default to /opt/homebrew to make development/testing easier
homebrew_directory="${2:-/opt/homebrew}"
if [[ ! -d "${homebrew_directory:?}" ]]
then
echo "no directory at ${tmp_brew}, exiting"
echo "no directory at ${homebrew_directory}!" >&2
exit 1
fi

# pick the correct target
# add Git to path
export PATH="/Library/Developer/CommandLineTools/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:${PATH}"

# reset Git repository
cd "${homebrew_directory}"
git reset --hard
git checkout -f master
git branch | grep -v '\*' | xargs -n 1 git branch -D

# move to /usr/local if on x86_64
if [[ $(uname -m) == "x86_64" ]]
then
target="/usr/local"
else
target="/opt/homebrew"
fi
mv "${homebrew_directory}" "/usr/local/Homebrew"
# create symlink to /usr/local/bin/brew
ln -s "/usr/local/Homebrew/bin/brew" "/usr/local/bin/brew"

loggedInUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
if [[ -f "${target}/bin/brew" ]]
then
if [[ $(sudo -u"${loggedInUser}" git -C "${target}" branch --show-current) != "master" ]]
then
echo "working on brew modifications, exiting"
rm -rf "${tmp_brew:?}/*"
exit 0
fi
if [[ $("${tmp_brew}/bin/brew" --version | head -n1) != $("${target}/bin/brew" --version | head -n1) ]]
then
echo "already an outdated install at ${target}, updating"
sudo -u"${loggedInUser}" "${target}/bin/brew" update --auto-update
else
echo "already an up-to-date install at ${target}, exiting"
fi

rm -rf "${tmp_brew:?}/*"
exit 0
homebrew_directory="/usr/local"
cd "${homebrew_directory}"
fi

group=$(id -gn "${loggedInUser}")

install -d -o "root" -g "wheel" -m "0755" "${target}"

cp -RX "${tmp_brew}/" "${target}"
# create missing directories
sudo mkdir -p Cellar Frameworks etc include lib opt sbin share var/homebrew/linked

# set permissions
chown -R "${loggedInUser}:${group}" "${target}/*"

# cleanup
rm -rf "${tmp_brew:?}/*"
logged_in_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
group=$(id -gn "${logged_in_user}")
if [[ "${homebrew_directory}" == "/usr/local" ]]
then
chown -R "${logged_in_user}:${group}" Cellar Frameworks Homebrew bin etc include lib sbin share var/homebrew/linked
else
chown -R "${logged_in_user}:${group}" .
fi
32 changes: 0 additions & 32 deletions package/scripts/preinstall

This file was deleted.

Loading