| @@ -25,6 +25,9 @@ EOF · 24 unmodified lines |
| 25 | 25 | cat > "$FAKE_BIN/codesign" <<'EOF' |
| 26 | 26 | #!/usr/bin/env bash |
| 27 | 27 | printf '%s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}" |
| 28 | +if [[ " $* " == *' --check-notarization '* && "${MOCK_NOTARIZATION_REJECT:-0}" == 1 ]]; then |
| 29 | + exit 1 |
| 30 | +fi |
| 28 | 31 | case " $* " in |
| 29 | 32 | *' -dvvv '*) |
| 30 | 33 | { |
| @@ -36,6 +39,32 @@ case " $* " in · 5 unmodified lines |
| 36 | 39 | esac |
| 37 | 40 | EOF |
| 38 | 41 | |
| 42 | +cat > "$FAKE_BIN/ditto" <<'EOF' |
| 43 | +#!/usr/bin/env bash |
| 44 | +previous= |
| 45 | +for arg in "$@"; do |
| 46 | + source=$previous |
| 47 | + previous=$arg |
| 48 | +done |
| 49 | +cp "$source" "$previous" |
| 50 | +printf 'ditto %s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}" |
| 51 | +EOF |
| 52 | + |
| 53 | +cat > "$FAKE_BIN/xcrun" <<'EOF' |
| 54 | +#!/usr/bin/env bash |
| 55 | +printf 'xcrun %s\n' "$*" >> "${MOCK_CODESIGN_LOG:?}" |
| 56 | +printf '{"id":"12345678-1234-1234-1234-123456789abc","status":"%s"}\n' "${MOCK_NOTARY_STATUS:-Accepted}" |
| 57 | +EOF |
| 58 | + |
| 59 | +cat > "$FAKE_BIN/plutil" <<'EOF' |
| 60 | +#!/usr/bin/env bash |
| 61 | +case "${2:-}" in |
| 62 | + status) printf '%s\n' "${MOCK_NOTARY_STATUS:-Accepted}" ;; |
| 63 | + id) printf '%s\n' '12345678-1234-1234-1234-123456789abc' ;; |
| 64 | + *) exit 1 ;; |
| 65 | +esac |
| 66 | +EOF |
| 67 | + |
| 39 | 68 | cat > "$FAKE_BIN/lipo" <<'EOF' |
| 40 | 69 | #!/usr/bin/env bash |
| 41 | 70 | case "${2:-}" in |
| @@ -47,6 +76,7 @@ EOF · 5 unmodified lines |
| 47 | 76 | chmod 0755 "$FAKE_BIN"/* |
| 48 | 77 | export PATH="$FAKE_BIN:$PATH" |
| 49 | 78 | export MOCK_CODESIGN_LOG="$WORK_DIR/codesign.log" |
| 79 | +unset NOTARYTOOL_KEYCHAIN_PROFILE |
| 50 | 80 | |
| 51 | 81 | test_binary="$WORK_DIR/gitcrawl" |
| 52 | 82 | cat > "$test_binary" <<'EOF' |
| @@ -62,15 +92,48 @@ if CODESIGN_IDENTITY='Developer ID Application: Peter Steinberger (Y5PE65HELJ)' · 9 unmodified lines |
| 62 | 92 | echo "package script accepted personal signing identity" >&2 |
| 63 | 93 | exit 1 |
| 64 | 94 | fi |
| 95 | +if CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \ |
| 96 | + "$ROOT/scripts/package-release.sh" v0.7.1 >/dev/null 2>&1; then |
| 97 | + echo "package script accepted a missing notary profile" >&2 |
| 98 | + exit 1 |
| 99 | +fi |
| 65 | 100 | if GITCRAWL_REQUIRE_CODESIGN=1 \ |
| 66 | 101 | CODESIGN_IDENTITY='Developer ID Application: Peter Steinberger (Y5PE65HELJ)' \ |
| 67 | 102 | "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then |
| 68 | 103 | echo "personal signing identity was accepted" >&2 |
| 69 | 104 | exit 1 |
| 70 | 105 | fi |
| 106 | +if GITCRAWL_REQUIRE_CODESIGN=1 \ |
| 107 | + CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \ |
| 108 | + "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then |
| 109 | + echo "official signing accepted a missing notary profile" >&2 |
| 110 | + exit 1 |
| 111 | +fi |
| 71 | 112 | GITCRAWL_REQUIRE_CODESIGN=1 \ |
| 72 | 113 | CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \ |
| 114 | + NOTARYTOOL_KEYCHAIN_PROFILE=test-profile \ |
| 73 | 115 | "$ROOT/scripts/codesign-macos.sh" "$test_binary" |
| 116 | +grep -F -- '--identifier org.openclaw.gitcrawl' "$MOCK_CODESIGN_LOG" >/dev/null |
| 117 | +grep -F 'FWJYW4S8P8' "$MOCK_CODESIGN_LOG" >/dev/null |
| 118 | +grep -F -- 'notarytool submit' "$MOCK_CODESIGN_LOG" >/dev/null |
| 119 | +grep -F -- '--keychain-profile test-profile --no-s3-acceleration --wait --output-format json' "$MOCK_CODESIGN_LOG" >/dev/null |
| 120 | +signed_hash=$(shasum -a 256 "$test_binary" | awk '{ print $1 }') |
| 121 | +if GITCRAWL_REQUIRE_CODESIGN=1 \ |
| 122 | + CODESIGN_IDENTITY="$EXPECTED_AUTHORITY" \ |
| 123 | + NOTARYTOOL_KEYCHAIN_PROFILE=test-profile \ |
| 124 | + MOCK_NOTARY_STATUS=Invalid \ |
| 125 | + "$ROOT/scripts/codesign-macos.sh" "$test_binary" >/dev/null 2>&1; then |
| 126 | + echo "invalid notarization status was accepted" >&2 |
| 127 | + exit 1 |
| 128 | +fi |
| 129 | +[[ "$(shasum -a 256 "$test_binary" | awk '{ print $1 }')" == "$signed_hash" ]] || { |
| 130 | + echo "failed notarization mutated the release binary" >&2 |
| 131 | + exit 1 |
| 132 | +} |
| 133 | +if find "$WORK_DIR" -maxdepth 1 -name '.gitcrawl-notary.*' | grep -q .; then |
| 134 | + echo "ephemeral notarization files were not removed" >&2 |
| 135 | + exit 1 |
| 136 | +fi |
| 74 | 137 | |
| 75 | 138 | ARTIFACTS="$WORK_DIR/artifacts" |
| 76 | 139 | mkdir -p "$ARTIFACTS" |
| @@ -84,7 +147,14 @@ for arch in amd64 arm64; do · 7 unmodified lines |
| 84 | 147 | shasum -a 256 "$ARTIFACTS/$archive" | awk -v name="$archive" '{ print $1 " " name }' >> "$ARTIFACTS/checksums.txt" |
| 85 | 148 | done |
| 86 | 149 | |
| 150 | +: > "$MOCK_CODESIGN_LOG" |
| 87 | 151 | "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" |
| 152 | +[[ "$(grep -F -c -- '--verify --strict --check-notarization -R=notarized' "$MOCK_CODESIGN_LOG")" == 2 ]] |
| 153 | +if MOCK_NOTARIZATION_REJECT=1 \ |
| 154 | + "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then |
| 155 | + echo "release verifier accepted a missing notarization ticket" >&2 |
| 156 | + exit 1 |
| 157 | +fi |
| 88 | 158 | if MOCK_CODESIGN_AUTHORITY='Developer ID Application: Peter Steinberger (Y5PE65HELJ)' \ |
| 89 | 159 | "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then |
| 90 | 160 | echo "personal signature was accepted" >&2 |
| @@ -104,9 +174,6 @@ if "$ROOT/scripts/verify-release.sh" v0.7.1 "$ARTIFACTS" >/dev/null 2>&1; then · 13 unmodified lines |
| 104 | 174 | exit 1 |
| 105 | 175 | fi |
| 106 | 176 | |
| 107 | | −grep -F -- '--identifier org.openclaw.gitcrawl' "$MOCK_CODESIGN_LOG" >/dev/null |
| 108 | | −grep -F 'FWJYW4S8P8' "$MOCK_CODESIGN_LOG" >/dev/null |
| 109 | | − |
| 110 | 177 | release_workflow="$ROOT/.github/workflows/release-assets.yml" |
| 111 | 178 | grep -F 'contents: write' "$release_workflow" >/dev/null |
| 112 | 179 | grep -F "github.ref == format('refs/heads/{0}', github.event.repository.default_branch)" "$release_workflow" >/dev/null |
| @@ -121,6 +188,10 @@ grep -F 'persist-credentials: false' "$release_workflow" >/dev/null · 8 unmodified lines |
| 121 | 188 | grep -F 'tag_name == $tag and (.draft == ($draft == "true"))' "$release_workflow" >/dev/null |
| 122 | 189 | grep -F 'Accept: application/octet-stream' "$release_workflow" >/dev/null |
| 123 | 190 | grep -F 'unset GH_TOKEN GITHUB_TOKEN' "$release_workflow" >/dev/null |
| 191 | +if grep -R -F 'NOTARYTOOL_KEYCHAIN_PROFILE' "$ROOT/.github/workflows" >/dev/null; then |
| 192 | + echo "notary profile must not be configured in GitHub Actions" >&2 |
| 193 | + exit 1 |
| 194 | +fi |
| 124 | 195 | if grep -F 'gh release download' "$release_workflow" >/dev/null; then |
| 125 | 196 | echo "release workflow cannot resolve draft assets through gh release download" >&2 |
| 126 | 197 | exit 1 |