Skip to content

feat(docs): validate USB Creator screenshot imports - #522

Merged
Eli Bosley (elibosley) merged 2 commits into
mainfrom
feat/usb-creator-screenshot-importer
Aug 6, 2026
Merged

feat(docs): validate USB Creator screenshot imports#522
Eli Bosley (elibosley) merged 2 commits into
mainfrom
feat/usb-creator-screenshot-importer

Conversation

@elibosley

@elibosley Eli Bosley (elibosley) commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

USB Creator's accepted E2E captures need a docs-owned trust boundary; this adds the importer that verifies and exactly replaces the public screenshot set before automation opens a docs PR.

Why This Exists

The Creator pipeline correctly keeps guide prose out of the product repository and produces an immutable screenshot handoff. The docs publication step needs a repository-local importer to reject malformed, stale, path-escaping, or digest-mismatched bundles before any image becomes public.

Resolution

Add a narrowly scoped importer for the unraid-os/create-unraid-usb flow. It validates schema version 2, the exact Linux publication identity, safe paths and filenames, every accepted SHA-256 digest, and contiguous step order. It writes the verified bytes into a complete staging set and swaps that set into place with rollback protection.

Reviewer Considerations

  • The importer intentionally accepts only the USB Creator category, flow, and Linux publication key; unrelated bundles cannot write elsewhere in the docs tree.
  • Guide prose remains human-owned. This tooling imports screenshots only.
  • The destination is replaced as an exact set so removed walkthrough frames cannot linger publicly.
  • Tests use isolated temporary destinations and cannot modify repository-owned screenshots.

Behavior Changes

Trusted USB Creator CI can create or refresh screenshot-only PRs in this repository after its destructive QEMU journey passes.

Implementation Summary

  • Add scripts/import-usb-creator-flow.mjs with schema, identity, path, filename, and digest validation.
  • Stage already-verified bytes and use reversible directory replacement.
  • Add focused tests for successful exact replacement, digest rejection, and rollback after publication failure.

Verification

  • node --test scripts/import-usb-creator-flow.test.mjs — 3 tests passed.
  • git diff --check — passed.
  • PR lint and Cloudflare preview build — passed on the initial head; follow-up head is running.

Risk

Low. Writes are confined to one static-image directory and occur only after the full incoming set validates and stages successfully; a failed final swap restores the previous set.

Repository checklist

  1. Internal wiki links use relative file links — not applicable; no documentation links changed.
  2. New documentation files are lowercase and dash-separated — not applicable; no documentation files added.
  3. Assets are next to their docs — not applicable; this PR adds import tooling, while generated screenshots use the existing static publication convention.
  4. Checked for overlapping open pull requests.
  5. Build succeeds — Cloudflare preview and PR lint passed on the initial head; current-head checks are required before merge.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

USB Creator import

Layer / File(s) Summary
Bundle and source validation
scripts/import-usb-creator-flow.mjs
The CLI validates bundle identifiers, publication metadata, step ordering, image paths, symlinks, regular files, and SHA-256 inputs.
Verified staged replacement
scripts/import-usb-creator-flow.mjs
The importer validates filenames and digests, copies screenshots to staging, replaces the destination, removes stale images, and cleans up on failure.
Importer integration coverage
scripts/import-usb-creator-flow.test.mjs
Integration tests verify successful import, stale-image removal, digest rejection, and temporary fixture cleanup.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant Importer as USB Creator importer
  participant Bundle as Guide bundle
  participant Destination as Static destination

  Operator->>Importer: Run importer with bundle path
  Importer->>Bundle: Load and validate metadata
  Importer->>Bundle: Verify image paths and SHA-256 digests
  Importer->>Destination: Replace destination with staged screenshots
  Destination-->>Operator: Imported screenshot set
Loading

Poem

A rabbit checks each hash in line,
Then stages screens in neat design.
Bad paths are stopped before they roam,
Good images hop safely home.
Stale files vanish with a cheer.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly identifies the main change: validation of USB Creator screenshot imports.
Description check ✅ Passed The description explains the change, rationale, implementation, testing, risk, and repository checklist with all required items addressed.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/usb-creator-screenshot-importer

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.

Eli Bosley (elibosley) added a commit to unraid/usb-creator-next that referenced this pull request Aug 6, 2026
## Summary
Trusted screenshot publication reached the docs step but failed with
exit 126; this invokes the checked-in publisher through Bash so its
non-executable Git mode cannot block the workflow.

## Why This Exists
The first main-branch run with `UNRAID_BOT_GITHUB_ADMIN_TOKEN`
successfully verified the credential and checked out `unraid/docs`, then
failed before publication because `e2e/docs/publish.sh` is mode
`100644`.

## Resolution
Invoke the script explicitly with Bash. This is portable across Git
checkouts and makes the interpreter choice visible in the workflow
without changing any publication boundary or credential handling.

## Reviewer Considerations
- This PR depends operationally on unraid/docs#522, which adds the
docs-owned verified screenshot importer called by the publisher.
- The trusted-event secret gate remains unchanged.

## Behavior Changes
Successful trusted QEMU runs can proceed into screenshot import instead
of stopping with permission denied.

## Implementation Summary
- Run `bash e2e/docs/publish.sh ...` in the publication step.

## Verification
- `bash -n e2e/docs/publish.sh`
- `actionlint .github/workflows/e2e-qemu.yml`
- `git diff --check`

## Risk
Low; only the invocation method changes.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 5

🤖 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/import-usb-creator-flow.mjs`:
- Around line 17-19: Update the DESTINATION constant in the import-usb creator
script to resolve from the repository location derived from import.meta.url,
rather than the caller’s working directory, while preserving the existing
static/img/unraid-os/getting-started/create-unraid-usb path.
- Around line 93-100: Update the publication identity validation in the flow
import logic to require identity.publicationKey to equal the USB Creator
publication key “usb-creator:linux:create-unraid-usb”, while retaining the
existing non-empty string validation and captureId checks. Keep captureId
variable per capture as currently supported.
- Around line 140-141: Update the publication sequence around rm and rename to
replace DESTINATION atomically or through a reversible swap, retaining the
existing destination until the staged directory is successfully published and
rolling back on failure. Add a failure-path test for the importer that verifies
the previous DESTINATION remains available when publication fails.
- Around line 126-137: Update the staging write in the import flow after digest
and filename validation to write the already verified bytes from
readFile(source), replacing copyFile(source, path.join(staging, filename)).
Preserve the existing validation and destination filename behavior.

In `@scripts/import-usb-creator-flow.test.mjs`:
- Around line 65-81: Make the importer destination configurable and update the
success test around its fixture setup to use a unique mkdtemp-created directory
instead of the repository publication directory. Pass that destination to the
importer, assert outputs there, and ensure every cleanup block removes only the
test-owned temporary directory while leaving the repository’s published
screenshots untouched.
🪄 Autofix

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4291e8c2-2034-4dc4-9496-fb9cafef41a7

📥 Commits

Reviewing files that changed from the base of the PR and between 1b4cb53 and 7e3b7b6.

📒 Files selected for processing (2)
  • scripts/import-usb-creator-flow.mjs
  • scripts/import-usb-creator-flow.test.mjs

Comment thread scripts/import-usb-creator-flow.mjs Outdated
Comment thread scripts/import-usb-creator-flow.mjs
Comment thread scripts/import-usb-creator-flow.mjs Outdated
Comment thread scripts/import-usb-creator-flow.mjs Outdated
Comment thread scripts/import-usb-creator-flow.test.mjs Outdated
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
unraid-docs 502abd6 Commit Preview URL

Branch Preview URL
Aug 06 2026, 02:30 PM

@elibosley
Eli Bosley (elibosley) merged commit b7bae12 into main Aug 6, 2026
4 checks passed
@elibosley
Eli Bosley (elibosley) deleted the feat/usb-creator-screenshot-importer branch August 6, 2026 14:31
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