Repository navigation
🐛 Location-agnostic sign release #268
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
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 |
|---|---|---|
|
|
@@ -111,6 +111,7 @@ export KO_DOCKER_REPO="gcr.io/knative-nightly" | |
| # Build stripped binary to reduce size | ||
| export GOFLAGS="-ldflags=-s -ldflags=-w" | ||
| export GITHUB_TOKEN="" | ||
| readonly IMAGES_REFS_FILE="${IMAGES_REFS_FILE:-$(mktemp -d)/images_refs.txt}" | ||
|
|
||
| # Convenience function to run the hub tool. | ||
| # Parameters: $1..$n - arguments to hub. | ||
|
|
@@ -313,64 +314,109 @@ function build_from_source() { | |
| } | ||
|
|
||
| function get_images_in_yamls() { | ||
| rm -rf imagerefs.txt | ||
| rm -rf "$IMAGES_REFS_FILE" | ||
| echo "Assembling a list of image refences to sign" | ||
| for file in $@; do | ||
| for file in "$@"; do | ||
| [[ "${file##*.}" != "yaml" ]] && continue | ||
| echo "Inspecting ${file}" | ||
| for image in $(grep -oh "\S*${KO_DOCKER_REPO}\S*" "${file}"); do | ||
| echo $image >> imagerefs.txt | ||
| done | ||
| while read -r image; do | ||
| echo "$image" >> "$IMAGES_REFS_FILE" | ||
| done < <(grep -oh "\S*${KO_DOCKER_REPO}\S*" "${file}") | ||
| done | ||
| if [[ -f "$IMAGES_REFS_FILE" ]]; then | ||
| sort -uo "$IMAGES_REFS_FILE" "$IMAGES_REFS_FILE" # Remove duplicate entries | ||
| fi | ||
| } | ||
|
|
||
| function find_checksums_file() { | ||
| for file in "$@"; do | ||
| if [[ "${file}" == *"checksums.txt" ]]; then | ||
| echo "${file}" | ||
| return 0 | ||
| fi | ||
| done | ||
| sort -uo imagerefs.txt imagerefs.txt # Remove duplicate entries | ||
| warning "cannot find checksums file" | ||
| } | ||
|
|
||
| # Build a release from source. | ||
| function sign_release() { | ||
| get_images_in_yamls "${ARTIFACTS_TO_PUBLISH}" | ||
| if (( ! IS_PROW )); then # This function can't be run by devs on their laptops | ||
| return 0 | ||
| fi | ||
| get_images_in_yamls "${ARTIFACTS_TO_PUBLISH}" | ||
| local checksums_file | ||
| checksums_file="$(find_checksums_file "${ARTIFACTS_TO_PUBLISH}")" | ||
|
|
||
| if ! [[ -f "${checksums_file}" ]]; then | ||
| echo '>> No checksums file found, generating one' | ||
| checksums_file="$(mktemp -d)/checksums.txt" | ||
| for file in ${ARTIFACTS_TO_PUBLISH}; do | ||
| pushd "$(dirname "$file")" >/dev/null | ||
| sha256sum "$(basename "$file")" >> "${checksums_file}" | ||
| popd >/dev/null | ||
| done | ||
| ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums_file}" | ||
| fi | ||
|
|
||
| # Notarizing mac binaries needs to be done before cosign as it changes the checksum values | ||
| # of the darwin binaries | ||
| if [ -n "${APPLE_CODESIGN_KEY}" ] && [ -n "${APPLE_CODESIGN_PASSWORD_FILE}" ] && [ -n "${APPLE_NOTARY_API_KEY}" ]; then | ||
| banner "Notarizing macOS Binaries for the release" | ||
| FILES=$(find -- * -type f -name "*darwin*") | ||
| for file in $FILES; do | ||
| rcodesign sign "${file}" --p12-file="${APPLE_CODESIGN_KEY}" \ | ||
| --code-signature-flags=runtime \ | ||
| --p12-password-file="${APPLE_CODESIGN_PASSWORD_FILE}" | ||
| done | ||
| zip files.zip ${FILES} | ||
| rcodesign notary-submit files.zip --api-key-path="${APPLE_NOTARY_API_KEY}" --wait | ||
| sha256sum ${ARTIFACTS_TO_PUBLISH//checksums.txt/} > checksums.txt | ||
| echo "🧮 Post Notarization Checksum:" | ||
| cat checksums.txt | ||
| local macos_artifacts | ||
| declare -a macos_artifacts=() | ||
|
Member
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. Would this be better as that fancy glob-equals used above?
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. I don't see any glob-equal anywhere. Could you explain it exactly?
Member
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. On line 333, you wrote: I wondered if that form would be better than
Member
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. Oops, this was supposed to be on line 368:
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, it may be written as if [[ "$file" == *"darwin"* ]]; thenIDK if it's worth changing though. This form is way less known, and it's very error prone. For example, someone could rewrite it to: if [[ "$file" == "*darwin*" ]]; thenWhich means completely different thing, and will not work. But, going back to your question: I'm not seeing much benefit in a rewrite, but we definitely could do it if you feel like it. |
||
| while read -r file; do | ||
| if echo "$file" | grep -q "darwin"; then | ||
| macos_artifacts+=("${file}") | ||
| rcodesign sign "${file}" --p12-file="${APPLE_CODESIGN_KEY}" \ | ||
| --code-signature-flags=runtime \ | ||
| --p12-password-file="${APPLE_CODESIGN_PASSWORD_FILE}" | ||
|
Member
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. I'll admit I'm slightly confused on preferring The explanation about subshells didn't make sense to me.
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. I don't know to what you are referring exactly. Is it https://www.shellcheck.net/wiki/SC2013 ? It shows couple valid options on how to iterate lines from a file/pipe/stdin. All of them are equally valid. The problem is people keep using the invalid iteration patterns. Habits from other programming languages often makes writing shell code harder, as bash is unique in many ways.
Member
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. I meant that this format: Seems clearer to me, because the set of things you're looping over is at the start. The linked docs suggest that the form using process substitution (
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. Both forms are equally valid. Matter of preference, I guess. Giving things to iterate over before the loop, can be very cloudy, especially if the command is long. Passing it to Your proposal has only one minor downside. Because it uses pipe, it may fail silently without stopping the script (if |
||
| fi | ||
| done < <(echo "${ARTIFACTS_TO_PUBLISH}" | tr ' ' '\n') | ||
| if [[ -z "${macos_artifacts[*]}" ]]; then | ||
| warning "No macOS binaries found, skipping notarization" | ||
| else | ||
| local zip_file | ||
| zip_file="$(mktemp -d)/files.zip" | ||
| zip "$zip_file" -@ < <(printf "%s\n" "${macos_artifacts[@]}") | ||
| rcodesign notary-submit "$zip_file" --api-key-path="${APPLE_NOTARY_API_KEY}" --wait | ||
| true > "${checksums_file}" # Clear the checksums file | ||
|
Member
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. Should this be a comparison, or do we want to avoid any file with
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. I don't follow, again. There's no comparison here. This line clears the checksums file content. The
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. What could have been done better here, is to not clear the file entirely, but replace just the signed files hashes. We could make such amend in a follow up, IMHO.
Member
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. It looks like GitHub made a mess of the line numbers on my comments, let me find the right line. |
||
| for file in ${ARTIFACTS_TO_PUBLISH}; do | ||
| if echo "$file" | grep -q "checksums.txt"; then | ||
| continue # Don't checksum the checksums file | ||
| fi | ||
| pushd "$(dirname "$file")" >/dev/null | ||
| sha256sum "$(basename "$file")" >> "${checksums_file}" | ||
| popd >/dev/null | ||
| done | ||
| echo "🧮 Post Notarization Checksum:" | ||
| cat "$checksums_file" | ||
| fi | ||
| fi | ||
|
|
||
| ID_TOKEN=$(gcloud auth print-identity-token --audiences=sigstore \ | ||
| --include-email \ | ||
| --impersonate-service-account="${SIGNING_IDENTITY}") | ||
| echo "Signing Images with the identity ${SIGNING_IDENTITY}" | ||
| ## Sign the images with cosign | ||
| if [[ -f "imagerefs.txt" ]]; then | ||
| COSIGN_EXPERIMENTAL=1 cosign sign $(cat imagerefs.txt) --recursive --identity-token="${ID_TOKEN}" | ||
| if [ -n "${ATTEST_IMAGES:-}" ]; then # Temporary Feature Gate | ||
| provenance-generator --clone-log=/logs/clone.json \ | ||
| --image-refs=imagerefs.txt --output=attestation.json | ||
| mkdir -p "${ARTIFACTS}"/attestation && cp attestation.json "${ARTIFACTS}"/attestation | ||
| COSIGN_EXPERIMENTAL=1 cosign attest $(cat imagerefs.txt) --recursive --identity-token="${ID_TOKEN}" \ | ||
| --predicate=attestation.json --type=slsaprovenance | ||
| fi | ||
| if [[ -f "$IMAGES_REFS_FILE" ]]; then | ||
| COSIGN_EXPERIMENTAL=1 cosign sign $(cat "$IMAGES_REFS_FILE") \ | ||
| --recursive --identity-token="${ID_TOKEN}" | ||
| if [ -n "${ATTEST_IMAGES:-}" ]; then # Temporary Feature Gate | ||
| provenance-generator --clone-log=/logs/clone.json \ | ||
| --image-refs="$IMAGES_REFS_FILE" --output=attestation.json | ||
| mkdir -p "${ARTIFACTS}"/attestation && cp attestation.json "${ARTIFACTS}"/attestation | ||
| COSIGN_EXPERIMENTAL=1 cosign attest $(cat "$IMAGES_REFS_FILE") \ | ||
| --recursive --identity-token="${ID_TOKEN}" \ | ||
| --predicate=attestation.json --type=slsaprovenance | ||
| fi | ||
| fi | ||
|
|
||
| ## Check if there is checksums.txt file. If so, sign the checksum file | ||
| if [[ -f "checksums.txt" ]]; then | ||
| echo "Signing Images with the identity ${SIGNING_IDENTITY}" | ||
| COSIGN_EXPERIMENTAL=1 cosign sign-blob checksums.txt --output-signature=checksums.txt.sig --output-certificate=checksums.txt.pem --identity-token="${ID_TOKEN}" | ||
| ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} checksums.txt.sig checksums.txt.pem" | ||
| fi | ||
| echo "Signing checksums with the identity ${SIGNING_IDENTITY}" | ||
| COSIGN_EXPERIMENTAL=1 cosign sign-blob "$checksums_file" \ | ||
| --output-signature="${checksums_file}.sig" \ | ||
| --output-certificate="${checksums_file}.pem" \ | ||
| --identity-token="${ID_TOKEN}" | ||
| ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums_file}.sig ${checksums_file}.pem" | ||
| } | ||
|
|
||
| # Copy tagged images from the nightly GCR to the release GCR, tagging them 'latest'. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Copyright 2022 The Knative Authors | ||
| # | ||
| # 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 -Eeuo pipefail | ||
|
|
||
| build_dir="${BUILD_DIR:-$(mktemp -d)}" | ||
| export ARTIFACTS_TO_PUBLISH | ||
|
|
||
| function build_release() { | ||
| local artifact_names | ||
| declare -a artifact_names | ||
| artifact_names=( | ||
| foo-linux-amd64 | ||
| foo-linux-arm64 | ||
| foo-linux-ppc64le | ||
| foo-linux-s390x | ||
| foo-darwin-amd64 | ||
| foo-darwin-arm64 | ||
| foo-windows-amd64.exe | ||
| foo.yaml | ||
| ) | ||
| for artifact_name in "${artifact_names[@]}"; do | ||
| hashCode "$artifact_name" > "${build_dir}/${artifact_name}" | ||
| echo "${build_dir}/${artifact_name}" >> "${build_dir}/artifacts.list" | ||
| done | ||
| ARTIFACTS_TO_PUBLISH="$(tr '\r\n' ' ' < "${build_dir}/artifacts.list")" | ||
| if [[ -n "${CALCULATE_CHECKSUMS:-}" ]]; then | ||
| calculate_checksums | ||
| fi | ||
| } | ||
|
|
||
| function calculate_checksums { | ||
| local checksums file | ||
| checksums="${build_dir}/checksums.txt" | ||
| rm -vf "${checksums}" | ||
| while read -r file; do | ||
| pushd "$(dirname "$file")" >/dev/null | ||
| sha256sum "$(basename "$file")" >> "${checksums}" | ||
| popd >/dev/null | ||
| done < "${build_dir}/artifacts.list" | ||
| ARTIFACTS_TO_PUBLISH="${ARTIFACTS_TO_PUBLISH} ${checksums}" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Copyright 2022 The Knative Authors | ||
| # | ||
| # 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. | ||
|
|
||
| add_trap teardown_fake_presubmit EXIT | ||
|
|
||
| VALIDATION_TESTS="$(mktemp -d)/presubmit-tests.sh" | ||
|
|
||
| cat <<EOF > "${VALIDATION_TESTS}" | ||
| #!/usr/bin/env bash | ||
|
|
||
| echo ">> Running fake presubmit tests" | ||
| echo "UNIT TESTS PASSED" | ||
| echo "INTEGRATION TESTS PASSED" | ||
| EOF | ||
|
|
||
| chmod +x "${VALIDATION_TESTS}" | ||
|
|
||
| function teardown_fake_presubmit() { | ||
| rm -rf "${VALIDATION_TESTS}" | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.