[release/v7.4]Convert powershell/PowerShell-Windows-CI to GitHub Actions (#24932)

This commit is contained in:
Travis Plunk
2025-02-04 14:23:32 -08:00
committed by GitHub
parent eb2bf0c448
commit 08414b5cd6
9 changed files with 354 additions and 44 deletions
+49
View File
@@ -0,0 +1,49 @@
name: CI Build
description: 'Builds PowerShell'
runs:
using: composite
steps:
- name: Capture Environment
if: success() || failure()
run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
shell: pwsh
- name: Set Build Name for Non-PR
if: github.event_name != 'PullRequest'
run: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))"
shell: pwsh
- 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
- name: Build
if: success()
run: |-
Write-Verbose -Verbose "Running Build..."
Import-Module .\tools\ci.psm1
Invoke-CIBuild
shell: pwsh
- name: xUnit Tests
if: success()
continue-on-error: true
run: |-
Write-Verbose -Verbose "Running xUnit tests..."
Import-Module .\tools\ci.psm1
Restore-PSOptions
Invoke-CIxUnit -SkipFailing
shell: pwsh
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build
path: ${{ runner.workspace }}/build
- name: Upload xunit artifact
uses: actions/upload-artifact@v4
with:
name: testResults-xunit
path: ${{ runner.workspace }}/xunit
@@ -0,0 +1,21 @@
name: verify_xunit
description: 'Verify xUnit Results'
runs:
using: composite
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
path: "${{ github.workspace }}"
- name: Capture artifacts directory
continue-on-error: true
run: dir "${{ github.workspace }}\testResults-xunit\*" -Recurse
shell: pwsh
- name: Test
if: success()
run: |-
Import-Module .\tools\ci.psm1
$xUnitTestResultsFile = "${{ github.workspace }}\testResults-xunit\xUnitTestResults.xml"
Test-XUnitTestResults -TestResultsFile $xUnitTestResultsFile
shell: pwsh
+107
View File
@@ -0,0 +1,107 @@
name: windows_test
description: 'Test PowerShell on Windows'
inputs:
purpose:
required: false
default: ''
type: string
tagSet:
required: false
default: CI
type: string
ctrfFolder:
required: false
default: ctrf
type: string
runs:
using: composite
steps:
- name: Capture Environment
if: success() || failure()
run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
shell: pwsh
- name: Download Build Artifacts
uses: actions/download-artifact@v4
with:
path: "${{ github.workspace }}"
- name: Capture Artifacts Directory
continue-on-error: true
run: Get-ChildItem "${{ github.workspace }}\build\*" -Recurse
shell: pwsh
- name: Bootstrap
shell: powershell
run: |-
# Remove "Program Files\dotnet" from the env variable PATH, so old SDKs won't affect us.
Write-Host "Old Path:"
Write-Host $env:Path
$dotnetPath = Join-Path $env:SystemDrive 'Program Files\dotnet'
$paths = $env:Path -split ";" | Where-Object { -not $_.StartsWith($dotnetPath) }
$env:Path = $paths -join ";"
Write-Host "New Path:"
Write-Host $env:Path
# Bootstrap
Import-Module .\tools\ci.psm1
Invoke-CIInstall
- name: Test
if: success()
run: |-
Import-Module .\build.psm1 -force
Start-PSBootstrap
Import-Module .\tools\ci.psm1
Restore-PSOptions -PSOptionsPath '${{ github.workspace }}\build\psoptions.json'
$options = (Get-PSOptions)
$path = split-path -path $options.Output
$rootPath = split-Path -path $path
Expand-Archive -Path '${{ github.workspace }}\build\build.zip' -DestinationPath $rootPath -Force
Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -OutputFormat JUnitXml
shell: pwsh
- name: Convert JUnit to CTRF
run: |-
Get-ChildItem -Path "${{ runner.workspace }}/testResults/*.xml" -Recurse | ForEach-Object {
npx --yes junit-to-ctrf $_.FullName --output .\${{ inputs.ctrfFolder }}\$($_.BaseName).json --tool Pester --env 'Windows ${{ inputs.purpose }} ${{ inputs.tagSet }}'
}
shell: powershell
# this task only takes / as directory separators
- name: Publish Test Report
uses: ctrf-io/github-test-reporter@v1
with:
report-path: './${{ inputs.ctrfFolder }}/*.json'
exit-on-fail: true
summary-report: true
test-report: false
test-list-report: false
failed-report: false
fail-rate-report: false
flaky-report: false
flaky-rate-report: false
failed-folded-report: true
previous-results-report: false
ai-report: true
skipped-report: false
suite-folded-report: false
suite-list-report: false
pull-request-report: false
commit-report: false
custom-report: false
if: always()
- name: Upload testResults artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: junit-pester-${{ inputs.purpose }}-${{ inputs.tagSet }}
path: ${{ runner.workspace }}\testResults
- name: Upload ctrf artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: ctrf-pester-${{ inputs.purpose }}-${{ inputs.tagSet }}
path: ${{ inputs.ctrfFolder }}
+2 -1
View File
@@ -1,6 +1,6 @@
name: Auto Assign PR Maintainer
on:
pull_request:
issues:
types: [opened, edited]
permissions:
contents: read
@@ -13,6 +13,7 @@ jobs:
pull-requests: write
steps:
- uses: wow-actions/auto-assign@67fafa03df61d7e5f201734a2fa60d1ab111880d # v3.0.2
if: github.event.issue.pull_request
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# using the `org/team_slug` or `/team_slug` syntax to add git team as reviewers
-39
View File
@@ -1,39 +0,0 @@
# This cannot rebase workflow changes into a PR
# It also only works if the GITHUB_TOKEN has permission to push to the branch
# see: https://github.com/cirrus-actions/rebase/issues/12#issuecomment-632594995
on:
issue_comment:
types: [created]
name: Automatic Rebase
permissions:
contents: read
jobs:
rebase:
permissions:
contents: write # for cirrus-actions/rebase to push code to rebase
pull-requests: write # for actions/github-script to create PR comment
name: Rebase
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
runs-on: ubuntu-latest
steps:
- name: Checkout the latest code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
- name: Post rebase started comment to pull request
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
continue-on-error: true
with:
script: |
const backport_start_body = `Started rebase: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`;
await github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: backport_start_body
});
- name: Automatic Rebase
uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+122
View File
@@ -0,0 +1,122 @@
name: Windows-CI
on:
workflow_dispatch:
push:
branches:
- master
- release/**
paths:
- "*"
- "!.vsts-ci/misc-analysis.yml"
- "!.github/ISSUE_TEMPLATE/*"
- "!.github/workflows/*"
- "!.dependabot/config.yml"
- "!test/perf/*"
- "!.pipelines/*"
pull_request:
branches:
- master
- release/**
paths:
- ".vsts-ci/templates/*"
- ".vsts-ci/windows.yml"
- "*.props"
- build.psm1
- src/*
- test/*
- tools/buildCommon/*
- tools/ci.psm1
- tools/WindowsCI.psm1
- "!test/common/markdown/*"
- "!test/perf/*"
permissions:
contents: read
run-name: "${{ github.ref_name }} - ${{ github.run_number }}"
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'"
NugetSecurityAnalysisWarningLevel: none
POWERSHELL_TELEMETRY_OPTOUT: 1
__SuppressAnsiEscapeSequences: 1
nugetMultiFeedWarnLevel: none
jobs:
ci_build:
name: Build PowerShell
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Build
uses: "./.github/actions/build/ci"
windows_test:
name: Windows Unelevated CI
needs: ci_build
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Windows Unelevated CI
uses: "./.github/actions/test/windows"
with:
purpose: UnelevatedPesterTests
tagSet: CI
windows_test_2:
name: Windows Elevated CI
needs: ci_build
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Windows Elevated CI
uses: "./.github/actions/test/windows"
with:
purpose: ElevatedPesterTests
tagSet: CI
windows_test_3:
name: Windows Unelevated Others
needs: ci_build
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Windows Unelevated Others
uses: "./.github/actions/test/windows"
with:
purpose: UnelevatedPesterTests
tagSet: Others
windows_test_4:
name: Windows Elevated Others
needs: ci_build
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Windows Elevated Others
uses: "./.github/actions/test/windows"
with:
purpose: ElevatedPesterTests
tagSet: Others
verify_xunit:
name: Verify xUnit test results
needs: ci_build
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v4.1.0
with:
fetch-depth: 1000
- name: Verify xUnit test results
uses: "./.github/actions/test/verify_xunit"
+7
View File
@@ -110,3 +110,10 @@ msbuild.binlog
# Ignore gzip files in the manpage folder
assets/manpage/*.gz
# Ignore files and folders generated by some gh cli extensions
tmp/*
.env.local
# Ignore CTRF report files
crtf/*
+10
View File
@@ -1751,6 +1751,16 @@ function Publish-TestResults
$resolvedPath = (Resolve-Path -Path $Path).ProviderPath
Write-Host "##vso[artifact.upload containerfolder=testResults;artifactname=testResults]$resolvedPath"
} elseif ($env:GITHUB_WORKFLOW -and $env:RUNNER_WORKSPACE) {
# In GitHub Actions
$destinationPath = Join-Path -Path $env:RUNNER_WORKSPACE -ChildPath 'testResults'
# Create the folder if it does not exist
if (!(Test-Path -Path $destinationPath)) {
$null = New-Item -ItemType Directory -Path $destinationPath -Force
}
Copy-Item -Path $Path -Destination $destinationPath -Force -Verbose
}
}
+36 -4
View File
@@ -17,8 +17,15 @@ if(Test-Path $dotNetPath)
# import build into the global scope so it can be used by packaging
# argumentList $true says ignore tha we may not be able to build
Import-Module (Join-Path $repoRoot 'build.psm1') -Verbose -Scope Global -ArgumentList $true
Import-Module (Join-Path $repoRoot 'tools\packaging') -Verbose -Scope Global
Write-Verbose "Importing build.psm1" -Verbose
Import-Module (Join-Path $repoRoot 'build.psm1') -Scope Global -ArgumentList $true
$buildCommands = Get-Command -Module build
Write-Verbose "Imported build.psm1 commands: $($buildCommands.Count)" -Verbose
Write-Verbose "Importing packaging.psm1" -Verbose
Import-Module (Join-Path $repoRoot 'tools\packaging') -Scope Global
$packagingCommands = Get-Command -Module packaging
Write-Verbose "Imported packaging.psm1 commands: $($packagingCommands.Count)" -Verbose
# import the windows specific functcion only in Windows PowerShell or on Windows
if($PSVersionTable.PSEdition -eq 'Desktop' -or $IsWindows)
@@ -224,9 +231,12 @@ function Invoke-CITest
[string] $Purpose,
[ValidateSet('CI', 'Others')]
[string] $TagSet,
[string] $TitlePrefix
[string] $TitlePrefix,
[string] $OutputFormat = "NUnitXml"
)
Write-Verbose -Verbose "CI test: OutputFormat: $OutputFormat"
# Set locale correctly for Linux CIs
Set-CorrectLocale
@@ -281,12 +291,14 @@ function Invoke-CITest
Terse = $true
Tag = @()
ExcludeTag = $ExcludeTag + 'RequireAdminOnWindows'
OutputFormat = $OutputFormat
}
$title = "Pester Unelevated - $TagSet"
if ($TitlePrefix) {
$title = "$TitlePrefix - $title"
}
Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)"
Start-PSPester @arguments -Title $title
# Fail the build, if tests failed
@@ -314,7 +326,10 @@ function Invoke-CITest
if ($TitlePrefix) {
$title = "$TitlePrefix - $title"
}
Start-PSPester @arguments -Title $title
# We just built the test tools, we don't need to rebuild them
Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)"
Start-PSPester @arguments -Title $title -SkipTestToolBuild
# Fail the build, if tests failed
Test-PSPesterResults -TestResultsFile $expFeatureTestResultFile
@@ -328,12 +343,15 @@ function Invoke-CITest
OutputFile = $testResultsAdminFile
Tag = @('RequireAdminOnWindows')
ExcludeTag = $ExcludeTag
OutputFormat = $OutputFormat
}
$title = "Pester Elevated - $TagSet"
if ($TitlePrefix) {
$title = "$TitlePrefix - $title"
}
Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)"
Start-PSPester @arguments -Title $title
# Fail the build, if tests failed
@@ -364,6 +382,8 @@ function Invoke-CITest
if ($TitlePrefix) {
$title = "$TitlePrefix - $title"
}
Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)"
Start-PSPester @arguments -Title $title
# Fail the build, if tests failed
@@ -437,6 +457,18 @@ function Push-Artifact
if ($env:TF_BUILD) {
# In Azure DevOps
Write-Host "##vso[artifact.upload containerfolder=$artifactName;artifactname=$artifactName;]$Path"
} elseif ($env:GITHUB_WORKFLOW -and $env:RUNNER_WORKSPACE) {
# In GitHub Actions
$destinationPath = Join-Path -Path $env:RUNNER_WORKSPACE -ChildPath $artifactName
# Create the folder if it does not exist
if (!(Test-Path -Path $destinationPath)) {
$null = New-Item -ItemType Directory -Path $destinationPath -Force
}
Copy-Item -Path $Path -Destination $destinationPath -Force -Verbose
} else {
Write-Warning "Push-Artifact is not supported in this environment."
}
}