Skip to content

chore: auto-rebuild all generated artifacts on commit + CI - #211

Merged
jackgranatowski merged 4 commits into
mainfrom
claude/laughing-noether-0V06F
Jun 3, 2026
Merged

chore: auto-rebuild all generated artifacts on commit + CI#211
jackgranatowski merged 4 commits into
mainfrom
claude/laughing-noether-0V06F

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds scripts/artifacts.json — a single manifest mapping source globs → build command → outputs for every generated/compiled file in the repo
  • Adds scripts/check-artifacts.js — reads the manifest and either auto-rebuilds + stages (pre-commit, --fix) or rebuilds + asserts git diff clean (CI, --check)
  • Rewrites .githooks/pre-commit to call the script instead of enumerating artifacts inline
  • Replaces the three separate *-freshness CI jobs (docs-freshness, editor-app-freshness, admin-app-freshness) with a single artifacts-freshness job

How to add a new build artifact going forward

Add one entry to scripts/artifacts.json. Nothing else needs to change — the pre-commit hook and CI pick it up automatically.

{
  "name": "my-new-thing",
  "srcGlobs": ["path/to/src/"],
  "cwd": "path/to/build/dir",
  "cmd": "npm ci --silent && npm run build --silent",
  "outputs": ["path/to/output.js"]
}

Artifacts covered

Artifact Source glob
docs/tokens.md, docs/classes.md, inventory.json, classes-hints.json core/, optional/
assets/editor-app/app.js+css editor-app/src/
assets/admin-app/app.js+css admin-app/src/

Test plan

  • Stage a file under editor-app/src/ and commit — confirm the hook auto-rebuilds and stages app.js/app.css
  • Stage a file under core/ and commit — confirm docs/inventory files are regenerated and staged
  • Confirm artifacts-freshness CI job passes on this PR
  • Confirm the three old freshness jobs are gone from CI

https://claude.ai/code/session_01MR5eh7i7GRVpvudPrCjm2w


Generated by Claude Code

Summary by CodeRabbit

  • Chores
    • Refactored artifact verification system to automate freshness checks during development and CI.
    • Introduced centralized artifact manifest for consistent build configuration and validation.
    • Simplified pre-commit workflow by removing bundle rebuilds in favor of targeted artifact checks.

claude added 3 commits June 3, 2026 18:35
When any file under editor-app/src/ is staged, the pre-commit hook
now runs npm ci + npm run build and stages the updated app.js/app.css
automatically — same pattern as the existing dist-bundle rebuild.

https://claude.ai/code/session_01MR5eh7i7GRVpvudPrCjm2w
Pre-commit hook now covers admin-app (same pattern as editor-app)
and regenerates docs/inventory when CSS sources change. CI gets a
matching admin-app-freshness job. Every committed build artifact now
has both a local auto-rebuild guard and a CI staleness check.

https://claude.ai/code/session_01MR5eh7i7GRVpvudPrCjm2w
scripts/artifacts.json is now the one place to register a build
artifact (source glob → build command → outputs). Both the pre-commit
hook and CI read from it via scripts/check-artifacts.js:

  --fix   (hook) rebuilds only affected artifacts and re-stages outputs
  --check (CI)   rebuilds everything and fails on any stale output

Replaces the three separate *-freshness CI jobs and the inline
per-artifact logic in the pre-commit hook.

https://claude.ai/code/session_01MR5eh7i7GRVpvudPrCjm2w
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 51 minutes and 22 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9dbf79d4-f249-4306-b9e0-f174c2b8372c

📥 Commits

Reviewing files that changed from the base of the PR and between 0924a11 and 7019136.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • scripts/artifacts.json
  • scripts/check-artifacts.js
📝 Walkthrough

Walkthrough

This PR introduces a centralized artifact verification system that replaces ad-hoc bundle rebuilding with a declarative manifest and script. The new scripts/check-artifacts.js supports two modes: --fix mode stages changed artifacts during pre-commit; --check mode verifies artifact freshness in CI. The manifest defines three build tasks with source globs, build commands, and expected outputs.

Changes

Artifact Verification System

Layer / File(s) Summary
Artifact manifest and verification script
scripts/artifacts.json, scripts/check-artifacts.js
Introduces scripts/artifacts.json defining three artifact tasks (CSS/docs, editor-app, admin-app) with source globs, build commands, and output paths. scripts/check-artifacts.js implements CLI entry point, git state helpers (run, git, isTracked), and --fix mode (rebuild staged artifacts, stage outputs) and --check mode (rebuild all, verify no git diff).
Pre-commit hook integration
.githooks/pre-commit
Updates hook to run scripts/check-artifacts.js --fix for artifact preparation, replacing previous scripts/bundle.js rebuild-and-conditional-stage logic.
CI workflow integration
.github/workflows/ci.yml
Replaces docs-focused git diff --exit-code checks with unified scripts/check-artifacts.js --check verification in the build job, and adds artifacts-freshness step group label.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing centralized artifact management with auto-rebuild on commit and CI verification.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/laughing-noether-0V06F

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
.github/workflows/ci.yml (1)

41-54: ⚡ Quick win

Add a least-privilege permissions block to the new job.

The new artifacts-freshness job inherits the workflow's default token permissions (flagged by zizmor as overly broad). It only needs read access to the checkout.

🔒 Proposed change
   artifacts-freshness:
     name: Verify all generated artifacts
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 41 - 54, The new artifacts-freshness
job is inheriting broad default token permissions; add a least-privilege
permissions block on the artifacts-freshness job to restrict the GITHUB_TOKEN to
read-only for repository contents (e.g., set permissions: contents: read) so the
job only has checkout/read access; locate the job named artifacts-freshness and
add the permissions entry directly under it.
scripts/check-artifacts.js (1)

31-33: 💤 Low value

Static-analysis command-injection flags here are false positives, but quote paths for space-safety.

cmd/outputs come from the version-controlled manifest, so there's no untrusted input — the OpenGrep exec-js findings on lines 24/28 can be dismissed. However, git add ${out} / git diff ${out} break on any output path containing spaces or shell metacharacters. Switching git calls to execFileSync('git', [...args]) removes both the static-analysis noise and the quoting hazard.

Also applies to: 45-47

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-artifacts.js` around lines 31 - 33, The git invocations
currently build shell commands with interpolated paths (see isTracked calling
git(`ls-files --error-unmatch ${path}`) and the uses that run git add ${out} /
git diff ${out}), which breaks on paths with spaces and triggers
command-injection warnings; change these to use child_process.execFileSync with
the git binary and argument arrays (e.g., execFileSync('git', ['ls-files',
'--error-unmatch', path])) for isTracked and similarly replace the git add/diff
calls with execFileSync('git', ['add', out]) and execFileSync('git', ['diff',
'--', out]) so paths are passed as separate args and static-analysis issues are
resolved.
scripts/artifacts.json (1)

17-17: 🏗️ Heavy lift

npm ci in the build cmd makes pre-commit (--fix) very slow.

In --fix mode this cmd runs on every commit that touches editor-app/src/ (or admin-app/src/). npm ci wipes and reinstalls node_modules from scratch, adding tens of seconds to minutes to each commit. CI needs npm ci, but the hook generally has deps installed already.

Consider a mode-aware command (e.g. npm ci only in --check, plain npm run build in --fix), or splitting the install step out of the rebuild cmd.

Also applies to: 27-27

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/artifacts.json` at line 17, The build cmd currently uses "npm ci
--silent && npm run build --silent" which causes pre-commit `--fix` to reinstall
node_modules every commit; update the "cmd" entries (the JSON key "cmd" that
currently contains that string for the editor/admin artifacts) to be mode-aware
or split install from build: run `npm ci` only when running in CI/`--check` mode
(or when no node_modules exist) and run just `npm run build --silent` for
`--fix`/local hooks, or separate into two artifact steps (one for install used
by CI, one for rebuild used by hooks) so pre-commit no longer calls `npm ci` on
every commit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check-artifacts.js`:
- Line 39: The current check uses prefix matching (artifact.srcGlobs.some(glob
=> [...staged].some(f => f.startsWith(glob))) ) so patterns in artifact.srcGlobs
(e.g., core/**/*.css) won't match; replace the startsWith logic with real glob
matching: import a glob matcher (e.g., picomatch or minimatch), compile each
pattern from artifact.srcGlobs into a matcher, and compute triggered as
artifact.srcGlobs.some(glob => [...staged].some(f => matcher(glob)(f))) or
equivalent API for the chosen library; update any references to srcGlobs
semantics (or rename to srcPrefixes if you prefer the prefix behavior) and
ensure bundle.js remains the source of truth for glob semantics.
- Around line 14-21: The script scripts/check-artifacts.js uses ESM features
(top-level import and import.meta.url) but the repo lacks "type":"module", so
either convert the file to CommonJS (replace import/ fileURLToPath usage with
require and __dirname) or declare "type":"module" in package.json so node can
run it as ESM; also adjust the git-staging logic that currently uses git
ls-files (which only returns tracked files) so newly generated/untracked outputs
are staged: stop filtering with git ls-files and instead run git add directly on
the generated output paths (or combine git ls-files with git ls-files --others
--exclude-standard to include untracked), and update the header text from “Skips
gitignored outputs silently” to “Skips untracked outputs silently” (references:
the top-level imports and import.meta.url usage, the mode variable checking
'--check', and the git staging code that uses git ls-files).

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 41-54: The new artifacts-freshness job is inheriting broad default
token permissions; add a least-privilege permissions block on the
artifacts-freshness job to restrict the GITHUB_TOKEN to read-only for repository
contents (e.g., set permissions: contents: read) so the job only has
checkout/read access; locate the job named artifacts-freshness and add the
permissions entry directly under it.

In `@scripts/artifacts.json`:
- Line 17: The build cmd currently uses "npm ci --silent && npm run build
--silent" which causes pre-commit `--fix` to reinstall node_modules every
commit; update the "cmd" entries (the JSON key "cmd" that currently contains
that string for the editor/admin artifacts) to be mode-aware or split install
from build: run `npm ci` only when running in CI/`--check` mode (or when no
node_modules exist) and run just `npm run build --silent` for `--fix`/local
hooks, or separate into two artifact steps (one for install used by CI, one for
rebuild used by hooks) so pre-commit no longer calls `npm ci` on every commit.

In `@scripts/check-artifacts.js`:
- Around line 31-33: The git invocations currently build shell commands with
interpolated paths (see isTracked calling git(`ls-files --error-unmatch
${path}`) and the uses that run git add ${out} / git diff ${out}), which breaks
on paths with spaces and triggers command-injection warnings; change these to
use child_process.execFileSync with the git binary and argument arrays (e.g.,
execFileSync('git', ['ls-files', '--error-unmatch', path])) for isTracked and
similarly replace the git add/diff calls with execFileSync('git', ['add', out])
and execFileSync('git', ['diff', '--', out]) so paths are passed as separate
args and static-analysis issues are resolved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 461ede9d-275d-4018-98b9-ef0bd29fd40b

📥 Commits

Reviewing files that changed from the base of the PR and between 2450efe and 0924a11.

📒 Files selected for processing (4)
  • .githooks/pre-commit
  • .github/workflows/ci.yml
  • scripts/artifacts.json
  • scripts/check-artifacts.js

Comment thread scripts/check-artifacts.js Outdated
Comment on lines +14 to +21
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const artifacts = JSON.parse(readFileSync(resolve(root, 'scripts/artifacts.json'), 'utf8'));
const mode = process.argv.includes('--check') ? 'check' : 'fix';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm the package.json governing scripts/ declares ESM.
fd -t f 'package.json' -d 2 -x sh -c 'echo "== {} =="; jq -r ".type // \"(no type → commonjs)\"" "{}"'

Repository: codeslash-dev/SLASHED

Length of output: 107


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Find any package.json files that could affect module type resolution
echo "## package.json files"
fd -t f 'package.json' -d 5 > /tmp/pjs.txt
cat /tmp/pjs.txt

# Show all "type" values (if jq exists)
echo
echo "## package.json: .type"
while IFS= read -r p; do
  echo "== $p =="
  jq -r '.type // "(no type → commonjs)"' "$p" 2>/dev/null || echo "(jq missing or parse error)"
  echo
done < /tmp/pjs.txt

# 2) Locate invocations of scripts/check-artifacts.js
echo "## invocations of scripts/check-artifacts.js"
rg -n --hidden --glob '!node_modules/**' 'check-artifacts\.js' .

# 3) Inspect the target script
echo
echo "## scripts/check-artifacts.js (top)"
sed -n '1,120p' scripts/check-artifacts.js

Repository: codeslash-dev/SLASHED

Length of output: 2604


Set correct Node module mode for scripts/check-artifacts.js (ESM import/meta)

  • The file uses top-level ESM (import ... / import.meta.url) but the repo root package.json has no "type": "module", and CI/hook invoke it via node scripts/check-artifacts.js ...—so it will fail with SyntaxError: Cannot use import statement outside a module.
  • In --fix mode it only git adds outputs that are already tracked (git ls-files ...), so newly generated/untracked outputs won’t be staged; the header text “Skips gitignored outputs silently” is misleading (should describe “skips untracked outputs”).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-artifacts.js` around lines 14 - 21, The script
scripts/check-artifacts.js uses ESM features (top-level import and
import.meta.url) but the repo lacks "type":"module", so either convert the file
to CommonJS (replace import/ fileURLToPath usage with require and __dirname) or
declare "type":"module" in package.json so node can run it as ESM; also adjust
the git-staging logic that currently uses git ls-files (which only returns
tracked files) so newly generated/untracked outputs are staged: stop filtering
with git ls-files and instead run git add directly on the generated output paths
(or combine git ls-files with git ls-files --others --exclude-standard to
include untracked), and update the header text from “Skips gitignored outputs
silently” to “Skips untracked outputs silently” (references: the top-level
imports and import.meta.url usage, the mode variable checking '--check', and the
git staging code that uses git ls-files).

Comment thread scripts/check-artifacts.js Outdated
- Convert to CommonJS (was ESM, root package.json has no type:module)
- Rename srcGlobs → srcPrefixes to match actual prefix-matching behaviour
- Split cmd → installCmd + buildCmd; pre-commit --fix skips installCmd
  so npm ci doesn't run on every local commit
- Use execFileSync with argument arrays for all git calls (space-safe,
  no shell-injection surface)
- Add permissions: contents: read to artifacts-freshness CI job

https://claude.ai/code/session_01MR5eh7i7GRVpvudPrCjm2w
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.

2 participants