Skip to content

Commit

Permalink
build, sign, notarize, and upload macos installer pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
patricksanders committed Aug 6, 2021
1 parent d610bc4 commit d7b59d0
Show file tree
Hide file tree
Showing 80 changed files with 749 additions and 192 deletions.
67 changes: 62 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.16
-
name: Set up pkger
run: |
go get github.com/markbates/pkger/cmd/pkger
-
name: Login to Public ECR
env:
Expand All @@ -40,8 +36,69 @@ jobs:
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
args: -f build/.goreleaser.yml release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
-
name: Store Binaries
uses: actions/upload-artifact@v2
with:
name: binaries
path: dist/bin/
retention-days: 5
package:
needs: goreleaser
runs-on: macos-latest
environment: Signing
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Retrieve Binaries
uses: actions/download-artifact@v2
with:
name: binaries
path: dist/bin/
-
name: Import Signing Certificates
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
-
name: Build, Sign, & Notarize Package
env:
AC_PASSWORD: ${{ secrets.AC_PASSWORD }}
VERSION: ${{ env.GITHUB_REF }}
run: |
./build/build_package.sh
-
name: Store Package
uses: actions/upload-artifact@v2
with:
name: package
path: dist/macos/*.pkg
upload:
needs: package
runs-on: ubuntu-latest
steps:
-
name: Retrieve Package
uses: actions/download-artifact@v2
with:
name: package
path: dist/macos/
-
name: Upload package to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/macos/*.pkg
file_glob: true
tag: ${{ github.ref }}
overwrite: true
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ dist/
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Generated source files
pkged.go

# Dependency directories (remove the comment below to include it)
# vendor/

# IDE configs
.idea/

# Build files
build/package/macos/tmp/
build/package/macos/application/bin/
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ pre-commit installed at .git/hooks/pre-commit

## Building

Weep is created with `pkger`. Install it with `go get github.com/markbates/pkger/cmd/pkger`.

In most cases, `weep` can be built by running the `make` command in the repository root. `make release` (requires
[`upx`](https://upx.github.io/)) will build and compress the binary for distribution.

Expand Down
15 changes: 9 additions & 6 deletions .goreleaser.yml → build/.goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ builds:
- -trimpath
ldflags:
- -s -w -extldflags "-static"
-X github.com/netflix/weep/metadata.Version={{.Version}}
-X github.com/netflix/weep/metadata.Commit={{.CommitDate}}
-X github.com/netflix/weep/metadata.Date={{.Date}}
-X github.com/netflix/weep/internal/metadata.Version={{.Version}}
-X github.com/netflix/weep/internal/metadata.Commit={{.CommitDate}}
-X github.com/netflix/weep/internal/metadata.Date={{.Date}}
mod_timestamp: '{{ .CommitTimestamp }}'
no_unique_dist_dir: true
binary: 'bin/{{ .Target }}/weep'
-
id: demo
env:
Expand All @@ -30,13 +32,13 @@ builds:
- -trimpath
ldflags:
- -s -w -extldflags "-static"
-X github.com/netflix/weep/config.EmbeddedConfigFile=/weep-demo.yaml
-X github.com/netflix/weep/config.EmbeddedConfigFile=configs/weep-demo.yaml
-X github.com/netflix/weep/metadata.Version={{.Version}}
-X github.com/netflix/weep/metadata.Commit={{.CommitDate}}
-X github.com/netflix/weep/metadata.Date={{.Date}}
mod_timestamp: '{{ .CommitTimestamp }}'
hooks:
pre: pkger -include /weep-demo.yaml
no_unique_dist_dir: true
binary: 'bin/demo/{{ .Target }}/weep'
archives:
-
builds:
Expand Down Expand Up @@ -73,6 +75,7 @@ dockers:
-
goos: linux
goarch: amd64
dockerfile: build/Dockerfile
ids:
- default
image_templates:
Expand Down
File renamed without changes.
149 changes: 149 additions & 0 deletions build/build_package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env bash
##############################################################################
# Build a macOS installer package containing a weep universal binary
# Author: Patrick Sanders <psanders@netflix.com>
##############################################################################
set -euo pipefail

BASE_DIR="build/package/macos"
APP_DIR="$BASE_DIR/application"
BIN_DIR="$APP_DIR/bin"
BUILD_DIR="$BASE_DIR/tmp"
PKG_DIR="$BUILD_DIR/darwinpkg"
OUT_DIR="dist/macos"
VERSION=${VERSION:=dev}
FINAL_PACKAGE="$OUT_DIR/weep-installer-macos-$VERSION.pkg"

rm -rf "$BIN_DIR"
rm -rf "$BUILD_DIR"
mkdir -p "$BIN_DIR"
mkdir -p "$OUT_DIR"
mkdir -p "$PKG_DIR"

cp -r "$BASE_DIR/darwin" "$BUILD_DIR/"
chmod -R 755 "$BUILD_DIR/darwin/scripts"
chmod 755 "$BUILD_DIR/darwin/Distribution.xml"

printf "🟢 starting build for %s\n" "$FINAL_PACKAGE"

function prep_package() {
# Prepare package structure
mkdir -p "$BUILD_DIR/darwinpkg/Library/weep"
cp -a "$APP_DIR/." "$BUILD_DIR/darwinpkg/Library/weep"
chmod -R 755 "$BUILD_DIR/darwinpkg/Library/weep"

# Replace tokens in package files
sed -i '' -e "s/__VERSION__/$VERSION/g" ${BUILD_DIR}/darwin/Resources/*.html
}

function combine_binaries() {
printf "🦾 creating universal binary..."
output=$1
bin1=$2
bin2=$3
lipo -create -output "$output" "$bin1" "$bin2"
printf " done ✅ \n"
}

function sign_binary() {
printf "🔏 signing binary..."
binary=$1
codesign \
--options runtime \
--sign "Developer ID Application: Netflix, Inc." \
--force \
--timestamp=http://timestamp.apple.com/ts01 \
"$binary" > /dev/null 2>&1
printf " done ✅ \n"
}

function build_package() {
printf "📦 building package..."
pkgbuild --identifier "com.netflix.weep" \
--version "$VERSION" \
--scripts "$BUILD_DIR/darwin/scripts" \
--root "$BUILD_DIR/darwinpkg" \
weep.pkg > /dev/null 2>&1

productbuild --distribution "$BUILD_DIR/darwin/Distribution.xml" \
--resources "$BUILD_DIR/darwin/Resources" \
--package-path "$BUILD_DIR/package" \
"$OUT_DIR/weep-$VERSION-unsigned.pkg" > /dev/null 2>&1
printf " done ✅ \n"
}

function sign_package() {
printf "🔏 signing package..."
productsign --sign "Developer ID Installer: Netflix, Inc." \
"$OUT_DIR/weep-$VERSION-unsigned.pkg" \
"$FINAL_PACKAGE" > /dev/null 2>&1

pkgutil --check-signature "$FINAL_PACKAGE" > /dev/null 2>&1
printf " done ✅ \n"
}

function notarize() {
printf "🔐 notarizing package..."
output=$(xcrun altool \
--notarize-app \
--primary-bundle-id "com.netflix.weep" \
--username "psanders@netflix.com" \
--password "$AC_PASSWORD" \
--file "$FINAL_PACKAGE")
printf " done ✅ \n"
request_id=$(echo "$output" | grep RequestUUID | awk '{ print $3 }')
printf "💡 notarize request id is %s\n" "$request_id"
# give the server side a few seconds to sort things out
sleep 3
while true; do
status=$(check_notarize_status "$request_id")
printf "👀 current status \"%s\"" "$status"
case "$status" in
"success")
printf ", done ✅ \n"
break
;;
"failure")
printf ", exiting! 🔴\n"
exit 1
;;
*)
printf ", not ready yet 😴\n"
sleep 5
;;
esac
done
}

function check_notarize_status() {
request_id=$1
output=$(xcrun altool \
--notarization-info "$request_id" \
--username "psanders@netflix.com" \
--password "$AC_PASSWORD")
status=$(echo "$output" | grep "Status:" | awk '{ for (i=2; i<=NF; i++) printf("%s ", $i) }' | awk '{$1=$1;print}')
echo "$status"
}

function staple() {
printf "📎 stapling..."
xcrun stapler staple "$FINAL_PACKAGE" > /dev/null 2>&1
printf " done ✅ \n"
}

function cleanup() {
rm dist/macos/*-unsigned.pkg
}

combine_binaries "$BIN_DIR/weep-universal" \
dist/bin/darwin_amd64/weep \
dist/bin/darwin_arm64/weep
sign_binary "$BIN_DIR/weep-universal"
prep_package
build_package
sign_package
notarize
staple
cleanup

printf "🙌 successfully built and notarized %s 🎉 \n" "$FINAL_PACKAGE"
46 changes: 46 additions & 0 deletions build/package/macos/application/uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

#Check running user
if (( $EUID != 0 )); then
echo "Please run as root."
exit
fi

echo "Welcome to the Weep Uninstaller"
echo "The following packages will be REMOVED:"
echo " weep"
while true; do
read -p "Do you wish to continue [Y/n]?" answer
[[ $answer == "y" || $answer == "Y" || $answer == "" ]] && break
[[ $answer == "n" || $answer == "N" ]] && exit 0
echo "Please answer with 'y' or 'n'"
done


echo "Uninstalling Weep"
# remove binary symlink
if rm -rf "/usr/local/bin/weep"
then
echo "[1/3] [DONE] Successfully deleted shortcut links"
else
echo "[1/3] [ERROR] Could not delete shortcut links" >&2
fi

#forget from pkgutil
if pkgutil --forget "com.netflix.weep" > /dev/null 2>&1
then
echo "[2/3] [DONE] Successfully deleted application information"
else
echo "[2/3] [ERROR] Could not delete application information" >&2
fi

#remove application source distribution
if rm -rf "/Library/weep"
then
echo "[3/3] [DONE] Successfully deleted application"
else
echo "[3/3] [ERROR] Could not delete application" >&2
fi

echo "Application uninstall process finished"
exit 0
29 changes: 29 additions & 0 deletions build/package/macos/darwin/Distribution.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-script minSpecVersion="1.000000">
<title>Weep</title>
<background mime-type="image/png" alignment="bottomleft" file="banner.png" scaling="proportional"/>
<welcome file="welcome.html" mime-type="text/html" />
<conclusion file="conclusion.html" mime-type="text/html" />
<license file="LICENSE"/>
<options customize="never" allow-external-scripts="no"/>
<domains enable_localSystem="true" />
<installation-check script="installCheck();"/>
<script>
function installCheck() {
if(system.files.fileExistsAtPath('/Library/weep/')) {
my.result.title = 'Previous Installation Detected';
my.result.message = 'A previous installation of Weep exists at /Library/weep. This installer will remove the previous installation prior to installing.';
my.result.type = 'Warning';
return false;
}
return true;
}
</script>
<choices-outline>
<line choice="Weep"/>
</choices-outline>
<choice id="Weep" title="Weep">
<pkg-ref id="weep.pkg"/>
</choice>
<pkg-ref id="weep.pkg" auth="Root">weep.pkg</pkg-ref>
</installer-script>
1 change: 1 addition & 0 deletions build/package/macos/darwin/Resources/LICENSE
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit d7b59d0

Please sign in to comment.