Conversation
β¦ add normalization pipeline and 31 tests
- fix(stats): read breakdown.byType/bySource/topCategories shape the CLI expects
- fix(export): import correct exporter functions (toJson/toCsv/toMarkdown)
- fix(getSvgPath): use verified local_path from schema v2; null for remote icons
- fix(search): cap relevance at 100; add tag/offset filters
- fix(cli): reject negative counts, handle --version/-v boolean flags, TTY-gated ANSI
- fix(loader): load normalized schema-v2 database, add clearCache/getSvgDir
- fix(stats): unique ids, correct pack counting, sources field
- feat(normalize): 10-stage idempotent pipeline (scripts/normalize-data.js, docs/PIPELINE.md)
* 874 duplicate SVGs removed (5237 -> 4363), 284 name mismatches flagged,
12 names self-corrected, 4 correction collisions removed, 9800+ tags generated
- feat(api): filterByTag, listSources, input validation, Fisher-Yates shuffle
- test: expand suite 14 -> 45 (schema contracts, exporter, CLI subprocess)
- docs: fix README overclaims, uthuman -> uthumany, THIRD_PARTY_NOTICES.md,
CHANGELOG v1.1.0; bump version to 1.1.0
|
Important Review available on request
Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment βοΈ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 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. Comment |
| function cliSafe(...args) { | ||
| const { execSync: nodeExecSync } = require('node:child_process'); | ||
| try { | ||
| const stdout = nodeExecSync(`${nodeBin} ${CLI} ${args.join(' ')}`, { |
β¦ance - Add 3-job pipeline: Security Gates (dependency review, npm audit --audit-level=high, dependency-tree lint), Build & Verify (lint, tests, rebuild normalized data, release-tag vs package.json version guard, tarball content inspection), Publish (npm publish --provenance) - Pin all actions to full commit SHAs (checkout v4.4.0, setup-node v4.4.0, dependency-review-action v4.9.0) - Add workflow_dispatch for manual retry; concurrency group per release - Least-privilege permissions: contents read + id-token write only - Add .github/dependabot.yml: weekly npm + github-actions updates
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
There was a problem hiding this comment.
Devin Review found 5 potential issues.
4 flags not posted on this PR by your GitHub settings β view them in Devin Review. (Configure)
There was a problem hiding this comment.
π¨ Export output permits arbitrary file writes
--output writes directly to any supplied path and follows symlinks. Automated or privileged callers can overwrite unrelated writable files.
(Refers to this code)
Was this helpful? React with π or π to provide feedback.
|
|
||
| - name: Inspect package tarball contents | ||
| run: | | ||
| TARBALL=$(npm pack --dry-run --json | node -p "JSON.parse(require('fs').readFileSync(0,'utf8'))[0].filename") |
There was a problem hiding this comment.
π΄ Tarball inspection blocks every release
Every release runs npm pack --dry-run, which names a tarball without creating it. The following tar command fails before publishing starts.
Learn more
The build job asks npm to simulate packing. Dry-run mode returns the prospective filename but does not write that file. The next command opens that nonexistent filename, and set -e behavior terminates the step.
Example: The command reports icon-intelligence-1.1.0.tgz. No such file exists, so tar tzf icon-intelligence-1.1.0.tgz exits nonzero and blocks the release.
Recommended fix: Run npm pack --json without --dry-run, inspect the created archive, then delete it if desired.
| TARBALL=$(npm pack --dry-run --json | node -p "JSON.parse(require('fs').readFileSync(0,'utf8'))[0].filename") | |
| TARBALL=$(npm pack --json | node -p "JSON.parse(require('fs').readFileSync(0,'utf8'))[0].filename") |
Was this helpful? React with π or π to provide feedback.
| workflow_dispatch: | ||
| inputs: | ||
| tag: | ||
| description: "Git tag to publish (e.g. v1.1.0). Must match package.json version." | ||
| required: true | ||
| type: string |
There was a problem hiding this comment.
π΄ Manual publishing ignores requested tag
A manual run accepts tag but publishes the default branch. It can release unintended code or fail on an existing version.
Learn more
The workflow-dispatch input is metadata only unless later expressions consume it. Every checkout currently uses the workflow's default ref, and tag/version validation only runs for release events. The manual path therefore cannot fulfill its stated tag-selection contract.
Example: A maintainer enters v1.1.0 after the default branch advances to 1.2.0. All jobs check out the default branch and attempt to publish 1.2.0, not v1.1.0.
Recommended fix: Derive one requested ref from inputs.tag for manual runs and github.ref for release runs. Pass it to every checkout, fetch tags, and validate its tag against package.json for both event types before any publish step.
Was this helpful? React with π or π to provide feedback.
| svg_url: rec.svg_url || rec.image_url || '', | ||
| preview_url: rec.preview_url || rec.image_url || '', | ||
| image_url: rec.image_url || '', | ||
| local_path: localPath, |
There was a problem hiding this comment.
π‘ Remote icons return fake local paths
Remote-only records store URLs in local_path, so getSvgPath() returns nonexistent package paths. PNG-only names return a path instead of null.
Learn more
local_path is the schema's package-relative filesystem location. The pipeline initializes it from image_url when no local path exists, leaving all remote PNG URLs and one remote SVG URL in that field. getSvgPath only checks whether the field is nonempty and then passes it to path.join.
Example: Award star add has local_path equal to https://icons.iconarchive.com/...png. getSvgPath('Award star add') returns a path resembling <package>/icons/https:/icons.iconarchive.com/...png, although no local file exists.
Recommended fix: Keep remote URLs only in svg_url, preview_url, or image_url. Set local_path to an empty string unless a package-relative file was resolved and verified, regenerate the normalized database, and test a remote-only icon explicitly.
Was this helpful? React with π or π to provide feedback.
| const byCategory = {}; | ||
| for (const rec of all) (byCategory[rec.category] = byCategory[rec.category] || []).push(rec.id); | ||
| writeJSON(path.join(outDir, 'icons-by-category.json'), byCategory); |
Summary
Implements the prioritized fixes from the repository review:
Bug fixes
statsandexportCLI commands no longer crashgetSvgPath()now resolves to verified bundled files (null for remote-only icons)--version/-v handled correctly; ANSI colors only on TTYsData quality
npm run normalize): 874 duplicate SVGs removed, 284 name-file mismatches flagged, 12 wrong names self-corrected, 9,800+ tags generatedTesting & docs
Local verification:
npm test45/45 pass,npm run lint0 errors, pipeline run clean (9,810 icons).