Skip to content

Commit ea253a5

Browse files
Merge branch 'main' into fix/workflow-run-pipeline-deletion
2 parents 9c065fd + 6bda396 commit ea253a5

9 files changed

Lines changed: 303 additions & 221 deletions

File tree

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
description: "Use when writing, editing, or reviewing Pester test files under the tests/ folder. Covers shared repository setup, auth case iteration, naming conventions, and skip patterns for the GitHub module integration tests."
3+
applyTo: "tests/**"
4+
---
5+
# Integration Test Conventions
6+
7+
## Test infrastructure accounts
8+
9+
### User
10+
11+
Login: `psmodule-user`
12+
Owner of:
13+
14+
- [psmodule-user](https://github.com/psmodule-user) (standalone org)
15+
- [psmodule-test-org2](https://github.com/orgs/psmodule-test-org2) (standalone org)
16+
17+
Secrets:
18+
19+
- `TEST_USER_PAT``psmodule-user` (user)
20+
- `TEST_USER_USER_FG_PAT``psmodule-user` (user)
21+
- `TEST_USER_ORG_FG_PAT``psmodule-test-org2` (org)
22+
23+
### APP_ENT — PSModule Enterprise App
24+
25+
Homed in `MSX`. ClientID: `Iv23lieHcDQDwVV3alK1`.
26+
Installed on [psmodule-test-org3](https://github.com/orgs/psmodule-test-org3) (enterprise org) with all permissions and push events.
27+
28+
Secrets: `TEST_APP_ENT_CLIENT_ID`, `TEST_APP_ENT_PRIVATE_KEY`
29+
30+
### APP_ORG — PSModule Organization App
31+
32+
Homed in `PSModule`. ClientID: `Iv23liYDnEbKlS9IVzHf`.
33+
Installed on [psmodule-test-org](https://github.com/orgs/psmodule-test-org) (standalone org) with all permissions and push events.
34+
35+
Secrets: `TEST_APP_ORG_CLIENT_ID`, `TEST_APP_ORG_PRIVATE_KEY`
36+
37+
## Auth cases
38+
39+
`AuthCases.ps1` defines 7 auth cases. Each test file iterates over all cases, skipping those
40+
that don't apply (e.g., `repository` and `enterprise` owner types skip repo-dependent tests).
41+
42+
| # | AuthType | TokenType | Owner | OwnerType |
43+
|---|----------|---------------|--------------------|--------------|
44+
| 1 | PAT | USER_FG_PAT | psmodule-user | user |
45+
| 2 | PAT | ORG_FG_PAT | psmodule-test-org2 | organization |
46+
| 3 | PAT | PAT | psmodule-user | user |
47+
| 4 | IAT | GITHUB_TOKEN | PSModule | repository |
48+
| 5 | App | APP_ORG | psmodule-test-org | organization |
49+
| 6 | App | APP_ENT | psmodule-test-org3 | organization |
50+
| 7 | App | APP_ENT | msx | enterprise |
51+
52+
Cases 4 (`repository`) and 7 (`enterprise`) skip repo creation. Cases 1 and 3 share the same user owner
53+
(`psmodule-user`) but have different `$TokenType` values, so repo names are unique.
54+
55+
## Setup and teardown
56+
57+
Shared test infrastructure is provisioned once per workflow run using `BeforeAll.ps1` and torn down using `AfterAll.ps1`.
58+
For generic guidance on setup/teardown scripts, see the
59+
[Process-PSModule documentation](https://github.com/PSModule/Process-PSModule#setup-and-teardown-scripts).
60+
61+
### `BeforeAll.ps1` — global setup
62+
63+
Runs once before all parallel test files. For each auth case (except `GITHUB_TOKEN`):
64+
65+
1. Connects using the auth case credentials
66+
2. Removes any existing repositories for the deterministic names used by the run
67+
3. Provisions a primary shared repository per OS using `Set-GitHubRepository`: `Test-{OS}-{TokenType}-{GITHUB_RUN_ID}`
68+
- Includes `-AddReadme`, `-License 'mit'`, and `-Gitignore 'VisualStudio'` so release tests have a default branch with content
69+
- For `user` owners: `Set-GitHubRepository -Name $repoName ...`
70+
- For `organization` owners: `Set-GitHubRepository -Organization $Owner -Name $repoName ...`
71+
4. For `organization` owners only, provisions two extra repositories per OS (`-2`, `-3` suffix) for
72+
Secrets/Variables `SelectedRepository` tests
73+
74+
`Set-GitHubRepository` is idempotent — if the repository already exists it updates it in place (issuing a
75+
PATCH), and if it does not exist it creates it. Because the same parameters are passed each time, the
76+
end-state is identical regardless of how many times the setup runs. The extra PATCH on the happy path is
77+
a deliberate trade-off for simplicity: one call handles both first-run and partial-rerun scenarios without
78+
branching logic.
79+
80+
### `AfterAll.ps1` — global teardown
81+
82+
Runs once after all parallel test files complete. For each auth case (except `GITHUB_TOKEN`):
83+
84+
1. Connects using the auth case credentials
85+
2. Removes the run-scoped repositories by their known names
86+
87+
## Shared test repositories
88+
89+
Each test file that depends on a GitHub repository must ensure it exists using `Set-GitHubRepository`
90+
in its per-context `BeforeAll`. `Set-GitHubRepository` is idempotent — if the repository already exists
91+
it updates it in place (PATCH), and if it does not exist it creates it. When the same parameters are
92+
passed each time the end-state is identical. This makes every test file self-sufficient regardless of
93+
whether the global `BeforeAll.ps1` already provisioned the repository.
94+
95+
**Do not** use `Get-GitHubRepository` with a throw guard — that breaks partial reruns.
96+
**Do not** use `New-GitHubRepository` — that fails if the repository already exists.
97+
98+
Primary repositories use `-AddReadme`, `-License 'mit'`, and `-Gitignore 'VisualStudio'` so that
99+
a default branch with content is available for tests that need commits (e.g., releases, tags).
100+
101+
Some auth cases (e.g., `repository`, `enterprise`) do not operate on a user- or org-owned repository.
102+
Skip provisioning for those owner types and set `$repo = $null` so that repo-dependent tests can
103+
be skipped cleanly:
104+
105+
```powershell
106+
$repoPrefix = "Test-$os-$TokenType"
107+
$repoName = "$repoPrefix-$id"
108+
if ($OwnerType -in ('repository', 'enterprise')) {
109+
$repo = $null
110+
} else {
111+
$repoParams = @{
112+
Name = $repoName
113+
AddReadme = $true
114+
License = 'mit'
115+
Gitignore = 'VisualStudio'
116+
}
117+
$repo = switch ($OwnerType) {
118+
'user' { Set-GitHubRepository @repoParams }
119+
'organization' { Set-GitHubRepository @repoParams -Organization $Owner }
120+
}
121+
}
122+
```
123+
124+
For organization-scoped tests that need companion repositories (Secrets/Variables `SelectedRepository`),
125+
provision `-2` and `-3` variants the same way:
126+
127+
```powershell
128+
$repo2 = Set-GitHubRepository -Organization $Owner -Name "$repoName-2"
129+
$repo3 = Set-GitHubRepository -Organization $Owner -Name "$repoName-3"
130+
```
131+
132+
## Test file structure
133+
134+
```powershell
135+
BeforeAll {
136+
$testName = 'TestName'
137+
$os = $env:RUNNER_OS
138+
$id = $env:GITHUB_RUN_ID
139+
}
140+
141+
Describe 'TestName' {
142+
$authCases = . "$PSScriptRoot/Data/AuthCases.ps1"
143+
144+
Context 'As <Type> using <Case> on <Target>' -ForEach $authCases {
145+
BeforeAll {
146+
$context = Connect-GitHubAccount @connectParams -PassThru -Silent
147+
if ($AuthType -eq 'APP') {
148+
$context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
149+
}
150+
151+
$repoPrefix = "Test-$os-$TokenType"
152+
$repoName = "$repoPrefix-$id"
153+
if ($OwnerType -in ('repository', 'enterprise')) {
154+
$repo = $null
155+
} else {
156+
$repoParams = @{
157+
Name = $repoName
158+
AddReadme = $true
159+
License = 'mit'
160+
Gitignore = 'VisualStudio'
161+
}
162+
$repo = switch ($OwnerType) {
163+
'user' { Set-GitHubRepository @repoParams }
164+
'organization' { Set-GitHubRepository @repoParams -Organization $Owner }
165+
}
166+
}
167+
}
168+
169+
AfterAll {
170+
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
171+
}
172+
173+
It 'Should do something' -Skip:($OwnerType -in ('repository', 'enterprise')) {
174+
# Test logic using $repo, $Owner, $repoName
175+
}
176+
}
177+
}
178+
```
179+
180+
## Naming conventions
181+
182+
| Resource | Pattern | Example |
183+
|------------|----------------------------------------------|----------------------------------|
184+
| Repo | `Test-{OS}-{TokenType}-{RunID}` | `Test-Linux-USER_FG_PAT-1234` |
185+
| Extra repo | `Test-{OS}-{TokenType}-{RunID}-{N}` | `Test-Linux-USER_FG_PAT-1234-2` |
186+
| Secret | `{TestName}_{OS}_{TokenType}_{RunID}` | `Secrets_Linux_PAT_1234` |
187+
| Variable | `{TestName}_{OS}_{TokenType}_{RunID}` | `Variables_Linux_PAT_1234` |
188+
| Team | `{TestName}_{OS}_{TokenType}_{RunID}_{Name}` | `Teams_Linux_APP_ORG_1234_Pull` |
189+
| Env | `{TestName}-{OS}-{TokenType}-{RunID}` | `Secrets-Linux-PAT-1234` |
190+
191+
## Key rules
192+
193+
- `$id` must always be `$env:GITHUB_RUN_ID` — never `[guid]::NewGuid()` or `Get-Random`.
194+
- Skip repo-dependent tests with `-Skip:($OwnerType -in ('repository', 'enterprise'))`.
195+
- Disconnect all sessions in `AfterAll`: `Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent`.
196+
- Test-specific ephemeral resources (releases, secrets, variables, environments, teams) are created and
197+
cleaned up within each test file. Only repositories are shared.
198+
- `Repositories.Tests.ps1` is the exception — it creates and deletes its own repos because it tests CRUD.

tests/Actions.Tests.ps1

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,15 @@ Describe 'Actions' {
6161
if ($OwnerType -in ('repository', 'enterprise')) {
6262
$repo = $null
6363
} else {
64-
$repo = Get-GitHubRepository -Owner $Owner -Name $repoName
65-
if (-not $repo) {
66-
throw "Shared test repository '$repoName' was not found for owner '$Owner' (OwnerType: '$OwnerType'). Ensure the repository was provisioned and the repository name is correct."
64+
$repoParams = @{
65+
Name = $repoName
66+
AddReadme = $true
67+
License = 'mit'
68+
Gitignore = 'VisualStudio'
69+
}
70+
$repo = switch ($OwnerType) {
71+
'user' { Set-GitHubRepository @repoParams }
72+
'organization' { Set-GitHubRepository @repoParams -Organization $Owner }
6773
}
6874
Write-Host ($repo | Select-Object * | Out-String)
6975
}

tests/BeforeAll.ps1

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,23 @@ LogGroup 'BeforeAll - Global Test Setup' {
6767
}
6868
}
6969

70-
# Create the primary shared repository (with readme, license, gitignore for release tests).
70+
# Provision the primary shared repository.
7171
$repoParams = @{
7272
Name = $repoName
7373
AddReadme = $true
7474
License = 'mit'
7575
Gitignore = 'VisualStudio'
7676
}
7777
switch ($OwnerType) {
78-
'user' {
79-
New-GitHubRepository @repoParams
80-
}
81-
'organization' {
82-
New-GitHubRepository @repoParams -Organization $Owner
83-
}
78+
'user' { Set-GitHubRepository @repoParams }
79+
'organization' { Set-GitHubRepository @repoParams -Organization $Owner }
8480
}
8581

86-
# Create extra repositories needed by Secrets/Variables SelectedRepository tests.
82+
# Provision extra repositories needed by Secrets/Variables SelectedRepository tests.
8783
# Only organization owners need them — those tests are skipped for user owners.
8884
if ($OwnerType -eq 'organization') {
8985
foreach ($suffix in 2, 3) {
90-
$extraName = "$repoName-$suffix"
91-
New-GitHubRepository -Organization $Owner -Name $extraName
86+
Set-GitHubRepository -Organization $Owner -Name "$repoName-$suffix"
9287
}
9388
}
9489
}

tests/Environments.Tests.ps1

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,19 @@ Describe 'Environments' {
4848
$environmentName = "$testName-$os-$TokenType-$id"
4949

5050
LogGroup "Using Repository - [$repoName]" {
51-
$repo = Get-GitHubRepository -Owner $Owner -Name $repoName
52-
if (($OwnerType -notin ('repository', 'enterprise')) -and (-not $repo)) {
53-
throw "Shared test repository '$repoName' was not found for owner '$Owner'. Ensure the repository was created before running the environment tests."
51+
if ($OwnerType -in ('repository', 'enterprise')) {
52+
$repo = $null
53+
} else {
54+
$repoParams = @{
55+
Name = $repoName
56+
AddReadme = $true
57+
License = 'mit'
58+
Gitignore = 'VisualStudio'
59+
}
60+
$repo = switch ($OwnerType) {
61+
'user' { Set-GitHubRepository @repoParams }
62+
'organization' { Set-GitHubRepository @repoParams -Organization $Owner }
63+
}
5464
}
5565
Write-Host ($repo | Select-Object * | Out-String)
5666
}

0 commit comments

Comments
 (0)