diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e2fad10..52c2c30 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -24,7 +24,7 @@ These instructions define how GitHub Copilot should assist with this project. Th > Notable `.editorconfig` rules: C/C++ files use 4-space indentation, `crlf` line endings, and `latin1` charset — avoid non-ASCII characters in source files. - **Documentation**: The project provides documentation on [Microsoft Learn](https://learn.microsoft.com/windows/win32/dxmath/directxmath-portal) with additional wiki pages available on [GitHub](https://github.com/microsoft/DirectXMath/wiki/). The project does **not** use Doxygen. - **Error Handling**: The majority of functions have no error conditions and do not throw C++ exceptions which is why they are marked `noexcept`. A few functions have `bool` results to indicate success or failure. -- **Testing**: Unit tests for this project are implemented in this repository [Test Suite](https://github.com/walbourn/directxmathtest/) and can be run using CTest per the instructions at [Test Documentation](https://github.com/walbourn/directxmathtest/wiki). See [test copilot instructions](https://github.com/walbourn/directxmathtest/blob/main/.github/copilot-instructions.md) for additional information on the tests. +- **Testing**: Unit tests for this project are implemented in a separate repository [Test Suite](https://github.com/walbourn/directxmathtest/) and can be run using CTest per the instructions at [Test Documentation](https://github.com/walbourn/directxmathtest/wiki). See [test copilot instructions](https://github.com/walbourn/directxmathtest/blob/main/.github/copilot-instructions.md) for additional information on the tests. - **Security**: This project uses secure coding practices from the Microsoft Secure Coding Guidelines, and is subject to the `SECURITY.md` file in the root of the repository. - **Dependencies**: The project has minimal dependencies, primarily relying on compiler intrinsics. It is designed to be self-contained and portable across different platforms and toolsets. - **Continuous Integration**: This project has 18 GitHub Actions workflows covering MSVC, Clang/LLVM, GCC (WSL), ARM64, Address Sanitizer, CodeQL, and super-linter. Workflows are in `.github/workflows/` and include compiler-specific builds (`msvc.yml`, `clangcl.yml`, `cxx.yml`), platform-specific builds (`arm64.yml`, `wsl.yml`), extension tests (`shmath.yml`, `xdsp.yml`), and static analysis (`codeql.yml`, `lint.yml`, `asan.yml`). Azure DevOps pipeline configurations are in `.azuredevops/`. @@ -438,7 +438,7 @@ These were legacy types originally from xboxmath on the Xbox 360 which no longer - [Source git repository on GitHub](https://github.com/microsoft/DirectXMath.git) - [DirectXMath wiki git repository on GitHub](https://github.com/microsoft/DirectXMath.wiki.git) -- [DirectXMath test suite git repository on GitHub](https://github.com/walbourn/directxmathtest.wiki.git). +- [DirectXMath test suite git repository on GitHub](https://github.com/walbourn/directxmathtest.git) - [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) - [Microsoft Secure Coding Guidelines](https://learn.microsoft.com/en-us/security/develop/secure-coding-guidelines) - [CMake Documentation](https://cmake.org/documentation/) @@ -493,7 +493,7 @@ Use these established guards — do not invent new ones: | `_M_ARM64EC` | ARM64EC ABI (ARM64 code with x64 interop using ARM-NEON) for MSVC | | `__aarch64__` / `__x86_64__` / `__i386__` / `__powerpc64__` | Additional architecture-specific symbols for MinGW/GNUC (`#if`) | -> `_M_ARM`/ `__arm__` is legacy 32-bit ARM which is deprecated. +> `_M_ARM` / `__arm__` is legacy 32-bit ARM which is deprecated. ## Code Review Instructions @@ -511,3 +511,27 @@ When reviewing code, focus on the following aspects: - Ensure that all public functions and classes are covered by unit tests located on [GitHub](https://github.com/walbourn/directxmathtest.git) where applicable. Report any gaps in test coverage. - Check for performance implications, especially in geometry processing algorithms. - Provide brutally honest feedback on code quality, design, and potential improvements as needed. + +## Release Process + +1. Ensure all changes are merged into the `main` branch and that all tests pass. +2. Git pull the local repository to ensure it is up to date with the `main` branch. +3. Run the PowerShell script `build\preparerelease.ps1` which will generate a topic branch for the release, update the version number in `CMakeLists.txt`, the `README.md` file, the release notes in the nuspec files, and create a stub in the `CHANGELOG.md` file for the new release. +4. Edit the `CHANGELOG.md` file to update it with a summary of changes. +5. Submit the topic branch for review and merge into `main` once approved. Allow the GitHub Actions workflows and the Azure DevOps pipelines to complete successfully before proceeding. +6. Run the PowerShell script `build\completerelease.ps1` which will set a tag on the project repo and the test repo, and create a release on GitHub with the release notes from `CHANGELOG.md`. Ensure you have set up GPG signing for your GitHub account so that the tags will be verified. +7. Git pull the local repository to ensure it is up to date with the `main` branch. Be sure to include `--tags`. +8. Push the `main` branch to the MSCodeHub mirror repository. Be sure to include `--tags`. +9. Create a PR on MSCodeHub from the `main` branch to the `release` branch. +10. Merge the PR on MSCodeHub to update the release branch, which will trigger the Azure DevOps pipeline to build the NuGet package. +11. Download the GitHub source .zip archive from the release. Unzip and compare to the local repo to ensure it matches — keep in mind there may be some CR/LF differences. Run minisign on the .zip to generate a signature file, and upload the signature file to the release assets. +12. Run the PowerShell script `build\promotenuget.ps1` with the `-Release` parameter to promote the version to the Release view on the project-scoped ADO feed. +13. Run the MSCodeHub pipeline to publish the NuGet package to nuget.org. The pipeline will automatically push the most recent package promoted to the Release view to nuget.org. +14. Git pull a local repository of VCPKG to `d:\vcpkg` in sync with the `main` branch of the VCPKG repository. +15. Run the PowerShell script `build\updatevcpkg.ps1` to update the DirectXMath port in VCPKG with the new release version. This will edit the files in `ports\directxmath`. +16. Test the VCPKG port using all appropriate triplets and features. +17. Run `.\vcpkg --x-add-version directxmath` to update the VCPKG versioning history. +18. Submit a PR to the VCPKG GitHub repository to update the DirectXMath port. The PR will be reviewed and merged by the VCPKG maintainers. +19. For the DirectXMath release to be included in the next Windows SDK, prepare a PR for the MSCodeHub project from the `main` branch to the `ms_sdk_release` branch. When the PR is complete, the Azure DevOps pipeline will automatically build vpack and submit a PR for further review. + +> When fully completed, be sure to update the GitHub release with links to the matching NuGet packages and the VCPKG port. diff --git a/.github/linters/.powershell-psscriptanalyzer.psd1 b/.github/linters/.powershell-psscriptanalyzer.psd1 index b771993..27e65c8 100644 --- a/.github/linters/.powershell-psscriptanalyzer.psd1 +++ b/.github/linters/.powershell-psscriptanalyzer.psd1 @@ -1,5 +1,5 @@ # PSScriptAnalyzerSettings.psd1 @{ Severity=@('Error','Warning') - ExcludeRules=@('PSAvoidUsingWriteHost') + ExcludeRules=@('PSAvoidUsingWriteHost', 'PSUseShouldProcessForStateChangingFunctions') } diff --git a/build/completerelease.ps1 b/build/completerelease.ps1 new file mode 100644 index 0000000..b92f896 --- /dev/null +++ b/build/completerelease.ps1 @@ -0,0 +1,275 @@ +<# + +.NOTES +Copyright (c) Microsoft Corporation. +Licensed under the MIT License. + +.SYNOPSIS +Completes the release process by creating verified GitHub tags and a release. + +.DESCRIPTION +Creates GPG-signed annotated tags on both the DirectXMath repository and the +DirectXMath test suite repository (Tests/), then publishes a GitHub release on +the DirectXMath repository using the signed tag. + +Tags are signed locally with 'git tag -s', which requires GPG signing to be +configured in git and the signing key to be registered with GitHub. This +produces the Verified badge in the GitHub UI. + +Run this script after the release PR (prepared by preparerelease.ps1) has been +merged into the main branch. + +.PARAMETER PAT +GitHub Personal Access Token with 'repo' scope, used to publish the GitHub +release on microsoft/DirectXMath. Can also be provided via the GITHUB_TOKEN +environment variable. If neither is provided, the script attempts to obtain a +token from the 'gh' CLI. + +.PARAMETER SkipTestRepo +If set, skips creating a tag on the test suite repository (Tests/). + +.PARAMETER WhatIf +Shows what would happen without creating tags, pushing, or publishing a release. + +.LINK +https://github.com/microsoft/DirectXMath/wiki + +#> + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingEmptyCatchBlock', '')] +param( + [string]$PAT = "", + [switch]$SkipTestRepo, + [switch]$WhatIf +) + +$reporoot = Split-Path -Path $PSScriptRoot -Parent +$readme = Join-Path $reporoot "README.md" +$history = Join-Path $reporoot "CHANGELOG.md" +$testsroot = Join-Path $reporoot "Tests" + +#--- Validate script location --- + +if ((-Not (Test-Path $readme)) -Or (-Not (Test-Path $history))) { + Write-Error "ERROR: Unexpected location of script file!" -ErrorAction Stop +} + +#--- Validate local repo state --- + +$branch = git -C $reporoot branch --show-current +if ($branch -ne "main") { + Write-Error "ERROR: Must be on the 'main' branch (currently on '$branch')!" -ErrorAction Stop +} + +Write-Host "Fetching from origin..." +git -C $reporoot fetch -q origin +if ($LastExitCode -ne 0) { + Write-Error "ERROR: Failed to fetch from origin!" -ErrorAction Stop +} + +$headHash = git -C $reporoot rev-parse HEAD +$remoteHash = git -C $reporoot rev-parse "origin/main" +if ($headHash -ne $remoteHash) { + Write-Error "ERROR: Local 'main' is not in sync with origin. Run 'git pull' first." -ErrorAction Stop +} + +#--- Derive release info from README.md --- + +$rawreleasedate = $(Get-Content $readme) | Select-String -Pattern "^## [A-Z][a-z]+ (?:\d+,?\s+)?\d{4}" | Select-Object -First 1 +if ([string]::IsNullOrEmpty($rawreleasedate)) { + Write-Error "ERROR: Failed to find a release date header in README.md!" -ErrorAction Stop +} + +$releasename = ($rawreleasedate.ToString() -replace '^## ', '').Trim() + +try { + $releaseDateTime = [datetime]::Parse($releasename) +} +catch { + Write-Error "ERROR: Failed to parse release date '$releasename': $_" -ErrorAction Stop +} + +$releasetag = (Get-Date -Date $releaseDateTime -Format "MMMyyyy").ToLower() + +Write-Host " Release Name: $releasename" +Write-Host " Release Tag: $releasetag" + +#--- Extract release notes from CHANGELOG.md --- + +$changelog = Get-Content $history +$notesStart = -1 +$notesEnd = $changelog.Count - 1 + +for ($i = 0; $i -lt $changelog.Count; $i++) { + if ($changelog[$i] -match "^### $([regex]::Escape($releasename))") { + $notesStart = $i + 1 + } + elseif ($notesStart -ge 0 -and $changelog[$i] -match "^### ") { + $notesEnd = $i - 1 + break + } +} + +if ($notesStart -lt 0) { + Write-Error "ERROR: Could not find release notes for '$releasename' in CHANGELOG.md!" -ErrorAction Stop +} + +$releaseNotes = (($changelog[$notesStart..$notesEnd] | Where-Object { $_ -ne "" }) -join "`n").Trim() + +Write-Host "Release Notes:" +Write-Host $releaseNotes +Write-Host "" + +#--- Acquire GitHub token --- + +if ($PAT.Length -eq 0) { + $PAT = [string]$env:GITHUB_TOKEN +} + +if ($PAT.Length -eq 0) { + try { + $ghToken = & gh auth token 2>$null + if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($ghToken)) { + $PAT = $ghToken.Trim() + Write-Host "Using token from 'gh' CLI." + } + } + catch { + # gh CLI not available + } +} + +if ($PAT.Length -eq 0) { + Write-Error "ERROR: No GitHub token found. Provide -PAT, set GITHUB_TOKEN, or sign in with 'gh auth login'." -ErrorAction Stop +} + +$apiHeaders = @{ + "Accept" = "application/vnd.github+json" + "Authorization" = "Bearer $PAT" + "X-GitHub-Api-Version" = "2022-11-28" +} + +#--- Helper: create a GPG-signed tag locally and push it --- + +function Push-SignedTag { + param( + [Parameter(Mandatory)] [string]$RepoPath, + [Parameter(Mandatory)] [string]$TagName, + [Parameter(Mandatory)] [string]$Message + ) + + # Check whether the tag already exists locally + $existing = git -C $RepoPath tag -l $TagName + if (-not [string]::IsNullOrEmpty($existing)) { + Write-Error "ERROR: Tag '$TagName' already exists in '$RepoPath'!" -ErrorAction Stop + } + + if ($WhatIf) { + Write-Host "[WhatIf] Would create signed tag '$TagName' in '$RepoPath' and push to origin" + return + } + + Write-Host "Creating signed tag '$TagName'..." + git -C $RepoPath tag -s $TagName -m $Message + if ($LastExitCode -ne 0) { + Write-Error "ERROR: Failed to create signed tag '$TagName'. Ensure GPG signing is configured." -ErrorAction Stop + } + + Write-Host "Pushing tag '$TagName' to origin..." + git -C $RepoPath push origin $TagName + if ($LastExitCode -ne 0) { + git -C $RepoPath tag -d $TagName 2>$null + Write-Error "ERROR: Failed to push tag '$TagName' to origin." -ErrorAction Stop + } +} + +#--- Helper: create a GitHub release --- + +function New-GitHubRelease { + param( + [Parameter(Mandatory)] [string]$Owner, + [Parameter(Mandatory)] [string]$Repo, + [Parameter(Mandatory)] [string]$TagName, + [Parameter(Mandatory)] [string]$ReleaseName, + [Parameter(Mandatory)] [string]$ReleaseBody + ) + + # Check whether a release already exists for this tag + $checkUri = "https://api.github.com/repos/$Owner/$Repo/releases/tags/$TagName" + $releaseExists = $false + + try { + $null = Invoke-RestMethod -Uri $checkUri -Method Get -Headers $apiHeaders -ErrorAction Stop + $releaseExists = $true + } + catch { + $sc = $null + try { $sc = [int]$_.Exception.Response.StatusCode } catch { } + if ($sc -ne 404) { + Write-Error "ERROR: Failed to check for existing release '$TagName' on ${Owner}/${Repo}: $_" -ErrorAction Stop + } + # 404 = no release exists yet, which is expected + } + + if ($releaseExists) { + Write-Error "ERROR: Release '$TagName' already exists on ${Owner}/${Repo}!" -ErrorAction Stop + } + + if ($WhatIf) { + Write-Host "[WhatIf] Would create release '$TagName' on ${Owner}/${Repo}" + return + } + + $payload = @{ + tag_name = $TagName + name = $ReleaseName + body = $ReleaseBody + draft = $false + prerelease = $false + make_latest = "true" + } | ConvertTo-Json + + Write-Host "Creating release '$TagName' on ${Owner}/${Repo}..." + + try { + $result = Invoke-RestMethod -Uri "https://api.github.com/repos/$Owner/$Repo/releases" ` + -Method Post -Headers $apiHeaders -Body $payload -ContentType "application/json" -ErrorAction Stop + Write-Host " Created: $($result.html_url)" + } + catch { + Write-Error "ERROR: Failed to create release '$TagName' on ${Owner}/${Repo}: $_" -ErrorAction Stop + } +} + +#--- Create verified tag and release on microsoft/DirectXMath --- + +Push-SignedTag -RepoPath $reporoot -TagName $releasetag -Message $releasename + +New-GitHubRelease ` + -Owner "microsoft" ` + -Repo "DirectXMath" ` + -TagName $releasetag ` + -ReleaseName $releasename ` + -ReleaseBody $releaseNotes + +#--- Create verified tag on walbourn/directxmathtest --- + +if (-Not $SkipTestRepo) { + if (-Not (Test-Path $testsroot)) { + Write-Warning "WARNING: Tests/ folder not found at '$testsroot'. Skipping test suite tag." + } + else { + Push-SignedTag -RepoPath $testsroot -TagName $releasetag -Message $releasename + } +} + +#--- Done --- + +if (-Not $WhatIf) { + Write-Host "" + Write-Host "Release complete. Sync the new tags locally with:" + Write-Host " git pull --tags" + if (-Not $SkipTestRepo) { + Write-Host " git -C Tests pull --tags" + } +} \ No newline at end of file diff --git a/build/preparerelease.ps1 b/build/preparerelease.ps1 index 7af3e74..74d5d15 100644 --- a/build/preparerelease.ps1 +++ b/build/preparerelease.ps1 @@ -24,6 +24,7 @@ https://github.com/microsoft/DirectXMath/wiki #> +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingEmptyCatchBlock', '')] param( [string]$BaseBranch = "main", [string]$TargetBranch = $null, @@ -31,28 +32,28 @@ param( ) $reporoot = Split-Path -Path $PSScriptRoot -Parent -$cmake = $reporoot + "\CMakeLists.txt" -$header = $reporoot + "\Inc\DirectXMath.h" -$readme = $reporoot + "\README.md" -$history = $reporoot + "\CHANGELOG.md" +$cmake = Join-Path $reporoot "CMakeLists.txt" +$header = Join-Path $reporoot "Inc\DirectXMath.h" +$readme = Join-Path $reporoot "README.md" +$history = Join-Path $reporoot "CHANGELOG.md" if ((-Not (Test-Path $cmake)) -Or (-Not (Test-Path $header)) -Or (-Not (Test-Path $readme)) -Or (-Not (Test-Path $history))) { Write-Error "ERROR: Unexpected location of script file!" -ErrorAction Stop } -$branch = git branch --show-current +$branch = git -C $reporoot branch --show-current if ($branch -ne $BaseBranch) { Write-Error "ERROR: Must be in the $BaseBranch branch!" -ErrorAction Stop } -git pull -q +git -C $reporoot pull -q if ($LastExitCode -ne 0) { Write-Error "ERROR: Failed to sync branch!" -ErrorAction Stop } $version = Get-Content ($cmake) | Select-String -Pattern "set\(DIRECTXMATH_VERSION" -CaseSensitive if (-Not ($version -match "([0-9]?\.[0-9]+)")) { - Write-Error "ERROR: Failed to current version!" -ErrorAction Stop + Write-Error "ERROR: Failed to find current version!" -ErrorAction Stop } $version = $Matches.0 $rawversion = $version.replace('.','') @@ -69,11 +70,11 @@ else { $newversion = $newrawversion[0] + "." + $newrawversion[1] + $newrawversion[2] -$rawreleasedate = $(Get-Content $readme) | Select-String -Pattern "\*\*[A-Z][a-z]+\S.?\S.\d\d\d\d\*\*" +$rawreleasedate = $(Get-Content $readme) | Select-String -Pattern "^## [A-Z][a-z]+ (?:\d+,?\s+)?\d{4}" | Select-Object -First 1 if ([string]::IsNullOrEmpty($rawreleasedate)) { - Write-Error "ERROR: Failed to current release date!" -ErrorAction Stop + Write-Error "ERROR: Failed to find current release date!" -ErrorAction Stop } -$releasedate = $rawreleasedate -replace '\*','' +$releasedate = ($rawreleasedate.ToString() -replace '^## ', '').Trim() if($releasedate -eq $newreleasedate) { Write-Error ("ERROR: Release "+$releasedate+" already exists!") -ErrorAction Stop @@ -84,7 +85,7 @@ if ($TargetBranch -ne 'none') { $TargetBranch = $newreleasetag + "release" } - git checkout -b $TargetBranch + git -C $reporoot checkout -b $TargetBranch if ($LastExitCode -ne 0) { Write-Error "ERROR: Failed to create new topic branch!" -ErrorAction Stop } @@ -102,9 +103,9 @@ if($UpdateVersion) { (Get-Content $header).Replace("#define DIRECTX_MATH_VERSION $rawversion","#define DIRECTX_MATH_VERSION $newrawversion") | Set-Content $header } -(Get-Content $readme).Replace("$rawreleasedate", "**$newreleasedate**") | Set-Content $readme +(Get-Content $readme).Replace("## $releasedate", "## $newreleasedate") | Set-Content $readme -Get-ChildItem -Path ($reporoot + "\.nuget") -Filter *.nuspec | Foreach-Object { +Get-ChildItem -Path (Join-Path $reporoot ".nuget") -Filter *.nuspec | Foreach-Object { (Get-Content -Path $_.Fullname).Replace("$releasedate", "$newreleasedate") | Set-Content -Path $_.Fullname -Encoding utf8 } diff --git a/build/updatevcpkg.ps1 b/build/updatevcpkg.ps1 new file mode 100644 index 0000000..9d82f92 --- /dev/null +++ b/build/updatevcpkg.ps1 @@ -0,0 +1,111 @@ +<# + +.NOTES +Copyright (c) Microsoft Corporation. +Licensed under the MIT License. + +.SYNOPSIS +Updates the vcpkg port for DirectXMath to match a GitHub release. + +.DESCRIPTION +This script updates the vcpkg port at D:\vcpkg\ports\directxmath to match a specific +GitHub release by tag. It updates the version-date in vcpkg.json and the tag and SHA512 +hash in portfile.cmake for the source archive. + +.PARAMETER Tag +The GitHub release tag (e.g., 'may2026', 'mar2026'). Defaults to the latest tag. + +.LINK +https://github.com/microsoft/DirectXMath/wiki + +#> + +param( + [string]$Tag = "" +) + +$repoRoot = Split-Path -Path $PSScriptRoot -Parent +$portDir = "D:\vcpkg\ports\directxmath" +$vcpkgJson = Join-Path $portDir "vcpkg.json" +$portfile = Join-Path $portDir "portfile.cmake" + +if ((-Not (Test-Path $vcpkgJson)) -Or (-Not (Test-Path $portfile))) { + Write-Error "ERROR: Cannot find vcpkg port files at $portDir" -ErrorAction Stop +} + +# Determine tag from latest git tag if not provided +if ($Tag.Length -eq 0) { + $Tag = (git --no-pager -C $repoRoot tag --sort=-creatordate | Select-Object -First 1).Trim() + if ($Tag.Length -eq 0) { + Write-Error "ERROR: Failed to determine latest tag!" -ErrorAction Stop + } +} + +Write-Host "Release Tag: $Tag" + +# Get version date from the git tag date +$tagDateStr = (git --no-pager -C $repoRoot log -1 --format=%ai $Tag).Trim() +if ([string]::IsNullOrEmpty($tagDateStr)) { + Write-Error "ERROR: Failed to get date for tag $Tag!" -ErrorAction Stop +} + +$versionDate = ([datetime]::Parse($tagDateStr)).ToString("yyyy-MM-dd") + +Write-Host "Version Date: $versionDate" + +# --- Update vcpkg.json --- +Write-Host "`nUpdating vcpkg.json..." + +$jsonContent = Get-Content $vcpkgJson -Raw +$jsonContent = $jsonContent -replace '"version-date":\s*"[^"]*"', "`"version-date`": `"$versionDate`"" +$jsonContent = $jsonContent -replace ',\s*"port-version":\s*\d+', '' +$jsonContent = $jsonContent -replace '"port-version":\s*\d+,?\s*', '' +Set-Content -Path $vcpkgJson -Value $jsonContent -NoNewline + +Write-Host " version-date set to $versionDate" + +# --- Update portfile.cmake tag --- +Write-Host "`nUpdating portfile.cmake tag..." + +$portContent = Get-Content $portfile -Raw +$portContent = $portContent -replace '(\n\s+REF\s+)\S+', "`${1}$Tag" +Set-Content -Path $portfile -Value $portContent -NoNewline + +Write-Host " Tag set to $Tag" + +# --- Download and hash source archive --- +$ProgressPreference = 'SilentlyContinue' +$tempDir = Join-Path $Env:Temp $(New-Guid) +New-Item -Type Directory -Path $tempDir | Out-Null + +$sourceUrl = "https://github.com/Microsoft/DirectXMath/archive/refs/tags/$Tag.tar.gz" +$sourcePath = Join-Path $tempDir "$Tag.tar.gz" + +Write-Host "`nDownloading source archive from $sourceUrl..." +try { + Invoke-WebRequest -Uri $sourceUrl -OutFile $sourcePath -ErrorAction Stop +} +catch { + Write-Error "ERROR: Failed to download source archive!" -ErrorAction Stop +} + +$sourceHash = (Get-FileHash -Path $sourcePath -Algorithm SHA512).Hash.ToLower() +Write-Host " Source SHA512: $sourceHash" + +# Replace SHA512 in vcpkg_from_github block +$portContent = Get-Content $portfile -Raw +$portContent = $portContent -replace '(vcpkg_from_github\s*\([^)]*SHA512\s+)[0-9a-fA-F]+', "`${1}$sourceHash" +Set-Content -Path $portfile -Value $portContent -NoNewline + +# --- Cleanup --- +Remove-Item -Recurse -Force $tempDir + +Write-Host "`nvcpkg port updated successfully!" +Write-Host "`nUpdated files:" +Write-Host " $vcpkgJson" +Write-Host " $portfile" + +$portContent = Get-Content $portfile -Raw +if ($portContent -match '\bPATCHES\b') { + Write-Warning "This port includes patches. Review them to either remove or update." +}