Skip to content
Merged
4 changes: 3 additions & 1 deletion .github/actions/build/ci/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ runs:
steps:
- name: Capture Environment
if: success() || failure()
run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
run: |-
Import-Module .\tools\ci.psm1
Show-Environment
shell: pwsh
- name: Set Build Name for Non-PR
if: github.event_name != 'PullRequest'
Expand Down
4 changes: 3 additions & 1 deletion .github/actions/test/linux-packaging/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ runs:
steps:
- name: Capture Environment
if: success() || failure()
run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose'
run: |-
Import-Module ./tools/ci.psm1
Show-Environment
shell: pwsh

- uses: actions/setup-dotnet@v5
Expand Down
6 changes: 2 additions & 4 deletions .github/actions/test/nix/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ runs:
- name: Capture Environment
if: success() || failure()
run: |-
Import-Module ./build.psm1
Write-LogGroupStart -Title 'Environment'
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
Write-LogGroupEnd -Title 'Environment'
Import-Module ./tools/ci.psm1
Show-Environment
shell: pwsh

- name: Download Build Artifacts
Expand Down
6 changes: 2 additions & 4 deletions .github/actions/test/windows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ runs:
- name: Capture Environment
if: success() || failure()
run: |-
Import-Module ./build.psm1
Write-LogGroupStart -Title 'Environment'
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
Write-LogGroupEnd -Title 'Environment'
Import-Module ./tools/ci.psm1
Show-Environment
shell: pwsh

- name: Download Build Artifacts
Expand Down
181 changes: 181 additions & 0 deletions .github/instructions/log-grouping-guidelines.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
applyTo:
- "build.psm1"
- "tools/ci.psm1"
- ".github/**/*.yml"
- ".github/**/*.yaml"
---

# Log Grouping Guidelines for GitHub Actions

## Purpose

Guidelines for using `Write-LogGroupStart` and `Write-LogGroupEnd` to create collapsible log sections in GitHub Actions CI/CD runs.

## Key Principles

### 1. Groups Cannot Be Nested

GitHub Actions does not support nested groups. Only use one level of grouping.

**❌ Don't:**
```powershell
Write-LogGroupStart -Title "Outer Group"
Write-LogGroupStart -Title "Inner Group"
# ... operations ...
Write-LogGroupEnd -Title "Inner Group"
Write-LogGroupEnd -Title "Outer Group"
```

**✅ Do:**
```powershell
Write-LogGroupStart -Title "Operation A"
# ... operations ...
Write-LogGroupEnd -Title "Operation A"

Write-LogGroupStart -Title "Operation B"
# ... operations ...
Write-LogGroupEnd -Title "Operation B"
```

### 2. Groups Should Be Substantial

Only create groups for operations that generate substantial output (5+ lines). Small groups add clutter without benefit.

**❌ Don't:**
```powershell
Write-LogGroupStart -Title "Generate Resource Files"
Write-Log -message "Run ResGen"
Start-ResGen
Write-LogGroupEnd -Title "Generate Resource Files"
```

**✅ Do:**
```powershell
Write-Log -message "Run ResGen (generating C# bindings for resx files)"
Start-ResGen
```

### 3. Groups Should Represent Independent Operations

Each group should be a logically independent operation that users might want to expand/collapse separately.

**✅ Good examples:**
- Install Native Dependencies
- Install .NET SDK
- Build PowerShell
- Restore NuGet Packages

**❌ Bad examples:**
- Individual project restores (too granular)
- Small code generation steps (too small)
- Sub-steps of a larger operation (would require nesting)

### 4. One Group Per Iteration Is Excessive

Avoid putting log groups inside loops where each iteration creates a separate group. This would probably cause nesting.

**❌ Don't:**
```powershell
$projects | ForEach-Object {
Write-LogGroupStart -Title "Restore Project: $_"
dotnet restore $_
Write-LogGroupEnd -Title "Restore Project: $_"
}
```

**✅ Do:**
```powershell
Write-LogGroupStart -Title "Restore All Projects"
$projects | ForEach-Object {
Write-Log -message "Restoring $_"
dotnet restore $_
}
Write-LogGroupEnd -Title "Restore All Projects"
```

## Usage Pattern

```powershell
Write-LogGroupStart -Title "Descriptive Operation Name"
try {
# ... operation code ...
Write-Log -message "Status updates"
}
finally {
# Ensure group is always closed
}
Write-LogGroupEnd -Title "Descriptive Operation Name"
```

## When to Use Log Groups

Use log groups for:
- Major build phases (bootstrap, restore, build, test, package)
- Installation operations (dependencies, SDKs, tools)
- Operations that produce 5+ lines of output
- Operations where users might want to collapse verbose output

Don't use log groups for:
- Single-line operations
- Code that's already inside another group
- Loop iterations with minimal output per iteration
- Diagnostic or debug output that should always be visible

## Examples from build.psm1

### Good Usage

```powershell
function Start-PSBootstrap {
# Multiple independent operations, each with substantial output
Write-LogGroupStart -Title "Install Native Dependencies"
# ... apt-get/yum/brew install commands ...
Write-LogGroupEnd -Title "Install Native Dependencies"

Write-LogGroupStart -Title "Install .NET SDK"
# ... dotnet installation ...
Write-LogGroupEnd -Title "Install .NET SDK"
}
```

### Avoid

```powershell
# Too small - just 2-3 lines
Write-LogGroupStart -Title "Generate Resource Files (ResGen)"
Write-Log -message "Run ResGen"
Start-ResGen
Write-LogGroupEnd -Title "Generate Resource Files (ResGen)"
```

## GitHub Actions Syntax

These functions emit GitHub Actions workflow commands:
- `Write-LogGroupStart` → `::group::Title`
- `Write-LogGroupEnd` → `::endgroup::`

In the GitHub Actions UI, this renders as collapsible sections with the specified title.

## Testing

Test log grouping locally:
```powershell
$env:GITHUB_ACTIONS = 'true'
Import-Module ./build.psm1
Write-LogGroupStart -Title "Test"
Write-Log -Message "Content"
Write-LogGroupEnd -Title "Test"
```

Output should show:
```
::group::Test
Content
::endgroup::
```

## References

- [GitHub Actions: Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines)
- `build.psm1`: `Write-LogGroupStart` and `Write-LogGroupEnd` function definitions
3 changes: 2 additions & 1 deletion .github/workflows/analyze-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ jobs:
# queries: ./path/to/local/query, your-org/your-repo/queries@main

- run: |
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
Import-Module .\tools\ci.psm1
Show-Environment
name: Capture Environment
shell: pwsh

Expand Down
13 changes: 7 additions & 6 deletions .github/workflows/linux-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
# Set job outputs to values from filter step
outputs:
source: ${{ steps.filter.outputs.source }}
buildModuleChanged: ${{ steps.filter.outputs.buildModuleChanged }}
packagingChanged: ${{ steps.filter.outputs.packagingChanged }}
steps:
- name: checkout
Expand All @@ -70,7 +71,7 @@ jobs:
name: Build PowerShell
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
steps:
- name: checkout
uses: actions/checkout@v5
Expand All @@ -84,7 +85,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
Expand All @@ -101,7 +102,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
Expand All @@ -118,7 +119,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
Expand All @@ -135,7 +136,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: ubuntu-latest
steps:
- name: checkout
Expand All @@ -151,7 +152,7 @@ jobs:
name: xUnit Tests
needs:
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
uses: ./.github/workflows/xunit-tests.yml
with:
runner_os: ubuntu-latest
Expand Down
15 changes: 8 additions & 7 deletions .github/workflows/macos-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
# Set job outputs to values from filter step
outputs:
source: ${{ steps.filter.outputs.source }}
buildModuleChanged: ${{ steps.filter.outputs.buildModuleChanged }}
steps:
- name: checkout
uses: actions/checkout@v5
Expand All @@ -67,7 +68,7 @@ jobs:
name: Build PowerShell
runs-on: macos-15-large
needs: changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
steps:
- name: checkout
uses: actions/checkout@v5
Expand All @@ -80,7 +81,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
Expand All @@ -97,7 +98,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
Expand All @@ -114,7 +115,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
Expand All @@ -131,7 +132,7 @@ jobs:
needs:
- ci_build
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on: macos-15-large
steps:
- name: checkout
Expand All @@ -147,7 +148,7 @@ jobs:
name: xUnit Tests
needs:
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
uses: ./.github/workflows/xunit-tests.yml
with:
runner_os: macos-15-large
Expand All @@ -156,7 +157,7 @@ jobs:
name: macOS packaging and testing
needs:
- changes
if: ${{ needs.changes.outputs.source == 'true' }}
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.buildModuleChanged == 'true' }}
runs-on:
- macos-15-large
steps:
Expand Down
Loading
Loading