molecule-core/.github/workflows
Hongming Wang 3a6d2f179d feat(ops): add sweep-cf-tunnels janitor — orphan Cloudflare Tunnels accumulate
CP's tenant-delete cascade removes the DNS record (with sweep-cf-orphans
as a backstop) but does NOT delete the underlying Cloudflare Tunnel.
Each E2E provision creates one Tunnel named `tenant-<slug>`; without
cleanup these accumulate indefinitely on the account, consuming the
tunnel quota and cluttering the dashboard.

Observed 2026-04-30: dozens of `tenant-e2e-canvas-*` tunnels in Down
state with zero replicas, weeks past their tenant's deletion. Same
class of bug as the DNS-records leak that drove sweep-cf-orphans
(controlplane#239).

Parallel-shape to sweep-cf-orphans:
  - Same dry-run-by-default + --execute pattern
  - Same MAX_DELETE_PCT safety gate (default 90% — higher than DNS
    sweep's 50% because tenant-shaped tunnels are orphans by design)
  - Same schedule/dispatch hardening (hard-fail on missing secrets
    when scheduled, soft-skip when dispatched)
  - Cron offset to :45 to avoid CF API bursts colliding with the DNS
    sweep at :15

Decision rules (in order):
  1. Name doesn't match `tenant-<slug>` → keep (unknown — never sweep
     tunnels that might belong to platform infra).
  2. Tunnel has active connections (status=healthy or non-empty
     connections array) → keep (defense-in-depth: don't kill a live
     tunnel even if CP forgot the org).
  3. Slug ∈ {prod_slugs ∪ staging_slugs} → keep.
  4. Otherwise → delete (orphan).

Verified by:
  - shell syntax check (bash -n)
  - YAML lint
  - Decide-logic offline smoke (7 cases, all pass)
  - End-to-end dry-run smoke with stubbed CP + CF APIs

Required secrets (added to existing org-secrets):
  CF_API_TOKEN          must include account:cloudflare_tunnel:edit
                        scope (separate from zone:dns:edit used by
                        sweep-cf-orphans — same token if scope is
                        broad, or a new token if narrowly scoped).
  CF_ACCOUNT_ID         account that owns the tunnels (visible in
                        dash.cloudflare.com URL path).
  CP_PROD_ADMIN_TOKEN   reused from sweep-cf-orphans.
  CP_STAGING_ADMIN_TOKEN reused from sweep-cf-orphans.

Note: CP-side root cause (tenant-delete should cascade to tunnel
delete) is in molecule-controlplane and worth fixing separately. This
janitor is the operational backstop in the meantime — same pattern
applied to DNS records when the same root cause was unaddressed.
2026-04-29 19:42:47 -07:00
..
auto-promote-on-e2e.yml ci: ancestry-check on auto-promote :latest (#2244) 2026-04-29 16:18:42 -07:00
auto-promote-staging.yml Merge remote-tracking branch 'origin/staging' into docs/auto-promote-staging-prereq-comment 2026-04-28 20:46:42 -07:00
auto-sync-main-to-staging.yml fix(ci): auto-sync opens a PR + uses merge queue, not direct push 2026-04-28 15:59:26 -07:00
auto-tag-runtime.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
block-internal-paths.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
canary-staging.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
canary-verify.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
check-merge-group-trigger.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
ci.yml ci: collapse all 4 path-filtered required checks to single-job-with-conditional-steps 2026-04-29 16:09:22 -07:00
codeql.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
e2e-api.yml ci: collapse two-jobs-sharing-name path-filter pattern in e2e-api/e2e-staging-canvas 2026-04-29 17:29:44 -07:00
e2e-staging-canvas.yml fix(e2e-canvas): kill teardown race that poisons concurrent runs 2026-04-29 19:23:56 -07:00
e2e-staging-saas.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
e2e-staging-sanity.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
pr-guards.yml ci: add pr-guards caller that disables auto-merge on push 2026-04-27 06:39:31 -07:00
promote-latest.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
publish-canvas-image.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
publish-runtime.yml Merge pull request #2249 from Molecule-AI/fix/publish-runtime-cascade-hard-fail-on-push 2026-04-29 01:33:10 +00:00
publish-workspace-server-image.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
railway-pin-audit.yml ci: daily Railway pin-audit cron + issue-on-failure (#2169) 2026-04-29 17:43:01 -07:00
redeploy-tenants-on-main.yml ci(redeploy): fire post-main tenant fleet redeploy via CP admin endpoint 2026-04-24 14:34:28 -07:00
retarget-main-to-staging.yml ci(retarget): handle 422 'duplicate PR' by closing redundant main-PR (closes #1884) 2026-04-26 00:53:55 -07:00
runtime-pin-compat.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
runtime-prbuild-compat.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
secret-pattern-drift.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
secret-scan.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
sweep-cf-orphans.yml Merge pull request #2248 from Molecule-AI/fix/sweep-cf-orphans-hard-fail-on-schedule 2026-04-29 01:16:22 +00:00
sweep-cf-tunnels.yml feat(ops): add sweep-cf-tunnels janitor — orphan Cloudflare Tunnels accumulate 2026-04-29 19:42:47 -07:00
sweep-stale-e2e-orgs.yml ci: hourly sweep of stale e2e-* orgs on staging 2026-04-24 23:07:57 -07:00
test-ops-scripts.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00