Skip to content

Commit 28c9909

Browse files
committed
dev
1 parent b4a3cb9 commit 28c9909

File tree

7 files changed

+99
-90
lines changed

7 files changed

+99
-90
lines changed

src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
2626
</PropertyGroup>
2727

28-
<PropertyGroup Condition="'$(CIBuild)' != 'true'">
29-
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
30-
</PropertyGroup>
31-
3228
<!-- For debugging purposes, uncomment this block to enable AOT builds -->
3329
<!--<PropertyGroup>
3430
<EnableCmdPalAOT>true</EnableCmdPalAOT>

src/modules/cmdpal/Microsoft.CmdPal.UI/Properties/PublishProfiles/win-arm64.pubxml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
1111
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
1212
<SelfContained>true</SelfContained>
1313
<PublishSingleFile>False</PublishSingleFile>
14+
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
1415
</PropertyGroup>
15-
</Project>
16+
</Project>

src/modules/cmdpal/Microsoft.CmdPal.UI/Properties/PublishProfiles/win-x64.pubxml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
1111
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
1212
<SelfContained>true</SelfContained>
1313
<PublishSingleFile>False</PublishSingleFile>
14+
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
1415
</PropertyGroup>
15-
</Project>
16+
</Project>

src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</PropertyGroup>
2626

2727
<ItemGroup>
28-
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\*.png" Link="Assets\%(Filename)%(Extension)">
28+
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\*.png" Link="WinUI3Apps\Assets\Settings\Icons\%(Filename)%(Extension)">
2929
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3030
</Content>
3131
</ItemGroup>

src/settings-ui/Settings.UI.XamlIndexBuilder/Settings.UI.XamlIndexBuilder.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@
3535
<GeneratedJsonFile Condition="'$(GeneratedJsonFile)' == ''">$(MSBuildProjectDirectory)\..\Settings.UI\Assets\Settings\search.index.json</GeneratedJsonFile>
3636
</PropertyGroup>
3737
<Target Name="GenerateSearchIndexSelf" AfterTargets="Build">
38-
<RemoveDir Directories="$(MSBuildProjectDirectory)\obj\ARM64;$(MSBuildProjectDirectory)\obj\x64;$(MSBuildProjectDirectory)\bin" />
38+
<RemoveDir Directories="$(MSBuildProjectDirectory)\obj\ARM64;$(MSBuildProjectDirectory)\obj\x64;$(MSBuildProjectDirectory)\bin" ContinueOnError="WarnAndContinue" />
3939
<MakeDir Directories="$([System.IO.Path]::GetDirectoryName('$(GeneratedJsonFile)'))" />
4040
<Message Importance="high" Text="[XamlIndexBuilder] Generating search index. Root='$(XamlRootDir)'; Out='$(GeneratedJsonFile)'; Tool='$(TargetPath)'; DotNet='$(DotNetExe)'." />
4141
<Exec Command="&quot;$(DotNetExe)&quot; &quot;$(TargetPath)&quot; &quot;$(XamlRootDir)&quot; &quot;$(GeneratedJsonFile)&quot;" />
42+
<ItemGroup>
43+
<_GeneratedSearchIndex Include="$(GeneratedJsonFile)" Condition="Exists('$(GeneratedJsonFile)')" />
44+
</ItemGroup>
45+
<Message Importance="high" Condition="Exists('$(GeneratedJsonFile)')" Text="[XamlIndexBuilder] Generated search index: '%(_GeneratedSearchIndex.FullPath)' (%(_GeneratedSearchIndex.FileSize) bytes)" />
46+
<Message Importance="high" Condition="!Exists('$(GeneratedJsonFile)')" Text="[XamlIndexBuilder] ERROR: search index was not created at '$(GeneratedJsonFile)'" />
4247
</Target>
4348
</Project>

src/settings-ui/Settings.UI/PowerToys.Settings.csproj

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,6 @@
142142

143143
<!-- Removed hard-coded resource exclusion. -->
144144

145-
<ItemGroup>
146-
<!-- Ensure the generated search index is present in the project; only if it exists to prevent CS1566 in clean CI -->
147-
<Content Include="$(GeneratedJsonFile)" Condition="Exists('$(GeneratedJsonFile)')">
148-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
149-
</Content>
150-
<!-- Embed the generated search index; logical name must match PrebuiltIndexResourceName -->
151-
<EmbeddedResource Include="$(GeneratedJsonFile)" Condition="Exists('$(GeneratedJsonFile)')">
152-
<LogicalName>Microsoft.PowerToys.Settings.UI.Assets.search.index.json</LogicalName>
153-
</EmbeddedResource>
154-
</ItemGroup>
155-
156145
<ItemGroup>
157146
<None Update="Assets\Settings\icon.ico">
158147
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -213,5 +202,20 @@
213202
<Target Name="BuildXamlIndexBeforeSettings" BeforeTargets="CoreCompile" Condition="'$(DesignTimeBuild)' != 'true'">
214203
<Message Importance="high" Text="[Settings] Building XamlIndexBuilder prior to compile. Views='$(MSBuildProjectDirectory)\SettingsXAML\Views' Out='$(GeneratedJsonFile)'" />
215204
<MSBuild Projects="..\Settings.UI.XamlIndexBuilder\Settings.UI.XamlIndexBuilder.csproj" Targets="Build" Properties="Configuration=$(Configuration);Platform=Any CPU;TargetFramework=net9.0;XamlViewsDir=$(MSBuildProjectDirectory)\SettingsXAML\Views;GeneratedJsonFile=$(GeneratedJsonFile)" />
205+
206+
<ItemGroup>
207+
<_GeneratedSearchIndex Include="$(GeneratedJsonFile)" Condition="Exists('$(GeneratedJsonFile)')" />
208+
</ItemGroup>
209+
<Message Importance="high" Condition="Exists('$(GeneratedJsonFile)')" Text="[Settings] Search index exists: '%(_GeneratedSearchIndex.FullPath)' (%(_GeneratedSearchIndex.FileSize) bytes)" />
210+
<Error Condition="!Exists('$(GeneratedJsonFile)')" Text="[Settings] XamlIndexBuilder did not produce expected search index at '$(GeneratedJsonFile)'." />
211+
212+
<ItemGroup>
213+
<Content Include="$(GeneratedJsonFile)">
214+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
215+
</Content>
216+
<EmbeddedResource Include="$(GeneratedJsonFile)">
217+
<LogicalName>Microsoft.PowerToys.Settings.UI.Assets.search.index.json</LogicalName>
218+
</EmbeddedResource>
219+
</ItemGroup>
216220
</Target>
217221
</Project>

tools/build/build-installer.ps1

Lines changed: 73 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,8 @@ Runs the pipeline for x64 Release with machine-wide installer.
2828
2929
.NOTES
3030
- Generated MSIX files will be signed using cert-sign-package.ps1.
31-
- This script uses git to manage workspace state:
32-
* Uncommitted changes are stashed before build and popped afterwards.
33-
* Version files and manifests modified during build are reverted.
34-
* Untracked generated files are cleaned up.
35-
- Use the -Clean parameter to clean build outputs (bin/obj) and ignored files.
31+
- If the working tree is not clean, the script will prompt before continuing (use -Force to skip the prompt).
32+
- Use the -Clean parameter to clean build outputs (bin/obj) and MSBuild outputs.
3633
- The built installer will be placed under: installer/PowerToysSetupVNext/[Platform]/[Configuration]/User[Machine]Setup
3734
relative to the solution root directory.
3835
- To run the full installation in other machines, call "./cert-management.ps1" to export the cert used to sign the packages.
@@ -44,18 +41,20 @@ param (
4441
[string]$Configuration = 'Release',
4542
[string]$PerUser = 'true',
4643
[string]$Version,
44+
[switch]$Force,
4745
[switch]$EnableCmdPalAOT,
4846
[switch]$Clean,
4947
[switch]$SkipBuild,
5048
[switch]$Help
5149
)
5250

5351
if ($Help) {
54-
Write-Host "Usage: .\build-installer.ps1 [-Platform <x64|arm64>] [-Configuration <Release|Debug>] [-PerUser <true|false>] [-Version <0.0.1>] [-EnableCmdPalAOT] [-Clean] [-SkipBuild]"
52+
Write-Host "Usage: .\build-installer.ps1 [-Platform <x64|arm64>] [-Configuration <Release|Debug>] [-PerUser <true|false>] [-Version <0.0.1>] [-Force] [-EnableCmdPalAOT] [-Clean] [-SkipBuild]"
5553
Write-Host " -Platform Target platform (default: auto-detect or x64)"
5654
Write-Host " -Configuration Build configuration (default: Release)"
5755
Write-Host " -PerUser Build per-user installer (default: true)"
5856
Write-Host " -Version Sets the PowerToys version (default: from src\Version.props)"
57+
Write-Host " -Force Continue even if the git working tree is not clean (skips the interactive prompt)."
5958
Write-Host " -EnableCmdPalAOT Enable AOT compilation for CmdPal (slower build)"
6059
Write-Host " -Clean Clean output directories before building"
6160
Write-Host " -SkipBuild Skip building the main solution and tools (assumes they are already built)"
@@ -103,6 +102,73 @@ if (-not $repoRoot -or -not (Test-Path (Join-Path $repoRoot "PowerToys.slnx")))
103102

104103
Write-Host "PowerToys repository root detected: $repoRoot"
105104

105+
# Safety check: avoid mixing build outputs with existing local changes unless the user confirms.
106+
if (-not $Force) {
107+
Push-Location $repoRoot
108+
try {
109+
$gitStatus = $null
110+
$gitRelevantStatus = @()
111+
try {
112+
$gitStatus = git status --porcelain=v1 --untracked-files=all --ignore-submodules=all
113+
} catch {
114+
Write-Warning ("[GIT] Failed to query git status: {0}" -f $_.Exception.Message)
115+
}
116+
117+
if ($gitStatus -and $gitStatus.Length -gt 0) {
118+
foreach ($line in $gitStatus) {
119+
if (-not $line) { continue }
120+
121+
# Porcelain v1 format: XY <path>
122+
# We only care about changes that affect the working tree (Y != ' ') or untracked files (??).
123+
# Index-only changes (staged, Y == ' ') are ignored per user request.
124+
if ($line.StartsWith('??')) {
125+
$gitRelevantStatus += $line
126+
continue
127+
}
128+
129+
if ($line.StartsWith('!!')) {
130+
continue
131+
}
132+
133+
if ($line.Length -ge 2) {
134+
$workTreeStatus = $line[1]
135+
if ($workTreeStatus -ne ' ') {
136+
$gitRelevantStatus += $line
137+
}
138+
}
139+
}
140+
}
141+
142+
if ($gitRelevantStatus.Count -gt 0) {
143+
Write-Warning "[GIT] Working tree is NOT clean."
144+
Write-Warning "[GIT] This build will generate untracked files and may modify tracked files, which can mix with your current changes."
145+
Write-Host "[GIT] Unstaged/untracked status (first 50 lines):"
146+
$gitRelevantStatus | Select-Object -First 50 | ForEach-Object { Write-Host (" {0}" -f $_) }
147+
148+
$shouldContinue = $false
149+
try {
150+
$choices = [System.Management.Automation.Host.ChoiceDescription[]]@(
151+
(New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Continue the build."),
152+
(New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Cancel the build.")
153+
)
154+
$decision = $Host.UI.PromptForChoice("Working tree not clean", "Continue anyway?", $choices, 1)
155+
$shouldContinue = ($decision -eq 0)
156+
} catch {
157+
Write-Warning "[GIT] Interactive prompt not available."
158+
Write-Error "Refusing to proceed with a dirty working tree. Re-run with -Force to continue anyway."
159+
exit 1
160+
}
161+
162+
if (-not $shouldContinue) {
163+
Write-Host "[GIT] Cancelled by user."
164+
exit 1
165+
}
166+
}
167+
} finally {
168+
Pop-Location
169+
}
170+
}
171+
106172
$cmdpalOutputPath = Join-Path $repoRoot "$Platform\$Configuration\WinUI3Apps\CmdPal"
107173
$buildOutputPath = Join-Path $repoRoot "$Platform\$Configuration"
108174

@@ -117,53 +183,10 @@ if ($Clean) {
117183
Remove-Item $buildOutputPath -Recurse -Force -ErrorAction Ignore
118184
}
119185

120-
Write-Host "[CLEAN] Cleaning all build artifacts (git clean -Xfd)..."
121-
Push-Location $repoRoot
122-
try {
123-
git clean -Xfd | Out-Null
124-
} catch {
125-
Write-Warning "[CLEAN] git clean failed: $_"
126-
} finally {
127-
Pop-Location
128-
}
129-
130186
Write-Host "[CLEAN] Cleaning solution (msbuild /t:Clean)..."
131187
RunMSBuild 'PowerToys.slnx' '/t:Clean' $Platform $Configuration
132188
}
133189

134-
# Git Stash Logic to handle workspace cleanup
135-
$stashedChanges = $false
136-
$scriptPathRelative = "tools/build/build-installer.ps1"
137-
138-
# Calculate relative path of this script to exclude it from stash/reset
139-
$currentScriptPath = $MyInvocation.MyCommand.Definition
140-
if ($currentScriptPath.StartsWith($repoRoot)) {
141-
$scriptPathRelative = $currentScriptPath.Substring($repoRoot.Length).TrimStart('\', '/')
142-
$scriptPathRelative = $scriptPathRelative -replace '\\', '/'
143-
}
144-
145-
Push-Location $repoRoot
146-
try {
147-
$gitStatus = git status --porcelain
148-
if ($gitStatus.Length -gt 0) {
149-
Write-Host "[GIT] Uncommitted changes detected. Stashing (excluding this script)..."
150-
$stashCountBefore = (git stash list).Count
151-
152-
# Exclude the current script from stash so we don't revert it while running
153-
git stash push --include-untracked -m "PowerToys Build Auto-Stash" -- . ":(exclude)$scriptPathRelative"
154-
155-
$stashCountAfter = (git stash list).Count
156-
if ($stashCountAfter -gt $stashCountBefore) {
157-
$stashedChanges = $true
158-
Write-Host "[GIT] Changes stashed."
159-
} else {
160-
Write-Host "[GIT] No changes to stash (likely only this script is modified)."
161-
}
162-
}
163-
} finally {
164-
Pop-Location
165-
}
166-
167190
try {
168191
if ($Version) {
169192
Write-Host "[VERSION] Setting PowerToys version to $Version using versionSetting.ps1..."
@@ -384,28 +407,7 @@ try {
384407
RunMSBuild 'installer\PowerToysSetup.slnx' "$commonArgs /m /t:PowerToysBootstrapperVNext /p:PerUser=$PerUser" $Platform $Configuration
385408

386409
} finally {
387-
# Restore workspace state using Git
388-
Write-Host "[GIT] Cleaning up build artifacts..."
389-
Push-Location $repoRoot
390-
try {
391-
# Revert all changes EXCEPT the script itself
392-
# This cleans up Version.props, AppxManifests, etc.
393-
git checkout HEAD -- . ":(exclude)$scriptPathRelative"
394-
395-
# Remove untracked files (generated manifests, etc.)
396-
# -f: force, -d: remove directories, -q: quiet
397-
git clean -fd -q
398-
399-
if ($stashedChanges) {
400-
Write-Host "[GIT] Restoring stashed changes..."
401-
git stash pop --index
402-
if ($LASTEXITCODE -ne 0) {
403-
Write-Warning "[GIT] 'git stash pop' reported conflicts or errors. Your changes are in the stash list."
404-
}
405-
}
406-
} finally {
407-
Pop-Location
408-
}
410+
# No git cleanup; leave workspace state as-is.
409411
}
410412

411413
Write-Host '[PIPELINE] Completed'

0 commit comments

Comments
 (0)