Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 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
32c55fe
Merge branch 'main' of https://github.com/PSModule/GitHub into copilo…
MariusStorhaug Feb 17, 2026
959366e
Move lightweight/medium test files back to tests/ and fix issues
MariusStorhaug Feb 17, 2026
29865ad
Move test files back to tmp/ for incremental migration
MariusStorhaug Feb 17, 2026
9c977a1
Add Enterprise tests to validate GitHubEnterprise properties and beha…
MariusStorhaug Feb 17, 2026
1e15271
Add 'API' tag to PSData in manifest.psd1
MariusStorhaug Feb 17, 2026
7d34687
Consolidate test setup configuration and update README formatting
MariusStorhaug Feb 17, 2026
5264066
Fix formatting in README-SETUP-TEARDOWN.md by removing extra whitespace
MariusStorhaug Feb 17, 2026
aba5a4e
Remove Enterprise.Tests.ps1 file to streamline test suite
MariusStorhaug Feb 17, 2026
1cab02e
Fix parameter name in Get-GitHubRepository call for clarity
MariusStorhaug Feb 17, 2026
ea974f7
Refactor test setup and teardown scripts to derive OS names from sett…
MariusStorhaug Feb 17, 2026
bc0a72f
Refactor test setup scripts to improve clarity and streamline reposit…
MariusStorhaug Feb 17, 2026
27ac6d3
Enhance test documentation and cleanup scripts for improved clarity a…
MariusStorhaug Feb 17, 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
21 changes: 11 additions & 10 deletions .github/PSModule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@
Test:
CodeCoverage:
PercentTarget: 50
# Skip: true
# TestResults:
# Skip: true
# SourceCode:
# Skip: true
# PSModule:
# Skip: true
Skip: true
TestResults:
Skip: true
SourceCode:
Skip: true
PSModule:
Skip: true
# Module:
# Skip: true
# Windows:
# Skip: true
# MacOS:
# Skip: true
# Build:
# Docs:
# Skip: true
Build:
Docs:
Skip: true

Linter:
Skip: true
env:
VALIDATE_BIOME_FORMAT: false
VALIDATE_BIOME_LINT: false
Expand Down
5 changes: 4 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Start by reading the general coding standards for [`PSModule`](https://psmodule.io/docs) which is the basis for all modules in the framework.
Additions or adjustments to those defaults are covered in this document to ensure that the modules drive consistancy for all developers.

**Folder-level README**
- When working with files in a folder, check if a `README.md` exists in that folder. If it does, read it first to
gather context on how to use or write code in that folder.

## General Coding Standards

1. **PowerShell Keywords**
Expand All @@ -18,7 +22,6 @@ Additions or adjustments to those defaults are covered in this document to ensur

4. **Convert Filter Types**
- Wherever filters are used, ensure they are implemented as standard PowerShell functions with `begin`, `process`, and `end` blocks.

---

## Functions
Expand Down
1 change: 1 addition & 0 deletions src/manifest.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Tags = @(
'GitHub'
'PSModule'
'API'
)
}
}
Expand Down
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'

# Derive the list of OS names from the Settings JSON provided by Process-PSModule.
$settings = $env:Settings | ConvertFrom-Json
$osNames = @($settings.TestSuites.Module.OSName | Sort-Object -Unique)
Write-Host "Cleaning up test repositories for OSes: $($osNames -join ', ')"

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

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

LogGroup "Teardown - $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)

foreach ($os in $osNames) {
$repoPrefix = "$prefix-$os-$TokenType"

LogGroup "Repository cleanup - $AuthType-$TokenType - $os" {
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
}
}
}
46 changes: 46 additions & 0 deletions tests/BeforeAll.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[CmdletBinding()]
param()

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

# Derive the list of OS names from the Settings JSON provided by Process-PSModule.
$settings = $env:Settings | ConvertFrom-Json
$osNames = @($settings.TestSuites.Module.OSName | Sort-Object -Unique)
Write-Host "Creating test repositories for OSes: $($osNames -join ', ')"

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
}
$context = Connect-GitHubAccount @connectParams -PassThru -Silent
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
}
Write-Host ($context | Format-List | Out-String)

foreach ($os in $osNames) {
$repoPrefix = "Test-$os-$TokenType"
$repoName = "$repoPrefix-$id"

LogGroup "Repository setup - $AuthType-$TokenType - $os" {
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
}
}
}
}

Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
}
}
31 changes: 7 additions & 24 deletions tests/Environments.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
param()

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

Describe 'Environments' {
Expand All @@ -40,34 +40,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 -Name $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
101 changes: 101 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,104 @@ Events:
Secrets:
- TEST_APP_ORG_CLIENT_ID
- TEST_APP_ORG_PRIVATE_KEY

## Auth cases

[AuthCases.ps1](../tests/Data/AuthCases.ps1) defines 7 auth cases. Each test file iterates over all cases, skipping those
that don't apply (e.g., `repository` and `enterprise` owner types skip repo-dependent tests).

| # | AuthType | TokenType | Owner | OwnerType |
|---|----------|---------------|--------------------|--------------|
| 1 | PAT | USER_FG_PAT | psmodule-user | user |
| 2 | PAT | ORG_FG_PAT | psmodule-test-org2 | organization |
| 3 | PAT | PAT | psmodule-user | user |
| 4 | IAT | GITHUB_TOKEN | PSModule | repository |
| 5 | App | APP_ORG | psmodule-test-org | organization |
| 6 | App | APP_ENT | psmodule-test-org3 | organization |
| 7 | App | APP_ENT | msx | enterprise |

Cases 4 (`repository`) and 7 (`enterprise`) skip repo creation. Cases 1 and 3 share the same user owner (`psmodule-user`)
but have different `$TokenType` values, so repo names are unique.

## Setup and teardown

Shared test infrastructure is provisioned once per workflow run using `BeforeAll.ps1` and torn down using `AfterAll.ps1`.
For generic guidance on setup/teardown scripts, see the
[Process-PSModule documentation](https://github.com/PSModule/Process-PSModule#setup-and-teardown-scripts).

### `BeforeAll.ps1` — global setup

Runs once before all parallel test files. For each auth case (except `GITHUB_TOKEN`):

1. Connects using the auth case credentials
2. Cleans up stale repos from previous failed runs (matching `Test-$os-$TokenType-*`)
3. Creates a shared repository per OS: `Test-{OS}-{TokenType}-{GITHUB_RUN_ID}`
- For `user` owners: `New-GitHubRepository -Name $repoName`
- For `organization` owners: `New-GitHubRepository -Organization $Owner -Name $repoName`

### `AfterAll.ps1` — global teardown

Runs once after all parallel test files complete. For each auth case (except `GITHUB_TOKEN`):

1. Connects using the auth case credentials
2. Removes all repositories matching the `Test-{OS}-{TokenType}-*` prefix

## Test file pattern

Each test file follows this pattern:

```powershell
BeforeAll {
$testName = 'TestName'
$os = $env:RUNNER_OS
$id = $env:GITHUB_RUN_ID
}

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

Context 'As <Type> using <Case> on <Target>' -ForEach $authCases {
BeforeAll {
# Connect
$context = Connect-GitHubAccount @connectParams -PassThru -Silent
if ($AuthType -eq 'APP') {
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
}

# Reference the shared repo (NOT New-GitHubRepository)
$repoPrefix = "Test-$os-$TokenType"
$repoName = "$repoPrefix-$id"
$repo = Get-GitHubRepository -Owner $Owner -Name $repoName
}

AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
}

It 'Should do something' -Skip:($OwnerType -in ('repository', 'enterprise')) {
# Test logic using $repo, $Owner, $repoName
}
}
}
```

### Key conventions

- **`$id = $env:GITHUB_RUN_ID`** — not `[guid]::NewGuid()` or `Get-Random`. This makes the repo name deterministic
per workflow run so shared infrastructure can be referenced by name.
- **`Get-GitHubRepository`** — test files fetch the shared repo, they do not create repos.
- **`-Skip:($OwnerType -in ('repository', 'enterprise'))`** — standard skip condition for repo-dependent tests.
- **`Disconnect-GitHubAccount`** — every context disconnects all sessions in `AfterAll`.
- Test-specific ephemeral resources (releases, secrets, variables, environments, teams) are still created and cleaned up
within each test file. Only repositories are shared.

## Naming conventions

| Resource | Pattern | Example |
|------------|----------------------------------------------|----------------------------------|
| Repo | `Test-{OS}-{TokenType}-{RunID}` | `Test-Linux-USER_FG_PAT-1234` |
| Extra repo | `Test-{OS}-{TokenType}-{RunID}-{N}` | `Test-Linux-USER_FG_PAT-1234-1` |
| Secret | `{TestName}_{OS}_{TokenType}_{RunID}` | `Secrets_Linux_PAT_1234` |
| Variable | `{TestName}_{OS}_{TokenType}_{RunID}` | `Variables_Linux_PAT_1234` |
| Team | `{TestName}_{OS}_{TokenType}_{RunID}_{Name}` | `Teams_Linux_APP_ORG_1234_Pull` |
| Env | `{TestName}-{OS}-{TokenType}-{RunID}` | `Secrets-Linux-PAT-1234` |
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,11 +19,7 @@
[CmdletBinding()]
param()

BeforeAll {
# DEFAULTS ACCROSS ALL TESTS
}

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

Context 'As <Type> using <Case> on <Target>' -ForEach $authCases {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading