Skip to content

chore(preview): fix pre-existing CI drift (web format + i18n types + oxlint warnings)#23

Merged
JOBYINC merged 2 commits into
previewfrom
chore/preview-hygiene
May 21, 2026
Merged

chore(preview): fix pre-existing CI drift (web format + i18n types + oxlint warnings)#23
JOBYINC merged 2 commits into
previewfrom
chore/preview-hygiene

Conversation

@JOBYINC
Copy link
Copy Markdown
Owner

@JOBYINC JOBYINC commented May 21, 2026

Why

origin/preview had three categories of pre-existing CI drift that silently blocked any PR touching apps/web or @plane/i18n from going green — surfaced while trying to land PR #21 (sort by custom field):

  1. check:format failed on 5 unformatted web files (none owned by a single PR; left-over whitespace drift).
  2. check:types failed in @plane/i18n on a import.meta.env access with no ImportMeta.env type declaration anywhere in the repo.
  3. pre-commit (lint-staged) hook failed on the same 5 files: CI tolerates 11957 oxlint warnings on web (--max-warnings), but the pre-commit hook uses --deny-warnings (0 tolerance). The moment any author runs oxfmt --write on these files, lint-staged exposes 16 pre-existing warnings and refuses to commit.

PR #22 (docs only) passed cleanly because turbo --affected correctly skipped web/i18n. Any other PR is blocked.

What

Fix 1 — oxfmt --write on 5 web files

Pure whitespace / line-wrapping. No behavior change.

apps/web/app/(all)/lark-quick-create/page.tsx
apps/web/ce/components/automations/root.tsx
apps/web/core/components/profile/overview/workload.tsx
apps/web/core/components/workspace/settings/lark-invite-modal.tsx
apps/web/core/services/project/project-automation.service.ts

Fix 2 — import.meta.env type in @plane/i18n

The package has no vite-env.d.ts and this is the only import.meta.env usage in it. Minimal inline typed cast — single line, no new file, no any:

// before
const envDefault = (import.meta.env?.VITE_DEFAULT_LANGUAGE ?? "") as string;

// after
const viteMeta = import.meta as { env?: { VITE_DEFAULT_LANGUAGE?: string } };
const envDefault = (viteMeta.env?.VITE_DEFAULT_LANGUAGE ?? "") as string;

Fix 3 — clear 16 pre-existing oxlint warnings exposed in fix 1

Categorized:

Category # Fix
Unused vars 8 Underscore-prefix (the rule's own suggested fix)
s.onload = … 2 s.addEventListener("load", …) (mechanical)
await inside sequential CDN-fallback loop 2 // eslint-disable-next-line no-await-in-loop + reason — Promise.all would change behavior (parallelize)
key={idx} on local-state lists (no stable id, no reorder UI) 2 // eslint-disable-next-line react/no-array-index-key + reason
<a> with no href on a non-link wrapper 1 Replaced with <div> (closest non-anchor element, zero behavior change)
.then() missing explicit return 1 Added return;

Total: +228 / −314 lines, of which most are whitespace re-wrap. Net real change is small.

Test plan

Marcus Cheung added 2 commits May 21, 2026 13:25
…+ oxlint warnings

Two pre-existing problems on preview were blocking any PR touching apps/web
or @plane/i18n from going green:

1. oxfmt --check flagged 5 web files as unformatted drift (none owned by a
   single PR). Ran oxfmt --write on:
     - apps/web/app/(all)/lark-quick-create/page.tsx
     - apps/web/ce/components/automations/root.tsx
     - apps/web/core/components/profile/overview/workload.tsx
     - apps/web/core/components/workspace/settings/lark-invite-modal.tsx
     - apps/web/core/services/project/project-automation.service.ts
   Pure whitespace / line-wrapping; no behavior change.

2. @plane/i18n tsc --noEmit failed at src/store/index.ts:68 with
   "Property 'env' does not exist on type 'ImportMeta'". The repo has no
   vite-env.d.ts ambient declaration anywhere, and this is the only
   import.meta.env usage in the package. Inline cast to a minimal typed
   shape — single line, no new file, no `any`.

3. The 5 web files also had 16 pre-existing oxlint warnings flagged the
   moment lint-staged ran on them. CI tolerates 11957 warnings on web, but
   the pre-commit hook uses --deny-warnings (0 tolerance). Fixed in place:
     - 8 unused vars → underscore-prefixed (the rule's own suggested fix)
     - 2 s.onload= / s.onerror= → addEventListener (mechanical)
     - 2 await-in-loop (sequential SDK fallback) → eslint-disable-next-line
       with reason ("intentional sequential CDN fallback")
     - 2 key={idx} on local-state lists with no stable id →
       eslint-disable-next-line with reason
     - 1 <a> with no href on a non-link wrapper → replaced with <div>
       (closest non-anchor element)
     - 1 .then() missing return → added explicit `return;`

Effect: any PR touching apps/web or @plane/i18n will pass check:format,
check:types, and pre-commit lint-staged again. Unblocks PR #21.
… i18n no longer short-circuits tsc

After the i18n fix in the previous commit, tsc no longer fails fast on
@plane/i18n, so check:types finally runs against apps/web — and surfaces
11 type errors that have been sitting on preview unnoticed:

1. Button variant="neutral-primary" (5 occurrences). The propel Button
   variant union was narrowed to remove neutral-primary; consumers were
   never updated. Closest semantic = "secondary" (bordered neutral button
   used for lower-emphasis actions next to a "primary" Add/Submit).
     - apps/web/.../members/page.tsx (2x: "Sync from Lark", "Invite from Lark")
     - apps/web/.../lark-invite-modal.tsx (1x: Cancel)
     - apps/web/.../lark-quick-create/page.tsx (1x: Cancel)
   Plus the 2nd "Invite from Lark" instance.

2. Button size="md" (2 occurrences). Same story for size — "md" was removed,
   the previous default-equivalent is "base".
     - apps/web/.../lark-invite-modal.tsx (Cancel + Invite N members)

3. `catch (err: unknown)` chains that produce `unknown | string` instead of
   `string` (2 occurrences). The pattern
     const message = (err && typeof err === "object" && "error" in err && (err as {error?: string}).error) || "fallback"
   returns `unknown | string` (because `err && X` returns `err` when `err` is
   falsy, and `err` is `unknown`). Rewrote with explicit narrowing + a
   `string` accumulator. Behavior unchanged.
     - apps/web/.../members/page.tsx (line 174-178)
     - apps/web/.../lark-invite-modal.tsx (line 120-124)

4. TLarkContact verbatim-import error (1 occurrence). TypeScript 5+ with
   verbatimModuleSyntax requires `import type` for type-only symbols.
     - apps/web/.../lark-invite-modal.tsx (line 14): split into
       `import type { TLarkContact }` and `import { WorkspaceService }`.

5. MemberDropdown multiple={false} prop mismatch (1 issue, 2 lines).
   The MemberDropdownProps union narrows by `multiple`:
     multiple: false  → value: string|null, onChange: (string|null)=>void
     multiple: true   → value: string[],    onChange: (string[])=>void
   lark-quick-create was passing `value={[id]}` and `onChange: (ids: string[])`
   under `multiple={false}`, which only the `true` branch accepts. Switched
   to the correct `multiple: false` shape.
     - apps/web/.../lark-quick-create/page.tsx (line 658-659)

6. fetchWorkspaceMembers callback signature mismatch (1 occurrence). The
   store returns `IWorkspaceMember[]` but the call site treats each member
   as a defensive `Record<string, unknown>` (member-object vs flat — depends
   on API shape evolution). Added an explicit boundary cast and let `.map`
   infer the parameter type. Behavior unchanged.
     - apps/web/.../lark-quick-create/page.tsx (line 391-392)

apps/web `tsc --noEmit` now passes (exit 0), apps/web `oxlint
--deny-warnings` passes on the 3 modified files, and `oxfmt --check` passes.
@JOBYINC JOBYINC merged commit 7967b8a into preview May 21, 2026
8 checks passed
@JOBYINC JOBYINC deleted the chore/preview-hygiene branch May 21, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant