-
Notifications
You must be signed in to change notification settings - Fork 0
V0.3.4/upstream fix #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "description": "Authoritative inventory of all required shared scaffold assets, including dot-prefixed files and folders. Used to detect installer truncation and drive restoration from upstream.", | ||
| "upstream": { | ||
| "repo": "https://github.com/codebeltnet/agentic", | ||
| "branch": "main", | ||
| "root": "skills/dotnet-new-app-slnx/assets/shared" | ||
| }, | ||
| "files": [ | ||
| ".bot/README.md", | ||
| ".editorconfig", | ||
| ".gitattributes", | ||
| ".github/CODE_OF_CONDUCT.md", | ||
| ".github/CONTRIBUTING.md", | ||
| ".github/copilot-instructions.md", | ||
| ".github/dependabot.yml", | ||
| ".github/workflows/ci-pipeline.yml", | ||
| ".gitignore", | ||
| "AGENTS.md", | ||
| "CHANGELOG.md", | ||
| "Directory.Build.targets", | ||
| "Directory.Packages.props", | ||
| "README.md", | ||
| "testenvironments.json" | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,105 @@ | ||||||||||||||||||||
| <# | ||||||||||||||||||||
| .SYNOPSIS | ||||||||||||||||||||
| Detects missing shared scaffold assets (including dotfiles) and restores them | ||||||||||||||||||||
| directly from the upstream repository. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| .DESCRIPTION | ||||||||||||||||||||
| Reads assets/shared.manifest.json, checks each required path relative to the | ||||||||||||||||||||
| skill root, and downloads any missing file from the authoritative GitHub source. | ||||||||||||||||||||
| Exits with code 1 if upstream fetch fails for any file. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| .PARAMETER SkillRoot | ||||||||||||||||||||
| Absolute path to the installed skill directory (parent of assets/). | ||||||||||||||||||||
| Defaults to the directory containing this script's parent. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| .PARAMETER DryRun | ||||||||||||||||||||
| Report missing files without downloading them. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||
| # Restore missing files into the installed skill copy | ||||||||||||||||||||
| scripts/restore-missing-shared-assets.ps1 | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Preview what is missing without restoring | ||||||||||||||||||||
| scripts/restore-missing-shared-assets.ps1 -DryRun | ||||||||||||||||||||
| #> | ||||||||||||||||||||
| [CmdletBinding()] | ||||||||||||||||||||
| param( | ||||||||||||||||||||
| [string] $SkillRoot = (Split-Path -Parent $PSScriptRoot), | ||||||||||||||||||||
| [switch] $DryRun | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Set-StrictMode -Version Latest | ||||||||||||||||||||
| $ErrorActionPreference = 'Stop' | ||||||||||||||||||||
|
|
||||||||||||||||||||
| $manifestPath = Join-Path $SkillRoot 'assets/shared.manifest.json' | ||||||||||||||||||||
| if (-not (Test-Path $manifestPath)) { | ||||||||||||||||||||
| Write-Error "Manifest not found at: $manifestPath" | ||||||||||||||||||||
| exit 1 | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| $manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json | ||||||||||||||||||||
| $repoUrl = $manifest.upstream.repo # e.g. https://github.com/codebeltnet/agentic | ||||||||||||||||||||
| $branch = $manifest.upstream.branch # e.g. main | ||||||||||||||||||||
| $remoteRoot = $manifest.upstream.root # e.g. skills/dotnet-new-app-slnx/assets/shared | ||||||||||||||||||||
| $localRoot = Join-Path $SkillRoot 'assets/shared' | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Build raw-content base URL | ||||||||||||||||||||
| $rawBase = $repoUrl -replace 'https://github.com', 'https://raw.githubusercontent.com' | ||||||||||||||||||||
| $rawBase = "$rawBase/$branch/$remoteRoot" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| $missing = [System.Collections.Generic.List[string]]::new() | ||||||||||||||||||||
| $restored = [System.Collections.Generic.List[string]]::new() | ||||||||||||||||||||
| $failed = [System.Collections.Generic.List[string]]::new() | ||||||||||||||||||||
|
|
||||||||||||||||||||
| foreach ($file in $manifest.files) { | ||||||||||||||||||||
| $localPath = Join-Path $localRoot $file | ||||||||||||||||||||
| if (-not (Test-Path $localPath)) { | ||||||||||||||||||||
| $missing.Add($file) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if ($missing.Count -eq 0) { | ||||||||||||||||||||
| Write-Host "✅ All shared assets present — nothing to restore." -ForegroundColor Green | ||||||||||||||||||||
| exit 0 | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Write-Host "⚠️ Missing shared assets ($($missing.Count)):" -ForegroundColor Yellow | ||||||||||||||||||||
| $missing | ForEach-Object { Write-Host " - $_" } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if ($DryRun) { | ||||||||||||||||||||
| Write-Host "`n[DryRun] No files downloaded." -ForegroundColor Cyan | ||||||||||||||||||||
| exit 0 | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Comment on lines
+69
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the script is invoked with
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: skills/dotnet-new-app-slnx/scripts/restore-missing-shared-assets.ps1
Line: 69-72
Comment:
**`-DryRun` always exits 0, even when files are missing**
When the script is invoked with `-DryRun` and missing files are detected, it exits with code `0`. Any CI pipeline or automated check that calls this script with `-DryRun` to audit completeness will never detect the gap from the exit code alone — it would need to parse stdout for the warning text. Exiting with code `1` when files are missing (even in dry-run mode) makes the script safe to use in `-WhatIf`-style pipeline steps.
```suggestion
if ($DryRun) {
Write-Host "`n[DryRun] No files downloaded." -ForegroundColor Cyan
if ($missing.Count -gt 0) { exit 1 }
exit 0
}
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||
|
|
||||||||||||||||||||
| Write-Host "`nRestoring from upstream: $repoUrl (branch: $branch)" -ForegroundColor Cyan | ||||||||||||||||||||
|
|
||||||||||||||||||||
| foreach ($file in $missing) { | ||||||||||||||||||||
| $url = "$rawBase/$file" | ||||||||||||||||||||
| $dest = Join-Path $localRoot $file | ||||||||||||||||||||
| $destDir = Split-Path $dest -Parent | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (-not (Test-Path $destDir)) { | ||||||||||||||||||||
| New-Item -ItemType Directory -Path $destDir -Force | Out-Null | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| try { | ||||||||||||||||||||
| Write-Host " ↓ $file" -NoNewline | ||||||||||||||||||||
| Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing | ||||||||||||||||||||
| $restored.Add($file) | ||||||||||||||||||||
| Write-Host " ✓" -ForegroundColor Green | ||||||||||||||||||||
| } | ||||||||||||||||||||
| catch { | ||||||||||||||||||||
| $failed.Add($file) | ||||||||||||||||||||
| Write-Host " ✗ ($($_.Exception.Message))" -ForegroundColor Red | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if ($restored.Count -gt 0) { | ||||||||||||||||||||
| Write-Host "`n✅ Restored $($restored.Count) file(s)." -ForegroundColor Green | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if ($failed.Count -gt 0) { | ||||||||||||||||||||
| Write-Host "❌ Failed to restore $($failed.Count) file(s):" -ForegroundColor Red | ||||||||||||||||||||
| $failed | ForEach-Object { Write-Host " - $_" } | ||||||||||||||||||||
| exit 1 | ||||||||||||||||||||
| } | ||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The restore script only checks and repairs
assets/shared, but the app scaffold also depends on hidden files underassets/app(for exampleassets/app/.github/workflows/ci-pipeline.ymlis required byskills/dotnet-new-app-slnx/SKILL.mdStep 5). If the installer drops dot-prefixed paths, this script will report success while that required app workflow file is still missing, leading to incomplete or incorrect app scaffolds.Useful? React with 👍 / 👎.