ci(e2e): address review findings
Refs #38 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
23816377a5
commit
da8305c12d
3 changed files with 57 additions and 17 deletions
|
|
@ -13,12 +13,24 @@ node e2e/support/tcp-forward.mjs "$DOCKER_GW" 54321 54322 54324 9998 &
|
||||||
relay=$!
|
relay=$!
|
||||||
trap 'kill "$relay" 2>/dev/null || true' EXIT
|
trap 'kill "$relay" 2>/dev/null || true' EXIT
|
||||||
|
|
||||||
for port in 54321 54322 54324 9998; do
|
# Warten, bis die Dienste HINTER dem Relay antworten (nicht nur der lokale Port); Timeout = Fehler.
|
||||||
for _ in $(seq 1 20); do
|
wait_http() {
|
||||||
(exec 3<>"/dev/tcp/127.0.0.1/${port}") 2>/dev/null && break
|
for _ in $(seq 1 60); do
|
||||||
sleep 0.5
|
curl -fsS -o /dev/null --max-time 3 -H "apikey: ${SUPABASE_ANON_KEY}" "$1" 2>/dev/null && return 0
|
||||||
|
sleep 1
|
||||||
done
|
done
|
||||||
|
echo "Timeout: $1 nicht erreichbar (Relay zu ${DOCKER_GW})" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
wait_http "http://127.0.0.1:54321/auth/v1/health" || exit 1 # Kong -> GoTrue
|
||||||
|
wait_http "http://127.0.0.1:54324/api/v1/info" || exit 1
|
||||||
|
wait_http "http://127.0.0.1:9998/health" || exit 1
|
||||||
|
pg_ok=""
|
||||||
|
for _ in $(seq 1 60); do
|
||||||
|
if (exec 3<>/dev/tcp/127.0.0.1/54322) 2>/dev/null; then pg_ok=1; break; fi
|
||||||
|
sleep 1
|
||||||
done
|
done
|
||||||
|
[ -n "$pg_ok" ] || { echo "Timeout: Postgres 54322 nicht erreichbar" >&2; exit 1; }
|
||||||
|
|
||||||
export SUPABASE_URL=http://127.0.0.1:54321
|
export SUPABASE_URL=http://127.0.0.1:54321
|
||||||
export MAILPIT_URL=http://127.0.0.1:54324
|
export MAILPIT_URL=http://127.0.0.1:54324
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,9 @@ jobs:
|
||||||
# Nutzt die eingecheckte supabase/config.toml. Ohne passenden Runner Job bei Bedarf deaktivieren.
|
# Nutzt die eingecheckte supabase/config.toml. Ohne passenden Runner Job bei Bedarf deaktivieren.
|
||||||
supabase-tests:
|
supabase-tests:
|
||||||
runs-on: docker-host
|
runs-on: docker-host
|
||||||
|
concurrency:
|
||||||
|
group: docker-host-supabase
|
||||||
|
cancel-in-progress: false
|
||||||
env:
|
env:
|
||||||
DOCKER_CLI_VERSION: 27.3.1
|
DOCKER_CLI_VERSION: 27.3.1
|
||||||
DIND_PORT: 2375
|
DIND_PORT: 2375
|
||||||
|
|
@ -187,12 +190,20 @@ jobs:
|
||||||
# Läuft wie supabase-tests auf "docker-host" (Docker-CLI + dind per TCP). Der Stack liegt im dind; ein
|
# Läuft wie supabase-tests auf "docker-host" (Docker-CLI + dind per TCP). Der Stack liegt im dind; ein
|
||||||
# TCP-Relay (e2e/support/tcp-forward.mjs) macht ihn im Job unter 127.0.0.1 erreichbar.
|
# TCP-Relay (e2e/support/tcp-forward.mjs) macht ihn im Job unter 127.0.0.1 erreichbar.
|
||||||
# SICHERHEIT: Der Job führt PR-Code mit Zugriff auf den dind-Daemon des Runners aus (Daemon = Root-Äquivalent).
|
# SICHERHEIT: Der Job führt PR-Code mit Zugriff auf den dind-Daemon des Runners aus (Daemon = Root-Äquivalent).
|
||||||
# Deshalb nicht für Fork-PRs (Bedingung unten); Fork-Beiträge nur nach Review und Übernahme in einen Branch dieses Repos.
|
# Der `if:` unten ist KEIN Schutz vor böswilligen Forks: Bei pull_request kommt der Workflow aus dem PR-Head,
|
||||||
# Gleiches Risiko hat supabase-tests; dort ist es (noch) nicht eingeschränkt.
|
# ein Fork kann die Bedingung einfach entfernen. Er verhindert nur versehentliche Läufe. Die echte Absicherung
|
||||||
# needs: supabase-tests, weil beide Jobs dieselben festen Container-Namen/Ports (project_id shuffle, 54321 ...) im dind belegen.
|
# gehört in Repo-/Runner-Einstellungen (Freigabe für Fork-PRs, Runner nur für vertrauenswürdige Repos; Folge-Issue).
|
||||||
|
# Gleiches Risiko hat supabase-tests.
|
||||||
|
# needs + concurrency: Beide Jobs belegen dieselben festen Container-Namen/Ports (project_id shuffle, 54321 ...) im dind.
|
||||||
|
# `needs` serialisiert innerhalb eines Laufs; die concurrency-Gruppe (auch an supabase-tests) soll Läufe verschiedener
|
||||||
|
# PRs hintereinander schalten. Ob Forgejo 8.0.3 / Runner v5.0.4 Job-concurrency auswertet, ist hier nicht verifiziert;
|
||||||
|
# sonst wird der Schlüssel ignoriert und Kollisionen bleiben möglich (dann Runner mit capacity 1 verwenden).
|
||||||
# Der Spike (SPIKE_GOTRUE_URL, Issue #37) läuft nicht in CI.
|
# Der Spike (SPIKE_GOTRUE_URL, Issue #37) läuft nicht in CI.
|
||||||
e2e:
|
e2e:
|
||||||
runs-on: docker-host
|
runs-on: docker-host
|
||||||
|
concurrency:
|
||||||
|
group: docker-host-supabase
|
||||||
|
cancel-in-progress: false
|
||||||
needs: [supabase-tests]
|
needs: [supabase-tests]
|
||||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||||
env:
|
env:
|
||||||
|
|
@ -206,9 +217,11 @@ jobs:
|
||||||
- name: Werkzeuge prüfen
|
- name: Werkzeuge prüfen
|
||||||
run: |
|
run: |
|
||||||
missing=""
|
missing=""
|
||||||
for t in git curl unzip xz jq; do command -v "$t" >/dev/null || missing="$missing $t"; done
|
for t in git curl unzip xz jq; do
|
||||||
|
command -v "$t" >/dev/null || { [ "$t" = xz ] && missing="$missing xz-utils" || missing="$missing $t"; }
|
||||||
|
done
|
||||||
if [ -n "$missing" ]; then
|
if [ -n "$missing" ]; then
|
||||||
apt-get update -qq && apt-get install -y -qq --no-install-recommends $missing xz-utils ca-certificates
|
apt-get update -qq && apt-get install -y -qq --no-install-recommends $missing ca-certificates
|
||||||
fi
|
fi
|
||||||
node --version
|
node --version
|
||||||
|
|
||||||
|
|
@ -224,20 +237,27 @@ jobs:
|
||||||
DOCKER_HOST="tcp://${gw}:${DIND_PORT}" docker version --format 'dind {{.Server.Version}}'
|
DOCKER_HOST="tcp://${gw}:${DIND_PORT}" docker version --format 'dind {{.Server.Version}}'
|
||||||
|
|
||||||
- name: Supabase starten (mit Mailpit, ohne Studio u. a.)
|
- name: Supabase starten (mit Mailpit, ohne Studio u. a.)
|
||||||
run: npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} start -x studio,imgproxy,edge-runtime,logflare,vector
|
# Ausgabe nicht ins Log: Die Zusammenfassung von `start` enthält die lokalen Schlüssel (noch nicht maskiert).
|
||||||
|
run: |
|
||||||
|
if ! npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} start -x studio,imgproxy,edge-runtime,logflare,vector >"${RUNNER_TEMP:-/tmp}/supabase-start.log" 2>&1; then
|
||||||
|
echo "supabase start fehlgeschlagen, letzte Zeilen (Schlüssel gefiltert):"
|
||||||
|
tail -n 40 "${RUNNER_TEMP:-/tmp}/supabase-start.log" | grep -viE 'key|secret|token|jwt'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "supabase start ok"
|
||||||
|
|
||||||
- name: Datenbank zurücksetzen
|
- name: Datenbank zurücksetzen
|
||||||
run: npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} db reset
|
run: npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} db reset
|
||||||
|
|
||||||
- name: Lokale Schlüssel lesen
|
- name: Lokale Schlüssel lesen
|
||||||
# Die Werte sind die öffentlichen Demo-Schlüssel der CLI, trotzdem nur maskiert weiterreichen.
|
# Öffentliche Demo-Schlüssel der CLI; trotzdem wird die Maske gesetzt, bevor sie irgendwo ausgegeben werden.
|
||||||
run: |
|
run: |
|
||||||
status=$(npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} status -o env)
|
status=$(npx --yes supabase@${{ env.SUPABASE_CLI_VERSION }} status -o env 2>/dev/null)
|
||||||
get() { printf '%s\n' "$status" | sed -n "s/^$1=\"\{0,1\}\([^\"]*\)\"\{0,1\}$/\1/p" | head -n1; }
|
get() { printf '%s\n' "$status" | sed -n "s/^$1=\"\{0,1\}\([^\"]*\)\"\{0,1\}$/\1/p" | head -n1; }
|
||||||
anon=$(get ANON_KEY); service=$(get SERVICE_ROLE_KEY)
|
anon=$(get ANON_KEY); service=$(get SERVICE_ROLE_KEY)
|
||||||
|
[ -z "$anon" ] || echo "::add-mask::$anon"
|
||||||
|
[ -z "$service" ] || echo "::add-mask::$service"
|
||||||
test -n "$anon" && test -n "$service" || { echo "ANON_KEY/SERVICE_ROLE_KEY nicht in 'supabase status -o env' gefunden"; exit 1; }
|
test -n "$anon" && test -n "$service" || { echo "ANON_KEY/SERVICE_ROLE_KEY nicht in 'supabase status -o env' gefunden"; exit 1; }
|
||||||
echo "::add-mask::$anon"
|
|
||||||
echo "::add-mask::$service"
|
|
||||||
echo "SUPABASE_ANON_KEY=${anon}" >> "$GITHUB_ENV"
|
echo "SUPABASE_ANON_KEY=${anon}" >> "$GITHUB_ENV"
|
||||||
echo "SUPABASE_SERVICE_ROLE_KEY=${service}" >> "$GITHUB_ENV"
|
echo "SUPABASE_SERVICE_ROLE_KEY=${service}" >> "$GITHUB_ENV"
|
||||||
# Env-Datei für den Web-Build: Platzhalter-Datei bleibt unverändert, der Schlüssel kommt zur Laufzeit.
|
# Env-Datei für den Web-Build: Platzhalter-Datei bleibt unverändert, der Schlüssel kommt zur Laufzeit.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
# Docker-in-Docker (CI, DOCKER_HOST=tcp://...): Der Port wird im dind veroeffentlicht, nicht im Job-Container.
|
# Docker-in-Docker (CI, DOCKER_HOST=tcp://...): Der Port wird im dind veroeffentlicht, nicht im Job-Container.
|
||||||
# Dann BIND_ADDR=0.0.0.0 und HEALTH_HOST=<dind-Gateway> setzen (siehe .forgejo/workflows/ci.yml, Job e2e);
|
# Dann BIND_ADDR=0.0.0.0 und HEALTH_HOST=<dind-Gateway> setzen (siehe .forgejo/workflows/ci.yml, Job e2e);
|
||||||
# die Tests erreichen den Container ueber e2e/support/tcp-forward.mjs auf 127.0.0.1.
|
# die Tests erreichen den Container ueber e2e/support/tcp-forward.mjs auf 127.0.0.1.
|
||||||
|
# Bindung: lokal nur 127.0.0.1. Unter dind muss 0.0.0.0 gelten (der Job-Container erreicht den dind nur ueber
|
||||||
|
# das Gateway; eine feinere Bindung ist dort nicht moeglich). Der Port ist dann im Netz des Runners sichtbar.
|
||||||
# Nur lokal/CI benutzen: Die kopierte Umgebung enthaelt die lokalen Demo-Secrets der CLI.
|
# Nur lokal/CI benutzen: Die kopierte Umgebung enthaelt die lokalen Demo-Secrets der CLI.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
@ -24,7 +26,9 @@ BIND_ADDR="${BIND_ADDR:-127.0.0.1}"
|
||||||
HEALTH_HOST="${HEALTH_HOST:-127.0.0.1}"
|
HEALTH_HOST="${HEALTH_HOST:-127.0.0.1}"
|
||||||
ACTION="${1:-start}"
|
ACTION="${1:-start}"
|
||||||
PROFILE="${2:-throttle}"
|
PROFILE="${2:-throttle}"
|
||||||
SOURCE="${SOURCE_CONTAINER:-$(docker ps --format '{{.Names}}' | grep -E '^supabase_auth_' | head -n1 || true)}"
|
# Auth-Container gezielt ueber die Projekt-ID (project_id in supabase/config.toml), nicht "erster Treffer"
|
||||||
|
PROJECT_ID="${SUPABASE_PROJECT_ID:-shuffle}"
|
||||||
|
SOURCE="${SOURCE_CONTAINER:-supabase_auth_${PROJECT_ID}}"
|
||||||
|
|
||||||
case "$PROFILE" in
|
case "$PROFILE" in
|
||||||
throttle) NAME="${CONTAINER_NAME:-shuffle_auth_throttle}"; HOST_PORT="${HOST_PORT:-9998}" ;;
|
throttle) NAME="${CONTAINER_NAME:-shuffle_auth_throttle}"; HOST_PORT="${HOST_PORT:-9998}" ;;
|
||||||
|
|
@ -39,8 +43,8 @@ if [ "$ACTION" = "stop" ]; then
|
||||||
fi
|
fi
|
||||||
[ "$ACTION" = "start" ] || { echo "Aktion: start|stop" >&2; exit 2; }
|
[ "$ACTION" = "start" ] || { echo "Aktion: start|stop" >&2; exit 2; }
|
||||||
|
|
||||||
if [ -z "$SOURCE" ]; then
|
if ! docker inspect "$SOURCE" >/dev/null 2>&1; then
|
||||||
echo "Kein laufender supabase_auth_*-Container gefunden. Zuerst 'supabase start'." >&2
|
echo "Container $SOURCE nicht gefunden. Zuerst 'supabase start' (oder SUPABASE_PROJECT_ID setzen)." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -52,6 +56,7 @@ ENV_ARGS=()
|
||||||
while IFS= read -r -d '' entry; do
|
while IFS= read -r -d '' entry; do
|
||||||
case "$entry" in
|
case "$entry" in
|
||||||
GOTRUE_RATE_LIMIT_HEADER=*) continue ;; # wird unten gezielt gesetzt
|
GOTRUE_RATE_LIMIT_HEADER=*) continue ;; # wird unten gezielt gesetzt
|
||||||
|
API_EXTERNAL_URL=*) continue ;; # wird unten explizit gesetzt
|
||||||
GOTRUE_SMTP_PORT=*) [ "$PROFILE" = "smtp-down" ] && continue ;;
|
GOTRUE_SMTP_PORT=*) [ "$PROFILE" = "smtp-down" ] && continue ;;
|
||||||
esac
|
esac
|
||||||
ENV_ARGS+=(-e "$entry")
|
ENV_ARGS+=(-e "$entry")
|
||||||
|
|
@ -62,6 +67,9 @@ case "$PROFILE" in
|
||||||
smtp-down) ENV_ARGS+=(-e "GOTRUE_SMTP_PORT=1") ;; # Host bleibt Mailpit, Port 1 lehnt die Verbindung ab
|
smtp-down) ENV_ARGS+=(-e "GOTRUE_SMTP_PORT=1") ;; # Host bleibt Mailpit, Port 1 lehnt die Verbindung ab
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# API_EXTERNAL_URL explizit (Spec D2): Kong-URL der CLI, nur Basis fuer Links in Mails/Redirects.
|
||||||
|
ENV_ARGS+=(-e "API_EXTERNAL_URL=${API_EXTERNAL_URL:-http://127.0.0.1:54321}")
|
||||||
|
|
||||||
docker run -d --name "$NAME" --network "$NETWORK" -p "${BIND_ADDR}:${HOST_PORT}:9999" \
|
docker run -d --name "$NAME" --network "$NETWORK" -p "${BIND_ADDR}:${HOST_PORT}:9999" \
|
||||||
"${ENV_ARGS[@]}" "$IMAGE" auth >/dev/null
|
"${ENV_ARGS[@]}" "$IMAGE" auth >/dev/null
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue