fix(dev-tunnel): warn when the dev server can't be embedded by the host #452
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: true | |
| - name: go vet | |
| run: go vet ./... | |
| - name: gofmt | |
| run: | | |
| unformatted=$(gofmt -s -l .) | |
| if [ -n "$unformatted" ]; then | |
| echo "These files are not gofmt-ed:" | |
| echo "$unformatted" | |
| exit 1 | |
| fi | |
| - name: test | |
| run: go test ./... | |
| - name: build | |
| run: go build ./... | |
| # Static-analysis gate: golangci-lint over the whole module using the curated | |
| # linter set in .golangci.yml (staticcheck / govet / ineffassign / unused / | |
| # misspell + gofmt). Runs on every PR. `make lint` mirrors this locally. | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: false # golangci-lint-action manages its own build/analysis cache | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@v8 | |
| with: | |
| version: v2.12.2 | |
| # Drift-guard: the vendored block-manifest schema (go:embed'd for offline | |
| # `civitai app validate`) must stay identical to the canonical the platform | |
| # publishes at civitai.com/schemas/app-block/v1.json (the single source of | |
| # truth). Fails if a server-side contract change leaves the CLI stale. | |
| schema-drift: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: check canonical schema | |
| run: ./scripts/check-canonical-schema.sh | |
| # Rot-guard: assert each scaffold template's `@civitai/*` pin still ADMITS the | |
| # version npm currently publishes as `latest`. A pre-1.0 caret (`^0.24.0`) | |
| # locks the minor, so a pin that falls behind npm silently ships apps that are | |
| # born stale — and `npm install` won't catch it (it resolves the caret to the | |
| # newest version the stale range still admits). This is the network half of | |
| # the scaffold guard; it's env-gated so the default `go test ./...` stays | |
| # offline, and it SKIPS (never false-fails) when npm is unreachable. | |
| pins-vs-published: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: true | |
| - name: check scaffold pins vs npm latest | |
| env: | |
| CIVITAI_CHECK_PUBLISHED_PINS: "1" | |
| run: go test ./internal/scaffold -run TestScaffoldPinsSatisfyPublished -v | |
| # Rot-guard: scaffold the page-money template and run its JS toolchain against | |
| # the PUBLISHED SDK (@civitai/blocks-react). Catches a template that renders | |
| # but no longer installs / typechecks / tests / builds after an SDK bump — the | |
| # out-of-the-box contract the template promises. | |
| template-page-money: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: true | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: scaffold page-money | |
| run: go run ./cmd/civitai app init "CI Money Block" --dir ./_ci-page-money --template page-money | |
| - name: install | |
| working-directory: ./_ci-page-money | |
| run: npm install --no-audit --no-fund | |
| - name: typecheck | |
| working-directory: ./_ci-page-money | |
| run: npm run typecheck | |
| - name: test (node + dom suites) | |
| working-directory: ./_ci-page-money | |
| run: npm test | |
| - name: build | |
| working-directory: ./_ci-page-money | |
| run: npm run build | |
| - name: validate | |
| working-directory: ./_ci-page-money | |
| run: go run ../cmd/civitai app validate | |
| # Scaffold-currency guard — the "born-broken app" gate. Two rot-classes that | |
| # pins-vs-published + template-page-money both MISS: | |
| # | |
| # (a) ANTI-PATTERN gate — scaffold the SDK template, then scan the generated | |
| # source for a curated denylist of dead/superseded platform surfaces | |
| # (the REMOVED /api/v1/blocks/buzz route, the superseded shared-storage | |
| # REST route, the deprecated @civitai/blocks-cli). A scaffold can compile | |
| # and pass the pins guard yet still fetch a route that 404s at runtime — | |
| # exactly how playable-collections shipped 3 broken features. The denylist | |
| # is precise: it does NOT flag legitimately-REST unbridged endpoints | |
| # (catalog /models, /images; the /me viewer read; the /dev-token mint). | |
| # Logic + fixtures live in internal/antipattern (offline table test); this | |
| # runs it against the real `civitai app init` output. | |
| # | |
| # (b) LATEST-SDK build — install the ACTUAL newest published @civitai/app-sdk | |
| # + @civitai/blocks-react (not the pinned caret npm resolves to) and | |
| # re-typecheck + re-build. pins-vs-published catches "the pin can't admit | |
| # latest"; THIS catches "the template code breaks against latest" (a | |
| # removed/renamed SDK export). Network-dependent, so it mirrors the | |
| # pins-vs-published SKIP-on-unreachable contract: a reachability PROBE | |
| # gates the install/typecheck/build steps — an npm outage (network / DNS / | |
| # 5xx / 429) SKIPS them (job stays green, indistinguishable-from-real is | |
| # avoided) while a reachable registry runs them and FAILS on a genuine | |
| # code-breaks-against-latest signal. (A peer-dep incompat where the pin | |
| # can't admit latest is already caught by pins-vs-published, so treating an | |
| # install failure under a REACHABLE registry as real is correct.) The | |
| # offline anti-pattern scan is hermetic and always runs. | |
| scaffold-currency: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: true | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: scaffold page-money | |
| run: go run ./cmd/civitai app init "CI Currency Block" --dir "$GITHUB_WORKSPACE/_ci-currency" --template page-money | |
| # (a) Anti-pattern gate on the scaffolded app. | |
| # CIVITAI_ANTIPATTERN_SCAN_DIR MUST be ABSOLUTE: `go test` runs the test | |
| # binary with its CWD set to the package dir (internal/antipattern), not | |
| # the repo root, so a relative `./_ci-currency` would resolve under the | |
| # package dir and lstat-fail. github.workspace anchors it to where the | |
| # scaffold step wrote the app. | |
| - name: anti-pattern scan (scaffolded app) | |
| env: | |
| CIVITAI_ANTIPATTERN_SCAN_DIR: ${{ github.workspace }}/_ci-currency | |
| run: go test ./internal/antipattern -run TestScanDirFromEnv -count=1 -v | |
| # (b) Build against the LATEST published SDK, not just the pinned caret. | |
| # Probe npm first; if the registry is unreachable (network/DNS/5xx/429) | |
| # the build steps SKIP so a transient outage can't red the job (mirrors | |
| # the pins-vs-published skip-on-unreachable contract). A 200 on the | |
| # /latest metadata means "reachable" — a real SDK break then fails at | |
| # typecheck/build, not here. | |
| - name: probe npm reachability | |
| id: npmprobe | |
| run: | | |
| code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 15 \ | |
| https://registry.npmjs.org/@civitai/app-sdk/latest 2>/dev/null) || code=000 | |
| [ -z "$code" ] && code=000 | |
| if [ "$code" = "200" ]; then | |
| echo "reachable=true" >> "$GITHUB_OUTPUT" | |
| echo "npm registry reachable (HTTP $code) — running the latest-SDK build check" | |
| else | |
| echo "reachable=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice title=scaffold-currency::skipped latest-SDK build check — npm registry unreachable (HTTP $code); not a real failure, re-run later" | |
| fi | |
| - name: install (pinned) | |
| if: steps.npmprobe.outputs.reachable == 'true' | |
| working-directory: ./_ci-currency | |
| run: npm install --no-audit --no-fund | |
| - name: install @latest SDK | |
| if: steps.npmprobe.outputs.reachable == 'true' | |
| working-directory: ./_ci-currency | |
| run: npm install --no-audit --no-fund @civitai/app-sdk@latest @civitai/blocks-react@latest | |
| - name: typecheck against latest SDK | |
| if: steps.npmprobe.outputs.reachable == 'true' | |
| working-directory: ./_ci-currency | |
| run: npm run typecheck | |
| - name: build against latest SDK | |
| if: steps.npmprobe.outputs.reachable == 'true' | |
| working-directory: ./_ci-currency | |
| run: npm run build |