# Pillar 2 / Phase 4 — Cold-start compat-matrix seed. # # This file is the SOURCE-OF-TRUTH copy. The deployed copy lives in # the Gitea repo at: # # odoo-tower/odoo-addons (branch `compat-bootstrap`) # └── .gitea/workflows/seed-compat.yml # # Why a dedicated branch instead of `main`/`18.0`/`19.0`: the addon # code lives on per-Odoo-major branches. The cold-start snapshot is # orthogonal data — keeping it on its own branch lets Tower fetch # from one stable place and lets the cron commit without touching # addon source. # # Schedule: daily 03:00 UTC. The emitter computes a content-hash # stampId, so identical results across nights produce no commit # (git diff is empty → push is skipped). When the catalog drifts # (a new addon, a fix, a regression), one commit lands and Tower's # next 24h tick replays it. # # Deployment (one-shot, manual until we mass-publish workflows): # # git -C /path/to/odoo-addons checkout -b compat-bootstrap origin/18.0 # mkdir -p .gitea/workflows compat-bootstrap # cp infrastructure/gitea-actions/workflows/seed-compat.yml \ # /path/to/odoo-addons/.gitea/workflows/ # cp scripts/qualify-addon.py scripts/emit-compat-bootstrap.py \ # /path/to/odoo-addons/scripts/ # git -C /path/to/odoo-addons add .gitea scripts compat-bootstrap # git -C /path/to/odoo-addons commit -m "feat(compat): seed bootstrap workflow" # git -C /path/to/odoo-addons push -u origin compat-bootstrap name: Cold-start compat seed on: schedule: - cron: '0 3 * * *' # nightly 03:00 UTC workflow_dispatch: {} # manual trigger from Gitea UI jobs: seed: runs-on: ubuntu-latest steps: - name: Checkout compat-bootstrap branch uses: actions/checkout@v4 with: ref: compat-bootstrap fetch-depth: 1 - name: Materialise per-major addon trees run: | set -euo pipefail # Detached worktrees keep each version branch's tree independent # so the qualifier sees a clean addon root with no cross-branch # contamination. Cleaned up in the final step. for major in 18.0 19.0; do git fetch --depth=1 origin "$major" git worktree add --detach "addons-$major" "origin/$major" ls -1 "addons-$major/addons" 2>/dev/null | head -5 || true done - name: Run qualifier + emit bootstrap snapshot per major run: | set -euo pipefail mkdir -p compat-bootstrap/per-major for major in 18.0 19.0; do # qualify-addon.py is vendored into each version branch under # .gitea/qualify-addon.py by Pillar 1; reuse that copy so static- # lint logic stays in lockstep with what addon-qualify.yml runs # on push. python3 scripts/emit-compat-bootstrap.py \ --addons-root "addons-$major/addons" \ --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" done - name: Merge per-major snapshots into seeded-ci.json run: | set -euo pipefail python3 - <<'PY' import hashlib, json, pathlib rows = [] for p in sorted(pathlib.Path('compat-bootstrap/per-major').glob('*.json')): rows.extend(json.loads(p.read_text())['rows']) rows.sort(key=lambda r: (r['addonCode'], r['addonVersion'], r['odooMajor'], r['postgresMajor'])) canonical = json.dumps(rows, sort_keys=True, separators=(',', ':')) stamp = 'sha256:' + hashlib.sha256(canonical.encode('utf-8')).hexdigest() out = { 'stampId': stamp, 'schemaVersion': 1, 'source': 'qualify-addon-v1', 'rows': rows, } pathlib.Path('compat-bootstrap/seeded-ci.json').write_text( json.dumps(out, indent=2) + '\n') print(f'merged {len(rows)} rows; stamp={stamp}') PY - name: Commit + push if content changed env: GIT_USER_TOKEN: ${{ secrets.COMPAT_PUSH_TOKEN }} run: | set -euo pipefail # Discard the per-major scratch files + addon worktrees; only # the consolidated snapshot is part of the canonical state. for major in 18.0 19.0; do git worktree remove --force "addons-$major" || true; done rm -rf compat-bootstrap/per-major git config user.email "compat-seeder@odoosky.cloud" git config user.name "compat-seeder" if git diff --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 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 is a repo-scoped PAT with # write access to odoo-tower/odoo-addons:compat-bootstrap. remote="https://compat-seeder:${GIT_USER_TOKEN}@git.odoosky.org/odoo-tower/odoo-addons.git" git push "$remote" HEAD:compat-bootstrap