a094460580
ci-arm64-advisory / fast-checks (push) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 9s
Block internal-flavored paths / Block forbidden paths (push) Successful in 34s
CI / Python Lint & Test (push) Successful in 14s
CI / Detect changes (push) Successful in 19s
publish-workspace-server-image / build-and-push (push) Successful in 2m58s
E2E Chat / detect-changes (push) Successful in 37s
E2E API Smoke Test / detect-changes (push) Successful in 37s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 31s
E2E Staging SaaS (full lifecycle) / pr-validate (push) Successful in 1m8s
Handlers Postgres Integration / detect-changes (push) Successful in 13s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (push) Successful in 2m2s
Harness Replays / detect-changes (push) Successful in 14s
publish-canvas-image / Build & push canvas image (push) Successful in 4m45s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 15s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (push) Has been skipped
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (push) Successful in 20s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 8s
review-check-tests / review-check.sh regression tests (push) Successful in 16s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 8s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m31s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m29s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m37s
CI / Shellcheck (E2E scripts) (push) Successful in 42s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (push) Successful in 5m20s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2m6s
Harness Replays / Harness Replays (push) Successful in 9s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 8s
Sweep stale AWS Secrets Manager secrets / Sweep AWS Secrets Manager (push) Successful in 10s
CI / Platform (Go) (push) Successful in 5m35s
E2E Chat / E2E Chat (push) Successful in 4m7s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m48s
CI / Canvas (Next.js) (push) Successful in 6m59s
CI / all-required (push) Successful in 14m21s
CI / Canvas Deploy Reminder (push) Successful in 2s
publish-workspace-server-image / Production auto-deploy (push) Successful in 13m0s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Successful in 4m57s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 7m2s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Successful in 5m23s
test(e2e): add real staging image upload smoke (#1790) Remove legacy test-token references, keep production test-token unavailable, add explicit tenant-header diagnostics, and verify real staging image upload/download through the live tenant workflow.
161 lines
6.1 KiB
Bash
161 lines
6.1 KiB
Bash
# shellcheck shell=bash
|
|
# Sourceable helper for harness replays. Centralises the
|
|
# curl-against-cf-proxy pattern so scripts don't depend on /etc/hosts.
|
|
#
|
|
# Production CF tunnel routes by Host header, not by DNS — the request
|
|
# URL is to a public CF endpoint and the Host header carries the
|
|
# per-tenant identity. We replay the same shape locally:
|
|
#
|
|
# curl -H "Host: harness-tenant-alpha.localhost" http://localhost:8080/health
|
|
#
|
|
# This matches what cf-proxy/nginx.conf already routes (`server_name
|
|
# *.localhost` + `map $host $tenant_upstream`) and avoids the macOS
|
|
# /etc/hosts requirement that previously gated the harness behind a
|
|
# sudo step.
|
|
#
|
|
# Multi-tenant since Phase 2: alpha and beta tenants run in parallel.
|
|
# `curl_alpha_admin` and `curl_beta_admin` target each tenant's URL
|
|
# with that tenant's ADMIN_TOKEN + MOLECULE_ORG_ID. The legacy
|
|
# `curl_admin` is aliased to alpha for backwards compat with the
|
|
# pre-Phase-2 single-tenant replays.
|
|
#
|
|
# Usage:
|
|
# HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# source "$HERE/../_curl.sh" # from replays/<name>.sh
|
|
# curl_alpha_admin "$BASE/health"
|
|
# curl_beta_admin "$BASE/health"
|
|
|
|
# Bind to the cf-proxy's loopback port — the proxy front-doors every
|
|
# tenant and routes by Host header, exactly like production's CF tunnel.
|
|
: "${BASE:=http://localhost:8080}"
|
|
|
|
# Per-tenant identity. Each pair must match the corresponding tenant
|
|
# container's environment in compose.yml or auth/TenantGuard will fail
|
|
# in non-obvious ways (401 vs 403 vs silent route to wrong tenant).
|
|
: "${ALPHA_HOST:=harness-tenant-alpha.localhost}"
|
|
: "${ALPHA_ADMIN_TOKEN:=harness-admin-token-alpha}"
|
|
: "${ALPHA_ORG_ID:=harness-org-alpha}"
|
|
|
|
: "${BETA_HOST:=harness-tenant-beta.localhost}"
|
|
: "${BETA_ADMIN_TOKEN:=harness-admin-token-beta}"
|
|
: "${BETA_ORG_ID:=harness-org-beta}"
|
|
|
|
# Legacy single-tenant aliases — pre-Phase-2 replays use these without
|
|
# knowing the topology grew. They map to alpha. New replays should use
|
|
# the explicit alpha/beta variants for clarity.
|
|
: "${TENANT_HOST:=$ALPHA_HOST}"
|
|
: "${ADMIN_TOKEN:=$ALPHA_ADMIN_TOKEN}"
|
|
: "${ORG_ID:=$ALPHA_ORG_ID}"
|
|
|
|
# ─── Anonymous (no auth) ──────────────────────────────────────────────
|
|
|
|
# Anonymous request to alpha. Use for /health, /buildinfo, etc.
|
|
curl_alpha_anon() {
|
|
curl -sS -H "Host: ${ALPHA_HOST}" "$@"
|
|
}
|
|
|
|
# Anonymous request to beta.
|
|
curl_beta_anon() {
|
|
curl -sS -H "Host: ${BETA_HOST}" "$@"
|
|
}
|
|
|
|
# Legacy alias for single-tenant replays.
|
|
curl_anon() {
|
|
curl -sS -H "Host: ${TENANT_HOST}" "$@"
|
|
}
|
|
|
|
# ─── Admin-token requests ─────────────────────────────────────────────
|
|
|
|
# Admin-token request to alpha tenant. SaaS-shape auth: bearer token,
|
|
# tenant org header (TenantGuard activates), JSON content type.
|
|
curl_alpha_admin() {
|
|
curl -sS \
|
|
-H "Host: ${ALPHA_HOST}" \
|
|
-H "Authorization: Bearer ${ALPHA_ADMIN_TOKEN}" \
|
|
-H "X-Molecule-Org-Id: ${ALPHA_ORG_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
"$@"
|
|
}
|
|
|
|
# Admin-token request to beta tenant.
|
|
curl_beta_admin() {
|
|
curl -sS \
|
|
-H "Host: ${BETA_HOST}" \
|
|
-H "Authorization: Bearer ${BETA_ADMIN_TOKEN}" \
|
|
-H "X-Molecule-Org-Id: ${BETA_ORG_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
"$@"
|
|
}
|
|
|
|
# Legacy alias.
|
|
curl_admin() {
|
|
curl_alpha_admin "$@"
|
|
}
|
|
|
|
# ─── Cross-tenant negative-test helpers ───────────────────────────────
|
|
# These exist to MAKE WRONG calls — replays use them to assert
|
|
# TenantGuard rejects them. Names spell out what's mismatched.
|
|
|
|
# alpha bearer + alpha org, but talking to beta's URL. TenantGuard
|
|
# should reject because the org header doesn't match beta's MOLECULE_ORG_ID.
|
|
curl_alpha_creds_at_beta() {
|
|
curl -sS \
|
|
-H "Host: ${BETA_HOST}" \
|
|
-H "Authorization: Bearer ${ALPHA_ADMIN_TOKEN}" \
|
|
-H "X-Molecule-Org-Id: ${ALPHA_ORG_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
"$@"
|
|
}
|
|
|
|
# beta bearer + beta org, but talking to alpha's URL.
|
|
curl_beta_creds_at_alpha() {
|
|
curl -sS \
|
|
-H "Host: ${ALPHA_HOST}" \
|
|
-H "Authorization: Bearer ${BETA_ADMIN_TOKEN}" \
|
|
-H "X-Molecule-Org-Id: ${BETA_ORG_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
"$@"
|
|
}
|
|
|
|
# ─── Workspace-scoped (per-workspace bearer) ──────────────────────────
|
|
|
|
# Workspace-scoped request to alpha — uses a real per-workspace bearer minted
|
|
# through the admin token route, not the local-dev fixture-token route. Caller
|
|
# must export WORKSPACE_TOKEN.
|
|
curl_workspace() {
|
|
: "${WORKSPACE_TOKEN:?WORKSPACE_TOKEN must be set — mint via POST /admin/workspaces/:id/tokens}"
|
|
curl -sS \
|
|
-H "Host: ${TENANT_HOST}" \
|
|
-H "Authorization: Bearer ${WORKSPACE_TOKEN}" \
|
|
-H "X-Molecule-Org-Id: ${ORG_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
"$@"
|
|
}
|
|
|
|
# ─── Postgres exec (per-tenant) ───────────────────────────────────────
|
|
|
|
# Direct postgres exec — for replays that need to seed activity_logs
|
|
# rows or read DB state that has no public HTTP route.
|
|
#
|
|
# SECRETS_ENCRYPTION_KEY placeholder lets compose validate without
|
|
# requiring up.sh's per-run key (exec doesn't actually use it but
|
|
# compose validates the file).
|
|
psql_exec_alpha() {
|
|
SECRETS_ENCRYPTION_KEY="${SECRETS_ENCRYPTION_KEY:-exec-placeholder}" \
|
|
docker compose -f "${HARNESS_COMPOSE:-$(dirname "${BASH_SOURCE[0]}")/compose.yml}" \
|
|
exec -T postgres-alpha \
|
|
psql -U harness -d molecule -At "$@"
|
|
}
|
|
|
|
psql_exec_beta() {
|
|
SECRETS_ENCRYPTION_KEY="${SECRETS_ENCRYPTION_KEY:-exec-placeholder}" \
|
|
docker compose -f "${HARNESS_COMPOSE:-$(dirname "${BASH_SOURCE[0]}")/compose.yml}" \
|
|
exec -T postgres-beta \
|
|
psql -U harness -d molecule -At "$@"
|
|
}
|
|
|
|
# Legacy alias — single-tenant replays default to alpha's DB.
|
|
psql_exec() {
|
|
psql_exec_alpha "$@"
|
|
}
|