Fix standalone doctor SEO audit for BOM noindex pages#228
Fix standalone doctor SEO audit for BOM noindex pages#228PrzemyslawKlys wants to merge 29 commits intomainfrom
Conversation
PR Review – Fix standalone doctor SEO audit for BOM noindex pagesOverall this is a well-structured fix with a clear regression test. The core BOM-trimming change is small and correct. The PR also bundles a large amount of new feature work (git freshness metadata, PowerShell example validation/execution, example media rendering) beyond the stated fix, so comments below address both. ✅ What looks good
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e7b211408
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| CoveragePath = result.CoveragePath, | ||
| XrefPath = result.XrefPath, | ||
| PowerShellExampleValidationPath = powerShellExampleValidationPath, | ||
| TypeCount = result.TypeCount, |
There was a problem hiding this comment.
Copy media manifest path when rebuilding JSON result
When outputJson is enabled and warning filtering changes the warning set, this branch rebuilds WebApiDocsResult but only copies a subset of fields. PowerShellExampleMediaManifestPath is omitted here, so JSON callers lose the manifest path even though generation succeeded and the file was written. This breaks downstream tooling that relies on the CLI JSON envelope to discover the media manifest.
Useful? React with 👍 / 👎.
| var updatedDays = Math.Max(options.GitFreshnessNewDays, options.GitFreshnessUpdatedDays); | ||
| var newDays = Math.Clamp(options.GitFreshnessNewDays, 0, updatedDays); |
There was a problem hiding this comment.
Clamp freshness days after normalizing negative values
This Math.Clamp call can throw when both freshness day options are negative, because updatedDays becomes negative and min (0) is greater than max (updatedDays). CLI integers are parsed without a lower-bound guard, so --git-freshness-new-days -1 --git-freshness-updated-days -1 can crash API docs generation instead of producing a warning or fallback behavior.
Useful? React with 👍 / 👎.
| foreach (var method in methods) | ||
| { | ||
| var code = BuildGeneratedPowerShellExample(type.Name, method); | ||
| if (string.IsNullOrWhiteSpace(code) || !seen.Add(code)) | ||
| continue; |
There was a problem hiding this comment.
Emit fallback example even when command syntax is missing
Generated fallback examples are now produced only by iterating type.Methods. If a PowerShell help entry has no <syntax> items, methods is empty and this function returns no fallback examples at all, whereas the previous behavior still emitted a basic command example. That regression leaves such commands undocumented in examples and can unexpectedly trip fallback-example coverage gates.
Useful? React with 👍 / 👎.
PR ReviewOverall this is a well-scoped fix with a solid regression test, plus a clean scaffolder refactor and a large batch of new features. A few observations below. Core BOM fix (
|
| Area | Status |
|---|---|
| BOM fix correctness | ✅ Clean |
| Regression test coverage | ✅ Good — catches the exact reported scenario |
Cleanup inconsistency in new test's finally |
TryDeleteDirectory |
| Removed scaffolder assertion | |
GITHUB_OUTPUT guard |
ℹ️ Intentional, consider a comment |
| Silent git-availability skip | ℹ️ Low priority |
The fix itself is solid. The main actionable items are the two minor test-coverage gaps noted above.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 604363af1b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (executePowerShellExamples || failOnPowerShellExampleExecution) | ||
| validatePowerShellExamples = true; |
There was a problem hiding this comment.
Enable validation when fail-on-validation is requested
The --fail-on-ps-example-validation flag is parsed, but validatePowerShellExamples is only auto-enabled when execution flags are set, so running apidocs with only --fail-on-ps-example-validation skips ValidatePowerShellExamples entirely and can incorrectly succeed even when example scripts are invalid. This makes a failure flag effectively a no-op unless users also remember to pass a separate validation flag.
Useful? React with 👍 / 👎.
| "executePowerShellExamples": { "type": "boolean", "description": "When true, execute matched PowerShell example scripts after syntax validation." }, | ||
| "execute-powershell-examples": { "type": "boolean", "description": "Alias of executePowerShellExamples." }, | ||
| "powerShellExampleExecutionTimeoutSeconds": { "type": "integer", "minimum": 1, "maximum": 600, "description": "Per-example execution timeout in seconds for matched PowerShell example scripts." }, | ||
| "powershell-example-execution-timeout-seconds": { "type": "integer", "minimum": 1, "maximum": 600, "description": "Alias of powerShellExampleExecutionTimeoutSeconds." }, | ||
| "failOnPowerShellExampleExecution": { "type": "boolean", "description": "Fail the apidocs step when matched PowerShell example scripts fail execution or execution cannot complete." }, | ||
| "fail-on-powershell-example-execution": { "type": "boolean", "description": "Alias of failOnPowerShellExampleExecution." }, |
There was a problem hiding this comment.
Add validation keys to ApiDocs pipeline schema
This schema section still runs under additionalProperties: false for ApiDocsStep, but it omits newly supported validation fields (validatePowerShellExamples, failOnPowerShellExampleValidation, and related validation report/timeout aliases) that the runner now reads. As a result, schema-aware tooling (including configs using the documented $schema) will reject valid pipeline files that use the new validation feature.
Useful? React with 👍 / 👎.
Agent Guide (PSPublishModule / PowerForge.Web + Websites)Last updated: 2026-03-11 This file is the "start here" context for any agent working on the PowerForge.Web engine and the three websites that use it. Repos / Local PathsThese are the maintainer's default Windows paths (safe to assume in this workspace):
Portable Path Discovery (WSL/macOS/Linux)If you're not on Windows or you don't have
Practical search strategy:
Recommended environment variable (makes site scripts deterministic):
What To Read First (Canonical)
Reference docs (as needed):
Repo Skills (.agents/skills)This repo ships agent skills under
Working Agreements (Best Practices)
Module LayeringWhen touching the PowerShell module stack, prefer this boundary:
Quick smell test before adding code to a cmdlet:
If the answer to any of those is yes, the code probably belongs in Stop extracting when the remaining code is only:
Preferred pattern for the last 10-20%:
Quality Gates (Pattern)Each website should have:
Commands (Engine)
Commands (PowerShell Module)
Commands (Websites)From a website repo folder:
Baselines:
Current State (As Of 2026-02-09)
|
Agent Guide (PSPublishModule / PowerForge.Web + Websites)Last updated: 2026-03-11 This file is the "start here" context for any agent working on the PowerForge.Web engine and the three websites that use it. Repos / Local PathsThese are the maintainer's default Windows paths (safe to assume in this workspace):
Portable Path Discovery (WSL/macOS/Linux)If you're not on Windows or you don't have
Practical search strategy:
Recommended environment variable (makes site scripts deterministic):
What To Read First (Canonical)
Reference docs (as needed):
Repo Skills (.agents/skills)This repo ships agent skills under
Working Agreements (Best Practices)
Module LayeringWhen touching the PowerShell module stack, prefer this boundary:
Quick smell test before adding code to a cmdlet:
If the answer to any of those is yes, the code probably belongs in Stop extracting when the remaining code is only:
Preferred pattern for the last 10-20%:
Quality Gates (Pattern)Each website should have:
Commands (Engine)
Commands (PowerShell Module)
Commands (Websites)From a website repo folder:
Baselines:
Current State (As Of 2026-02-09)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 68f079eadf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var failOnPowerShellExampleValidation = GetBool(step, "failOnPowerShellExampleValidation") ?? GetBool(step, "fail-on-powershell-example-validation") ?? false; | ||
| var executePowerShellExamples = GetBool(step, "executePowerShellExamples") ?? GetBool(step, "execute-powershell-examples") ?? false; | ||
| var powerShellExampleExecutionTimeoutSeconds = GetInt(step, "powerShellExampleExecutionTimeoutSeconds") ?? GetInt(step, "powershell-example-execution-timeout-seconds") ?? 60; | ||
| var failOnPowerShellExampleExecution = GetBool(step, "failOnPowerShellExampleExecution") ?? GetBool(step, "fail-on-powershell-example-execution") ?? false; | ||
| if (executePowerShellExamples || failOnPowerShellExampleExecution) |
There was a problem hiding this comment.
Promote fail-on-validation to enable validation in pipeline
When failOnPowerShellExampleValidation is set in an apidocs pipeline step without also setting validatePowerShellExamples, validation never runs because only executePowerShellExamples/failOnPowerShellExampleExecution force-enable it. That makes the fail-on-validation flag a no-op in a common CI configuration and lets invalid example scripts pass unexpectedly.
Useful? React with 👍 / 👎.
| if (failOnPowerShellExampleExecution && | ||
| (!powerShellExampleValidation.ExecutionCompleted || powerShellExampleValidation.FailedExecutionFileCount > 0)) |
There was a problem hiding this comment.
Gate fail-on-execution on actual execution attempts
This failure check treats ExecutionCompleted == false as an execution failure even when no execution was requested or possible. With --fail-on-ps-example-execution (especially without --execute-ps-examples, or when no example files are discovered), ExecutionCompleted stays false and the command fails spuriously despite no script run actually failing.
Useful? React with 👍 / 👎.
|
PR Review Summary This PR addresses a real bug where BOM-prefixed HTML pages with noindex were being falsely flagged by the SEO auditor. The fix is clean and well-contained. The PR also bundles significant new features: PowerShell example validation/execution, git freshness badges, reusable CI workflows, and scoring-based example import. Core Bug Fix: BOM stripping The fix in ReadFileAsUtf8 / TrimLeadingByteOrderMark is correct and minimal:
Minor note: Encoding.UTF8 in .NET emits a BOM by default, so the regression test (Audit_SkipsSeoMetaChecks_WhenNoIndexPageUsesUtf8Bom) correctly produces a BOM-prefixed file via File.WriteAllText(..., Encoding.UTF8). A brief inline comment noting this is intentional would help future readers. Reusable Workflow Files The security posture is solid -- the Resolve PowerForge engine source step enforces an immutable commit SHA at runtime, which is a meaningful supply-chain guard.
PowerShell Example Scoring The GetImportedPowerShellExampleScore heuristic (filename exact-match to filename contains to path contains to noun) is well-designed. The OrderByDescending(score).ThenBy(filePath).ThenBy(lineNumber) tie-breaking gives deterministic results across runs. Documentation The updates in PowerForge.Web.ApiDocs.md and PowerForge.Web.Pipeline.md are thorough and well-organized. The freshness badge CSS class catalog, media node XML examples, and provenance badge documentation all clearly map to the described implementation. Overall The BOM fix is correct, tested, and safe to merge. The bundled features are well-documented with corresponding test coverage. Two items worth clarifying before merge:
Reviewed by Claude Sonnet 4.6 |
|
test comment placeholder |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a9f52fd687
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| GITHUB_TOKEN: ${{ github.token }} | ||
| INDEXNOW_KEY: ${{ secrets.INDEXNOW_KEY }} | ||
| run: | | ||
| dotnet run --project ./.powerforge-engine/PowerForge.Web.Cli -- pipeline --config ./${{ inputs.pipeline_config }} --mode ci |
There was a problem hiding this comment.
Run pipeline from website_root for reusable workflows
This reusable workflow takes both website_root and pipeline_config, but the run step always loads ./${{ inputs.pipeline_config }} from repo root. When a caller keeps a site in a subfolder (for example website_root: docs/site) and passes pipeline_config: pipeline.json in that folder, the command cannot find the config and CI fails before any checks run. Resolve config paths relative to website_root (or set the step working-directory) so subdirectory sites work consistently; the maintenance workflow has the same pattern.
Useful? React with 👍 / 👎.
|
DELETE - test placeholder |
PR ReviewThe core bug fix (BOM stripping) is correct and well-tested. The broader PR also ships substantial new features. Here is detailed feedback. Core Bug Fix - BOM Stripping (WebSiteAuditor.AssetsAndRendered.cs)The fix is correct and clean:
Regression test ( GitHub Actions Reusable Workflows
Git Freshness (WebApiDocsGenerator.Freshness.cs)
Source ValidationThe new PowerShell Validation (WebApiDocsGenerator.PowerShellValidation.cs)At 630 lines this is a large new file. The implicit enabling of validation when execution is requested is sensible - execution logically requires validation to have passed first. Scope / PR HygieneThe title targets a narrow bug fix, but the diff is +5,612 / -323 across 35 files (new features: git freshness, PS validation, PS media manifest, coverage thresholds, refactored workflows). This makes it harder to bisect regressions. Consider splitting features from bug fixes in future, or at minimum update the PR description to call out the full scope. VerdictThe BOM fix is correct and regression-tested. The new features are well-structured with solid coverage. Two items to consider before merging:
|
PR Review: Fix standalone doctor SEO audit for BOM noindex pagesThis is a substantial, well-engineered PR that goes well beyond the stated title. The headline fix (BOM stripping for noindex SEO audit) is a legitimate bug fix with proper regression testing. The remaining ~5,500 lines introduce coherent, opt-in features: git freshness metadata, example provenance tracking, PowerShell example validation/execution, playback sidecar media, and centralized reusable CI workflows. Overall code quality is high: public APIs have XML-doc comments, internal models are sealed, error paths are handled defensively, and test coverage is thorough. Issues FoundMedium Severity1. Blocking async-over-sync in Two // Fragile pattern:
var result = gitClient.RunRawAsync(...).GetAwaiter().GetResult();2. Silent exception swallow in The empty 3. Inconsistent cleanup in Several older test methods still use the raw 4. The maintenance wrapper hard-codes Low Severity / Style5. Replacing template tokens with literal values to construct a parseable URI is clever but fragile. If a future token's replacement value contains 6. stats.RepoMismatchUrlSamples = stats.RepoMismatchUrlSamples
.Append(urlSample)
.Distinct(...)
.Take(sampleLimit)
.ToArray(); // allocates on every hitFor projects with many mismatched symbols, this generates GC pressure. A 7. Test helpers copy-pasted across test classes
8. Unnecessary In Security
Test CoverageCoverage is thorough and includes:
The SummaryThe blocking async-over-sync pattern in the freshness implementation is the most important concern to address before this feature is used in any async host context. The other issues are minor and do not block the PR. This is a solid contribution overall. 🤖 Generated with Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16d9c9546c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (failOnPowerShellExampleExecution && | ||
| (!powerShellExampleValidation.ExecutionCompleted || powerShellExampleValidation.FailedExecutionFileCount > 0)) |
There was a problem hiding this comment.
Gate fail-on-execution on actual execution attempts
When failOnPowerShellExampleExecution is set without executePowerShellExamples, this block still treats ExecutionCompleted == false as a hard failure, even though no example execution was requested. Earlier in the same method the fail flag only forces validation (validatePowerShellExamples = true) and does not enable execution, so pipeline steps can fail spuriously in CI with zero scripts run. This should be gated on execution actually being requested/attempted (or the fail flag should auto-enable execution).
Useful? React with 👍 / 👎.
| if (parent is not null && | ||
| parent.Exists && | ||
| ShouldProbePowerShellHelpParentDirectory(helpDir)) |
There was a problem hiding this comment.
Preserve parent probing for sibling Examples layouts
This new guard only adds the help-file parent directory for a narrow set of folder names (help/docs/reference or culture names). In common module layouts where help XML sits under a module folder and curated scripts live in a sibling Examples directory one level up, parent probing now gets skipped, so imported script examples are no longer discovered and docs regress to generated fallback examples. That can unexpectedly trip quality gates that require imported examples/media.
Useful? React with 👍 / 👎.
Code ReviewThis PR combines a targeted bug fix, new CLI capability, a workflow refactor, documentation updates, and PowerShell example validation. Overall the code quality is high. A few items worth discussing: Core Bug Fix - UTF-8 BOM Stripping (WebSiteAuditor.AssetsAndRendered.cs) The fix is correct, minimal, and well-targeted. TrimLeadingByteOrderMark is applied in both the success path and the DecoderFallbackException catch path. The null/empty guard is correct and value[1..] is idiomatic C#. The regression test uses Encoding.UTF8 (BOM-emitting) with File.WriteAllText, which correctly exercises the fixed code path. Minor: the new test finally block still uses inline if (Directory.Exists) Directory.Delete while other tests in the same PR were refactored to TryDeleteDirectory. Workflow Security - Bootstrap Checkout Ref (powerforge-website-run.yml) The bootstrap checkout uses ref: github.workflow_sha to check out EvotecIT/PSPublishModule. github.workflow_sha is the SHA of the workflow file in the calling repos tree, not a stable pin of PSPublishModule. For workflow_call across repos, that SHA resolves inside the callers repo and is then used to check out PSPublishModule. This will fail or resolve to the wrong commit for any repo other than PSPublishModule itself. The engine checkout immediately after correctly uses the immutable SHA from the lock file, but the bootstrap step (which builds the engine-lock resolve binary) does not get the same pinning guarantee. Suggestion: Pin the bootstrap checkout to a stable tag or SHA of PSPublishModule, or add a bootstrap_ref input similar to how powerforge_ref is handled for the engine. Scaffolded CI Workflow Pins to @main (WebSiteScaffolder.cs) The scaffolded website-ci.yml now generates: uses: EvotecIT/PSPublishModule/.github/workflows/powerforge-website-ci.yml@main Pinning to @main means every scaffolded site picks up whatever is on main at run time, including future breaking changes. For a build/publish tool this can cause surprise regressions for downstream consumers. Worth deciding whether living at HEAD is intentional, or whether consumers should get a version tag or SHA for reproducibility. Engine-Lock Resolve Command (WebCliCommandHandlers.EngineLockCommands.cs) Precedence logic is clear and correct: (1) lock file defaults, (2) explicit --repository/--ref args fill empty values, (3) env overrides with --use-env, (4) override args/env always replace. One edge case worth a comment: if POWERFORGE_REPOSITORY or POWERFORGE_REF are set to an empty string, they pass the IsNullOrWhiteSpace guard on the fill path but the direct override assignment skips that guard. Net behavior is correct (empty env var does not clobber lock value), but a comment would make the intent explicit. PowerShell Validation (WebApiDocsGenerator.PowerShellValidation.cs) Timeout clamping to [5, 600] seconds is a good defensive measure. The --use-env flag gate on env variable reads is a sensible opt-in. Only executing scripts that both parse cleanly and reference documented commands is a solid safety filter before running arbitrary scripts. Surfacing asset-health warnings through coverage report fields rather than only console output is a good design decision for CI gating. Test Infrastructure Improvements The TryDeleteDirectory helper refactoring across WebApiDocsGeneratorPowerShellTests is a clean improvement. New engine-lock resolve tests cover both lock-file and env-override paths and verify the GitHub output key=value format. Minor Observations powerforge-website-maintenance.yml correctly sets cancel-in-progress: false so maintenance jobs run to completion and do not leave artifacts half-pruned. actions: write permission is scoped only to the maintenance workflow, which is appropriate. The pipeline_mode input in powerforge-website-maintenance.yml hardcodes ci (same as the CI wrapper) - if maintenance mode is eventually meant to differ from CI, this may need its own distinct value. Verdict The BOM fix is correct and well-tested. The two items most worth addressing before merge are the github.workflow_sha bootstrap ref (will silently misbehave for any consumer repo) and the @main pin in scaffolded workflows (affects reproducibility for downstream users). Everything else looks solid. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18144823ac
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: EvotecIT/PSPublishModule | ||
| ref: ${{ github.workflow_sha }} |
There was a problem hiding this comment.
Pin bootstrap checkout to the called workflow ref
In reusable-workflow runs from other repositories, ${{ github.workflow_sha }} points to the caller workflow commit (GitHub documents that reusable workflows use the caller github context), not to a commit in EvotecIT/PSPublishModule. That means this checkout usually requests a ref that does not exist in the bootstrap repository, so Checkout PowerForge workflow bootstrap fails before any pipeline steps run. Use the called-workflow ref (or pass the intended bootstrap ref as an explicit input) instead of github.workflow_sha.
Useful? React with 👍 / 👎.
This reverts commit 1814482.
PR ReviewOverall this is a well-structured PR. The core BOM fix is correct and the workflow refactoring cleanly DRYs up the duplicated CI/maintenance logic. A few items worth addressing: Potential Bug / Security Concern
dotnet run --project ./.powerforge-engine/PowerForge.Web.Cli -- pipeline --config ./${{ inputs.pipeline_config }} --mode ${{ inputs.pipeline_mode }}Both $pipelineConfig = '${{ inputs.pipeline_config }}'
$pipelineMode = '${{ inputs.pipeline_mode }}'
dotnet run --project ./.powerforge-engine/PowerForge.Web.Cli -- pipeline --config "./$pipelineConfig" --mode $pipelineModeDesign IssueMaintenance workflow hardcodes
Code Quality —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16db966a21
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| website-maintenance: | ||
| uses: ./.github/workflows/powerforge-website-run.yml | ||
| with: |
There was a problem hiding this comment.
Forward IndexNow secret in maintenance workflow call
The maintenance wrapper calls powerforge-website-run.yml without passing indexnow_key, and this workflow also does not declare an INDEXNOW_KEY input secret. Because powerforge-website-run.yml reads secrets.indexnow_key into INDEXNOW_KEY, maintenance runs cannot receive the key even when callers provide it, so maintenance pipelines that include IndexNow submission will run with an empty key and fail/skip publishing unexpectedly.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ac8f5e223
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (inspectedPlaybackMediaFiles is not null && !inspectedPlaybackMediaFiles.Add(normalizedExamplePath)) | ||
| return new PowerShellPlaybackAssetHealth(false, false, false); |
There was a problem hiding this comment.
Preserve playback health flags for reused example scripts
This early return clears all playback-health flags for repeated script paths, so when one .ps1 example is reused by multiple commands only the first command keeps hasUnsupportedSidecars/hasOversizedAssets/hasStaleAssets. That makes later commands look healthy even though they reference the same problematic media, which underreports command-level coverage metrics and can hide real quality regressions.
Useful? React with 👍 / 👎.
| var examplesRoot = Path.GetFullPath(options.PowerShellExamplesPath); | ||
| var relativeToExamples = Path.GetRelativePath(examplesRoot, fullPath); | ||
| if (!relativeToExamples.StartsWith("..", StringComparison.Ordinal) && !Path.IsPathRooted(relativeToExamples)) |
There was a problem hiding this comment.
Resolve manifest paths from examples folder for file inputs
The CLI supports PowerShellExamplesPath as either a directory or a single .ps1 file, but this branch always treats it as a root folder. When a single file is provided, Path.GetRelativePath(examplesRoot, fullPath) can evaluate to ".", and that value is emitted as the manifest sourcePath, which is not a usable example-script path for downstream tooling.
Useful? React with 👍 / 👎.
| ["lastModifiedUtc"] = freshness.LastModifiedUtc.ToString("O"), | ||
| ["commitSha"] = freshness.CommitSha, | ||
| ["ageDays"] = freshness.AgeDays, | ||
| ["sourcePath"] = freshness.SourcePath |
There was a problem hiding this comment.
Remove absolute source paths from freshness JSON output
With --git-freshness enabled, the freshness payload currently serializes sourcePath from an absolute filesystem path. Publishing API docs then exposes build-agent/local directory structure (for example, runner workspace paths) and makes output vary by machine, which is a data-leak and reproducibility regression compared to repository-relative metadata.
Useful? React with 👍 / 👎.
Code ReviewSummaryThis PR ships three distinct changes: (1) a targeted BOM-stripping bug fix in the website auditor, (2) centralised reusable GitHub Actions workflows for PowerForge.Web sites, and (3) a large batch of new API docs features (git freshness metadata, PowerShell example provenance/validation/execution, playback sidecar support, richer coverage reporting). Bug Fix — BOM stripping (
|
Summary
Testing
WebCliEngineLockTests|FullyQualifiedNameWebPipelineRunnerEngineLockTests"WebSiteScaffolderTests|FullyQualifiedNameWebCliDoctorAuditDefaultsTests|FullyQualifiedName~WebPipelineRunnerDoctorDefaultsTests"