Block internal-flavored paths / Block forbidden paths (push) Skipped
boot-to-registration-e2e / Minimal cell (SSOT runtime + molecules-server) (push) Skipped
ci-required-drift / drift (push) Skipped
CI / Detect changes (push) Skipped
CI / Platform (Go) (push) Skipped
CI / Canvas (Next.js) (push) Skipped
CI / Python Lint & Test (push) Skipped
Concierge Creates Workspace Hermetic / Concierge Creates Workspace Hermetic (push) Skipped
E2E Chat / E2E Chat (push) Skipped
E2E Ephemeral CP Happy Path / detect (push) Skipped
Harness Replays / detect-changes (push) Skipped
Harness Replays / Harness Replays (push) Skipped
lint-bp-context-emit-match / lint-bp-context-emit-match (push) Skipped
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Skipped
Lint schedule budget / Zero-cron ratchet (push) Skipped
lint-setup-go-cache / lint-setup-go-cache (push) Skipped
lint-staging-tenant-cd-gate-chain / lint-staging-tenant-cd-gate-chain (push) Skipped
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (push) Skipped
main-canary / canary (push) Skipped
merge-commit-guard / Verify merged PR commits are on main (push) Skipped
nodup-lint / no-duplication (push) Skipped
publish-canvas-image / Build & push canvas image (push) Skipped
publish-workspace-server-image / Build & push tenant image (push) Skipped
publish-workspace-server-image / Promote tenant :latest to CI-green build (push) Skipped
redeploy-tenants-on-main / redeploy (push) Skipped
redeploy-tenants-on-main / redeploy-k8s (push) Skipped
runtime-default-flip-gate / flip-gate (push) Skipped
sdk-pin-drift / SDK consumer pin vs molecule-ai-sdk main (push) Skipped
sdk-route-milestone-contract-drift / SDK route + milestone derive-gates (push) Skipped
SECRET_PATTERNS drift lint / Detect SECRET_PATTERNS drift (push) Skipped
Secret scan / Scan diff for credential-shaped strings (push) Skipped
staging-tenant-cd / await-image (staging-<sha> published) (push) Skipped
staging-tenant-cd / advance-pin (staging tenant image DB pin) (push) Skipped
staging-tenant-cd / redeploy-fleet (roll staging tenants, session-preserving) (push) Skipped
staging-tenant-cd / e2e-smoke (staging real provision + A2A HARD GATE) (push) Skipped
staging-tenant-cd / rollback-pin (revert pin if the fleet roll failed) (push) Skipped
Check migration collisions / Migration version collision check (pull_request) Skipped
Harness Replays / detect-changes (pull_request) Skipped
Harness Replays / Harness Replays (pull_request) Skipped
nodup-lint / no-duplication (pull_request) Skipped
SECRET_PATTERNS drift lint / Detect SECRET_PATTERNS drift (pull_request) Skipped
sync-providers-yaml / Verify SDK registry dependency (pull_request) Skipped
Block integration-tester contamination artifacts / Block staging-trigger / invalid manifest contamination (push) Skipped
CI / Shellcheck (E2E scripts) (push) Skipped
CI / Canvas Deploy Status (push) Skipped
CI / all-required (push) Skipped
contract-ssot-sync / Verify vendored plugin-manifest schema matches the molecule-ai-sdk SSOT (push) Skipped
cron-fixtures-ssot-drift / Verify vendored cron fixtures are byte-identical to the molecule-ai-sdk SSOT (push) Skipped
design-token-drift / Canvas ↔ app design-token SSOT drift (push) Skipped
E2E API Smoke Test / detect-changes (push) Skipped
E2E API Smoke Test / E2E API Smoke Test (push) Skipped
E2E Ephemeral CP Happy Path / E2E Ephemeral CP Happy Path (push) Skipped
E2E External Connect-Snippet + Leak-Lint / E2E External Connect-Snippet + Leak-Lint (push) Skipped
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (push) Skipped
Handlers Postgres Integration / detect-changes (push) Skipped
Handlers Postgres Integration / Handlers Postgres Integration (push) Skipped
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Skipped
lint-env-coupling-dismissal / lint-env-coupling-dismissal (push) Skipped
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Skipped
Lint forbidden hand-written mcp__ tool-id literals / Scan for hand-written mcp__ tool-id literals (push) Skipped
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Skipped
lint-no-coe-on-required / lint-no-coe-on-required (push) Skipped
lint-phantom-gate / lint-phantom-gate (push) Skipped
Lint publish-runner timeout-minutes / Lint publish-runner timeout-minutes (push) Skipped
Lint workflow YAML (repository compatibility policy) / Lint workflow YAML for repository compatibility policy (push) Skipped
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (push) Skipped
mcp-plugin-delivery-contract-drift / Compare MCP plugin delivery contract against template and runtime canonicals (push) Skipped
mcp-verb-published-manifest / Published mcp-server manifest ⊇ contract required verbs (push) Skipped
pin-provenance-guard / Pin provenance (push) Skipped
provision-request-ssot-sync / Verify core's provision-request mirror matches the molecule-ai-sdk SSOT (push) Skipped
publish-desktop-image / Build & push desktop image (push) Skipped
publish-desktop-image / Promote desktop :latest to CI-green build (push) Skipped
Self-Host Concierge Schedules E2E / Self-Host Concierge Schedules E2E (stub) (push) Skipped
staging-tenant-cd / runtime-image-readiness (exact promoted digests on provisioner daemon) (push) Skipped
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Skipped
sync-providers-yaml / Verify SDK registry dependency (push) Skipped
template-delivery-e2e / detect-changes (push) Skipped
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (push) Skipped
staging-tenant-cd / rollback-audit (prove rollback-pin itself actually executed) (push) Skipped
Ops Scripts Tests / Ops scripts (unittest) (push) Skipped
verify-providers-gen / Regenerate providers artifact and fail on drift (push) Skipped
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 5s
Block integration-tester contamination artifacts / Block staging-trigger / invalid manifest contamination (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
E2E Ephemeral CP Happy Path / detect (pull_request) Successful in 9s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
contract-ssot-sync / Verify vendored plugin-manifest schema matches the molecule-ai-sdk SSOT (pull_request) Skipped
cron-fixtures-ssot-drift / Verify vendored cron fixtures are byte-identical to the molecule-ai-sdk SSOT (pull_request) Skipped
design-token-drift / Canvas ↔ app design-token SSOT drift (pull_request) Skipped
E2E External Connect-Snippet + Leak-Lint / E2E External Connect-Snippet + Leak-Lint (pull_request) Skipped
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (pull_request) Skipped
manifest-entry-existence-check / Verify manifest entries exist on Gitea (pull_request) Skipped
mcp-plugin-delivery-contract-drift / Compare MCP plugin delivery contract against template and runtime canonicals (pull_request) Skipped
mcp-verb-published-manifest / Published mcp-server manifest ⊇ contract required verbs (pull_request) Skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
provision-request-ssot-sync / Verify core's provision-request mirror matches the molecule-ai-sdk SSOT (pull_request) Skipped
Self-Host Concierge Schedules E2E / Self-Host Concierge Schedules E2E (stub) (pull_request) Skipped
verify-providers-gen / Regenerate providers artifact and fail on drift (pull_request) Skipped
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 6s
Lint forbidden hand-written mcp__ tool-id literals / Scan for hand-written mcp__ tool-id literals (pull_request) Successful in 5s
ci-required-drift / drift (pull_request) Successful in 26s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 24s
lint-env-coupling-dismissal / lint-env-coupling-dismissal (pull_request) Successful in 25s
Concierge Creates Workspace Hermetic / Concierge Creates Workspace Hermetic (pull_request) Successful in 35s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 24s
lint-bp-context-emit-match / lint-bp-context-emit-match (pull_request) Successful in 33s
lint-no-coe-on-required / lint-no-coe-on-required (pull_request) Successful in 20s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 23s
Lint publish-runner timeout-minutes / Lint publish-runner timeout-minutes (pull_request) Successful in 18s
lint-phantom-gate / lint-phantom-gate (pull_request) Successful in 33s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 28s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 22s
lint-context-set-shrink / lint-context-set-shrink (pull_request) Successful in 1m25s
Lint schedule budget / Zero-cron ratchet (pull_request) Successful in 21s
lint-setup-go-cache / lint-setup-go-cache (pull_request) Successful in 26s
lint-staging-tenant-cd-gate-chain / lint-staging-tenant-cd-gate-chain (pull_request) Successful in 23s
Lint workflow YAML (repository compatibility policy) / Lint workflow YAML for repository compatibility policy (pull_request) Successful in 24s
pin-provenance-guard / Pin provenance (pull_request) Successful in 22s
sdk-pin-drift / SDK consumer pin vs molecule-ai-sdk main (pull_request) Successful in 20s
Secret scan / Scan diff for credential-shaped strings (pull_request) No credential-shaped strings (deterministic re-assert)
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
template-delivery-e2e / detect-changes (pull_request) Successful in 11s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 5s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 1m1s
sdk-route-milestone-contract-drift / SDK route + milestone derive-gates (pull_request) Successful in 48s
boot-to-registration-e2e / Minimal cell (SSOT runtime + molecules-server) (pull_request) Successful in 2m51s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 48s
E2E Chat / E2E Chat (pull_request) Successful in 3m24s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 2m16s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3m4s
CI / Platform (Go) (pull_request) Successful in 6m46s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6m43s
CI / Canvas (Next.js) (pull_request) Successful in 7m29s
CI / Canvas Deploy Status (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 3s
E2E Ephemeral CP Happy Path / E2E Ephemeral CP Happy Path (pull_request) Successful in 26m43s
gitea-merge-queue / queue (pull_request_review) Successful in 14s
audit-force-merge / audit (pull_request_target) Successful in 7s
265 lines
15 KiB
YAML
265 lines
15 KiB
YAML
name: Ops Scripts Tests
|
|
|
|
# Ported from .github/workflows/test-ops-scripts.yml on 2026-05-11 per
|
|
# RFC internal#219 §1 sweep.
|
|
#
|
|
# Differences from the GitHub version:
|
|
# - Omitted GitHub's `merge_group:` trigger; this repository uses its
|
|
# serialized Gitea queue plus pull-request/push statuses.
|
|
# - on.paths references .gitea/workflows/test-ops-scripts.yml (this
|
|
# file) instead of the .github/ one.
|
|
# - Workflow-level env.GITHUB_SERVER_URL set.
|
|
# - (WAS: `continue-on-error: true` on the job, RFC §1 contract. REMOVED
|
|
# 2026-07-14 — see the job comment below. This lane is the meta-gate; a mask
|
|
# on it made every OTHER gate unverifiable.)
|
|
#
|
|
# Runs the unittest suite for scripts/ on every PR + push that touches
|
|
# anything under scripts/ or .gitea/scripts/. Kept separate from the main CI
|
|
# so a script-only change doesn't trigger the heavier Go/Canvas/Python
|
|
# pipelines.
|
|
#
|
|
# Discovery layout: tests sit alongside the code they test (see
|
|
# scripts/ops/test_managed_flags_wiring.py for the pattern; scripts/
|
|
# test_build_runtime_package.py for the rewriter coverage). The job
|
|
# below runs `unittest discover` TWICE — once from `scripts/`, once
|
|
# from `scripts/ops/` — because neither dir has an `__init__.py`, so
|
|
# a single discover from `scripts/` doesn't recurse into the ops
|
|
# subdir. Two passes is simpler than retrofitting namespace packages.
|
|
|
|
on:
|
|
push:
|
|
branches: [main, staging]
|
|
paths:
|
|
- 'scripts/**'
|
|
- 'docker-compose*.yml'
|
|
- '.gitea/scripts/**'
|
|
# #4322: test_managed_flags_wiring.py asserts every workflow STEP rolling the
|
|
# staging fleet wires STAGING_TENANT_FLAGS in — so ALL workflow files must run it,
|
|
# else a PR deleting that env: line (the exact mutation the test catches) runs no
|
|
# guard. The `.gitea/workflows/**` glob covers that (and test-ops-scripts.yml +
|
|
# local-provision-e2e.yml).
|
|
# #4346: the ws-teardown guard also asserts on the e2e driver script, which is NOT
|
|
# under .gitea/workflows/, so it needs its own path — else a PR reverting the
|
|
# teardown to the sweep that deletes a concurrent run's live container runs no
|
|
# guard. A guard CI does not run on the files it guards is not a guard.
|
|
- '.gitea/workflows/**'
|
|
# #114: test_ephemeral_gate_is_enforced.py asserts the ephemeral-CP gate's
|
|
# context sits ABOVE the first `# pending-` marker (i.e. is merge-queue
|
|
# enforced, not merely documented). The mutation it exists to catch — moving
|
|
# that line back down into the parked half — touches ONLY this file, so
|
|
# without this path the guard would not run on the very diff it guards.
|
|
- '.gitea/required-contexts.txt'
|
|
# core#4977: test_check_onconflict_partial_index.py runs the ON CONFLICT /
|
|
# partial-index lint against the REAL workspace-server tree + migrations, so the
|
|
# mutation it exists to catch -- dropping a partial index's predicate from an ON
|
|
# CONFLICT clause, which Postgres rejects at RUNTIME while compiling, vetting and
|
|
# sqlmock-ing perfectly clean -- touches ONLY those paths. Without them the guard
|
|
# would not run on the very diff it guards, same reasoning as #4322/#4346 above.
|
|
# That exact bug shipped and reached a customer: every drift enqueue failed for
|
|
# the life of the feature and the queue sat empty. Suite is ~3s.
|
|
- 'workspace-server/**'
|
|
# The marketplace SSOT test guards this public stub as well as its own
|
|
# test file. A stub-only regression must therefore emit this gate.
|
|
- 'docs/design/rfc-marketplace-delivery.md'
|
|
- 'tests/e2e/test_local_provision_lifecycle_e2e.sh'
|
|
# Active staging guidance is linted by
|
|
# test_deploy_comment_accuracy.py; changes to either harness must run it.
|
|
- 'tests/e2e/test_staging_concierge_creates_workspace_e2e.sh'
|
|
- 'tests/e2e/test_staging_full_saas.sh'
|
|
# test_dind_self_reaping.py drives the per-job dind harness; a PR editing only
|
|
# the harness must still run the guard that pins its self-reaping.
|
|
- 'tests/harness/dind.sh'
|
|
pull_request:
|
|
branches: [main, staging]
|
|
paths:
|
|
- 'scripts/**'
|
|
- 'docker-compose*.yml'
|
|
- '.gitea/scripts/**'
|
|
# #4322: test_managed_flags_wiring.py asserts every workflow STEP rolling the
|
|
# staging fleet wires STAGING_TENANT_FLAGS in — so ALL workflow files must run it,
|
|
# else a PR deleting that env: line (the exact mutation the test catches) runs no
|
|
# guard. The `.gitea/workflows/**` glob covers that (and test-ops-scripts.yml +
|
|
# local-provision-e2e.yml).
|
|
# #4346: the ws-teardown guard also asserts on the e2e driver script, which is NOT
|
|
# under .gitea/workflows/, so it needs its own path — else a PR reverting the
|
|
# teardown to the sweep that deletes a concurrent run's live container runs no
|
|
# guard. A guard CI does not run on the files it guards is not a guard.
|
|
- '.gitea/workflows/**'
|
|
# #114: test_ephemeral_gate_is_enforced.py asserts the ephemeral-CP gate's
|
|
# context sits ABOVE the first `# pending-` marker (i.e. is merge-queue
|
|
# enforced, not merely documented). The mutation it exists to catch — moving
|
|
# that line back down into the parked half — touches ONLY this file, so
|
|
# without this path the guard would not run on the very diff it guards.
|
|
- '.gitea/required-contexts.txt'
|
|
# core#4977: test_check_onconflict_partial_index.py runs the ON CONFLICT /
|
|
# partial-index lint against the REAL workspace-server tree + migrations, so the
|
|
# mutation it exists to catch -- dropping a partial index's predicate from an ON
|
|
# CONFLICT clause, which Postgres rejects at RUNTIME while compiling, vetting and
|
|
# sqlmock-ing perfectly clean -- touches ONLY those paths. Without them the guard
|
|
# would not run on the very diff it guards, same reasoning as #4322/#4346 above.
|
|
# That exact bug shipped and reached a customer: every drift enqueue failed for
|
|
# the life of the feature and the queue sat empty. Suite is ~3s.
|
|
- 'workspace-server/**'
|
|
# The marketplace SSOT test guards this public stub as well as its own
|
|
# test file. A stub-only regression must therefore emit this gate.
|
|
- 'docs/design/rfc-marketplace-delivery.md'
|
|
- 'tests/e2e/test_local_provision_lifecycle_e2e.sh'
|
|
# Active staging guidance is linted by
|
|
# test_deploy_comment_accuracy.py; changes to either harness must run it.
|
|
- 'tests/e2e/test_staging_concierge_creates_workspace_e2e.sh'
|
|
- 'tests/e2e/test_staging_full_saas.sh'
|
|
# test_dind_self_reaping.py drives the per-job dind harness; a PR editing only
|
|
# the harness must still run the guard that pins its self-reaping.
|
|
- 'tests/harness/dind.sh'
|
|
|
|
env:
|
|
GITHUB_SERVER_URL: https://git.moleculesai.app
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
test:
|
|
name: Ops scripts (unittest)
|
|
runs-on: ubuntu-latest
|
|
# continue-on-error REMOVED 2026-07-14. mc#3436 asked for exactly this:
|
|
# "pre-existing continue-on-error mask; root-fix and remove, do not renew
|
|
# silently."
|
|
#
|
|
# This is the META-GATE, and it was the most consequential mask in the repo.
|
|
# It is the ONLY PR lane that tests `.gitea/scripts/**` — 31 test files
|
|
# covering detect-changes.py, all-required-check.sh, ci-required-drift.py, the
|
|
# phantom-gate lint, the approval validator, and gitea-merge-queue.py itself:
|
|
# the machinery that enforces every OTHER gate. Masked, it could not fail.
|
|
#
|
|
# And it COMPOUNDED. The `ci` profile in detect-changes.py matches
|
|
# ^workspace-server/ ^canvas/ ^workspace/ ^tests/e2e/ ^scripts/ ^infra/scripts/
|
|
# — none of which match `.gitea/` (note `^scripts/` is anchored and does NOT
|
|
# match `.gitea/scripts/`). So a PR touching ONLY the CI machinery makes every
|
|
# profile false, every heavy job takes its no-op arm, and `CI / all-required`
|
|
# reports SUCCESS having run zero tests. The one lane that DID cover those
|
|
# files was this one — and it was forbidden from going red.
|
|
#
|
|
# Net: the merge queue and the gate scripts were the one thing CI could not
|
|
# see change. That is how the other vacuous gates survived, including the
|
|
# canvas lane that was green-by-no-op for a month while failing 3/3
|
|
# (core#4321 / core#4323).
|
|
#
|
|
# Verified green BEFORE unmasking (a mask must never be removed from a red
|
|
# suite — that wedges the repo): `python -m pytest .gitea/scripts/tests -q`
|
|
# => 611 passed, 2 skipped, 75 subtests passed. Removing the mask blocks
|
|
# nothing that was passing; it only stops a future break sliding through.
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
with:
|
|
python-version: '3.11'
|
|
- name: Install .gitea script test dependencies
|
|
run: python -m pip install --quiet 'pytest==9.0.2' 'PyYAML==6.0.2'
|
|
- name: Run scripts/ unittests (fail-closed on 0 collected)
|
|
# Top-level scripts/ tests live alongside their target file. The
|
|
# runtime packaging tests moved to molecule-ai-workspace-runtime, so
|
|
# this pass may legitimately find NO test files today.
|
|
#
|
|
# Gate-integrity fix: the previous guard keyed off `rc==5` to detect
|
|
# "no tests collected", but Python 3.12's unittest exits 0 (not 5)
|
|
# when discovery finds 0 tests ("NO TESTS RAN"). The guard therefore
|
|
# never fired, so any test_*.py added here would silently run 0 tests
|
|
# while this step stayed GREEN. A green step that runs 0 tests is
|
|
# worse than a red one. We now fail-closed:
|
|
# - genuinely NO test_*.py present -> loud SKIP (legitimate no-op)
|
|
# - test_*.py present but 0 collected -> FAIL (broken import/empty)
|
|
working-directory: scripts
|
|
run: |
|
|
set -euo pipefail
|
|
# Non-recursive count: scripts/ has no __init__.py, so unittest
|
|
# discover does not recurse into subdirs (ops/ is run separately
|
|
# below) — top-level files are the entire discovery scope here.
|
|
nfiles=$(find . -maxdepth 1 -name 'test_*.py' | wc -l | tr -d ' ')
|
|
if [ "$nfiles" -eq 0 ]; then
|
|
echo "SKIP: no top-level scripts/ test_*.py files present (genuine no-op)."
|
|
exit 0
|
|
fi
|
|
echo "Found $nfiles top-level scripts/ test_*.py file(s); asserting they collect >0 tests."
|
|
ncollected=$(python -c "import unittest; print(unittest.TestLoader().discover('.', pattern='test_*.py', top_level_dir='.').countTestCases())")
|
|
echo "Collected $ncollected test case(s)."
|
|
if [ "$ncollected" -eq 0 ]; then
|
|
echo "FAIL: test_*.py file(s) present but 0 tests collected (broken import / empty file / discovery error)."
|
|
exit 1
|
|
fi
|
|
python -m unittest discover -t . -p 'test_*.py' -v
|
|
- name: Run scripts/ops/ unittests (sweep_cf_decide, ...)
|
|
# Real gate: scripts/ops/ must always run tests. Assert >0 collected so
|
|
# deleting all test files (or breaking an import) can't pass GREEN by
|
|
# running 0 tests — same gate-integrity class as the scripts/ step.
|
|
working-directory: scripts/ops
|
|
run: |
|
|
set -euo pipefail
|
|
ncollected=$(python -c "import unittest; print(unittest.TestLoader().discover('.', pattern='test_*.py').countTestCases())")
|
|
echo "scripts/ops/ collected $ncollected test case(s)."
|
|
if [ "$ncollected" -eq 0 ]; then
|
|
echo "FAIL: scripts/ops/ collected 0 tests — this gate must run real tests (deleted/broken import?)."
|
|
exit 1
|
|
fi
|
|
python -m unittest discover -p 'test_*.py' -v
|
|
- name: Run .gitea/scripts pytest suite
|
|
run: python -m pytest .gitea/scripts/tests -q
|
|
|
|
- name: audit-force-merge pagination contract (network-free)
|
|
# This is a shell integration test, so pytest does not collect it.
|
|
# Its fake Gitea API reproduces the live server's limit=50 clamp and
|
|
# proves that status/file pagination continues to an explicit empty
|
|
# page while malformed or ambiguous status histories fail closed.
|
|
run: bash .gitea/scripts/tests/test_audit_force_merge.sh
|
|
|
|
- name: all-required-check.sh fail-closed contract
|
|
# Regression lock for molecule-core#656 / #2615. The CI / all-required
|
|
# aggregation logic was extracted to .gitea/scripts/all-required-check.sh;
|
|
# this step runs its shell unit test so a weakening of the fail-closed
|
|
# contract (e.g. accepting skipped/failure as success, or re-inlining
|
|
# the logic into ci.yml) fails CI.
|
|
run: bash .gitea/scripts/tests/test_all_required_check.sh
|
|
|
|
- name: E2E HTTP diagnostic sanitizer contract
|
|
# This required context runs for the E2E/workflow path shape changed by
|
|
# the redaction PR. Keep the behavioral test here as well as in ci.yml
|
|
# so a path-classifier decision cannot leave credential diagnostics
|
|
# locally green but unexecuted on the pull request.
|
|
run: python3 tests/e2e/test_sanitize_http_body.py
|
|
|
|
- name: clone-manifest.sh tolerant-bootstrap contract (network-free)
|
|
# Regression lock for the strict/best-effort split in clone-manifest.sh:
|
|
# tokenless dev bootstrap must skip ONLY `private: true` repos and still
|
|
# hard-fail on any public-repo clone failure (so a real outage / bad ref
|
|
# is never swallowed as a missing-creds skip). git-stubbed, no network.
|
|
run: |
|
|
set -euo pipefail
|
|
command -v jq >/dev/null 2>&1 || { sudo apt-get update -qq && sudo apt-get install -y -qq jq; }
|
|
# bash, not sh: the runner's /bin/sh is dash, and clone-manifest.sh
|
|
# (which this test drives) uses `set -o pipefail` — undefined in dash.
|
|
bash scripts/test-clone-manifest-tolerant.sh
|
|
|
|
- name: clone-manifest.sh provider-resolution contract (network-free)
|
|
# Regression lock for per-provider host+token resolution in clone-manifest.sh:
|
|
# provider absent ⇒ moleculesai (git.moleculesai.app + MOLECULE_GITEA_TOKEN),
|
|
# github ⇒ github.com + MOLECULE_GITHUB_TOKEN, unknown provider ⇒ fail-closed.
|
|
# git-stubbed, no network.
|
|
run: |
|
|
set -euo pipefail
|
|
command -v jq >/dev/null 2>&1 || { sudo apt-get update -qq && sudo apt-get install -y -qq jq; }
|
|
# bash, not sh (see tolerant step above): clone-manifest.sh needs pipefail.
|
|
bash scripts/test-clone-manifest-provider.sh
|
|
|
|
- name: dev-start.sh Langfuse readiness contract (network-free)
|
|
# Regression lock for local dev bootstrap truthfulness:
|
|
# ClickHouse's HTTP health can pass before the native migration port is
|
|
# usable, so dev-start.sh must wait for that path before starting
|
|
# Langfuse and must not print the ready banner until Langfuse HTTP works.
|
|
run: bash scripts/test-dev-start-langfuse-readiness.sh
|
|
|
|
- name: dev-start.sh platform startup behavior
|
|
run: |
|
|
node --test scripts/test-dev-port.cjs
|
|
bash scripts/test-dev-start-platform.sh
|