ci: add k8s stack PR preview via labeled deploy + Cloudflare Tunnel - #205
ci: add k8s stack PR preview via labeled deploy + Cloudflare Tunnel#205aktech wants to merge 15 commits into
Conversation
Labeling a PR with deploy-preview spins up the full NIC platform stack plus this chart in an ephemeral k3d cluster, then exposes JupyterHub through a per-PR Cloudflare Tunnel gated by Cloudflare Access (GitHub org SSO), posting the link as a sticky PR comment. Includes a standalone tunnel-only smoketest workflow for validating the Cloudflare plumbing without the full stack deploy.
|
K8s stack preview for Deployed: 2026-08-05 14:21 UTC · Expires: 2026-08-05 15:51 UTC You'll be asked to sign in via Cloudflare Access (GitHub SSO) before This goes straight to JupyterHub's proxy; the operator-provisioned Live until the expiry time above, or until the |
pull_request/synchronize on this one file, scoped narrowly, so the tunnel-only smoketest can run without waiting for main to see the workflow_dispatch trigger. Remove before merging.
--no-autoupdate is a tunnel-level flag, not a run-subcommand flag; placed after `run` it errored with "flag provided but not defined" and the tunnel process exited immediately without ever connecting.
Two-level hostnames (pr-<n>.dspack.iakte.ch) aren't covered by Cloudflare's default Universal SSL, which only auto-issues a cert for the zone apex plus one wildcard level. Switching to a dedicated single-level domain (pr-<n>.github.fyi) avoids needing the paid Advanced Certificate Manager add-on.
workflow_dispatch is now registered and reachable; the iteration workaround is no longer needed.
charts/ is gitignored, so the vendored jupyterhub-4.3.2.tgz seen in local dev never reaches a fresh CI checkout. helm dependency build resolves it against the already-committed Chart.lock digest.
workflow_dispatch has no PR context to auto-detect, so the comment step uses number_force (sticky-pull-request-comment's any-event PR number override, distinct from number which is push-event only).
|
Tunnel smoketest (static page, not the real stack): Sign-in via Cloudflare Access (GitHub SSO), then should show "Tunnel smoketest OK". |
helm dependency build resolves against locally-registered repos, not just the Chart.lock digest; a fresh runner has none configured. Added helm repo add before the build step. Verified against a clean clone.
…debugging nic-operator ignores any namespace without nebari.dev/managed=true, so the NebariApp CRD never reconciled. Also adds a static pod/job/event dump and an interactive tmate SSH session (actor-restricted, 20min cap) on deploy failure, since the cluster is deleted right after and static logs alone weren't enough to diagnose the last two failures.
00-gateway-auth.py reads /etc/oauth/issuer-url unconditionally at import time. That file only exists once the operator's async Keycloak client provisioning finishes, which Helm doesn't wait for, so the hub pod crash-loops immediately when nebariapp.auth.enabled=true. Confirmed via kubectl logs during a failed run. Dropping nebariapp entirely for this preview; operator/OIDC reconcile isn't exercised here.
Without it, 02-jhub-apps.py falls back to bind_url=http://0.0.0.0:8000, which JupyterHub then bakes into browser-facing OAuth redirect URLs for the jhub-apps service (client_id=service-japps), breaking the login flow after dummy-auth. Confirmed via a real login attempt on the deployed preview.
The preview URL is stable per-PR, so redeploys posted byte-identical comment text and looked like they never updated. Adding deployed-at and expires-at timestamps makes every redeploy visibly change the comment and tells reviewers exactly when the link goes dead.
…ri-data-science-pack into add-k8s-preview-workflow
A workflow retry keeps the same github.run_id (only run_attempt changes), so a re-run after an attempt already created the tunnel but didn't reach its cleanup step hit a 409 name conflict. Now falls back to looking up and reusing the existing tunnel by name instead of failing outright. Confirmed via a real run_attempt=2 failure.
Adds a
deploy-previewlabel-triggered workflow that spins up the full NIC platform stack plus this chart in an ephemeral k3d cluster, then exposes JupyterHub through a per-PR Cloudflare Tunnel gated by Cloudflare Access (GitHub org SSO), posting the link as a sticky PR comment.Also adds a standalone
workflow_dispatchsmoketest workflow that validates just the Cloudflare Tunnel/DNS/Access plumbing against a trivial static page, for fast iteration without paying for the full stack deploy each time.Draft PR to test the preview workflow on itself — add the
deploy-previewlabel to try it.