-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
REC-55: refactor release workflow (#53)
Previously, it was one job that ran on Linux with CI runners. We need to sign and notarize macOS binaries though, and we can only do that on a macOS machine. So this change splits the workflow into multiple jobs. The first job checks the version string, next we build binaries (signing not done yet), last we create the release.
- Loading branch information
Showing
5 changed files
with
351 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Copyright 2024 EngFlow Inc. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
set -o nounset -o pipefail -o errexit | ||
[[ "${SCRIPT_DEBUG:-"off"}" == "on" ]] && set -o xtrace | ||
|
||
if [[ -z "${OS:-}" ]]; then | ||
echo >&2 "OS not set" | ||
exit 1 | ||
fi | ||
if [[ "${OS}" == 'macos' && -z "${APPLE_CERT_BASE64:-}" ]]; then | ||
echo >&2 "APPLE_CERT_BASE64 not set" | ||
exit 1 | ||
fi | ||
if [[ -z "${RELEASE_VERSION:-}" ]]; then | ||
echo >&2 "RELEASE_VERSION not set" | ||
exit 1 | ||
fi | ||
|
||
APPLE_CERT_ID= | ||
install_cert () { | ||
if [[ "${OS}" != 'macos' ]]; then | ||
return | ||
fi | ||
# Files in $RUNNER_TEMP are automatically removed on completion. | ||
local p12_path="${RUNNER_TEMP}/build_certificate.p12" | ||
base64 --decode <<<"${APPLE_CERT_BASE64}" >"${p12_path}" | ||
local keychain_path="${RUNNER_TEMP}/dev.keychain" | ||
security create-keychain -p '' "${keychain_path}" | ||
security set-keychain-settings "${keychain_path}" | ||
security unlock-keychain -p '' "${keychain_path}" | ||
security import "${p12_path}" -P '' -A -t cert -f pkcs12 -k "${keychain_path}" | ||
# Allow productsign to access the identity | ||
# This prints some info from the keychain, not sure if it's sensitive. | ||
security >/dev/null set-key-partition-list -S apple-tool:,apple:,codesign:,productsign: -s -k '' "${keychain_path}" | ||
# Overwrite the keychain search list with the new keychain | ||
security list-keychain -d user -s "${keychain_path}" | ||
local identities_path="${RUNNER_TEMP}/identities.txt" | ||
security find-identity -v | tee "${identities_path}" | ||
if ! grep --quiet '1 valid identities found' "${identities_path}"; then | ||
echo >&2 "did not find exactly 1 identity" | ||
return 1 | ||
fi | ||
APPLE_CERT_ID=$(grep --extended-regexp --only '\b[0-9A-F]{40}\b' "${identities_path}") | ||
echo >&2 "Installed certificate with identity ${APPLE_CERT_ID}" | ||
} | ||
|
||
uninstall_cert () { | ||
if [[ "${OS}" != 'macos' ]]; then | ||
return | ||
fi | ||
security list-keychains -s ~/Library/Keychains/login.keychain | ||
security delete-keychain "${RUNNER_TEMP}/dev.keychain" | ||
} | ||
|
||
sign_and_notarize_binary () { | ||
# TODO(REC-55): implement signing and notarization for macOS and Windows. | ||
return | ||
} | ||
|
||
case "${OS}" in | ||
macos) | ||
TARGETS=( | ||
//cmd/engflow_auth:engflow_auth_macos_arm64 | ||
//cmd/engflow_auth:engflow_auth_macos_x64 | ||
) | ||
;; | ||
linux) | ||
TARGETS=( | ||
//cmd/engflow_auth:engflow_auth_linux_arm64 | ||
//cmd/engflow_auth:engflow_auth_linux_x64 | ||
) | ||
;; | ||
windows) | ||
TARGETS=( | ||
//cmd/engflow_auth:engflow_auth_windows_x64 | ||
) | ||
;; | ||
esac | ||
|
||
mkdir _out | ||
BUILD_RELEASE_VERSION="${RELEASE_VERSION}" \ | ||
bazel build \ | ||
--config=release \ | ||
-- \ | ||
"${TARGETS[@]}" | ||
|
||
install_cert | ||
trap uninstall_cert EXIT | ||
|
||
for target in "${TARGETS[@]}"; do | ||
target_file=$(bazel cquery --output=files "${target}") | ||
sign_and_notarize_binary "${target_file}" | ||
cp "${target_file}" _out/ | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Copyright 2024 EngFlow Inc. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
set -o nounset -o pipefail -o errexit | ||
[[ "${SCRIPT_DEBUG:-"off"}" == "on" ]] && set -o xtrace | ||
|
||
if [[ -z "${RELEASE_VERSION:-}" ]]; then | ||
echo >&2 "RELEASE_VERSION not set" | ||
exit 1 | ||
fi | ||
|
||
# Taken from https://semver.org/, with a `v` prepended | ||
readonly SEMVER_REGEX='^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$' | ||
|
||
# Supplied version string must follow semver | ||
if ! grep --quiet --extended-regexp "${SEMVER_REGEX}" <<<${RELEASE_VERSION}; then | ||
echo "Supplied version string '${RELEASE_VERSION}' does not follow semver; exiting" | ||
exit 1 | ||
fi | ||
|
||
# If this is a release version (not a prerelease), the commit must be on main or | ||
# the correct release branch (e.g., release/v1.2). This constraint doesn't apply | ||
# to prereleases so we can test this workflow. | ||
if [[ "${RELEASE_VERSION}" != *-* ]]; then | ||
readonly EXPECTED_RELEASE_BRANCH="$(sed --regexp-extended 's|(^v[0-9]+\.[0-9]+)\..*$|release/\1|' <<<${RELEASE_VERSION})" | ||
if ! git branch \ | ||
--contains "$(git rev-parse HEAD)" \ | ||
| grep --quiet --extended-regexp "main|${EXPECTED_RELEASE_BRANCH}"; then | ||
echo "Commit $(git rev-parse HEAD) is not on main or release branch ${EXPECTED_RELEASE_BRANCH}; exiting" | ||
exit 1 | ||
fi | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Copyright 2024 EngFlow Inc. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
set -o nounset -o pipefail -o errexit | ||
[[ "${SCRIPT_DEBUG:-"off"}" == "on" ]] && set -o xtrace | ||
|
||
if [[ -z "${RELEASE_VERSION:-}" ]]; then | ||
echo >&2 "RELEASE_VERSION not set" | ||
exit 1 | ||
fi | ||
|
||
readonly ARTIFACTS_DIR=_out | ||
readonly GH_CLI_DIR="$(mktemp -d -t 'gh_cli_XXXXXXXX')" | ||
readonly GH_CLI_URL='https://storage.googleapis.com/engflow-tools-public/github.com/cli/cli/releases/download/v2.52.0/gh_2.52.0_linux_amd64.tar.gz' | ||
readonly GH_CLI_EXPECTED_SHA256='3ea6ed8b2585f406a064cecd7e1501e58f56c8e7ca764ae1f3483d1b8ed68826' | ||
readonly GH_CLI="${GH_CLI_DIR}/bin/gh" | ||
|
||
function cleanup { | ||
echo "[START] Temp directory cleanup" | ||
rm -rf "${GH_CLI_DIR}" | ||
echo "[FINISH] Temp directory cleanup" | ||
} | ||
trap 'cleanup' EXIT | ||
|
||
# TODO(CUS-353): Remove this after installing Github CLI in the self-hosted | ||
# environment (run via Docker?) | ||
echo "[START] Downloading gh CLI" | ||
curl --silent --location "${GH_CLI_URL}" \ | ||
| tee >(sha256sum - > "${GH_CLI_DIR}/archive_checksum.txt") \ | ||
| tar \ | ||
-C "${GH_CLI_DIR}" \ | ||
--strip-components 1 \ | ||
-xzf \ | ||
- | ||
readonly GH_CLI_ACTUAL_SHA256="$(cat ${GH_CLI_DIR}/archive_checksum.txt | awk '{ print $1 }')" | ||
if [[ "${GH_CLI_ACTUAL_SHA256}" != "${GH_CLI_EXPECTED_SHA256}" ]]; then | ||
echo "SHA256 for Github CLI tarball ${GH_CLI_ACTUAL_SHA256} doesn't match expected value ${GH_CLI_ACTUAL_SHA256}; exiting" | ||
exit 1 | ||
fi | ||
echo "[FINISH] Downloading gh CLI" | ||
|
||
RELEASE_ARGS=() | ||
for file in $(find "${ARTIFACTS_DIR}" -type f); do | ||
os=$(echo "$file" | sed -E -e 's,^.*_([^_]*)_[^_]*$,\1,' -e 's,macos,macOS,' -e 's,windows,Windows,') | ||
arch=$(echo "$file" | sed -E -e 's,^.*_([^_]*),\1,') | ||
arg="${file}#engflow_auth (${os}, ${arch})" | ||
RELEASE_ARGS+=("${arg}") | ||
done | ||
if [[ "${DRY_RUN}" == true ]]; then | ||
echo "Release arguments:" | ||
for arg in "${RELEASE_ARGS[@]}"; do | ||
echo "${arg}" | ||
done | ||
echo "[SKIP] Creating release" | ||
exit 0 | ||
fi | ||
"${GH_CLI}" release create \ | ||
"${RELEASE_VERSION}" \ | ||
--generate-notes \ | ||
"${RELEASE_ARGS[@]}" | ||
echo "[FINISH] Creating release" |
Oops, something went wrong.