Persist SPFxScaffoldLog to disk and restrict --package-manager to new projects#221
Conversation
0613a0e to
8efd8b4
Compare
463d91b to
dd85453
Compare
… projects Adds loadAsync/saveAsync/hasEntries to SPFxScaffoldLog so it can be persisted as .spfx-scaffold.jsonl. CreateAction now loads the log from disk to detect existing projects and ignores --package-manager with a warning when adding components to an existing solution. Closes SharePoint#100, closes SharePoint#165. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dd85453 to
0e376da
Compare
Manual test resultsAll scenarios tested locally with
Additional checks
|
There was a problem hiding this comment.
Pull request overview
This PR introduces persistence for SPFxScaffoldLog (as .spfx-scaffold.jsonl in the project root) and uses that persisted log in spfx create to detect existing projects and restrict how --package-manager behaves.
Changes:
- Add
hasEntries,lastPackageManager,loadAsync, andsaveAsynctoSPFxScaffoldLogand exportSCAFFOLD_LOG_FILENAME. - Update
CreateActionto load/save the scaffold log and adjust package-manager behavior for existing projects. - Add/adjust unit tests, snapshots, and documentation to account for the new log file and CLI behavior.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/spfx-template-test/src/tests/templates.test.ts | Ignore .spfx-scaffold.jsonl in scaffolded output comparisons. |
| common/docs/spfx-cli-architecture.md | Document scaffold log persistence and describe existing-project behavior. |
| common/changes/@microsoft/spfx-cli/audit-log-package-manager-restriction_2026-04-01.json | Rush change file for lockstep policy. |
| apps/spfx-cli/src/cli/actions/tests/CreateAction.test.ts | Add tests covering existing-project package-manager behavior and log saving. |
| apps/spfx-cli/src/cli/actions/tests/snapshots/CreateAction.test.ts.snap | Snapshot updates for new tests/output. |
| apps/spfx-cli/src/cli/actions/CreateAction.ts | Load persisted scaffold log, use it for “existing project” detection, and save it after runs. |
| apps/spfx-cli/README.md | Document --package-manager and its behavior for existing projects. |
| api/spfx-template-api/src/logging/test/SPFxScaffoldLog.test.ts | Add unit tests for persistence helpers and new getters. |
| api/spfx-template-api/src/logging/SPFxScaffoldLog.ts | Implement log persistence and new API surface. |
| api/spfx-template-api/src/logging/index.ts | Export SCAFFOLD_LOG_FILENAME. |
| api/spfx-template-api/src/index.ts | Re-export SCAFFOLD_LOG_FILENAME from the package root. |
| api/spfx-template-api/README.md | Update usage examples to show loadAsync/saveAsync. |
| api/spfx-template-api/etc/spfx-template-api.api.md | API report updates for new exports/members. |
Comments suppressed due to low confidence (1)
apps/spfx-cli/src/cli/actions/CreateAction.ts:242
package-manager-selectedis appended before resolving the effective package manager for existing projects. If--package-managergets overridden later, the persisted scaffold log will record the requested value (and become the newlastPackageManager), which can flip the log’s package-manager history and break subsequent runs. Append the event after resolving, or record the resolved value (and optionally add a separate field/event for the user-requested value).
log.append({
kind: 'package-manager-selected',
packageManager,
targetDir
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Validate previousPackageManager against known values before cast - Fix README example referencing deleted SPFxCreationAuditLog - Update all docs to describe override-and-warn behavior (not "ignored") Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename loadAsync/saveAsync to loadFromFolderAsync/saveToFolderAsync - Cache lastPackageManager in a field, update on append() (O(1) reads) - Simplify catch clause: remove `as Error` cast for isNotExistError - Add ISessionStartedEvent, log session-started at top of CreateAction - Extract VALID_PACKAGE_MANAGERS to module-level ReadonlySet<PackageManager> - Improve warning message: extract longName, append "will be ignored" - Update READMEs, docs, tests, and API report Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Manual Test Pass (post-review, commit 45563b9)Re-ran the full 6-scenario matrix after addressing Ian's review feedback. All pass.
Additional checks:
Review changes addressed in this round:
|
- Move package-manager-selected log append to after override resolution so the log records the *resolved* PM, not the user-provided one - Only log package-manager-selected when actually installing (not none) so skipping install doesn't erase the previously recorded PM - Make lastPackageManager sticky: "none" no longer clears the cache - Add test assertions verifying what gets appended to the scaffold log Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- saveToFolderAsync and round-trip test use .name pattern - hasEntries/lastPackageManager kept as strings (getters lack .name) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… projects (SharePoint#221) ## Description Closes SharePoint#165 (restrict `--package-manager` to new projects). Partially addresses SharePoint#100 (scaffold log persistence). - Adds `loadAsync`, `saveAsync`, and `hasEntries` to `SPFxScaffoldLog` so it can be persisted as `.spfx-scaffold.jsonl` in the project root - `CreateAction` loads the log from disk to detect existing projects. When `--package-manager` is specified on an existing project, it emits a warning and skips installation - The log file accumulates events (JSONL) across runs, recording templates rendered, files written/merged, and package manager usage ## How was this tested? - `rush build` passes for both `@microsoft/spfx-template-api` and `@microsoft/spfx-cli` - 10 new unit tests for `SPFxScaffoldLog` persistence (`hasEntries`, `loadAsync`, `saveAsync`, round-trip) - 8 new unit tests for `CreateAction` (existing project: warn + skip install; new project: allow install + save log) - All existing tests continue to pass (314 API + 105 CLI) ## Type of change - [x] New feature / enhancement 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Follow-up to SharePoint#221: since scaffold now persists the log to disk, gitignore it in every template, example, and test fixture so it doesn't appear as an untracked file in generated projects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Follow-up to SharePoint#221: since scaffold now persists the log to disk, gitignore it in every template, example, and test fixture so it doesn't appear as an untracked file in generated projects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…227) ## Description Follow-up to #221: since the scaffold now persists the log to disk as `.spfx-scaffold.jsonl`, this PR gitignores that file in every template, example, and test fixture so it doesn't appear as an untracked file in generated projects. ## How was this tested - `rushx build` in `tests/spfx-template-test` — snapshot updated to reflect that templates now emit a `.gitignore` file (file count 1→2) ## Type of change - [ ] Bug fix - [ ] New feature - [x] Template change (modifies template files or examples) - [ ] Docs / CI change only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…227) ## Description Follow-up to #221: since the scaffold now persists the log to disk as `.spfx-scaffold.jsonl`, this PR gitignores that file in every template, example, and test fixture so it doesn't appear as an untracked file in generated projects. ## How was this tested - `rushx build` in `tests/spfx-template-test` — snapshot updated to reflect that templates now emit a `.gitignore` file (file count 1→2) ## Type of change - [ ] Bug fix - [ ] New feature - [x] Template change (modifies template files or examples) - [ ] Docs / CI change only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Description
Closes #165 (restrict
--package-managerto new projects). Partially addresses #100 (scaffold log persistence).loadAsync,saveAsync, andhasEntriestoSPFxScaffoldLogso it can be persisted as.spfx-scaffold.jsonlin the project rootCreateActionloads the log from disk to detect existing projects. When--package-manageris specified on an existing project, it emits a warning and skips installationHow was this tested?
rush buildpasses for both@microsoft/spfx-template-apiand@microsoft/spfx-cliSPFxScaffoldLogpersistence (hasEntries,loadAsync,saveAsync, round-trip)CreateAction(existing project: warn + skip install; new project: allow install + save log)Type of change
🤖 Generated with Claude Code