-
Notifications
You must be signed in to change notification settings - Fork 0
REC-55: refactor release workflow #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fb3414a
68decce
e42ebb5
b62df6d
c5048f9
830fbd9
a979f81
6d63da7
64e15a8
d34f29d
b69bd09
3ef88e5
9274a65
823fa1f
73e25c8
79863d3
bcb1e3e
a589707
96f9ff4
4ad6b06
d990dc2
a8e3810
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (future PR idea) if this is true, then
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that would work. I just learned about For |
||
| 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 | ||
| 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 |
| 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" |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(for my own education) what would it take to build a compatible version without relying on the remote runner's userspace? Is this a deficiency in bazel + rules_go, or in the Go tooling, or in our own setup?
EDIT: It seems clear that rules_go does depend on a C++ toolchain, so I guess the first issue is that we don't define hermetic C++ toolchains in this repo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could build a binary in "pure" mode, without a C++ toolchain. That means we wouldn't build any cgo code, Go's linker would not invoke the C linker, and we would not depend on libc.
The main drawback is that some standard library packages work differently without cgo.
netuses its own DNS resolver (probably fine), andos/userreads/etc/passwddirectly instead of integrating with PAM. We useos/user, so I'm worried that would change behavior on systems that don't use/etc/passwd.