Skip to content

Commit 3b3b5a6

Browse files
stubbiclaude
andauthored
fix(ci): semantic Bundle RBAC sync check (was: file-diff flake) (#16)
## Summary `hack/sync-bundle-rbac.sh --check` mutated the CSV via yq then compared the working tree to HEAD. yq's output reformatted unrelated parts of the CSV, so the check failed even when the rules were in sync. Worse, running the sync twice produced two different files (not idempotent). Switched the check to compare just the `.rules` array, normalized through `yq -P`. No file mutation in check mode. ## Test plan - [x] `bash hack/sync-bundle-rbac.sh --check` passes against the current `main` Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 69524c6 commit 3b3b5a6

1 file changed

Lines changed: 21 additions & 10 deletions

File tree

hack/sync-bundle-rbac.sh

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
# Extract rules from the kubebuilder-generated ClusterRole and splice them
5-
# into the bundle CSV's clusterPermissions[0].rules block. Idempotent.
4+
# Compare/sync the rules in bundle/manifests/...clusterserviceversion.yaml
5+
# against the kubebuilder-generated ClusterRole. Compares semantically (parses
6+
# both sides through yq and compares the normalized rules array), so YAML
7+
# style differences in the rest of the CSV don't produce false positives.
8+
#
9+
# sync-bundle-rbac.sh write the generated rules into the CSV
10+
# sync-bundle-rbac.sh --check exit non-zero if the rules don't match
611

712
CSV=bundle/manifests/hermes-operator.clusterserviceversion.yaml
813
ROLE=config/rbac/role.yaml
@@ -12,19 +17,25 @@ if [ ! -f "$ROLE" ]; then
1217
exit 1
1318
fi
1419

15-
# yq merges: replace the rules array on the first clusterPermissions entry.
16-
TMP=$(mktemp)
17-
yq eval \
18-
'.spec.install.spec.clusterPermissions[0].rules = load("'"$ROLE"'").rules' \
19-
"$CSV" > "$TMP"
20-
mv "$TMP" "$CSV"
20+
# Normalize both sides through yq -P (pretty) so we compare canonical forms.
21+
GENERATED=$(yq -P '.rules' "$ROLE")
22+
EMBEDDED=$(yq -P '.spec.install.spec.clusterPermissions[0].rules' "$CSV")
2123

22-
# In --check mode (CI), bail if the working tree is dirty after sync.
2324
if [ "${1:-}" = "--check" ]; then
24-
if ! git diff --exit-code -- "$CSV"; then
25+
if [ "$GENERATED" != "$EMBEDDED" ]; then
2526
echo "::error::Bundle CSV RBAC drifted from $ROLE. Run 'make sync-bundle-rbac' locally." >&2
27+
diff <(echo "$GENERATED") <(echo "$EMBEDDED") >&2 || true
2628
exit 1
2729
fi
30+
echo "Bundle CSV RBAC matches $ROLE."
31+
exit 0
2832
fi
2933

34+
# Mutate mode: replace the rules array in place.
35+
TMP=$(mktemp)
36+
yq eval \
37+
'.spec.install.spec.clusterPermissions[0].rules = load("'"$ROLE"'").rules' \
38+
"$CSV" > "$TMP"
39+
mv "$TMP" "$CSV"
40+
3041
echo "Bundle CSV RBAC synced from $ROLE."

0 commit comments

Comments
 (0)