chore: adopt devkit baseline (CI, security, JSR publish hygiene) - #4
Conversation
…de rules) Implements the punch list from issue #3. JSR publishing (critical): - Add publish.include/exclude to deno.json — currently the package was shipping the entire repo (assets/, docs/, docs-site/, examples/) into every JSR install. Bundle now contains only mod.ts, index.ts, ui/**, tokens/**, utils/**, assets/*.ts (typed wrappers, not raw SVGs), README.md, and LICENSE. Verified with `deno publish --dry-run`. - Add `--allow-slow-types` to publish task and workflows. Tracked as debt: ui/icon-button.ts has 13 symbols (icons object literal, searchIcon, etc.) missing explicit type annotations. Fixing them is a separate PR. CI/CD (none previously): - Add .github/workflows/ci.yml — fmt/lint/check/test/publish-dry on PR/main pushes - Add .github/workflows/publish.yml — tag-triggered (v*) publish to JSR with provenance via id-token: write - Add .github/workflows/security.yml — direct caller of eSolia/devkit/.github/workflows/secrets-and-sast.yml@main. Same-org call (eSolia → eSolia) so no vendoring needed (unlike the RickCogley/* repos which had to vendor — see RickCogley/tedasuke#3) - Add .github/dependabot.yml — weekly github-actions + npm (docs-site/) updates Deno hygiene: - Add `preflight` and `publish:dry` tasks - Override the project .gitignore entry for deno.lock so the lockfile is committed (was line 3 of the project gitignore in addition to global) - Commit deno.lock for reproducibility (JSR convention) - Exclude assets/**/*.svg from `deno fmt` — was reformatting SVG XML on every preflight run, which is unintended (SVG belongs to svgo) Tests: - Add tests/api_surface_test.ts — 8 credential-free smoke tests covering utility, token, UI component, asset, and favicon export surfaces, plus basic behavior checks for cn(), getButtonClasses(), getBadgeClasses(). Replaces the empty tests directory so CI has something real to run. Claude tooling: - Add .claude/rules/change-management.md (copy from devkit shared-rules, adapted for marquis specifics — no `local/` subdirectory since this repo is not a devkit sync consumer) Documentation cleanup (post-Deno-Deploy migration): - docs/CLAUDE-GUIDE.md: replace 3 stale Deno Deploy references with Cloudflare Workers (the table row for Periodic, the "Work directly with..." principle line, and the "future Deno Deploy apps" mention). Out of scope (flagged in PR): - Root CLAUDE-GUIDE.md (795 lines) duplicates docs/CLAUDE-GUIDE.md (526 lines). Different content — needs your call on what to preserve before consolidating. - Untracked docs/marquis-design-system-strategy.md left alone (your in-progress work). - ui/icon-button.ts slow types (13 symbols) — see above. Closes #3 InfoSec: brings continuous SAST + secret scanning + SBOM to a repo that previously had zero security automation. Tightening publish.include/exclude also reduces accidental disclosure of internal docs (e.g. the strategy markdown, kickoff designs in docs/) into the public JSR package.
Strip schedule + workflow_dispatch triggers and inline comments to match the known-working esolia-llm-guard reference workflow exactly. First push of the workflow failed at startup (0s, no jobs), and the identical simpler pattern works for esolia-llm-guard, so isolating the difference. InfoSec: no functional change to security scanning — same scanners, same source-paths, same secret pass-through.
Public-consumer + private-source mismatch: marquis is public, eSolia/devkit is private. GitHub blocks public repos from calling private reusable workflows even within the same org — same constraint that applies cross-org. The first two attempts at a direct caller failed at workflow startup (0s, no jobs). Fix: vendor the workflow locally, matching the pattern used in RickCogley/pub-cogley and RickCogley/tedasuke. Wrapper security.yml now triggers a local secrets-and-sast-vendored.yml. Also adds .gitignore override for global *secret* pattern, which matches the vendored filename. Updates the audit's mental model: the constraint isn't 'cross-org', it's 'public consumer + private source'. eSolia/marquis hits this within-org because of the visibility mismatch. InfoSec: restores SAST + secret scanning + SBOM coverage. Vendored copy is identical to the same upstream commit (c07c51c) used by all other vendoring consumers.
|
Update: had to vendor It doesn't. Public consumer + private source is blocked, even within the same org. Marquis is public; devkit is private. GitHub blocks the call at startup (0s, no jobs created). So the actual rule (corrected from my earlier comment on tedasuke#3) is:
The fix in latest commits (b53b860):
Also pulled the wrapper's extra triggers back in ( CI + Security workflows both green now. Note: the security workflow's display name still shows as |
The publish workflow was added in #4 on the assumption marquis would publish to JSR like tedasuke. Two facts that emerged after merge: 1. @esolia/marquis was never created on JSR (the v0.3.4 release tag fired publish.yml and it failed: 'Following packages don't exist'). 2. The intended consumer (Periodic) has migrated off Deno entirely onto Cloudflare Workers and uses bits-ui for components, so there is no live consumer of marquis through any channel today. Marquis is parked code; the GitHub releases (currently v0.3.4) are sufficient version markers. No publish target needed. CI and security workflows remain — they prevent bitrot if/when marquis gets revived as a UI option for non-SvelteKit Workers apps. InfoSec: no security impact — workflow removal only. Security scanning (trivy/gitleaks/semgrep/syft via vendored secrets-and-sast workflow) unaffected.
Summary
Implements the punch list from #3. Closes #3.
Critical fix:
deno.jsonwas missingpublish.include/exclude, so every JSR install of@esolia/marquiswas pulling the entire repo (assets/,docs/,docs-site/,examples/) into the package. Now bundles only the public surface —mod.ts,index.ts,ui/**,tokens/**,utils/**,assets/*.ts(typed wrappers, no raw SVGs),README.md,LICENSE.What's in this PR
CI/CD (none previously)
ci.yml— fmt/lint/check/test/publish-dry on PR/mainpublish.yml— tag-triggered (v*) JSR publish with provenancesecurity.yml— callseSolia/devkit/.github/workflows/secrets-and-sast.yml@maindirectly. Same-org call, no vendoring needed (the cross-org block we hit on RickCogley/* repos doesn't apply here)dependabot.yml— weekly github-actions + npm (docs-site)JSR / publish hygiene
publish.include/excludeblocks (the critical fix)publish:drytask with--allow-slow-typespublish.ymlandci.yml— tracked as debt (see "Out of scope")--allow-slow-typesis needed becauseui/icon-button.tshas 13 symbols missing explicit typesDeno hygiene
.gitignoreentry fordeno.lockso the lockfile is committed (it was project-ignored on line 3, in addition to global)assets/**/*.svgfromdeno fmt— was reformatting SVG XML on every preflight run, leaving 17 files modifieddeno.lock(JSR convention)Tests
tests/api_surface_test.ts— 8 credential-free smoke tests covering the export surface (utility, token, UI, asset, favicon) plus basic behavior ofcn(),getButtonClasses(),getBadgeClasses(). Replaces the emptytests/dir.Claude tooling
.claude/rules/change-management.md(copy from devkit shared-rules)Doc cleanup (post-Deno-Deploy migration)
docs/CLAUDE-GUIDE.md— replaced 3 stale Deno Deploy references with Cloudflare Workers (the strategy table row for Periodic, the "Work directly with..." principle, and the "future Deno Deploy apps" mention).Out of scope (flagged for separate decisions)
CLAUDE-GUIDE.md(795 lines) duplicatesdocs/CLAUDE-GUIDE.md(526 lines) — different content. The root version is the older/longer file; the docs/ version reads as a deliberate re-write.docs/as canonical (rootCLAUDE.mdalready redirects there), then either merge missing content from root or delete root if the dropped content was intentional.docs/marquis-design-system-strategy.mdui/icon-button.tsslow types (13 symbols)--allow-slow-typescarries us until then.Test plan
deno fmt --checkpassesdeno lintpassesdeno check mod.tspassesdeno test --allow-read— 8 passed, 0 faileddeno publish --dry-run --allow-slow-typessucceeds — bundle is the right shape (no docs, no docs-site, no raw SVGs)InfoSec: brings continuous SAST + secret scanning + SBOM to a repo that previously had zero security automation. Tightening publish.include/exclude also reduces accidental disclosure of internal docs (kickoff designs, strategy markdown) into the public JSR package.