Merge pull request #7555 from paulober/feature-macos-pkg-installer

Add macOS pkg installer to deployment (#7554)
This commit is contained in:
Andy Feller 2024-05-24 15:35:52 -04:00 committed by GitHub
commit 1bc3cfa460
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 188 additions and 2 deletions

View file

@ -108,6 +108,19 @@ jobs:
run: |
shopt -s failglob
script/sign dist/gh_*_macOS_*.zip
- name: Build universal macOS pkg installer
if: inputs.environment != 'production'
env:
TAG_NAME: ${{ inputs.tag_name }}
run: script/pkgmacos "$TAG_NAME"
- name: Build & notarize universal macOS pkg installer
if: inputs.environment == 'production'
env:
TAG_NAME: ${{ inputs.tag_name }}
APPLE_DEVELOPER_INSTALLER_ID: ${{ vars.APPLE_DEVELOPER_INSTALLER_ID }}
run: |
shopt -s failglob
script/pkgmacos "$TAG_NAME"
- uses: actions/upload-artifact@v4
with:
name: macos
@ -116,7 +129,8 @@ jobs:
path: |
dist/*.tar.gz
dist/*.zip
dist/*.pkg
windows:
runs-on: windows-latest
environment: ${{ inputs.environment }}

2
.gitignore vendored
View file

@ -12,6 +12,8 @@
/.goreleaser.generated.yml
/script/build
/script/build.exe
/pkg_payload
/build/macOS/resources
# VS Code
.vscode

View file

@ -93,3 +93,11 @@ uninstall:
rm -f ${DESTDIR}${datadir}/bash-completion/completions/gh
rm -f ${DESTDIR}${datadir}/fish/vendor_completions.d/gh.fish
rm -f ${DESTDIR}${datadir}/zsh/site-functions/_gh
.PHONY: macospkg
macospkg: manpages completions
ifndef VERSION
$(error VERSION is not set. Use `make macospkg VERSION=vX.Y.Z`)
endif
./script/release --local "$(VERSION)" --platform macos
./script/pkgmacos $(VERSION)

View file

@ -21,7 +21,7 @@ If you are a hubber and are interested in shipping new commands for the CLI, che
### macOS
`gh` is available via [Homebrew][], [MacPorts][], [Conda][], [Spack][], [Webi][], and as a downloadable binary from the [releases page][].
`gh` is available via [Homebrew][], [MacPorts][], [Conda][], [Spack][], [Webi][], and as a downloadable binary including Mac OS installer `.pkg` from the [releases page][].
#### Homebrew

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<installer-gui-script minSpecVersion="2">
<title>GitHub CLI</title>
<license file="LICENSE" mime-type="text/plain"/>
<options hostArchitectures="arm64,x86_64" customize="never" require-scripts="true" allow-external-scripts="false"/>
<domains enable_localSystem="true"/>
<installation-check script="installCheck();"/>
<script>
function installCheck() {
// this check is redundant, but it produces a user friendly error message
// compared to a disabled install button caused by allowed-os-versions
if (!(system.compareVersions(system.version.ProductVersion, '12') &gt;= 0)) {
my.result.title = 'Unable to install';
my.result.message = 'GitHub CLI requires macOS 12 or later.';
my.result.type = 'Fatal';
return false;
}
return true;
}
</script>
<allowed-os-versions>
<os-version min="12.0" />
</allowed-os-versions>
<choices-outline>
<line choice="gh-cli"/>
</choices-outline>
<choice id="gh-cli" title="GitHub CLI (universal)">
<pkg-ref id="com.github.cli.pkg"/>
</choice>
<pkg-ref id="com.github.cli.pkg" auth="root">#com.github.cli.pkg</pkg-ref>
</installer-gui-script>

129
script/pkgmacos Executable file
View file

@ -0,0 +1,129 @@
#!/bin/zsh
set -e
print_help() {
cat <<EOF
To build a universal pkg for macOS:
script/pkgmacos <tag-name>
To build and sign set APPLE_DEVELOPER_INSTALLER_ID environment variable before.
For example, if you have a signing identity with the identifier
"Developer ID Installer: Your Name (ABC123DEF)" set it in the variable.
EOF
}
if [ $# -eq 0 ]; then
print_help >&2
exit 1
fi
tag_name=""
while [ $# -gt 0 ]; do
case "$1" in
-h | --help )
print_help
exit 0
;;
-* )
printf "unrecognized flag: %s\n" "$1" >&2
exit 1
;;
* )
tag_name="${1#v}"
shift 1
;;
esac
done
# check os requirements: is running macOS 12+ and pkgbuild + productbuild are available
os_version=$(sw_vers -productVersion)
major_version=${os_version%%.*}
if (( major_version < 12 )); then
echo "This script requires macOS 12 or later. You are running macOS ${os_version}." >&2
exit 1
fi
if ! command -v pkgbuild &> /dev/null; then
echo "pkgbuild could not be found. Please install Xcode Command Line Tools." >&2
exit 1
fi
if ! command -v productbuild &> /dev/null; then
echo "productbuild could not be found. Please install Xcode Command Line Tools." >&2
exit 1
fi
# end of os requirements check
# gh-binary paths
bin_path="/bin/gh"
arm64_bin="./dist/macos_darwin_arm64$bin_path"
amd64_bin="./dist/macos_darwin_amd64_v1$bin_path"
# payload paths
payload_root="pkg_payload"
payload_local_bin="${payload_root}/usr/local/bin"
payload_zsh_site_functions="${payload_root}/usr/local/share/zsh/site-functions"
payload_man1="${payload_root}/usr/local/share/man/man1"
merge_binaries() {
lipo -create -output "${payload_local_bin}/gh" "$arm64_bin" "$amd64_bin"
}
build_pkg() {
# setup payload
mkdir -p "${payload_local_bin}"
mkdir -p "${payload_man1}"
mkdir -p "${payload_zsh_site_functions}"
# copy man pages
for file in ./share/man/man1/gh*.1; do
cp "$file" "${payload_man1}"
done
# Include only Zsh completions,
# the recommended/only option on macOS since Catalina for default shell.
cp "./share/zsh/site-functions/_gh" "${payload_zsh_site_functions}"
# merge binaries
merge_binaries
# build pkg
pkgbuild \
--root "$payload_root" \
--identifier "com.github.cli" \
--version "$tag_name" \
--install-location "/" \
"./dist/com.github.cli.pkg"
# setup resources
mkdir -p "./build/macOS/resources"
cp "LICENSE" "./build/macOS/resources"
PRODUCTBUILD_ARGS=()
# include signing if developer id is set
if [ -n "$APPLE_DEVELOPER_INSTALLER_ID" ]; then
PRODUCTBUILD_ARGS+=("--timestamp")
PRODUCTBUILD_ARGS+=("--sign")
PRODUCTBUILD_ARGS+=("${APPLE_DEVELOPER_INSTALLER_ID}")
else
echo "skipping macOS pkg code-signing; APPLE_DEVELOPER_INSTALLER_ID not set" >&2
fi
# build distribution
productbuild \
--distribution "./build/macOS/distribution.xml" \
--resources "./build/macOS/resources" \
--package-path "./dist" \
"${PRODUCTBUILD_ARGS[@]}" \
"./dist/gh_${tag_name}_macOS_universal.pkg"
}
cleanup() {
# remove temp installer so it does not get uploaded
rm -f "./dist/com.github.cli.pkg"
}
trap cleanup EXIT
build_pkg