Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: "Copilot Setup Steps"

# Allow testing of the setup steps from your repository's "Actions" tab.
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.
# See https://docs.github.com/en/copilot/customizing-copilot/customizing-the-development-environment-for-copilot-coding-agent
copilot-setup-steps:
runs-on: 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

- name: Bootstrap
if: success()
run: |-
$title = 'Import Build.psm1'
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
Write-LogGroupEnd -Title $title

$title = 'Bootstrap'
Write-LogGroupStart -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

$title = 'Setup .NET environment variables'
Write-LogGroupStart -Title $title
Find-DotNet -SetDotnetRoot
Write-LogGroupEnd -Title $title
shell: pwsh
106 changes: 98 additions & 8 deletions build.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -2282,7 +2282,12 @@ function Start-PSBootstrap {
[switch]$BuildLinuxArm,
[switch]$Force,
[Parameter(Mandatory = $true)]
[ValidateSet("Package", "DotNet", "Both")]
# Package: Install dependencies for packaging tools (fpm, rpmbuild, WiX)
# DotNet: Install the .NET SDK
# 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")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed offline, the Both value should be remove, so that

  • for dev/CI, we can use -Scenario All
  • for official build, we must use individual scenario explicitly

The cleanup can be done in a separate PR.
Ideally, this parameter should be made a flags Enum, so a caller can provide arbitrary combination :)

[string]$Scenario = "Package"
)

Expand Down Expand Up @@ -2402,15 +2407,15 @@ 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"
Install-GlobalGem -Sudo $sudo -GemName "ffi" -GemVersion "1.16.3"
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..."
Expand All @@ -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"

Expand Down Expand Up @@ -2479,6 +2484,19 @@ function Start-PSBootstrap {
}
}

if ($Scenario -in 'All', '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
Expand Down Expand Up @@ -2646,6 +2664,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
Expand Down Expand Up @@ -2676,25 +2751,40 @@ 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.")) {
# 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) {
Write-Verbose -Verbose "Adding .NET tools path to PATH: $dotnetToolsPath"
Add-PSEnvironmentPath -Path $dotnetToolsPath
}
}
}

<#
Expand Down
Loading