chore(compat): land closeout — pinned cosign + JSON-only diff + minrows floor
All checks were successful
addon-qualify / qualify (push) Successful in 12s

This commit is contained in:
2026-05-10 17:44:14 +03:00
parent 72a1c1a94c
commit 73fe38e3b7
2 changed files with 71 additions and 18 deletions

View File

@@ -39,6 +39,9 @@ on:
jobs:
seed:
runs-on: ubuntu-latest
# LOW — bound the worst-case runtime so a hung git fetch can't
# block the next nightly tick from starting.
timeout-minutes: 30
steps:
- name: Checkout compat-bootstrap branch
uses: actions/checkout@v4
@@ -72,7 +75,8 @@ jobs:
--qualifier "addons-$major/.gitea/qualify-addon.py" \
--output "compat-bootstrap/per-major/$major.json" \
--pg-by-major '{"18.0":"16","19.0":"17"}' \
--source "qualify-addon-v1"
--source "qualify-addon-v1" \
--min-rows 5
done
- name: Merge per-major snapshots into seeded-ci.json
@@ -101,9 +105,19 @@ jobs:
- name: Install cosign
run: |
set -euo pipefail
# H3 — pin the v2.4.1 cosign-linux-amd64 SHA256 and verify
# before chmod+exec. Without this, a MITM (or a compromised
# GitHub edge cache) can substitute a binary that exfiltrates
# COSIGN_PRIVATE_KEY on the next sign-blob call.
# Cross-checked against
# https://github.com/sigstore/cosign/releases/download/v2.4.1/cosign_checksums.txt
# on 2026-05-10.
COSIGN_SHA256=8b24b946dd5809c6bd93de08033bcf6bc0ed7d336b7785787c080f574b89249b
if ! command -v cosign >/dev/null 2>&1; then
curl -sSL -o /usr/local/bin/cosign \
curl -sSL -o /tmp/cosign \
https://github.com/sigstore/cosign/releases/download/v2.4.1/cosign-linux-amd64
echo "$COSIGN_SHA256 /tmp/cosign" | sha256sum -c -
mv /tmp/cosign /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign
fi
cosign version | head -3
@@ -125,9 +139,16 @@ jobs:
--key env://COSIGN_PRIVATE_KEY \
--output-signature compat-bootstrap/seeded-ci.json.sig \
compat-bootstrap/seeded-ci.json
# Sanity: verify with the public copy on disk before we push.
# Catches a key-rotation mismatch while we still can.
# (skips the Sigstore tlog — we're not relying on Rekor)
# H4 — Self-verify is a key-rotation TRIPWIRE, NOT a trust
# anchor. The on-disk cosign.pub lives in the same branch we
# push to; anyone holding COMPAT_PUSH_TOKEN can replace it.
# The real verification is Tower-side, against the pubkey
# baked into the binary at backend/cmd/api/compat_bootstrap_pubkey.pem
# (compat_seed_loader.go:38, go:embed). This step only catches
# "the operator rotated the keypair on lab1 but forgot to
# update either the Gitea secrets or the on-disk pubkey" —
# cheap CI-time signal so the next Tower deploy doesn't
# surprise-fail the verifier.
if [ -f compat-bootstrap/cosign.pub ]; then
cosign verify-blob --insecure-ignore-tlog \
--key compat-bootstrap/cosign.pub \
@@ -141,8 +162,9 @@ jobs:
GIT_USER_TOKEN: ${{ secrets.COMPAT_PUSH_TOKEN }}
run: |
set -euo pipefail
# Discard the per-major scratch files + addon worktrees; only
# the consolidated snapshot + sig are part of the canonical state.
# M3 — worktree cleanup runs even if a prior step crashed
# (a `trap` would be cleaner, but we're already in a fresh
# step with `set -e`; the loop just no-ops on absent paths).
for major in 18.0 19.0; do git worktree remove --force "addons-$major" || true; done
rm -rf compat-bootstrap/per-major
@@ -163,19 +185,30 @@ jobs:
exit 1
fi
# Stage both the JSON and its sig. The .sig changes whenever
# the JSON changes (different SHA256 → different signature),
# so a content-stable run will produce a no-op diff for both.
git add compat-bootstrap/seeded-ci.json compat-bootstrap/seeded-ci.json.sig
if git diff --cached --quiet -- compat-bootstrap/seeded-ci.json compat-bootstrap/seeded-ci.json.sig; then
# M1 — diff check against the JSON ONLY. Cosign's ECDSA
# sign-blob uses random k by default, so the .sig is fresh
# bytes every run even when the JSON is byte-identical.
# Including the .sig in the diff would push a noise commit
# nightly. Stage the .sig first so it's part of the commit
# IF we end up making one, but only the .json drives the
# decision.
git add compat-bootstrap/seeded-ci.json
if git diff --cached --quiet -- compat-bootstrap/seeded-ci.json; then
echo "no content change in seeded-ci.json; nothing to commit"
exit 0
fi
git add compat-bootstrap/seeded-ci.json.sig
stamp=$(python3 -c "import json,sys; print(json.load(open('compat-bootstrap/seeded-ci.json'))['stampId'])")
git commit -m "chore(compat): refresh cold-start seed (${stamp})"
# Push via token. COMPAT_PUSH_TOKEN belongs to git_admin and
# is whitelisted on the compat-bootstrap branch protection.
remote="https://git_admin:${GIT_USER_TOKEN}@git.odoosky.org/odoo-tower/odoo-addons.git"
git push "$remote" HEAD:compat-bootstrap
# H5 — push via http.extraHeader, not credential-in-URL.
# If git push fails (network timeout, ref reject, redirect
# following), the URL is echoed in error context AND captured
# by the runner's stderr log; embedding the token in the URL
# leaks it in any of those paths. extraHeader is git-internal,
# never echoed.
git push \
-c "http.extraHeader=Authorization: token ${GIT_USER_TOKEN}" \
https://git.odoosky.org/odoo-tower/odoo-addons.git \
HEAD:compat-bootstrap