Skip to content

ci: add sample-app PR gate#595

Merged
Raina451 merged 9 commits into
mainfrom
chore/sample-app-pr-gates
Jul 20, 2026
Merged

ci: add sample-app PR gate#595
Raina451 merged 9 commits into
mainfrom
chore/sample-app-pr-gates

Conversation

@Raina451

@Raina451 Raina451 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Sample-app PR gate

Adds scripts/check-samples.mjs and a Sample App Checks workflow that enforces the sample-app conventions.

Rules

Rule Applies to
has uipath.json.example all apps
.gitignore present and ignores .uipath all apps
README has a Preview heading with an image/gif/video all apps
index.html favicon <link> points at a file that exists apps with index.html
a coded-apps harness dep (@uipath/coded-apps-dev, or @uipath/coded-action-app for action apps) apps with index.html
vite.config sets base: './' and (non-action apps) imports @uipath/coded-apps-dev apps with a vite config

Apps are auto-discovered (any tracked package.json under samples/). Rules are pure functions with a --selftest. Run all apps locally: npm run check:samples.

How the files are read

The favicon rule reads an attribute out of index.html, so it parses the HTML with node-html-parser rather than a regex. The rest are grep-style checks (does the README mention media, does the vite config contain base: './'), which is what regex and String.includes are for. The vite check greps the source on purpose: loading the config to read base would need npm ci per app, which is too heavy for a structural gate.

Scope: changed apps only (for now)

The CI job runs --changed, gating only the sample apps touched in a PR. Existing apps currently have 47 violations (mostly missing demo gifs/favicons and per-app config the app owners need to supply). Rather than block every PR on that backlog, each app becomes enforced the next time it is changed. Flip CI to a full npm run check:samples once the backlog is cleared.

Generated with Claude Code

Raina451 and others added 2 commits July 10, 2026 15:27
Adds scripts/check-samples.mjs and a Sample App Checks workflow that
validates sample apps under samples/: example config present, no committed
uipath.json, .gitignore ignoring .uipath, README Preview section with media,
and (where applicable) favicon, @uipath/coded-apps-dev devDependency, and
vite.config base + import.

Rules are pure functions with a --selftest. The CI job gates only the apps
changed in a PR (--changed), so new/edited samples must comply while the
existing backlog is fixed over time. Run all apps locally with
npm run check:samples.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Committing uipath.json is allowed; remove that check.
Comment thread scripts/check-samples.mjs Outdated
Comment thread scripts/check-samples.mjs Outdated
@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review summary

One issue found:

scripts/check-samples.mjs lines 155–156 — Module side-effect fires at import time. checkApp is exported for testability but run() (which spawns git ls-files) executes unconditionally on import. Guard with the ES-module main-check (import.meta.url === process.argv[1]) so the function is safely importable by unit tests.

Comment thread scripts/check-samples.mjs Outdated
Raina451 and others added 2 commits July 10, 2026 15:48
A rel=icon link passes even when the referenced file was deleted. Resolve
the href (handling absolute /public and root paths) and assert the file
exists, so the check validates the artifact rather than the promise.
The favicon check pulled the href out of index.html with two regexes.
Regex on HTML breaks on attribute order and quoting, so this uses
node-html-parser and a `link[rel~=icon]` selector instead. The other
checks are grep/presence tests, not parsers, and stay as-is.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread .github/workflows/sample-checks.yml Outdated
@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding this run:

.github/workflows/sample-checks.yml line 22 — Missing install step. The script opens with a top-level ESM import of node-html-parser, which is evaluated at load time. Every workflow run will fail with ERR_MODULE_NOT_FOUND before any checks execute. Needs a npm ci step between Setup Node.js and the check step.

(Three previously-raised threads on scripts/check-samples.mjs — selftest coverage gaps, unconditional run() at import, and previewSection off-by-one — remain open.)

Action apps use the @uipath/coded-action-app harness, which supplies
base and config at runtime, so they don't need @uipath/coded-apps-dev or
its vite import. The coded-apps-dev and vite-config rules now accept
either harness and skip the vite-import check for action apps.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread scripts/check-samples.mjs Outdated
@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding this run:

scripts/check-samples.mjs line 136exists uses existsSync (filesystem) while has uses git tracking (tracked.has). When a developer runs npm run check:samples locally with an untracked favicon file on disk, the favicon rule passes — but CI (clean checkout) will fail. Fix: exists: file => tracked.has(${dir}/${file}) to make both callbacks use the same source of truth.

(Four previously-raised threads remain open: missing npm ci in the workflow, unconditional run() at import time, previewSection off-by-one, and selftest coverage gaps for example-config / coded-apps-dev.)

@Raina451
Raina451 marked this pull request as ready for review July 10, 2026 13:35
@Raina451
Raina451 requested a review from a team July 10, 2026 13:35
Comment thread .github/workflows/sample-checks.yml Outdated
@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding this run:

.github/workflows/sample-checks.yml line 29 — Missing selftest invocation. PRs that modify rule logic in check-samples.mjs but touch no sample apps will run --changed against 0 apps and exit 0, so a logic regression silently passes CI. Suggest running --selftest before (or alongside) the main check step — depends on the open npm ci thread at line 22 being resolved first.

(Five previously-raised threads remain open: missing npm ci in the workflow, unconditional run() at import time, previewSection off-by-one, selftest coverage gaps for example-config/coded-apps-dev, and exists using existsSync vs. git tracking.)

Comment thread .github/workflows/sample-checks.yml Outdated
Moves the sample-app gate from a standalone sample-checks.yml workflow into
a check-samples job in pr-checks.yml (SHA-pinned actions, npm ci, and a
--selftest step), and deletes sample-checks.yml. These are filesystem
/structural checks, so they stay a script + CI job rather than an oxlint rule.

Also addresses review findings in check-samples.mjs:
- guard the entry point so importing checkApp doesn't run() / shell out to git
- favicon check uses the git-tracked set (not existsSync) so local matches CI
- previewSection includes the heading line (media on the heading line counts)
- selftest: add negative cases for example-config and coded-apps-dev

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread .github/workflows/pr-checks.yml
@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding this run:

.github/workflows/pr-checks.yml line 105 — Empty BASE_REF on workflow_dispatch. When the workflow is triggered manually, github.base_ref is an empty string, so the check step runs --changed "origin/". The || 'origin/main' fallback in the script doesn't help because "origin/" is truthy — git then rejects origin/...HEAD as an invalid ref and the step fails. Suggested fix: guard the step with if [ -n "$BASE_REF" ]; then ... else node scripts/check-samples.mjs; fi.

@Raina451
Raina451 requested a review from vnaren23 July 13, 2026 09:01
github.base_ref is empty on workflow_dispatch, which produced an invalid
"origin/" ref and failed the job on every manual trigger. Fall back to
main so it diffs against origin/main instead.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@claude

claude Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

Comment thread package.json
Comment thread .github/workflows/pr-checks.yml Outdated
Replaces the always-run --selftest CI step with a vitest unit test
(tests/unit/scripts/check-samples.test.ts) that exercises the rule engine.
The rule logic is now covered by the normal test run, and the check-samples
job only gates the apps changed in a PR.
@Raina451
Raina451 requested a review from vnaren23 July 20, 2026 05:11

it('flags a Preview heading with no media', () => {
expect(rules({ ...clean, 'README.md': '# App\n## Preview\njust text' })).toContain('readme-preview');
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The previewSection off-by-one fix changed slice(start + 1, …) to slice(start, …) specifically to handle media placed directly on the heading line (e.g. ## Preview ![](./demo.gif)). Neither of the two existing readme-preview tests exercises that case:

  • '# App\n## Preview\n![](./demo.gif)\n' — media is on the next line; both old and new slice would match.
  • '# App\n## Preview\njust text' — no media anywhere; both would fail.

If the slice were accidentally reverted to start + 1, all current tests would still pass. Suggest adding:

Suggested change
});
});
it('passes when media is placed on the Preview heading line', () => {
expect(rules({ ...clean, 'README.md': '# App\n## Preview ![](./demo.gif)\n' })).not.toContain('readme-preview');
});
it('flags a missing favicon link', () => {

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding:

tests/unit/scripts/check-samples.test.ts line 37 — Missing test for media on the Preview heading line. The previewSection off-by-one fix (slice(start) instead of slice(start+1)) was specifically for the case where media sits on the heading line itself (e.g. ## Preview ). Neither existing readme-preview test exercises that case, so reverting the fix would silently pass the whole suite. Suggested test added inline.

@sonarqubecloud

Copy link
Copy Markdown

@Raina451
Raina451 merged commit 26ed2d5 into main Jul 20, 2026
20 of 24 checks passed
@Raina451
Raina451 deleted the chore/sample-app-pr-gates branch July 20, 2026 07:18
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