Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
84d99ad
Initial plan
Copilot Jan 5, 2026
581213b
Add BeforeAll.ps1 and AfterAll.ps1 for global test setup/teardown
Copilot Jan 5, 2026
e68238d
Add documentation for test setup/teardown scripts
Copilot Jan 5, 2026
5a69d8e
Fix hashtable splatting syntax in BeforeAll.ps1 and AfterAll.ps1
Copilot Jan 5, 2026
8ec4641
Add context logging for better debugging visibility
Copilot Jan 5, 2026
268c05c
Refactor: Move app authentication to BeforeAll blocks
MariusStorhaug Jan 6, 2026
333143d
Reset the tests and clear the AfterAll and BeforeAll files.
MariusStorhaug Jan 6, 2026
8867fe7
Add initial Pester tests for GitHub API interactions
MariusStorhaug Jan 12, 2026
6869f4a
Add Pester tests for GitHub API interactions
MariusStorhaug Jan 12, 2026
9e41346
Refactor: Add structure to Variables and Secrets setup log groups
MariusStorhaug Jan 12, 2026
f899e1e
Refactor: Enhance logging for repository setup in BeforeAll script
MariusStorhaug Jan 14, 2026
82d0a10
Refactor: Standardize context output formatting in repository setup
MariusStorhaug Jan 14, 2026
eda2347
Refactor: Remove redundant parameter from Connect-GitHubAccount call …
MariusStorhaug Jan 14, 2026
801b90a
Refactor: Skip setup for existing repositories using GITHUB_TOKEN
MariusStorhaug Jan 14, 2026
286ca3b
Refactor: Consolidate repository setup and environment initialization…
MariusStorhaug Jan 14, 2026
e70369c
Refactor: Remove unused variables and streamline repository setup in …
MariusStorhaug Jan 14, 2026
d3c5531
Merge branch 'main' of https://github.com/PSModule/GitHub into copilo…
MariusStorhaug Feb 15, 2026
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
47 changes: 47 additions & 0 deletions tests/AfterAll.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[CmdletBinding()]
param()

LogGroup 'AfterAll - Global Test Teardown' {
$authCases = . "$PSScriptRoot/Data/AuthCases.ps1"

$prefix = 'Test'
$os = $env:RUNNER_OS
$id = $env:GITHUB_RUN_ID

foreach ($authCase in $authCases) {
$authCase.GetEnumerator() | ForEach-Object { Set-Variable -Name $_.Key -Value $_.Value }

if ($TokenType -eq 'GITHUB_TOKEN') {
Write-Host "Skipping setup for $AuthType-$TokenType (uses existing repository)"
continue
}

LogGroup "Repository setup - $AuthType-$TokenType" {
$context = Connect-GitHubAccount @connectParams -PassThru -Silent
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
}
Write-Host ($context | Format-List | Out-String)

$repoPrefix = "$prefix-$os-$TokenType"

switch ($OwnerType) {
'user' {
Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
}
'organization' {
Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
}
}
}
LogGroup 'Environment setup' {
$environmentName = "$prefix-$os-$TokenType-$id"
}
LogGroup 'Variables setup' {

}
LogGroup 'Secrets setup' {

}
}
}
39 changes: 39 additions & 0 deletions tests/BeforeAll.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[CmdletBinding()]
param()

LogGroup 'BeforeAll - Global Test Setup' {
$authCases = . "$PSScriptRoot/Data/AuthCases.ps1"
$os = $env:RUNNER_OS
$id = $env:GITHUB_RUN_ID

foreach ($authCase in $authCases) {
$authCase.GetEnumerator() | ForEach-Object { Set-Variable -Name $_.Key -Value $_.Value }

if ($TokenType -eq 'GITHUB_TOKEN') {
Write-Host "Skipping setup for $AuthType-$TokenType (uses existing repository)"
continue
}

LogGroup "Repository setup - $AuthType-$TokenType" {
$context = Connect-GitHubAccount @connectParams -PassThru -Silent
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
}
Write-Host ($context | Format-List | Out-String)

$repoPrefix = "Test-$os-$TokenType"
$repoName = "$repoPrefix-$id"

switch ($OwnerType) {
'user' {
Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
New-GitHubRepository -Name $repoName -Confirm:$false
}
'organization' {
Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
New-GitHubRepository -Organization $Owner -Name $repoName -Confirm:$false
}
}
}
}
}
30 changes: 6 additions & 24 deletions tests/Environments.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
param()

BeforeAll {
$testName = 'EnvironmentsTests'
$os = $env:RUNNER_OS
$guid = [guid]::NewGuid().ToString()
$id = $env:GITHUB_RUN_ID
}

Describe 'Environments' {
Expand All @@ -40,34 +39,17 @@ Describe 'Environments' {
Write-Host ($context | Format-List | Out-String)
}
}
$repoPrefix = "$testName-$os-$TokenType"
$repoName = "$repoPrefix-$guid"
$environmentName = "$testName-$os-$TokenType-$guid"
$repoPrefix = "Test-$os-$TokenType"
$repoName = "$repoPrefix-$id"
$environmentName = "$testName-$os-$TokenType-$id"

switch ($OwnerType) {
'user' {
Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
$repo = New-GitHubRepository -Name $repoName -Confirm:$false
}
'organization' {
Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
$repo = New-GitHubRepository -Organization $owner -Name $repoName -Confirm:$false
}
}
LogGroup "Repository - [$repoName]" {
LogGroup "Using Repository - [$repoName]" {
$repo = Get-GitHubRepository -Owner $Owner -Repository $repoName
Write-Host ($repo | Select-Object * | Out-String)
}
}

AfterAll {
switch ($OwnerType) {
'user' {
Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
}
'organization' {
Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false
}
}
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}
Expand Down
File renamed without changes.
File renamed without changes.
18 changes: 5 additions & 13 deletions tests/Emojis.Tests.ps1 → tmp/Emojis.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,18 @@ Describe 'Emojis' {
LogGroup 'Context' {
Write-Host ($context | Format-List | Out-String)
}
}
AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}

# Tests for APP goes here
if ($AuthType -eq 'APP') {
It 'Connect-GitHubApp - Connects as a GitHub App to <Owner>' {
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
LogGroup 'Context' {
Write-Host ($context | Format-List | Out-String)
}
}
}
AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}

# Tests for runners goes here
if ($Type -eq 'GitHub Actions') {}

# Tests for IAT UAT and PAT goes here
It 'Get-GitHubEmoji - Gets a list of all emojis' {
$emojis = Get-GitHubEmoji
LogGroup 'emojis' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
[CmdletBinding()]
param()

BeforeAll {
# DEFAULTS ACCROSS ALL TESTS
}

Describe 'Template' {
$authCases = . "$PSScriptRoot/Data/AuthCases.ps1"

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
159 changes: 159 additions & 0 deletions tmp/README-SETUP-TEARDOWN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Test Setup/Teardown Scripts

This document describes the global test setup and teardown scripts used in the GitHub module test suite.

## Overview

The GitHub module uses Process-PSModule's BeforeAll/AfterAll support to optimize test execution and reduce rate limiting issues.

### Key Concepts

1. **BeforeAll.ps1** - Runs once before all parallel test jobs
- Cleans up stale resources from previous failed test runs
- Reduces rate limiting by removing orphaned artifacts upfront
- Does NOT replace individual test BeforeAll blocks

2. **AfterAll.ps1** - Runs once after all parallel test jobs complete
- Performs final cleanup of any remaining test resources
- Provides a safety net for resources missed by individual tests
- Generates a cleanup report

3. **Individual Test Files** - Keep their existing BeforeAll/AfterAll blocks
- Handle authentication (Connect-GitHubAccount, Connect-GitHubApp)
- Create and clean up their own isolated resources
- Support parallel execution across different auth scenarios

## How It Works

### Before Tests Run

```
Process-PSModule Workflow
↓
BeforeAll.ps1 (runs once)
↓
Parallel Test Matrix
├─ Test File 1 → BeforeAll → Tests → AfterAll
├─ Test File 2 → BeforeAll → Tests → AfterAll
└─ Test File 3 → BeforeAll → Tests → AfterAll
↓
AfterAll.ps1 (runs once)
```

### What Gets Cleaned Up

Both BeforeAll.ps1 and AfterAll.ps1 clean up test resources across all authentication scenarios:

- **Repositories**: Any repository with test name prefixes (e.g., `RepositoriesTests-*`)
- **Teams**: Teams created during tests (organization contexts only)
- **Secrets**: Organization secrets created during tests
- **Variables**: Organization variables created during tests
- **App Installations**: GitHub App installations on test organizations (APP auth only)

### Resource Naming Convention

Tests use a consistent naming pattern that allows the cleanup scripts to identify test resources:

```powershell
$testName = 'RepositoriesTests' # Test file identifier
$os = $env:RUNNER_OS # Linux, Windows, macOS
$tokenType = 'USER_FG_PAT' # Auth type identifier
$guid = [guid]::NewGuid() # Unique run identifier

$resourceName = "$testName-$os-$tokenType-$guid"
```

Examples:
- `RepositoriesTests-Linux-USER_FG_PAT-a1b2c3d4`
- `TeamsTests-Windows-APP_ORG-e5f6g7h8`

The cleanup scripts look for resources matching the test name prefixes (e.g., `RepositoriesTests-*`).

## Benefits

1. **Speed**: Pre-cleanup ensures tests don't encounter conflicts with stale resources
2. **Rate Limiting**: Significantly fewer API calls by removing orphaned resources upfront
3. **Reliability**: Consistent test environment across all test runs
4. **Cost**: Fewer parallel operations hitting API rate limits
5. **Maintainability**: Centralized cleanup logic in two files

## Test Prefixes

The following test prefixes are recognized by the cleanup scripts:

- `RepositoriesTests`
- `TeamsTests`
- `EnvironmentsTests`
- `SecretsTests`
- `VariablesTests`
- `AppsTests`
- `ArtifactsTests`
- `ReleasesTests`
- `PermissionsTests`
- `MsxOrgTests`
- `GitHubTests`

## Authentication Scenarios

The cleanup scripts process all authentication scenarios defined in `tests/Data/AuthCases.ps1`:

1. **Fine-grained PAT** - User account (`psmodule-user`)
2. **Fine-grained PAT** - Organization account (`psmodule-test-org2`)
3. **Classic PAT** - User account (`psmodule-user`)
4. **GitHub Actions Token** - Repository context (`PSModule/GitHub`)
5. **GitHub App** - Organization installation (`psmodule-test-org`)
6. **GitHub App** - Enterprise installation (`psmodule-test-org3`)
7. **GitHub App** - Enterprise context (`msx`)

## Cleanup Statistics

Both scripts generate statistics showing:
- Number of repositories removed
- Number of teams removed
- Number of secrets removed
- Number of variables removed
- Number of app installations removed
- Number of errors encountered

## Example Output

```
BeforeAll - Global Test Setup
Cleanup - psmodule-user (user) using USER_FG_PAT
Connecting to GitHub as psmodule-user...
Checking for stale repositories...
Found 3 stale repositories to remove
Removing repository: psmodule-user/RepositoriesTests-Linux-USER_FG_PAT-old1
Removing repository: psmodule-user/TeamsTests-Linux-USER_FG_PAT-old2
Removing repository: psmodule-user/SecretsTests-Linux-USER_FG_PAT-old3
No stale teams found

Cleanup Summary
Repositories removed: 12
Teams removed: 5
Secrets removed: 3
Variables removed: 2
App installations removed: 0
Errors encountered: 0

All cleanup operations completed successfully.
```

## Troubleshooting

### Tests Fail Due to Missing Resources

The cleanup scripts only remove resources that match test name prefixes. If your tests are failing due to missing resources, ensure your test is creating its own resources in the BeforeAll block.

### Cleanup Script Errors

If the cleanup scripts encounter errors, they will continue processing other resources. Check the error messages in the workflow logs to identify the issue. Common causes:
- Insufficient permissions for the authentication token
- Rate limiting (should be rare with pre-cleanup)
- Network connectivity issues

### Resources Not Being Cleaned

Ensure your test resources follow the naming convention: `{TestName}-{OS}-{TokenType}-{GUID}`

The cleanup scripts look for resources starting with the test name prefixes listed above.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 5 additions & 10 deletions tests/Users.Tests.ps1 → tmp/Users.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,18 @@ Describe 'Users' {
LogGroup 'Context' {
Write-Host ($context | Format-List | Out-String)
}
}
AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}

# Tests for APP goes here
if ($AuthType -eq 'APP') {
It 'Connect-GitHubApp - Connects as a GitHub App to <Owner>' {
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
LogGroup 'Context' {
Write-Host ($context | Format-List | Out-String)
}
}
}
AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}

# Tests for IAT UAT and PAT goes here
It 'Get-GitHubUser - Get the specified user' {
{ Get-GitHubUser -Name 'Octocat' } | Should -Not -Throw
}
Expand Down
File renamed without changes.
Loading