run signing as post-build step (#803)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2022-02-07 16:55:15 -05:00 committed by GitHub
parent 5519a25035
commit 2c62651c82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 109 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -ue
set +xu set +xu
if [ -z "$AC_USERNAME" ]; then if [ -z "$AC_USERNAME" ]; then
@ -11,58 +10,30 @@ if [ -z "$AC_PASSWORD" ]; then
fi fi
set -u set -u
# repackage [archive-path]
#
# returns an archive compatible for Apple's notarization process, repackaging the input archive as needed
#
repackage() {
archive=$1
case "$archive" in
*.tar.gz)
new_archive=${archive%.tar.gz}.zip
(
tmp_dir=$(mktemp -d)
cd "$tmp_dir"
# redirect stdout to stderr to preserve the return value
tar xzf "$archive" && zip "$new_archive" ./* 1>&2
rm -rf "$tmp_dir"
)
echo "$new_archive"
;;
*.zip)
echo "$archive"
;;
*) return 1
;;
esac
}
# notarize [archive-path] # notarize [archive-path]
# #
notarize() { notarize() {
archive_path=$1 binary_path=$1
archive_path=${binary_path}-archive-for-notarization.zip
title "notarizing binaries found in the release archive" title "archiving release binary into ${archive_path}"
payload_archive_path=$(repackage "$archive_path") zip "${archive_path}" "${binary_path}"
if [ "$?" != "0" ]; then
exit_with_error "cannot prepare payload for notarization: $archive_path"
fi
if [ ! -f "$payload_archive_path" ]; then if [ ! -f "$archive_path" ]; then
exit_with_error "cannot find payload for notarization: $payload_archive_path" exit_with_error "cannot find payload for notarization: $archive_path"
fi fi
# install gon # install gon
which gon || (brew tap mitchellh/gon && brew install mitchellh/gon/gon) which gon || (brew tap mitchellh/gon && brew install mitchellh/gon/gon)
# create config (note: json via stdin with gon is broken, can only use HCL from file) # create config (note: json via stdin with gon is broken, can only use HCL from file)
tmp_file=$(mktemp).hcl hcl_file=$(mktemp).hcl
cat <<EOF > "$tmp_file" cat <<EOF > "$hcl_file"
notarize { notarize {
path = "$payload_archive_path" path = "$archive_path"
bundle_id = "com.anchore.toolbox.syft" bundle_id = "com.anchore.toolbox.syft"
} }
@ -72,14 +43,8 @@ apple_id {
} }
EOF EOF
gon -log-level info "$tmp_file" gon -log-level info "$hcl_file"
result="$?" rm "${hcl_file}" "${archive_path}"
rm "$tmp_file"
if [ "$result" -ne "0" ]; then
exit_with_error "notarization failed"
fi
} }

View File

@ -1,8 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu set -eu -o pipefail
ARCHIVE_PATH="$1" BINARY_PATH="$1"
IS_SNAPSHOT="$2" IS_SNAPSHOT="$2"
TARGET_NAME="$3"
## grab utilities ## grab utilities
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
@ -39,58 +40,14 @@ sign_binary() {
fi fi
codesign --verify "$exe_path" --verbose=4 codesign --verify "$exe_path" --verbose=4
if [ $? -ne 0 ]; then
exit_with_error "signing verification failed"
fi
}
# sign_binaries_in_archive [archive-abs-path] [signing-identity]
#
# signs all binaries within an archive (there must be at least one)
#
sign_binaries_in_archive() {
archive_abs_path=$1
identity=$2
scratch_path=$(mktemp -d)
trap "rm -rf -- $scratch_path" EXIT
title "getting contents from the release archive: $archive_abs_path"
tar -C "$scratch_path" -xvf "$archive_abs_path"
# invalidate the current archive, we only want an asset with signed binaries from this point forward
rm "$archive_abs_path"
title "signing binaries found in the release archive"
discovered_binaries=0
tmp_pipe=$(mktemp -ut pipe.XXX)
mkfifo "$tmp_pipe"
find "$scratch_path" -perm +111 -type f > "$tmp_pipe" &
while IFS= read -r binary; do
sign_binary "$binary" "$identity"
((discovered_binaries++))
done < "$tmp_pipe"
rm "$tmp_pipe"
if [ "$discovered_binaries" = "0" ]; then
exit_with_error "found no binaries to sign"
fi
title "recreating the release archive: $archive_abs_path"
(cd "$scratch_path" && tar -czvf "$archive_abs_path" .)
} }
main() { main() {
archive_abs_path=$(realpath "$ARCHIVE_PATH") binary_abs_path=$(realpath "$BINARY_PATH")
if [ ! -f "$archive_abs_path" ]; then if [ ! -f "$binary_abs_path" ]; then
echo "archive does not exist: $archive_abs_path" echo "archive does not exist: $binary_abs_path"
fi fi
case "$IS_SNAPSHOT" in case "$IS_SNAPSHOT" in
@ -115,11 +72,11 @@ main() {
MAC_SIGNING_IDENTITY=$(cat "$SCRIPT_DIR/$SIGNING_IDENTITY_FILENAME") MAC_SIGNING_IDENTITY=$(cat "$SCRIPT_DIR/$SIGNING_IDENTITY_FILENAME")
# sign all of the binaries in the archive and recreate the input archive with the signed binaries # sign all of the binaries in the archive and recreate the input archive with the signed binaries
sign_binaries_in_archive "$archive_abs_path" "$MAC_SIGNING_IDENTITY" sign_binary "$binary_abs_path" "$MAC_SIGNING_IDENTITY"
# send all of the binaries off to apple to bless # send all of the binaries off to apple to bless
if $perform_notarization ; then if $perform_notarization ; then
notarize "$archive_abs_path" notarize "$binary_abs_path"
else else
commentary "skipping notarization..." commentary "skipping notarization..."
fi fi
@ -129,9 +86,9 @@ main() {
( ( ( (
set +u set +u
if [ -n "$SKIP_SIGNING" ]; then if [ -n "$SKIP_SIGNING" ]; then
commentary "skipping signing setup..." commentary "skipping signing..."
else else
set -u set -u
main main
fi fi
) 2>&1) | tee "$SCRIPT_DIR/log/signing-$(basename $ARCHIVE_PATH).txt" ) 2>&1) | tee "$SCRIPT_DIR/log/signing-$(basename $BINARY_PATH)-$TARGET_NAME.txt"

View File

@ -41,6 +41,11 @@ builds:
mod_timestamp: *build-timestamp mod_timestamp: *build-timestamp
env: *build-env env: *build-env
ldflags: *build-ldflags ldflags: *build-ldflags
hooks:
post:
# we must have signing as a build hook instead of the signs section. The signs section must register a new asset, where we want to replace an existing asset.
# a post-build hook has the advantage of not needing to unpackage and repackage a tar.gz with a signed binary
- ./.github/scripts/apple-signing/sign.sh "{{ .Path }}" "{{ .IsSnapshot }}" "{{ .Target }}"
- id: windows-build - id: windows-build
binary: syft binary: syft
@ -67,15 +72,6 @@ archives:
builds: builds:
- windows-build - windows-build
signs:
- artifacts: archive
ids:
- darwin-archives
cmd: ./.github/scripts/apple-signing/sign.sh
args:
- "${artifact}"
- "{{ .IsSnapshot }}"
nfpms: nfpms:
- license: "Apache 2.0" - license: "Apache 2.0"
maintainer: "Anchore, Inc" maintainer: "Anchore, Inc"

View File

@ -104,7 +104,7 @@ bootstrap-tools: $(TEMPDIR)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMPDIR)/ v1.42.1 curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMPDIR)/ v1.42.1
curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMPDIR)/ v0.3.0 curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMPDIR)/ v0.3.0
curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMPDIR)/ v0.3.0 curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMPDIR)/ v0.3.0
.github/scripts/goreleaser-install.sh -d -b $(TEMPDIR)/ v1.3.1 .github/scripts/goreleaser-install.sh -d -b $(TEMPDIR)/ v1.4.1
GOBIN="$(shell realpath $(TEMPDIR))" go install github.com/neilpa/yajsv@v1.4.0 GOBIN="$(shell realpath $(TEMPDIR))" go install github.com/neilpa/yajsv@v1.4.0
.PHONY: bootstrap-go .PHONY: bootstrap-go