You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/docs/PowerShell/Modules/Standards.md
+185-4Lines changed: 185 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,10 @@
1
1
# PowerShell module standard
2
2
3
-
Standards for implementing and reviewing PowerShell modules in the PSModule organization. These rules apply to modules built with the [PSModule framework](https://github.com/PSModule/PSModule).
3
+
Standards for implementing and reviewing PowerShell modules in the PSModule organization. These rules apply to modules built with the [PSModule framework](https://github.com/PSModule/Process-PSModule).
4
4
5
5
For general PowerShell coding standards (naming, style, function structure, documentation, readability, error handling), see [PowerShell Standards](../Standard/index.md). This page covers only module-specific conventions.
6
6
7
-
> **Repo-local config wins.** Repo-level `PSScriptAnalyzerSettings.psd1`, `.github/linters/.powershell-psscriptanalyzer.psd1`, and equivalent local rules override anything below. This standard fills the gap.
7
+
> **Repo-local config wins.** Repo-level `.github/linters/.powershell-psscriptanalyzer.psd1` and `.github/PSModule.yml` override anything below. This standard fills the gap.
8
8
9
9
## Repository layout
10
10
@@ -13,7 +13,7 @@ The framework treats `src/` as the source for the compiled module. Place code in
@@ -110,12 +112,180 @@ The release process treats each merged PR as a release on a single linear ancest
110
112
111
113
For large work, open a release branch and target it from feature branches. Apply the `Prerelease` label on the release branch PR to publish preview versions before the final merge to `main`.
112
114
115
+
## CI/CD pipeline
116
+
117
+
The [Process-PSModule](https://github.com/PSModule/Process-PSModule) workflow orchestrates the full lifecycle. Every PR triggers a **Plan** job that resolves configuration and version, then conditionally runs build, test, lint, and publish stages.
118
+
119
+
### Pipeline stages
120
+
121
+
```mermaid
122
+
graph LR
123
+
Plan --> Lint-Repository
124
+
Plan --> Build-Module
125
+
Plan --> Test-SourceCode
126
+
Plan --> Lint-SourceCode
127
+
Build-Module --> Test-Module
128
+
Build-Module --> BeforeAll-ModuleLocal
129
+
BeforeAll-ModuleLocal --> Test-ModuleLocal
130
+
Test-ModuleLocal --> AfterAll-ModuleLocal
131
+
Test-SourceCode --> Get-TestResults
132
+
Test-Module --> Get-TestResults
133
+
Test-ModuleLocal --> Get-TestResults
134
+
Test-Module --> Get-CodeCoverage
135
+
Test-ModuleLocal --> Get-CodeCoverage
136
+
Get-TestResults --> Publish-Module
137
+
Get-CodeCoverage --> Publish-Module
138
+
Build-Module --> Build-Docs
139
+
Build-Docs --> Build-Site
140
+
Build-Site --> Publish-Site
141
+
```
142
+
143
+
| Stage | Runs on | Purpose |
144
+
| ----- | ------- | ------- |
145
+
|**Plan**| All events | Loads `.github/PSModule.yml`, resolves version from PR labels, produces the Settings JSON |
146
+
|**Lint-Repository**| Open/Updated PR | Runs super-linter on the full repo (markdown, YAML, etc.) |
|**Get-TestResults**| Always (if Plan succeeded) | Aggregates and reports test results |
155
+
|**Get-CodeCoverage**| Always (if Plan succeeded) | Calculates and reports code coverage |
156
+
|**Publish-Module**| Merged PR (or Prerelease label) | Publishes to PowerShell Gallery and creates a GitHub Release |
157
+
|**Build-Docs / Build-Site**| Open/Updated PR, Merged PR, Manual | Generates documentation site from source |
158
+
|**Publish-Site**| Merged PR | Deploys documentation site to GitHub Pages |
159
+
160
+
### Important file patterns
161
+
162
+
The workflow only triggers build, test, and publish stages when changed files match the `ImportantFilePatterns` setting. The default patterns are:
163
+
164
+
```text
165
+
^src/
166
+
^README\.md$
167
+
```
168
+
169
+
Changes that do not match any pattern result in `ReleaseType: None` — the pipeline skips build, test, and publish entirely. Override in `.github/PSModule.yml`:
170
+
171
+
```yaml
172
+
ImportantFilePatterns:
173
+
- '^src/'
174
+
- '^README\.md$'
175
+
- '^\.github/workflows/'
176
+
```
177
+
178
+
### Version resolution
179
+
180
+
The **Plan** job resolves the next version before any build occurs. This means the tested artifact carries the exact version that will be published — no re-stamping happens at publish time.
181
+
182
+
**Flow:**
183
+
184
+
1. `Get-PSModuleSettings` loads `.github/PSModule.yml` and determines `ReleaseType` from PR labels
185
+
2. `Resolve-PSModuleVersion` calculates the next semantic version from the latest Git tag
186
+
3. `Build-PSModule` stamps the resolved version into the compiled manifest
187
+
4. `Publish-PSModule` reads the version from the manifest (read-only) and publishes
| None of the above | Patch (when `AutoPatching: true`) | — |
198
+
199
+
**Prerelease versions:** Adding a `Prerelease` label to the PR produces a prerelease tag (e.g., `1.2.3-preview0001`). The format is controlled by `IncrementalPrerelease` (sequential numbering) or `DatePrereleaseFormat` (.NET DateTime format string).
200
+
201
+
**Tag format:** Releases are tagged with a configurable prefix (default `v`) — e.g., `v1.2.3`.
202
+
203
+
### Configuration (`.github/PSModule.yml`)
204
+
205
+
All settings have sensible defaults. An empty or missing file uses the defaults below:
206
+
207
+
```yaml
208
+
Name: null # Defaults to the repository name
209
+
210
+
ImportantFilePatterns:
211
+
- '^src/'
212
+
- '^README\.md$'
213
+
214
+
Build:
215
+
Skip: false
216
+
Module:
217
+
Skip: false
218
+
Docs:
219
+
Skip: false
220
+
Site:
221
+
Skip: false
222
+
223
+
Test:
224
+
Skip: false
225
+
Linux:
226
+
Skip: false
227
+
MacOS:
228
+
Skip: false
229
+
Windows:
230
+
Skip: false
231
+
SourceCode:
232
+
Skip: false
233
+
PSModule:
234
+
Skip: false
235
+
Module:
236
+
Skip: false
237
+
TestResults:
238
+
Skip: false
239
+
CodeCoverage:
240
+
Skip: false
241
+
PercentTarget: 0
242
+
243
+
Publish:
244
+
Module:
245
+
Skip: false
246
+
AutoCleanup: true # Delete prerelease tags after stable release
247
+
AutoPatching: true # Unlabeled PRs default to patch bump
- One test file per public command for unit tests; integration tests grouped by scenario.
118
-
- Tests run against the dot-sourced source files, not against an installed module — see [PSModule Test Specification](https://psmodule.io/docs/PowerShell-Modules/Test-Specification/).
288
+
- Tests run against the built module artifact installed locally, across a multi-OS matrix (Linux, macOS, Windows).
119
289
120
290
### Shared test infrastructure
121
291
@@ -156,3 +326,14 @@ To skip a specific rule for one file only, add a comment at the very top of that
156
326
```
157
327
158
328
Use skip comments sparingly and always include a meaningful reason. Prefer refactoring to comply over skipping.
329
+
330
+
### PSScriptAnalyzer linting
331
+
332
+
Source code is linted with PSScriptAnalyzer using the repo-level settings at `.github/linters/.powershell-psscriptanalyzer.psd1`. Key enforced rules include:
333
+
334
+
- `PSAlignAssignmentStatement`— aligned assignment operators in hashtables
335
+
- `PSAvoidLongLines`— maximum 150 characters per line
336
+
- `PSAvoidSemicolonsAsLineTerminators`— no trailing semicolons
0 commit comments