From 969938a76886aba2dd2ae69d56999383f38a073e Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 22 Oct 2025 16:59:34 -0700 Subject: [PATCH 1/8] Create github copilot setup workflow --- .github/workflows/copilot-setup-steps.yml | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/copilot-setup-steps.yml diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 00000000000..54395615936 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,35 @@ +name: "Copilot Setup Steps" + +# Allow testing of the setup steps from your repository's "Actions" tab. +on: workflow_dispatch + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + # See https://docs.github.com/en/copilot/customizing-copilot/customizing-the-development-environment-for-copilot-coding-agent + copilot-setup-steps: + runs-on: 8-core-ubuntu-latest + + permissions: + contents: read + + # You can define any steps you want, and they will run before the agent starts. + # If you do not check out your code, Copilot will do this for you. + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 1000 + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: ./global.json + + - name: Bootstrap + if: success() + run: |- + Write-Verbose -Verbose "Running Bootstrap..." + Import-Module .\tools\ci.psm1 + Invoke-CIInstall -SkipUser + Write-Verbose -Verbose "Start Sync-PSTags" + Sync-PSTags -AddRemoteIfMissing + Write-Verbose -Verbose "End Sync-PSTags" + shell: pwsh From 2b60d3ab1ce6a86bc4901e8ef9311537aa2a7c26 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 11:39:56 -0700 Subject: [PATCH 2/8] Enhance CI workflow with logging and .NET setup Refactor CI setup steps to include logging and environment setup. --- .github/workflows/copilot-setup-steps.yml | 35 +++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 54395615936..798e731e0a9 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -19,17 +19,34 @@ jobs: with: fetch-depth: 1000 - - uses: actions/setup-dotnet@v4 - with: - global-json-file: ./global.json - - name: Bootstrap if: success() run: |- - Write-Verbose -Verbose "Running Bootstrap..." - Import-Module .\tools\ci.psm1 - Invoke-CIInstall -SkipUser - Write-Verbose -Verbose "Start Sync-PSTags" + $title = 'Import Build.psm1' + Write-Host "::group::$title" + Import-Module ./build.psm1 -Verbose -ErrorAction Stop + Write-LogGroupEnd -Title $title + + $title = 'Bootstrap' + Write-LogGroupStart -Title $title + # Switch to public sources in CI + Start-PSBootstrap -scenario dotnet + Write-LogGroupEnd -Title $title + + $title = 'switch to public feed' + Write-LogGroupStart -Title $title + # Switch to public sources in CI + Switch-PSNugetConfig -Source Public + Write-LogGroupEnd -title $title + + $title = 'Sync Tags' + Write-LogGroupStart -Title $title Sync-PSTags -AddRemoteIfMissing - Write-Verbose -Verbose "End Sync-PSTags" + Write-LogGroupEnd -title $title + + + $title = 'Setup .NET environment variables' + Write-LogGroupStart -Title $title + Find-DotNet -SetDotnetRoot + Write-LogGroupEnd -title $title shell: pwsh From f6e3706845e23b4abcaf04d8a7245fd7af733752 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 19:17:30 +0000 Subject: [PATCH 3/8] Refactor Copilot setup steps and enhance .NET tool installation process --- .github/workflows/copilot-setup-steps.yml | 22 +++--- build.psm1 | 95 +++++++++++++++++++++-- 2 files changed, 101 insertions(+), 16 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 798e731e0a9..ea065308832 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -27,26 +27,28 @@ jobs: Import-Module ./build.psm1 -Verbose -ErrorAction Stop Write-LogGroupEnd -Title $title - $title = 'Bootstrap' + $title = 'Switch to public feed' Write-LogGroupStart -Title $title - # Switch to public sources in CI - Start-PSBootstrap -scenario dotnet + Switch-PSNugetConfig -Source Public Write-LogGroupEnd -Title $title - $title = 'switch to public feed' + $title = 'Bootstrap' Write-LogGroupStart -Title $title - # Switch to public sources in CI - Switch-PSNugetConfig -Source Public - Write-LogGroupEnd -title $title + Start-PSBootstrap -Scenario DotNet + Write-LogGroupEnd -Title $title + + $title = 'Install .NET Tools' + Write-LogGroupStart -Title $title + Start-PSBootstrap -Scenario Tools + Write-LogGroupEnd -Title $title $title = 'Sync Tags' Write-LogGroupStart -Title $title Sync-PSTags -AddRemoteIfMissing - Write-LogGroupEnd -title $title - + Write-LogGroupEnd -Title $title $title = 'Setup .NET environment variables' Write-LogGroupStart -Title $title Find-DotNet -SetDotnetRoot - Write-LogGroupEnd -title $title + Write-LogGroupEnd -Title $title shell: pwsh diff --git a/build.psm1 b/build.psm1 index 88878bdd635..d0f12346523 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2282,7 +2282,7 @@ function Start-PSBootstrap { [switch]$BuildLinuxArm, [switch]$Force, [Parameter(Mandatory = $true)] - [ValidateSet("Package", "DotNet", "Both")] + [ValidateSet("Package", "DotNet", "Both", "Tools")] [string]$Scenario = "Package" ) @@ -2410,7 +2410,7 @@ function Start-PSBootstrap { Install-GlobalGem -Sudo $sudo -GemName "fpm" -GemVersion "1.15.1" Install-GlobalGem -Sudo $sudo -GemName "rexml" -GemVersion "3.2.5" } - + # For RPM-based systems, ensure rpmbuild is available if ($environment.IsLinux -and ($environment.IsRedHatFamily -or $environment.IsSUSEFamily -or $environment.IsMariner)) { Write-Verbose -Verbose "Checking for rpmbuild..." @@ -2479,6 +2479,19 @@ function Start-PSBootstrap { } } + if ($Scenario -eq 'Tools') { + Write-Log -message "Installing .NET global tools" + + # Ensure dotnet is available + Find-Dotnet + + # Install dotnet-format + Write-Verbose -Verbose "Installing dotnet-format global tool" + Start-NativeExecution { + dotnet tool install --global dotnet-format + } + } + if ($env:TF_BUILD) { Write-Verbose -Verbose "--- Start - Capturing nuget sources" dotnet nuget list source --format detailed @@ -2646,6 +2659,63 @@ function Start-ResGen } } +function Add-PSEnvironmentPath { + <# + .SYNOPSIS + Adds a path to the process PATH and persists to GitHub Actions workflow if running in GitHub Actions + .PARAMETER Path + Path to add to PATH + .PARAMETER Prepend + If specified, prepends the path instead of appending + #> + param ( + [Parameter(Mandatory)] + [string]$Path, + + [switch]$Prepend + ) + + # Set in current process + if ($Prepend) { + $env:PATH = $Path + [IO.Path]::PathSeparator + $env:PATH + } else { + $env:PATH += [IO.Path]::PathSeparator + $Path + } + + # Persist to GitHub Actions workflow if running in GitHub Actions + if ($env:GITHUB_ACTIONS -eq 'true') { + Write-Verbose -Verbose "Adding $Path to GITHUB_PATH" + Add-Content -Path $env:GITHUB_PATH -Value $Path + } +} + +function Set-PSEnvironmentVariable { + <# + .SYNOPSIS + Sets an environment variable in the process and persists to GitHub Actions workflow if running in GitHub Actions + .PARAMETER Name + The name of the environment variable + .PARAMETER Value + The value of the environment variable + #> + param ( + [Parameter(Mandatory)] + [string]$Name, + + [Parameter(Mandatory)] + [string]$Value + ) + + # Set in current process + Set-Item -Path "env:$Name" -Value $Value + + # Persist to GitHub Actions workflow if running in GitHub Actions + if ($env:GITHUB_ACTIONS -eq 'true') { + Write-Verbose -Verbose "Setting $Name in GITHUB_ENV" + Add-Content -Path $env:GITHUB_ENV -Value "$Name=$Value" + } +} + function Find-Dotnet { param ( [switch] $SetDotnetRoot @@ -2676,25 +2746,38 @@ function Find-Dotnet { if ($dotnetCLIInstalledVersion -ne $chosenDotNetVersion) { Write-Warning "The 'dotnet' in the current path can't find SDK version ${dotnetCLIRequiredVersion}, prepending $dotnetPath to PATH." # Globally installed dotnet doesn't have the required SDK version, prepend the user local dotnet location - $env:PATH = $dotnetPath + [IO.Path]::PathSeparator + $env:PATH + Add-PSEnvironmentPath -Path $dotnetPath -Prepend if ($SetDotnetRoot) { Write-Verbose -Verbose "Setting DOTNET_ROOT to $dotnetPath" - $env:DOTNET_ROOT = $dotnetPath + Set-PSEnvironmentVariable -Name 'DOTNET_ROOT' -Value $dotnetPath } } elseif ($SetDotnetRoot) { Write-Verbose -Verbose "Expected dotnet version found, setting DOTNET_ROOT to $dotnetPath" - $env:DOTNET_ROOT = $dotnetPath + Set-PSEnvironmentVariable -Name 'DOTNET_ROOT' -Value $dotnetPath } } else { Write-Warning "Could not find 'dotnet', appending $dotnetPath to PATH." - $env:PATH += [IO.Path]::PathSeparator + $dotnetPath + Add-PSEnvironmentPath -Path $dotnetPath + + if ($SetDotnetRoot) { + Write-Verbose -Verbose "Setting DOTNET_ROOT to $dotnetPath" + Set-PSEnvironmentVariable -Name 'DOTNET_ROOT' -Value $dotnetPath + } } if (-not (precheck 'dotnet' "Still could not find 'dotnet', restoring PATH.")) { $env:PATH = $originalPath } + elseif ($SetDotnetRoot) { + # Add .NET global tools to PATH when setting up the environment + $dotnetToolsPath = Join-Path $dotnetPath "tools" + if (Test-Path $dotnetToolsPath) { + Write-Verbose -Verbose "Adding .NET tools path to PATH: $dotnetToolsPath" + Add-PSEnvironmentPath -Path $dotnetToolsPath + } + } } <# From 6d85f6335b5f6966ac9d9fa205c81314c09f8d64 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 13:26:08 -0700 Subject: [PATCH 4/8] Apply suggestion from @TravisEz13 --- .github/workflows/copilot-setup-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index ea065308832..79e13e6586d 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -7,7 +7,7 @@ jobs: # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. # See https://docs.github.com/en/copilot/customizing-copilot/customizing-the-development-environment-for-copilot-coding-agent copilot-setup-steps: - runs-on: 8-core-ubuntu-latest + runs-on: ubuntu-latest permissions: contents: read From a3b18ca953ee03730e29e5aa1de8fed7d9b4484d Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 21:54:24 +0000 Subject: [PATCH 5/8] Update workflow triggers for Copilot setup steps to include pull request events --- .github/workflows/copilot-setup-steps.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index ea065308832..397c947812f 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -1,7 +1,14 @@ name: "Copilot Setup Steps" # Allow testing of the setup steps from your repository's "Actions" tab. -on: workflow_dispatch +on: + workflow_dispatch: + + pull_request: + branches: + - master + paths: + - ".github/workflows/copilot-setup-steps.yml" jobs: # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. @@ -18,7 +25,7 @@ jobs: - uses: actions/checkout@v5 with: fetch-depth: 1000 - + - name: Bootstrap if: success() run: |- @@ -26,7 +33,7 @@ jobs: Write-Host "::group::$title" Import-Module ./build.psm1 -Verbose -ErrorAction Stop Write-LogGroupEnd -Title $title - + $title = 'Switch to public feed' Write-LogGroupStart -Title $title Switch-PSNugetConfig -Source Public @@ -36,7 +43,7 @@ jobs: Write-LogGroupStart -Title $title Start-PSBootstrap -Scenario DotNet Write-LogGroupEnd -Title $title - + $title = 'Install .NET Tools' Write-LogGroupStart -Title $title Start-PSBootstrap -Scenario Tools @@ -46,7 +53,7 @@ jobs: Write-LogGroupStart -Title $title Sync-PSTags -AddRemoteIfMissing Write-LogGroupEnd -Title $title - + $title = 'Setup .NET environment variables' Write-LogGroupStart -Title $title Find-DotNet -SetDotnetRoot From ae2f30460058ad183558d433ccc2dff854d1fe9b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 22:06:24 +0000 Subject: [PATCH 6/8] Enhance Start-PSBootstrap function to include 'All' option for dependency installation scenarios --- build.psm1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/build.psm1 b/build.psm1 index d0f12346523..5c74c130787 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2282,7 +2282,12 @@ function Start-PSBootstrap { [switch]$BuildLinuxArm, [switch]$Force, [Parameter(Mandatory = $true)] - [ValidateSet("Package", "DotNet", "Both", "Tools")] + # Package: Install dependencies for packaging tools (fpm, rpmbuild, WiX) + # DotNet: Install the .NET SDK + # Both: Install both packaging and .NET SDK dependencies + # Tools: Install .NET global tools (e.g., dotnet-format) + # All: Install all dependencies (packaging, .NET SDK, and tools) + [ValidateSet("Package", "DotNet", "Both", "Tools", "All")] [string]$Scenario = "Package" ) @@ -2402,7 +2407,7 @@ function Start-PSBootstrap { # Install [fpm](https://github.com/jordansissel/fpm) # Note: fpm is now only needed for DEB and macOS packages; RPM packages use rpmbuild directly - if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { + if ($Scenario -in 'All', 'Both', 'Package') { # Install fpm on Debian-based systems, macOS, and Mariner (where DEB packages are built) if (($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) -or $environment.IsMacOS) { Install-GlobalGem -Sudo $sudo -GemName "dotenv" -GemVersion "2.8.1" @@ -2422,7 +2427,7 @@ function Start-PSBootstrap { } } - if ($Scenario -eq 'DotNet' -or $Scenario -eq 'Both') { + if ($Scenario -in 'All', 'Both', 'DotNet') { Write-Verbose -Verbose "Calling Find-Dotnet from Start-PSBootstrap" @@ -2479,7 +2484,7 @@ function Start-PSBootstrap { } } - if ($Scenario -eq 'Tools') { + if ($Scenario -in 'All', 'Tools') { Write-Log -message "Installing .NET global tools" # Ensure dotnet is available From 7d0b581d89e5542c7f718082113c08e4dd455bfa Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 23 Oct 2025 22:07:10 +0000 Subject: [PATCH 7/8] Enhance Find-Dotnet function to restore original PATH and add .NET global tools path when found --- build.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.psm1 b/build.psm1 index 5c74c130787..a4d148e4789 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2773,9 +2773,11 @@ function Find-Dotnet { } if (-not (precheck 'dotnet' "Still could not find 'dotnet', restoring PATH.")) { + # Give up, restore original PATH. There is nothing to persist since we didn't make a change. $env:PATH = $originalPath } elseif ($SetDotnetRoot) { + # If we found dotnet, also add the global tools path to PATH # Add .NET global tools to PATH when setting up the environment $dotnetToolsPath = Join-Path $dotnetPath "tools" if (Test-Path $dotnetToolsPath) { From b86fe1c740e2c6b10a4f306b5df494601ccfd61d Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Thu, 23 Oct 2025 16:02:49 -0700 Subject: [PATCH 8/8] Apply suggestion from @TravisEz13 Co-authored-by: Travis Plunk --- build.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.psm1 b/build.psm1 index a4d148e4789..1b56d9d545d 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2284,7 +2284,7 @@ function Start-PSBootstrap { [Parameter(Mandatory = $true)] # Package: Install dependencies for packaging tools (fpm, rpmbuild, WiX) # DotNet: Install the .NET SDK - # Both: Install both packaging and .NET SDK dependencies + # Both: Package and DotNet scenarios # Tools: Install .NET global tools (e.g., dotnet-format) # All: Install all dependencies (packaging, .NET SDK, and tools) [ValidateSet("Package", "DotNet", "Both", "Tools", "All")]