diff --git a/.github/workflows/build-pkg.yml b/.github/workflows/build-pkg.yml index 9306e3bfb880b..ef10308906a6e 100644 --- a/.github/workflows/build-pkg.yml +++ b/.github/workflows/build-pkg.yml @@ -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 }} @@ -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() }} @@ -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 diff --git a/.gitignore b/.gitignore index 026f2af6218c9..80675e31e1a07 100644 --- a/.gitignore +++ b/.gitignore @@ -337,6 +337,7 @@ # Unignore our packaging files !/package +/package/resources/LICENSE.rtf # Ignore generated documentation site /docs/_site diff --git a/package/Distribution.xml b/package/Distribution.xml new file mode 100644 index 0000000000000..71927bc4c9733 --- /dev/null +++ b/package/Distribution.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + Homebrew.pkg + + Homebrew + sh.brew + + + + + + + + + + + + + diff --git a/package/resources/CONCLUSION.rtf b/package/resources/CONCLUSION.rtf new file mode 100644 index 0000000000000..a853dc32fb28a --- /dev/null +++ b/package/resources/CONCLUSION.rtf @@ -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} \ No newline at end of file diff --git a/package/resources/Homebrew.png b/package/resources/Homebrew.png new file mode 100644 index 0000000000000..d529a08dff4b2 Binary files /dev/null and b/package/resources/Homebrew.png differ diff --git a/package/resources/WELCOME.rtf b/package/resources/WELCOME.rtf new file mode 100644 index 0000000000000..98a36a2d262c1 --- /dev/null +++ b/package/resources/WELCOME.rtf @@ -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} \ No newline at end of file diff --git a/package/scripts/postinstall b/package/scripts/postinstall index 2db8e8483b952..083cb8c48a263 100755 --- a/package/scripts/postinstall +++ b/package/scripts/postinstall @@ -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 diff --git a/package/scripts/preinstall b/package/scripts/preinstall deleted file mode 100755 index 49afc85251fdc..0000000000000 --- a/package/scripts/preinstall +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Checked for installed CLT -if [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] -then - exit 0 -fi - -CLT_PLACEHOLDER="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress" -touch "${CLT_PLACEHOLDER}" - -CLT_PACKAGE=$(softwareupdate -l | - grep -B 1 "Command Line Tools" | - awk -F"*" '/^ *\*/ {print $2}' | - sed -e 's/^ *Label: //' -e 's/^ *//' | - sort -V | - tail -n1) -softwareupdate -i "${CLT_PACKAGE}" -rm -f "${CLT_PLACEHOLDER}" -if ! [[ -f "/Library/Developer/CommandLineTools/usr/bin/git" ]] -then - if [[ -z "${COMMAND_LINE_INSTALL}" ]] - then - echo - printf "Requesting user install of Xcode Command Line Tools:" - /usr/bin/xcode-select --install - else - echo - printf "Run 'xcode-select --install' to install the Xcode Command Line Tools before running a headless brew install." - exit 1 - fi -fi