[release/v7.6] Refactor: Centralize xUnit tests into reusable workflow and remove legacy verification (#26488)

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: TravisEz13 <10873629+TravisEz13@users.noreply.github.com>
This commit is contained in:
Travis Plunk
2025-11-19 14:55:27 -08:00
committed by GitHub
co-authored by Copilot TravisEz13
parent 46f219cbd0
commit 51e4d5c0ba
11 changed files with 515 additions and 71 deletions
-14
View File
@@ -31,22 +31,8 @@ runs:
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
@@ -1,21 +0,0 @@
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
@@ -0,0 +1,95 @@
# Build Configuration Guide
## Choosing the Right Configuration
### For Testing
**Use: Default (Debug)**
```yaml
- name: Build for Testing
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
**Why Debug:**
- Includes debugging symbols
- Better error messages
- Faster build times
- Suitable for xUnit and Pester tests
**Do NOT use:**
- `-Configuration 'Release'` (unnecessary for tests)
- `-ReleaseTag` (not needed for tests)
- `-CI` (unless you specifically need Pester module)
### For Release/Packaging
**Use: Release with version tag**
```yaml
- name: Build for Release
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
```
**Why Release:**
- Optimized binaries
- No debug symbols (smaller size)
- Production-ready
### For Code Coverage
**Use: CodeCoverage configuration**
```yaml
- name: Build with Coverage
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild -Configuration 'CodeCoverage'
```
## Platform Considerations
### All Platforms
Same commands work across Linux, Windows, and macOS:
```yaml
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Build PowerShell
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
### Output Locations
**Linux/macOS:**
```
src/powershell-unix/bin/Debug/<netversion>/<runtime>/publish/
```
**Windows:**
```
src/powershell-win-core/bin/Debug/<netversion>/<runtime>/publish/
```
## Best Practices
1. Use default configuration for testing
2. Avoid redundant parameters
3. Match configuration to purpose
4. Use `-CI` only when needed
5. Always specify `-ReleaseTag` for release or packaging builds
@@ -0,0 +1,71 @@
# Git Requirements for Building PowerShell
## Fetch Depth
**Required:** `fetch-depth: 1000`
The PowerShell build process uses `git describe --abbrev=60 --long` to generate version information. This requires access to git history and tags.
### Problem
Without sufficient fetch depth, builds fail with:
```
error MSB3073: The command "git describe --abbrev=60 --long" exited with code 128.
```
### Solution
Always use `fetch-depth: 1000` in the checkout step:
```yaml
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
```
## Tag Synchronization
**Required:** `Sync-PSTags -AddRemoteIfMissing`
The build process needs git tags to properly version the build.
### Problem
Without tag synchronization:
- Version information is incorrect
- Build versioning fails
### Solution
Include tag synchronization in the bootstrap step:
```yaml
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Sync-PSTags -AddRemoteIfMissing
```
## Complete Example
```yaml
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
```
@@ -0,0 +1,92 @@
# Start-PSBuild Basics
## Purpose
`Start-PSBuild` builds PowerShell from source. It's defined in `build.psm1` and used in CI/CD workflows.
## Default Usage
For most scenarios, use with no parameters:
```powershell
Import-Module ./tools/ci.psm1
Start-PSBuild
```
**Default behavior:**
- Configuration: `Debug`
- PSModuleRestore: Enabled
- Runtime: Auto-detected for platform
## Common Configurations
### Debug Build (Default)
```powershell
Start-PSBuild
```
Use for:
- Testing (xUnit, Pester)
- Development
- Debugging
### Release Build
```powershell
Start-PSBuild -Configuration 'Release'
```
Use for:
- Production packages
- Distribution
- Performance testing
### Code Coverage Build
```powershell
Start-PSBuild -Configuration 'CodeCoverage'
```
Use for:
- Code coverage analysis
- Test coverage reports
## Common Parameters
### -Configuration
Values: `Debug`, `Release`, `CodeCoverage`, `StaticAnalysis`
Default: `Debug`
### -CI
Restores Pester module for CI environments.
```powershell
Start-PSBuild -CI
```
### -PSModuleRestore
Now enabled by default. Use `-NoPSModuleRestore` to skip.
### -ReleaseTag
Specifies version tag for release builds:
```powershell
$releaseTag = Get-ReleaseTag
Start-PSBuild -Configuration 'Release' -ReleaseTag $releaseTag
```
## Workflow Example
```yaml
- name: Build PowerShell
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
@@ -0,0 +1,92 @@
# Troubleshooting Build Issues
## Git Describe Error
**Error:**
```
error MSB3073: The command "git describe --abbrev=60 --long" exited with code 128.
```
**Cause:** Insufficient git history (shallow clone)
**Solution:** Add `fetch-depth: 1000` to checkout step
```yaml
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
```
## Version Information Incorrect
**Symptom:** Build produces wrong version numbers
**Cause:** Git tags not synchronized
**Solution:** Run `Sync-PSTags -AddRemoteIfMissing`:
```yaml
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
```
## PowerShell Binary Not Built
**Error:**
```
Exception: CoreCLR pwsh.exe was not built
```
**Causes:**
1. Build failed (check logs)
2. Wrong configuration used
3. Build output location incorrect
**Solutions:**
1. Check build logs for errors
2. Verify correct configuration for use case
3. Use default parameters: `Start-PSBuild`
## Module Restore Issues
**Symptom:** Slow build or module restore failures
**Causes:**
- Network issues
- Module cache problems
- Package source unavailable
**Solutions:**
1. Retry the build
2. Check network connectivity
3. Use `-NoPSModuleRestore` if modules not needed
4. Clear package cache if persistent
## .NET SDK Not Found
**Symptom:** Build can't find .NET SDK
**Solution:** Ensure .NET setup step runs first:
```yaml
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
```
## Bootstrap Failures
**Symptom:** Invoke-CIInstall fails
**Causes:**
- Missing dependencies
- Network issues
- Platform-specific requirements not met
**Solution:** Check prerequisites for your platform in build system docs
@@ -0,0 +1,91 @@
# Workflow Prerequisites for Building PowerShell
## Required Steps Before Start-PSBuild
These steps must run before calling `Start-PSBuild`:
### 1. Checkout
```yaml
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000 # Required for version generation
```
### 2. Setup .NET
```yaml
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
```
### 3. Bootstrap
```yaml
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
```
## Complete Prerequisites Example
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
- name: Build PowerShell
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
```
## Why Each Step Matters
**Checkout with fetch-depth:**
- Build needs git history for versioning
- Without it: `git describe` fails
**Setup .NET:**
- Provides SDK for building
- Uses version from global.json
**Bootstrap:**
- Installs dependencies
- Syncs git tags
- Prepares build environment
## Optional Steps
### Environment Capture (Debugging)
```yaml
- name: Capture Environment
run: |
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | Write-Verbose -Verbose
shell: pwsh
```
+7 -12
View File
@@ -146,20 +146,15 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
verify_xunit:
name: Verify xUnit test results
xunit_tests:
name: xUnit Tests
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 1000
- name: Verify xUnit test results
uses: "./.github/actions/test/verify_xunit"
uses: ./.github/workflows/xunit-tests.yml
with:
runner_os: ubuntu-latest
test_results_artifact_name: testResults-xunit
## Temporarily disable the CodeQL analysis on Linux as it doesn't work for .NET SDK 10-rc.2.
# analyze:
@@ -224,7 +219,7 @@ jobs:
ready_to_merge:
name: Linux ready to merge
needs:
- verify_xunit
- xunit_tests
- linux_test_elevated_ci
- linux_test_elevated_others
- linux_test_unelevated_ci
+7 -12
View File
@@ -143,20 +143,15 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
verify_xunit:
name: Verify xUnit test results
xunit_tests:
name: xUnit Tests
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 1000
- name: Verify xUnit test results
uses: "./.github/actions/test/verify_xunit"
uses: ./.github/workflows/xunit-tests.yml
with:
runner_os: macos-15-large
test_results_artifact_name: testResults-xunit
PackageMac-macos_packaging:
name: macOS packaging (bootstrap only)
needs:
@@ -176,7 +171,7 @@ jobs:
ready_to_merge:
name: macos ready to merge
needs:
- verify_xunit
- xunit_tests
- PackageMac-macos_packaging
- macos_test_elevated_ci
- macos_test_elevated_others
+7 -12
View File
@@ -147,20 +147,15 @@ jobs:
with:
purpose: ElevatedPesterTests
tagSet: Others
verify_xunit:
name: Verify xUnit test results
xunit_tests:
name: xUnit Tests
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
runs-on: windows-latest
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 1000
- name: Verify xUnit test results
uses: "./.github/actions/test/verify_xunit"
uses: ./.github/workflows/xunit-tests.yml
with:
runner_os: windows-latest
test_results_artifact_name: testResults-xunit
windows_packaging:
name: Windows Packaging
needs:
@@ -170,7 +165,7 @@ jobs:
ready_to_merge:
name: windows ready to merge
needs:
- verify_xunit
- xunit_tests
- windows_test_elevated_ci
- windows_test_elevated_others
- windows_test_unelevated_ci
+53
View File
@@ -0,0 +1,53 @@
name: xUnit Tests (Reusable)
on:
workflow_call:
inputs:
runner_os:
description: 'Runner OS for xUnit tests'
type: string
required: false
default: ubuntu-latest
test_results_artifact_name:
description: 'Artifact name for xUnit test results directory'
type: string
required: false
default: testResults-xunit
jobs:
xunit:
name: Run xUnit Tests
runs-on: ${{ inputs.runner_os }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1000
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: ./global.json
- name: Bootstrap
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Invoke-CIInstall -SkipUser
Sync-PSTags -AddRemoteIfMissing
- name: Build PowerShell and run xUnit tests
shell: pwsh
run: |
Import-Module ./tools/ci.psm1
Start-PSBuild
Write-Host "Running full xUnit test suite (no skipping)..."
Invoke-CIxUnit
Write-Host "Completed xUnit test run."
- name: Upload xUnit results
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ inputs.test_results_artifact_name }}
path: ${{ github.workspace }}/xUnitTestResults.xml