191 lines · 6.7 KB · Shell
RawDownload
#!/usr/bin/env bashset -euo pipefail ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)EXPECTED_AUTHORITY='Developer ID Application: OpenClaw Foundation (FWJYW4S8P8)' for script in codesign-macos.sh package-release.sh verify-release.sh; do  bash -n "$ROOT/scripts/$script"done WORK_DIR=$(mktemp -d "${TMPDIR:-/tmp}/gitcrawl-release-test.XXXXXX")trap 'rm -rf "$WORK_DIR"' EXITFAKE_BIN="$WORK_DIR/bin"mkdir -p "$FAKE_BIN" cat > "$FAKE_BIN/uname" <<'EOF'#!/usr/bin/env bashcase "${1:-}" in  -s) echo Darwin ;;  -m) echo arm64 ;;  *) echo Darwin ;;esacEOF cat > "$FAKE_BIN/codesign" <<'EOF'#!/usr/bin/env bashprintf '%s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}"if [[ " $* " == *' --check-notarization '* && "${MOCK_NOTARIZATION_REJECT:-0}" == 1 ]]; then  exit 1ficase " $* " in  *' -dvvv '*)    {      echo 'Identifier=org.openclaw.gitcrawl'      echo "Authority=${MOCK_CODESIGN_AUTHORITY:-Developer ID Application: OpenClaw Foundation (FWJYW4S8P8)}"      echo "TeamIdentifier=${MOCK_CODESIGN_TEAM_ID:-FWJYW4S8P8}"    } >&2    ;;esacEOF cat > "$FAKE_BIN/ditto" <<'EOF'#!/usr/bin/env bashprevious=for arg in "$@"; do  source=$previous  previous=$argdonecp "$source" "$previous"printf 'ditto %s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}"EOF cat > "$FAKE_BIN/xcrun" <<'EOF'#!/usr/bin/env bashprintf 'xcrun %s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}"printf '{"id":"12345678-1234-1234-1234-123456789abc","status":"%s"}\n' "${MOCK_NOTARY_STATUS:-Accepted}"EOF cat > "$FAKE_BIN/plutil" <<'EOF'#!/usr/bin/env bashcase "${2:-}" in  status) printf '%s\n' "${MOCK_NOTARY_STATUS:-Accepted}" ;;  id) printf '%s\n' '12345678-1234-1234-1234-123456789abc' ;;  *) exit 1 ;;esacEOF cat > "$FAKE_BIN/lipo" <<'EOF'#!/usr/bin/env bashcase "${2:-}" in  */amd64/*) echo x86_64 ;;  *) echo arm64 ;;esacEOF chmod 0755 "$FAKE_BIN"/*export PATH="$FAKE_BIN:$PATH"export MOCK_CODESIGN_LOG="$WORK_DIR/codesign.log"unset NOTARYTOOL_KEYCHAIN_PROFILE test_binary="$WORK_DIR/gitcrawl"cat > "$test_binary" <<'EOF'#!/usr/bin/env bash[[ "${1:-}" == --version ]] || exit 2echo 0.7.1EOFchmod 0755 "$test_binary" GITCRAWL_REQUIRE_CODESIGN=0 "$ROOT/scripts/codesign-macos.sh" "$test_binary"if package_output=$("$ROOT/scripts/package-release.sh" 2>&1); then  echo "local package script unexpectedly succeeded" >&2  exit 1figrep -F 'gh workflow run release-unified.yml --repo openclaw/gitcrawl -f version=X.Y.Z' <<<"$package_output" >/dev/nullif GITCRAWL_REQUIRE_CODESIGN=1 \  CODESIGN_IDENTITY='Developer ID Application: Peter Steinberger (Y5PE65HELJ)' \  "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then  echo "personal signing identity was accepted" >&2  exit 1fiif GITCRAWL_REQUIRE_CODESIGN=1 \  CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \  "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then  echo "official signing accepted a missing notary profile" >&2  exit 1fiGITCRAWL_REQUIRE_CODESIGN=1 \  CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \  NOTARYTOOL_KEYCHAIN_PROFILE=test-profile \  "$ROOT/scripts/codesign-macos.sh" "$test_binary"grep -F -- '--identifier org.openclaw.gitcrawl' "$MOCK_CODESIGN_LOG" >/dev/nullgrep -F 'FWJYW4S8P8' "$MOCK_CODESIGN_LOG" >/dev/nullgrep -F -- 'notarytool submit' "$MOCK_CODESIGN_LOG" >/dev/nullgrep -F -- '--keychain-profile test-profile --no-s3-acceleration --wait --output-format json' "$MOCK_CODESIGN_LOG" >/dev/nullsigned_hash=$(shasum -a 256 "$test_binary" | awk '{ print $1 }')if GITCRAWL_REQUIRE_CODESIGN=1 \  CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \  NOTARYTOOL_KEYCHAIN_PROFILE=test-profile \  MOCK_NOTARY_STATUS=Invalid \  "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then  echo "invalid notarization status was accepted" >&2  exit 1fi[[ "$(shasum -a 256 "$test_binary" | awk '{ print $1 }')" == "$signed_hash" ]] || {  echo "failed notarization mutated the release binary" >&2  exit 1}if find "$WORK_DIR" -maxdepth 1 -name '.gitcrawl-notary.*' | grep -q .; then  echo "ephemeral notarization files were not removed" >&2  exit 1fi ARTIFACTS="$WORK_DIR/artifacts"mkdir -p "$ARTIFACTS"for arch in amd64 arm64; do  stage="$WORK_DIR/$arch"  mkdir -p "$stage"  cp "$test_binary" "$stage/gitcrawl"  cp "$ROOT/CHANGELOG.md" "$ROOT/LICENSE" "$ROOT/README.md" "$stage/"  archive="gitcrawl_0.7.1_darwin_${arch}.tar.gz"  tar -czf "$ARTIFACTS/$archive" -C "$stage" .  shasum -a 256 "$ARTIFACTS/$archive" | awk -v name="$archive" '{ print $1 "  " name }' >> "$ARTIFACTS/checksums.txt"done : > "$MOCK_CODESIGN_LOG""$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS"[[ "$(grep -F -c -- '--verify --strict --check-notarization -R=notarized' "$MOCK_CODESIGN_LOG")" == 2 ]]if MOCK_NOTARIZATION_REJECT=1 \  "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then  echo "release verifier accepted a missing notarization ticket" >&2  exit 1fiif MOCK_CODESIGN_AUTHORITY='Developer ID Application: Peter Steinberger (Y5PE65HELJ)' \  "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then  echo "personal signature was accepted" >&2  exit 1fi echo unexpected > "$WORK_DIR/arm64/unexpected"tar -czf "$ARTIFACTS/gitcrawl_0.7.1_darwin_arm64.tar.gz" \  -C "$WORK_DIR/arm64" CHANGELOG.md LICENSE README.md gitcrawl unexpectedshasum -a 256 "$ARTIFACTS/gitcrawl_0.7.1_darwin_arm64.tar.gz" | \  awk '{ print $1 "  gitcrawl_0.7.1_darwin_arm64.tar.gz" }' > "$ARTIFACTS/arm64.checksum"awk '$2 != "gitcrawl_0.7.1_darwin_arm64.tar.gz"' "$ARTIFACTS/checksums.txt" > "$ARTIFACTS/checksums.next"cat "$ARTIFACTS/arm64.checksum" >> "$ARTIFACTS/checksums.next"mv "$ARTIFACTS/checksums.next" "$ARTIFACTS/checksums.txt"if "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then  echo "archive with extra entries was accepted" >&2  exit 1fi release_workflow="$ROOT/.github/workflows/release-unified.yml"grep -F 'uses: openclaw/release-workflows/.github/workflows/release-go-cli.yml@v1' "$release_workflow" >/dev/nullgrep -F 'checksum-filename: checksums.txt' "$release_workflow" >/dev/nullgrep -F 'archive-files: '\''["CHANGELOG.md","LICENSE","README.md"]'\''' "$release_workflow" >/dev/nullgrep -F 'stable-identifier: org.openclaw.gitcrawl' "$release_workflow" >/dev/nullgrep -F 'darwin-universal: disabled' "$release_workflow" >/dev/nullif grep -F 'require-signed-tag:' "$release_workflow" >/dev/null; then  echo "unified release must own the annotated tag" >&2  exit 1fiif [[ -e "$ROOT/.github/release-allowed-signers" ]]; then  echo "unified release must not require a local tag-signing allowlist" >&2  exit 1fiif grep -R -F 'NOTARYTOOL_KEYCHAIN_PROFILE' "$ROOT/.github/workflows" >/dev/null; then  echo "notary profile must not be configured in GitHub Actions" >&2  exit 1fi echo "release script tests passed"