216974c10e
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 47s
Check migration collisions / Migration version collision check (pull_request) Successful in 51s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 53s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 46s
Harness Replays / detect-changes (pull_request) Successful in 14s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 12s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 28s
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 40s
review-check-tests / review-check.sh regression tests (pull_request) Successful in 13s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m30s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 9s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 14s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m33s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m23s
qa-review / approved (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request) Successful in 12s
security-review / approved (pull_request) Successful in 7s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m48s
sop-checklist-gate / gate (pull_request) Successful in 7s
sop-tier-check / tier-check (pull_request) Successful in 7s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m46s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 34s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 13s
Runtime Pin Compatibility / PyPI-latest install + import smoke (pull_request) Successful in 1m52s
Harness Replays / Harness Replays (pull_request) Successful in 6s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m30s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m22s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 4m2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3m44s
CI / Platform (Go) (pull_request) Successful in 6m29s
CI / Python Lint & Test (pull_request) Successful in 7m2s
CI / Canvas (Next.js) (pull_request) Successful in 7m29s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 10m6s
sop-checklist / all-items-acked (pull_request) acked: 7/7
audit-force-merge / audit (pull_request) Successful in 3s
121 lines
4.5 KiB
YAML
121 lines
4.5 KiB
YAML
name: lint-bp-context-emit-match
|
|
|
|
# Tier 2f scheduled lint (per mc#774) — detects drift between
|
|
# `branch_protections/<branch>.status_check_contexts` and the set of
|
|
# contexts emitted by `.gitea/workflows/*.yml`.
|
|
#
|
|
# Rule
|
|
# ----
|
|
# For each protected branch context (Source A — BP), there must exist
|
|
# at least one emitting workflow + job pair (Source B — workflow YAML
|
|
# + on:-event mapping) whose runtime status-name maps to it. The
|
|
# inverse direction (emitter without BP context) is informational
|
|
# only — Tier 2g handles that at PR-time.
|
|
#
|
|
# Why this exists
|
|
# ---------------
|
|
# A BP-required context with no emitter blocks merges forever — Gitea
|
|
# 1.22.6 treats absent-as-`pending`, NOT absent-as-`skipped`. The
|
|
# phantom-required-check class previously surfaced as
|
|
# `feedback_phantom_required_check_after_gitea_migration` (a port
|
|
# kept the GitHub context name after rename to Gitea, but no
|
|
# workflow emitted under the new name).
|
|
#
|
|
# This lint catches the same class structurally + a forward case:
|
|
# workflow renamed/deleted while still in BP.
|
|
#
|
|
# Scope
|
|
# -----
|
|
# Scheduled daily. We DON'T run on `pull_request` because (a) the
|
|
# emitter side moves with PR diffs (transitional state false-flags)
|
|
# and (b) Tier 2g handles emitter-side drift at PR-time.
|
|
#
|
|
# Cross-repo
|
|
# ----------
|
|
# Today this runs only on molecule-core/main. Per internal#349
|
|
# (cross-repo BP sweep) Class-D repos will get the same lint after
|
|
# their BP rollouts.
|
|
#
|
|
# Auth
|
|
# ----
|
|
# `GET /repos/.../branch_protections/{branch}` requires repo-admin
|
|
# role on Gitea 1.22.6. We use DRIFT_BOT_TOKEN (same persona as
|
|
# ci-required-drift.yml — `internal#329` provisioning trail).
|
|
# Graceful-degrade per Tier 2a contract: 403/404 → exit 0 with
|
|
# ::error::.
|
|
#
|
|
# Idempotency
|
|
# -----------
|
|
# The drift issue is filed with title prefix
|
|
# `[ci-bp-drift] {repo}/{branch}: BP→emitter mismatch`. The script
|
|
# searches OPEN issues for an exact title-prefix match and PATCHes
|
|
# the existing issue (if any) instead of POSTing a duplicate.
|
|
# Mirrors `ci-required-drift.py`'s contract.
|
|
#
|
|
# Phase contract (RFC internal#219 §1 ladder)
|
|
# -------------------------------------------
|
|
# Lands at `continue-on-error: true` (Phase 3). After 7 days of clean
|
|
# scheduled runs on `main`, flip to `false` so a scheduled failure
|
|
# becomes a hard CI signal.
|
|
#
|
|
# Cross-links
|
|
# -----------
|
|
# - mc#774 (the RFC that specs this lint)
|
|
# - internal#349 (cross-repo BP sweep)
|
|
# - feedback_phantom_required_check_after_gitea_migration
|
|
# - feedback_tier_label_ids_are_per_repo
|
|
# - ci-required-drift.yml (F2 detector, narrower-scope sibling)
|
|
|
|
on:
|
|
schedule:
|
|
# Daily at 03:31 UTC — off-peak, prime-staggered from other
|
|
# scheduled jobs (ci-required-drift :00 hourly, lint-coe-tracking
|
|
# 13:11). At 03:31 the CI fleet is quietest in EMEA hours.
|
|
- cron: '31 3 * * *'
|
|
workflow_dispatch:
|
|
# No `push` / `pull_request` here — Tier 2g owns PR-time drift.
|
|
|
|
env:
|
|
GITHUB_SERVER_URL: https://git.moleculesai.app
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write # needed to file/edit the drift issue
|
|
|
|
concurrency:
|
|
group: lint-bp-context-emit-match-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
lint:
|
|
name: lint-bp-context-emit-match
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
# Phase 3 (RFC #219 §1): surface drift without blocking. After 7
|
|
# clean scheduled runs on main, flip to false so a scheduled
|
|
# failure is a hard CI signal.
|
|
continue-on-error: true # mc#774 Phase 3 — flip to false after 7 clean main runs
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: '3.12'
|
|
- name: Install PyYAML
|
|
run: python -m pip install --quiet 'PyYAML==6.0.2'
|
|
- name: Run lint-bp-context-emit-match
|
|
env:
|
|
# DRIFT_BOT_TOKEN — repo-admin on this repo (internal#329
|
|
# provisioning trail). Required for branch_protections read.
|
|
GITEA_TOKEN: ${{ secrets.DRIFT_BOT_TOKEN }}
|
|
GITEA_HOST: git.moleculesai.app
|
|
REPO: ${{ github.repository }}
|
|
BRANCH: main
|
|
WORKFLOWS_DIR: .gitea/workflows
|
|
DRIFT_LABEL: ci-bp-drift
|
|
GITHUB_RUN_URL: https://git.moleculesai.app/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: python3 .gitea/scripts/lint_bp_context_emit_match.py
|
|
- name: Run lint-bp-context-emit-match unit tests
|
|
run: |
|
|
python -m pip install --quiet pytest
|
|
python3 -m pytest tests/test_lint_bp_context_emit_match.py -v
|