Skip to content

Commit 8ccb4fa

Browse files
alexeaglecopybara-github
authored andcommitted
chore: add a unit test for .github/release_prep.sh (#26247)
Requested by protobuf team after having a rough time in v34.0 release Closes #26247 COPYBARA_INTEGRATE_REVIEW=#26247 from protocolbuffers:test_release_sh c6f620d PiperOrigin-RevId: 944502159
1 parent 342944a commit 8ccb4fa

4 files changed

Lines changed: 225 additions & 1 deletion

File tree

.github/BUILD.bazel

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
load("@build_bazel_apple_support//xcode:xcode_config.bzl", "xcode_config")
22
load("@build_bazel_apple_support//xcode:xcode_version.bzl", "xcode_version")
3+
load("@rules_shell//shell:sh_test.bzl", "sh_test")
4+
5+
sh_test(
6+
name = "release_prep_test",
7+
srcs = ["workflows/release_prep_test.sh"],
8+
data = [
9+
"workflows/release_prep.sh",
10+
"@jq_toolchains//:resolved_toolchain",
11+
],
12+
env = {
13+
"JQ_BIN": "$(JQ_BIN)",
14+
},
15+
target_compatible_with = select({
16+
"@platforms//os:windows": ["@platforms//:incompatible"],
17+
"//conditions:default": [],
18+
}),
19+
toolchains = ["@jq_toolchains//:resolved_toolchain"],
20+
deps = ["@bazel_tools//tools/bash/runfiles"],
21+
)
322

423
# This information is extracted from the MacOS runner specs located at:
524
# https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#!/usr/bin/env bash
2+
set -o errexit -o nounset -o pipefail
3+
4+
# --- begin runfiles.bash initialization ---
5+
if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
6+
if [[ -f "$0.runfiles_manifest" ]]; then
7+
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
8+
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
9+
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
10+
elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
11+
export RUNFILES_DIR="$0.runfiles"
12+
fi
13+
fi
14+
if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
15+
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
16+
elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
17+
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
18+
"$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
19+
else
20+
# Not running under Bazel; fall back to co-located script
21+
rlocation() { echo "$(cd "$(dirname "$0")" && pwd)/$(basename "$1")"; }
22+
fi
23+
# --- end runfiles.bash initialization ---
24+
25+
RELEASE_PREP=$(rlocation _main/.github/workflows/release_prep.sh)
26+
TEST_DIR=$(mktemp -d)
27+
trap 'rm -rf "$TEST_DIR"' EXIT
28+
29+
TAG="v99.0"
30+
PREFIX="protobuf-99.0"
31+
32+
##############################
33+
# Fixture: a git repo with a tag and the placeholder integrity file
34+
##############################
35+
cd "$TEST_DIR"
36+
git init -q
37+
git config user.email "test@test.com"
38+
git config user.name "Test"
39+
40+
mkdir -p bazel/private/oss/toolchains/prebuilt
41+
cat > bazel/private/oss/toolchains/prebuilt/tool_integrity.bzl <<'BZL'
42+
"Placeholder"
43+
RELEASE_VERSION = "v0.0.0"
44+
RELEASED_BINARY_INTEGRITY = {}
45+
BZL
46+
47+
echo "compatibility/ export-ignore" > .gitattributes
48+
mkdir -p compatibility
49+
echo "should be excluded" > compatibility/README
50+
echo "# protobuf" > README.md
51+
52+
git add -A
53+
git commit -q -m "initial"
54+
git tag "$TAG"
55+
56+
##############################
57+
# Fixture: the script needs GNU tar (--delete/--append); shim it
58+
##############################
59+
TAR=$(command -v gtar || command -v tar)
60+
mkdir -p "$TEST_DIR/.mock_bin"
61+
ln -sf "$TAR" "$TEST_DIR/.mock_bin/tar"
62+
63+
##############################
64+
# Fixture: put jq (from Bazel toolchain) on the PATH
65+
##############################
66+
ln -sf "$(rlocation ${JQ_BIN#"external/"})" "$TEST_DIR/.mock_bin/jq"
67+
68+
##############################
69+
# Fixture: mock curl returning a GitHub Releases API response
70+
##############################
71+
cat > "$TEST_DIR/.mock_bin/curl" <<'MOCK'
72+
#!/usr/bin/env bash
73+
cat <<'JSON'
74+
{
75+
"assets": [
76+
{
77+
"name": "protoc-99.0-linux-x86_64.zip",
78+
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
79+
},
80+
{
81+
"name": "protoc-99.0-osx-aarch_64.zip",
82+
"digest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
83+
},
84+
{
85+
"name": "protoc-99.0-win64.zip",
86+
"digest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
87+
}
88+
]
89+
}
90+
JSON
91+
MOCK
92+
chmod +x "$TEST_DIR/.mock_bin/curl"
93+
export PATH="$TEST_DIR/.mock_bin:$PATH"
94+
95+
##############################
96+
# Run the script under test
97+
##############################
98+
bash "$RELEASE_PREP" "$TAG"
99+
100+
##############################
101+
# Assertions
102+
##############################
103+
ARCHIVE="$PREFIX.bazel.tar.gz"
104+
FAILURES=0
105+
106+
fail() {
107+
echo "FAIL: $1"
108+
FAILURES=$((FAILURES + 1))
109+
}
110+
111+
pass() {
112+
echo "PASS: $1"
113+
}
114+
115+
assert_file_exists() {
116+
[[ -f "$1" ]] && pass "$2" || fail "$2"
117+
}
118+
119+
assert_file_absent() {
120+
[[ ! -e "$1" ]] && pass "$2" || fail "$2"
121+
}
122+
123+
assert_contains() {
124+
if echo "$3" | grep -qF -- "$2"; then
125+
pass "$1"
126+
else
127+
fail "$1 — expected to find: $2"
128+
fi
129+
}
130+
131+
# 1. Archive is produced with the expected name
132+
assert_file_exists "$ARCHIVE" "archive file $ARCHIVE exists"
133+
134+
# 2. Archive is gzip-compressed
135+
if file "$ARCHIVE" | grep -q gzip; then
136+
pass "archive is gzip"
137+
else
138+
fail "archive is gzip"
139+
fi
140+
141+
# 3. Extract and inspect
142+
EXTRACT_DIR=$(mktemp -d)
143+
tar xzf "$ARCHIVE" -C "$EXTRACT_DIR"
144+
145+
# 4. Patched tool_integrity.bzl is present
146+
INTEGRITY="$EXTRACT_DIR/$PREFIX/bazel/private/oss/toolchains/prebuilt/tool_integrity.bzl"
147+
assert_file_exists "$INTEGRITY" "tool_integrity.bzl present in archive"
148+
149+
CONTENT=$(cat "$INTEGRITY")
150+
151+
# 5. RELEASE_VERSION matches the tag
152+
assert_contains "RELEASE_VERSION matches tag" "RELEASE_VERSION=\"$TAG\"" "$CONTENT"
153+
154+
# 6. RELEASED_BINARY_INTEGRITY is populated from mock curl
155+
assert_contains "integrity map present" "RELEASED_BINARY_INTEGRITY =" "$CONTENT"
156+
assert_contains "linux hash" \
157+
'"protoc-99.0-linux-x86_64.zip": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' \
158+
"$CONTENT"
159+
assert_contains "osx hash" \
160+
'"protoc-99.0-osx-aarch_64.zip": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"' \
161+
"$CONTENT"
162+
assert_contains "win hash" \
163+
'"protoc-99.0-win64.zip": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"' \
164+
"$CONTENT"
165+
166+
# 7. Original placeholder content is NOT in the patched file
167+
if echo "$CONTENT" | grep -qF "v0.0.0"; then
168+
fail "placeholder content should be replaced"
169+
else
170+
pass "placeholder content replaced"
171+
fi
172+
173+
# 8. compatibility/ excluded from archive (via .gitattributes export-ignore)
174+
assert_file_absent "$EXTRACT_DIR/$PREFIX/compatibility" "compatibility/ excluded from archive"
175+
176+
# 9. Other repo files are included
177+
assert_file_exists "$EXTRACT_DIR/$PREFIX/README.md" "README.md included in archive"
178+
179+
# 10. All archive entries live under the expected prefix directory
180+
BAD_ENTRIES=$(tar tzf "$ARCHIVE" | grep -cv "^${PREFIX}/") || true
181+
if [[ "$BAD_ENTRIES" -eq 0 ]]; then
182+
pass "all entries under $PREFIX/ prefix"
183+
else
184+
fail "found $BAD_ENTRIES entries outside $PREFIX/ prefix"
185+
fi
186+
187+
rm -rf "$EXTRACT_DIR"
188+
189+
##############################
190+
echo
191+
if [[ "$FAILURES" -gt 0 ]]; then
192+
echo "$FAILURES test(s) FAILED"
193+
exit 1
194+
else
195+
echo "All tests passed"
196+
fi

MODULE.bazel

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ ruby.toolchain(
7575
version = "system",
7676
)
7777
use_repo(ruby, "ruby")
78-
7978
ruby.bundle_fetch(
8079
name = "protobuf_bundle",
8180
gem_checksums = {
@@ -356,3 +355,8 @@ use_repo(
356355
"nuget_python_x86-64_3.10.0",
357356
"python-3.10.0",
358357
)
358+
359+
bazel_dep(name = "jq.bzl", version = "0.6.1", dev_dependency = True)
360+
361+
jq = use_extension("@jq.bzl//jq:extensions.bzl", "toolchains", dev_dependency = True)
362+
use_repo(jq, "jq_toolchains")

bazel/BUILD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,8 @@ filegroup(
8787
"//bazel/private:__pkg__",
8888
],
8989
)
90+
91+
test_suite(
92+
name = "release_tests",
93+
tests = ["//.github:release_prep_test"],
94+
)

0 commit comments

Comments
 (0)