mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
codex/cloudplot-showcase-migration
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8714ab569b |
chore(showcase): apply oxfmt formatting across showcase scripts and shells
oxfmt --write normalized formatting on showcase scripts, the four shells, and the new oxlint rule; required for the repo-root oxfmt --check CI gate. |
||
|
|
7284ed3d84 |
fix(showcase): guard redeploy-summary download against legit no-redeploy + harden env lint rule
D1 — showcase_deploy.yml false-red fix
======================================
The build workflow legitimately uploads no `redeploy-summary` artifact when it ran
(push touched `showcase/**` so `paths:` matched) but `detect-changes` found no
buildable service, so `redeploy-staging` was skipped. The build still concludes
`success`, so `showcase_deploy.yml` fires on `workflow_run` and `resolve-matrix`
runs. `actions/download-artifact@v4` with `name:` HARD-FAILS on a missing
artifact, so the unguarded download was failing the job, and a downstream guard
that trips `enforce-redeploy-gate` on `resolve-matrix.result == 'failure'` was
flipping the workflow RED — a false-red on a routine showcase-docs/script change.
Add an artifact-existence pre-check using `actions/github-script` (pinned by SHA,
matching the existing repo convention) that lists the artifacts for
`workflow_run.id` via `actions: read` (already granted to `resolve-matrix`) and
sets `summary_present=true|false`. Gate the existing download step on
`summary_present == 'true'`. Keep NO `continue-on-error`, so the C1 property
holds: when the artifact exists but the download genuinely fails, the job still
fails loud and `enforce-redeploy-gate` correctly reds the workflow. When the
artifact is legitimately absent, the bash gate's existing `[ ! -f "$SUMMARY" ]`
branch no-ops (`redeploy_red=false`, `ok_services=""`) — nothing was
redeployed, so there is nothing to gate.
Updated the step comment block to enumerate the three distinct cases now
handled: workflow_dispatch (no download); workflow_run + artifact absent
(graceful skip); workflow_run + artifact present (download with fail-loud).
L1-L5 — env lint rule hardening
===============================
- L1: route the destructuring (VariableDeclarator/ObjectPattern) branch through
the shared `staticKeyName()` helper so the computed-string-key form
`const { ["NEXT_PUBLIC_X"]: y } = process.env` and the no-expression
template-literal form `const { [\`NEXT_PUBLIC_X\`]: y } = process.env` are
caught with the same parity as the bracket-member read.
- L2: unwrap a wrapping `ChainExpression` at the top of `isProcessEnv()` so
`process.env?.X` is matched robustly across parser flavors; corrected the
helper's doc comment to describe the actual semantics.
- L3: export `BANNED_KEYS` from the rule module and have the table-driven test
dynamically import the rule's own Set instead of hand-mirroring it — the
test set now cannot drift from the rule.
- L4: added override-scoping fixtures for `showcase/shell/src/**` and
`showcase/shell-dojo/src/**`; the `.oxlintrc.json` override list already
includes these, but the test now exercises them so an accidental drop is
caught.
- L5: expanded the file-header "Out of scope" doc list to include bulk-iteration
reads (`Object.keys/values/entries(process.env)`, for-in, spread
`{...process.env}`), rest-pattern destructuring, compound-assignment LHS, and
update operators. Documentation-only — the deliberate non-coverage is now
auditable.
Validation
==========
- RED→GREEN confirmed for L1 (two new destructuring computed-key tests) and L3
(dynamic `await import(...)` of BANNED_KEYS failed pre-fix with
"Rule module did not export a non-empty BANNED_KEYS Set", green after export).
- vitest: 38 passed (was 34 baseline + 4 new); aggregate-build-results 6 passed.
- Ruby promote suite: 87 runs, 251 assertions, 0 failures (unchanged).
- python3 yaml.safe_load: showcase_deploy.yml + showcase_build.yml +
showcase_promote.yml all parse OK.
- actionlint: zero NEW findings on the changed file. The pre-existing
showcase_build.yml SC2086/SC2129/runner-label findings are identical on the
integration baseline (unchanged by this commit).
|
||
|
|
a6239cde11 |
fix(showcase): close deploy-gate false-greens and broaden public-env lint rule
Seven-agent CR surfaced correctness defects in the build/deploy/promote pipeline and in the no-public-env-shell-read oxlint rule. This commit closes the false-green paths and broadens lint coverage. Workflow fixes: - showcase_deploy.yml: drop `continue-on-error: true` on the redeploy-summary artifact download. The dispatch path is already guarded by the `if: workflow_run` clause, so the bash "no summary" branch handles legitimate manual dispatches. A genuine workflow_run download failure must now fail loud instead of silently widening verify to the full service set against stale `:latest`. - showcase_build.yml: redeploy-staging now intersects the build matrix with the aggregator success set (`needs.aggregate-build-results.outputs.results`, status == "success") before producing the redeploy CSV. Failed/skipped slots no longer get redeployed (which would just re-pull stale `:latest` and look healthy). - showcase_build.yml: `notify-all-builds-failed` now additionally requires `needs.build.result == 'failure'` so it doesn't Slack-spam when the build job was SKIPPED (verify-image-refs upstream failure). - showcase_build.yml: `notify` now lists [build, aggregate-build-results, redeploy-staging] in `needs:` so aggregator/redeploy failures still emit a Slack signal. `if: failure()` still skips when none of the needs failed. - showcase_build.yml: `set -euo pipefail` on the Prepare build args step so a transient $GITHUB_OUTPUT write failure can't ship images without COMMIT_SHA/BRANCH baked in. - showcase_deploy.yml: `enforce-redeploy-gate` now also trips on a resolve-matrix failure (`needs.resolve-matrix.result == 'failure'`) so an upstream crash that leaves `redeploy_red` empty can't bypass the gate. - Doc-comment accuracy: drop stale `(PR #5093)` reference; correct the env-IDs source-of-truth comment; document the optional `skip_build` field in ALL_SERVICES; clarify that health_path is informational and verify uses per-service drivers; add the missing `resolve-targets` step 0 to the promote workflow's "Order:" header. Aggregator fix (RED-GREEN): - aggregate-build-results.ts: throw on zero slot dirs. The job is gated upstream on has_changes == 'true', so zero slot dirs is a broken artifact download, not a legitimate empty build set. Silently emitting any_success=false + results=[] is indistinguishable from "all builds failed" and lets the deploy workflow fall back to probing the full service set against stale `:latest`. Refuse the ambiguity. - aggregate-build-results.test.ts: existing empty-INPUT_DIR test was updated to assert the throw (was: return []). Oxlint rule (RED-GREEN): - no-public-env-shell-read.mjs: handle destructuring reads (const { NEXT_PUBLIC_X } = process.env and aliased form), template-literal computed keys (process.env[\`NEXT_PUBLIC_X\`]), and explicitly skip assignment-LHS / `delete` targets (writes are not reads). Optional chaining already worked through the existing MemberExpression path. Aliasing (`const e = process.env; e.X`) is intentionally documented as out of scope (needs scope tracking). Description sharpened to say the rule guards a specific banned-key set, not all NEXT_PUBLIC_* reads. - .oxlintrc.json: tighten the off-override glob from `showcase/**/*runtime-config*` to `showcase/**/lib/runtime-config*.{ts,tsx}` so it only silences the intended implementation files, not arbitrary paths containing that substring. - lint-rule-no-public-env.test.ts: rewritten as table-driven coverage of every BANNED_KEYS entry (dotted + bracket-string forms), every ALLOWED key (asserting non-firing), all new variants from the rule expansion, the assignment/delete non-fire cases, and override scoping (runtime-config exempt; packages exempt; shell-tree non-runtime-config flagged). Validation: - actionlint on all three workflows: 8 pre-existing findings (depot label, pre-existing SC2086 infos in untouched steps); my edits add zero. - python3 yaml.safe_load: all three workflows OK. - vitest aggregate-build-results.test.ts: 6/6 pass (incl. new throw test). - vitest lint-rule-no-public-env.test.ts: 34/34 pass. - vitest full showcase/scripts suite: 1654/1654 pass across 46 files. - ruby showcase/bin/spec/all_tests.rb: 87 runs, 0 failures. - Intersection jq proof (matrix a,b,c × success a,c) → "a,c"; all-failed → ""; skipped status excluded. |
||
|
|
73e4d29443 |
feat(showcase): add oxlint guard against NEXT_PUBLIC_* shell reads
Plan-B / Option-B migration moved every shell URL/analytics key off the
build-time NEXT_PUBLIC_* env channel and onto runtime config served via
__SHOWCASE_CONFIG__ + getRuntimeConfig(). To prevent a silent regression
where a future change reintroduces a direct process.env.NEXT_PUBLIC_*
read in shell code (which would re-freeze the value at build time and
break no-rebuild env switching), add a focused lint rule.
The rule (copilotkit/no-public-env-shell-read) is implemented as a
custom oxlint JS plugin rule in the existing copilotkit plugin and
enabled under shell-scoped overrides in .oxlintrc.json:
- Errors on process.env.NEXT_PUBLIC_<URL/ANALYTICS> reads in:
showcase/shell-dashboard/src/**, showcase/shell-docs/src/**,
showcase/shell/src/**, showcase/shell-dojo/src/**
- Banned keys: POCKETBASE_URL, SHELL_URL, BASE_URL, OPS_BASE_URL,
INTELLIGENCE_SIGNUP_URL, POSTHOG_KEY, POSTHOG_HOST, SCARF_PIXEL_ID,
GOOGLE_ANALYTICS_TRACKING_ID, REB2B_KEY, REO_KEY
- Intentionally allowed (NOT banned): NEXT_PUBLIC_COMMIT_SHA and
NEXT_PUBLIC_BRANCH (build-stamped artifact identifiers per B10/B11)
and NEXT_PUBLIC_LOCAL_BACKENDS (computed from shared/local-ports.json
at build, local-dev only).
- Excluded files (rule disabled via a follow-up override): MDX content
under shell-docs/src/content/**, runtime-config implementation files,
and *.test.{ts,tsx} / *.spec.{ts,tsx}. oxlint does not support
excludedFiles inside an override block, so the exclusion is expressed
as a later override that sets the rule to off.
Plan-B originally targeted oxlint's eslint/no-restricted-syntax with an
AST-selector regex. oxlint 1.x does not implement that rule (only
no-restricted-globals / no-restricted-imports), so the equivalent guard
is realized as a small custom rule in the existing copilotkit JS plugin
(meta.name=copilotkit), reusing the same plugin loader the repo already
has for require-cpk-prefix and no-single-arg-zod-record.
Verification (red-green): the rule fires on a fixture containing
process.env.NEXT_PUBLIC_POCKETBASE_URL and does NOT fire on a fixture
containing process.env.NEXT_PUBLIC_COMMIT_SHA. Test pins the config via
-c so it works inside git worktrees nested under .claude/worktrees/
where oxlint's automatic upward config search can miss the worktree's
own .oxlintrc.json.
All four shells lint clean: 0 errors of the new rule across
shell-dashboard (114 files), shell-docs (137), shell (29), shell-dojo (6).
|
||
|
|
70f54a8403 |
fix: use two-argument z.record for Zod 4 compatibility, add lint guard
Zod 4 made the key schema mandatory for z.record, so the single-argument z.record(valueType) form is a compile-time error (TS2554) when built against Zod 4. @copilotkit/react-core declares zod ">=3.0.0", so downstream apps on Zod 4 are affected; runtime parsing is unaffected under both majors. - react-core + vue MCPAppsActivityContentSchema: toolInput now uses the two-argument z.record(z.string(), z.unknown()) form - react-core defineToolCallRenderer test: same fix for a metadata schema - add a toolInput field-contract test (round-trips mixed value types) - add copilotkit/no-single-arg-zod-record oxlint rule (autofix), enabled as error for packages/**; the incompatibility is type-level, so no runtime test can guard it while the workspace lockfile pins Zod 3 Closes #4295 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
79ce60c580 |
chore: migrate from eslint+prettier to oxlint+oxfmt
Replace eslint and prettier with oxlint and oxfmt for faster linting and formatting across the monorepo. Remove all eslint and prettier configs, dependencies, and related packages. Add .oxlintrc.json and .oxfmtrc.json for the new tooling. Update CI workflows and lefthook hooks accordingly. Reformat codebase with oxfmt. https://claude.ai/code/session_01GMkSf29p78HuMR1mbXn8He |