-
Notifications
You must be signed in to change notification settings - Fork 301
Refactor build/versioning: shell-agnostic builds, auto NuGet versioning, and Copilot-ready workflow #514
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
base: release/experimental
Are you sure you want to change the base?
Refactor build/versioning: shell-agnostic builds, auto NuGet versioning, and Copilot-ready workflow #514
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,37 @@ | ||
| # GitHub Copilot Instructions (WindowsAppSDK-Samples) | ||
|
|
||
| Read scripts first; improve their headers instead of duplicating detail here. | ||
|
|
||
| ## Build | ||
| Use only `build.ps1` / `build.cmd`. Read `build.ps1` before invoking. It auto: detects platform, picks solutions (current dir > selected sample > all), initializes VS DevShell, restores via local nuget, emits `.binlog` per solution. Do NOT hand-roll msbuild/nuget restore logic. | ||
|
|
||
| ## Versions | ||
| Run `UpdateVersions.ps1` only after reading it. Get the WinAppSDK version string from: https://www.nuget.org/packages/Microsoft.WindowsAppSdk/ (stable/preview/servicing) and pass as `-WinAppSDKVersion`. If script params unclear, fix that script. | ||
|
|
||
| ## Coding Guidelines | ||
| - Small, focused diffs; no mass reformatting; ensure SOLID principles. | ||
| - Preserve APIs, encoding, line endings, relative paths. | ||
| - Support arm64 & x64 paths. | ||
| - PowerShell: approved verbs; each new script has Synopsis/Description/Parameters/Examples header. | ||
| - C#/C++: follow existing style; lean headers; forward declare where practical; keep samples illustrative. | ||
| - Minimal necessary comments; avoid noise. Centralize user strings for localization. | ||
| - Never log secrets or absolute external paths. | ||
|
|
||
| ## PR Guidance | ||
| - One intent per PR. Update script README/header if behavior changes. | ||
| - Provide summary: what / why / validation. | ||
| - Run a targeted build (e.g. `pwsh -File build.ps1 -Sample AppLifecycle`). | ||
| - For version bumps: inspect at least one changed project file. | ||
| - No new warnings/errors or large cosmetic churn. | ||
|
|
||
| ## Design Docs (Large / Cross-Sample) | ||
| Before broad edits create `DESIGN-<topic>.md`: | ||
| - Single sample: `Samples/<Sample>/DESIGN-<topic>.md` | ||
| - Multi-sample/shared: repo root. | ||
| Include: Problem, Goals/Non-Goals, Affected Areas, Approach, Risks, Validation Plan. Reference doc in PR. | ||
|
|
||
| ## When Unsure | ||
| Draft a design doc or WIP PR summarizing assumptions—don't guess. | ||
|
|
||
| --- | ||
| Keep this file lean; source-of-truth for behavior lives in script headers. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,79 +1,21 @@ | ||
| @echo off | ||
| :: Thin wrapper calling PowerShell implementation | ||
| set SCRIPT_DIR=%~dp0 | ||
| set PS_SCRIPT=%SCRIPT_DIR%build.ps1 | ||
|
|
||
| if "%1"=="/?" goto :usage | ||
| if "%1"=="-?" goto :usage | ||
| if "%VSINSTALLDIR%" == "" goto :usage | ||
|
|
||
| setlocal enabledelayedexpansion enableextensions | ||
|
|
||
| set BUILDCMDSTARTTIME=%time% | ||
|
|
||
| set platform=%1 | ||
| set configuration=%2 | ||
| set sample_filter=%3\ | ||
|
|
||
| if "%platform%"=="" set platform=x64 | ||
| if "%configuration%"=="" set configuration=Release | ||
|
|
||
| if not exist ".\.nuget" mkdir ".\.nuget" | ||
| if not exist ".\.nuget\nuget.exe" powershell -Command "Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile .\.nuget\nuget.exe" | ||
|
|
||
| set NUGET_RESTORE_MSBUILD_ARGS=/p:PublishReadyToRun=true | ||
|
|
||
| for /f "delims=" %%D in ('dir /s/b samples\%sample_filter%*.sln') do ( | ||
| call .nuget\nuget.exe restore "%%D" -configfile Samples\nuget.config -PackagesDirectory %~dp0packages | ||
| call msbuild /warnaserror /p:platform=%platform% /p:configuration=%configuration% /p:NugetPackageDirectory=%~dp0packages /bl:"%%~nD.binlog" "%%D" | ||
|
|
||
| if ERRORLEVEL 1 goto :eof | ||
| ) | ||
|
|
||
| :showDurationAndExit | ||
| set BUILDCMDENDTIME=%time% | ||
| :: Note: The '1's in this line are to convert a value like "08" to "108", since numbers which | ||
| :: begin with '0' are interpreted as octal, which makes "08" and "09" invalid. Adding the | ||
| :: '1's effectively adds 100 to both sides of the subtraction, avoiding this issue. | ||
| :: Hours has a leading space instead of 0, so the '1's trick isn't used on that one. | ||
| set /a BUILDDURATION_HRS= %BUILDCMDENDTIME:~0,2%- %BUILDCMDSTARTTIME:~0,2% | ||
| set /a BUILDDURATION_MIN=1%BUILDCMDENDTIME:~3,2%-1%BUILDCMDSTARTTIME:~3,2% | ||
| set /a BUILDDURATION_SEC=1%BUILDCMDENDTIME:~6,2%-1%BUILDCMDSTARTTIME:~6,2% | ||
| set /a BUILDDURATION_HSC=1%BUILDCMDENDTIME:~9,2%-1%BUILDCMDSTARTTIME:~9,2% | ||
| if %BUILDDURATION_HSC% lss 0 ( | ||
| set /a BUILDDURATION_HSC=!BUILDDURATION_HSC!+100 | ||
| set /a BUILDDURATION_SEC=!BUILDDURATION_SEC!-1 | ||
| ) | ||
| if %BUILDDURATION_SEC% lss 0 ( | ||
| set /a BUILDDURATION_SEC=!BUILDDURATION_SEC!+60 | ||
| set /a BUILDDURATION_MIN=!BUILDDURATION_MIN!-1 | ||
| ) | ||
| if %BUILDDURATION_MIN% lss 0 ( | ||
| set /a BUILDDURATION_MIN=!BUILDDURATION_MIN!+60 | ||
| set /a BUILDDURATION_HRS=!BUILDDURATION_HRS!-1 | ||
| ) | ||
| if %BUILDDURATION_HRS% lss 0 ( | ||
| set /a BUILDDURATION_HRS=!BUILDDURATION_HRS!+24 | ||
| ) | ||
| :: Add a '0' at the start to ensure at least two digits. The output will then just | ||
| :: show the last two digits for each. | ||
| set BUILDDURATION_HRS=0%BUILDDURATION_HRS% | ||
| set BUILDDURATION_MIN=0%BUILDDURATION_MIN% | ||
| set BUILDDURATION_SEC=0%BUILDDURATION_SEC% | ||
| set BUILDDURATION_HSC=0%BUILDDURATION_HSC% | ||
| echo --- | ||
| echo Start time: %BUILDCMDSTARTTIME%. End time: %BUILDCMDENDTIME% | ||
| echo Elapsed: %BUILDDURATION_HRS:~-2%:%BUILDDURATION_MIN:~-2%:%BUILDDURATION_SEC:~-2%.%BUILDDURATION_HSC:~-2% | ||
| endlocal | ||
|
|
||
| goto :eof | ||
| :: Forward all arguments directly; build.ps1 handles defaults/validation | ||
| powershell -NoProfile -ExecutionPolicy Bypass -File "%PS_SCRIPT%" %* | ||
| exit /b %ERRORLEVEL% | ||
|
|
||
| :usage | ||
| echo Usage: | ||
| echo This script should be run under a Visual Studio Developer Command Prompt. | ||
| echo. | ||
| echo build.cmd [Platform] [Configuration] [Sample] | ||
| echo. | ||
| echo [Platform] Either x86, x64, or arm64. Default is x64. | ||
| echo [Configuration] Either Debug or Release. Default is Release. | ||
| echo [Sample] The sample folder under Samples to build. If none specified, all samples are built. | ||
| echo. | ||
| echo If no parameters are specified, all samples are built for x64 Release. | ||
|
|
||
| exit /b /1 | ||
| echo (Wrapper over build.ps1) | ||
| echo Platform: x86|x64|arm64 (default x64) | ||
| echo Configuration: Debug|Release (default Release) | ||
| echo Sample: Optional sample folder name under Samples | ||
| exit /b 1 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,163 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <#! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .SYNOPSIS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Builds WindowsAppSDK Samples solutions (or local solution(s)). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .DESCRIPTION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PowerShell port of the original build.cmd logic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Ensures Visual Studio Developer environment (DevShell) is initialized. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Downloads a local nuget.exe if not present and restores packages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Builds one or more .sln files with MSBuild producing a .binlog per solution. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Solution discovery order: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. If -Sample is specified: build all .sln files under Samples/<Sample>. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 2. Else if the current working directory (where you invoked the script) contains one or more .sln files: build those only (no recursion). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 3. Else build all .sln files under Samples (recursive). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER Platform | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Target platform (x86, x64, arm64, auto). Default: auto (arm64 on ARM64 OS, else x64). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER Configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Build configuration (Debug or Release). Default: Release. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER Sample | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Optional sample folder name (child of Samples) to restrict the build scope. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER Help | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Show usage information. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ./build.ps1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (Auto-detect platform, build local solutions or all samples.) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ./build.ps1 -Platform arm64 -Configuration Debug -Sample AppLifecycle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (Build only the AppLifecycle sample solutions for arm64 Debug.) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[CmdletBinding()] parameters | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[CmdletBinding()] parameters | |
| # Parameters definition |
Copilot
AI
Sep 11, 2025
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.
Inconsistent indentation: this function has an extra leading space compared to other functions. All functions should use consistent indentation.
| # Build-Solution: Invoke MSBuild on a solution with platform/config and emit binlog. | |
| function Build-Solution { param([string]$SolutionPath,[string]$Platform,[string]$Configuration) | |
| # Build-Solution: Invoke MSBuild on a solution with platform/config and emit binlog. | |
| function Build-Solution { param([string]$SolutionPath,[string]$Platform,[string]$Configuration) |
Copilot
AI
Sep 11, 2025
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.
Inconsistent indentation: this function and the following Build-Solution function have an extra leading space compared to other functions. All functions should use consistent indentation.
| # Restore-Solution: Perform NuGet restore for a solution (.sln) using repo nuget.exe. | |
| function Restore-Solution { param([string]$SolutionPath) | |
| Write-Host "Restoring: $SolutionPath" -ForegroundColor Cyan | |
| & $nugetExe restore $SolutionPath -ConfigFile (Join-Path $samplesRoot 'nuget.config') -PackagesDirectory $packagesDir | |
| if ($LASTEXITCODE -ne 0) { Write-Error 'NuGet restore failed.'; exit $LASTEXITCODE } | |
| } | |
| # Build-Solution: Invoke MSBuild on a solution with platform/config and emit binlog. | |
| function Build-Solution { param([string]$SolutionPath,[string]$Platform,[string]$Configuration) | |
| $binlog = Join-Path (Split-Path $SolutionPath -Parent) ("{0}.binlog" -f ([IO.Path]::GetFileNameWithoutExtension($SolutionPath))) | |
| Write-Host "Building: $SolutionPath" -ForegroundColor Cyan | |
| & msbuild /warnaserror /p:Platform=$Platform /p:Configuration=$Configuration /p:NugetPackageDirectory=$packagesDir /bl:"$binlog" "$SolutionPath" | |
| if ($LASTEXITCODE -ne 0) { Write-Error 'MSBuild failed.'; exit $LASTEXITCODE } | |
| } | |
| # Restore-Solution: Perform NuGet restore for a solution (.sln) using repo nuget.exe. | |
| function Restore-Solution { param([string]$SolutionPath) | |
| Write-Host "Restoring: $SolutionPath" -ForegroundColor Cyan | |
| & $nugetExe restore $SolutionPath -ConfigFile (Join-Path $samplesRoot 'nuget.config') -PackagesDirectory $packagesDir | |
| if ($LASTEXITCODE -ne 0) { Write-Error 'NuGet restore failed.'; exit $LASTEXITCODE } | |
| } | |
| # Build-Solution: Invoke MSBuild on a solution with platform/config and emit binlog. | |
| function Build-Solution { param([string]$SolutionPath,[string]$Platform,[string]$Configuration) | |
| $binlog = Join-Path (Split-Path $SolutionPath -Parent) ("{0}.binlog" -f ([IO.Path]::GetFileNameWithoutExtension($SolutionPath))) | |
| Write-Host "Building: $SolutionPath" -ForegroundColor Cyan | |
| & msbuild /warnaserror /p:Platform=$Platform /p:Configuration=$Configuration /p:NugetPackageDirectory=$packagesDir /bl:"$binlog" "$SolutionPath" | |
| if ($LASTEXITCODE -ne 0) { Write-Error 'MSBuild failed.'; exit $LASTEXITCODE } | |
| } |
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 comment has a trailing comma that should be removed for proper grammar.