Skip to content
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ Depending on the labels in the pull requests, the [workflow will result in diffe
- [Example - `BeforeAll.ps1`](#example---beforeallps1)
- [Teardown - `AfterAll.ps1`](#teardown---afterallps1)
- [Example - `AfterAll.ps1`](#example---afterallps1)
- [Best practices for shared test infrastructure](#best-practices-for-shared-test-infrastructure)
- [Use deterministic naming with `$env:GITHUB_RUN_ID`](#use-deterministic-naming-with-envgithub_run_id)
- [Clean up stale resources from previous failed runs](#clean-up-stale-resources-from-previous-failed-runs)
- [Tests reference shared resources β€” they do not create them](#tests-reference-shared-resources--they-do-not-create-them)
- [Naming conventions](#naming-conventions)
- [Module tests](#module-tests)
- [Get test results](#get-test-results)
- [Get code coverage](#get-code-coverage)
Expand Down Expand Up @@ -94,7 +99,12 @@ Depending on the labels in the pull requests, the [workflow will result in diffe
- [Related Configuration](#related-configuration)
- [Repository structure](#repository-structure)
- [Module source code structure](#module-source-code-structure)
- [Declaring module dependencies](#declaring-module-dependencies)
- [Principles and practices](#principles-and-practices)
- [Linear versioning](#linear-versioning)
- [Release and feature branches](#release-and-feature-branches)
- [Colocation of concerns](#colocation-of-concerns)
- [Compatibility](#compatibility)

### Get-Settings

Expand Down Expand Up @@ -953,18 +963,45 @@ How the module is built.
β”‚ └── README.md # Module-level docs ingested by Document-PSModule
```

### Declaring module dependencies

Declare module dependencies using
[`#Requires -Modules`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires)
statements at the top of function files in `src/functions/public/` or `src/functions/private/` that require external modules.
[Build-PSModule](https://github.com/PSModule/Build-PSModule) collects every `#Requires -Modules` declaration across all
source files, de-duplicates the list, and writes it into the `RequiredModules` field of the compiled manifest
automatically. For the full range of supported syntax variants, see the
[about_Requires](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires)
documentation.

> [!IMPORTANT]
> Adding `RequiredModules` to `src/manifest.psd1` is **not** supported for this purpose. Those entries are silently
> ignored by the build and will not appear in the compiled manifest. Use `#Requires -Modules` in function files instead.

## Principles and practices

### Linear versioning

The contribution and release process is based on the idea that a PR is a release, and we only maintain a single linear ancestry of versions, not going
back to patch and update old versions of the modules. This means that if we are on version `2.1.3` of a module and there is a security issue, we only
patch the latest version with a fix, not releasing new versions based on older versions of the module, i.e. not updating the latest 1.x with the
patch.

### Release and feature branches

If you need to work forth a bigger release, create a branch representing the release (a release branch) and open a PR towards `main` for this branch.
For each topic or feature to add to the release, open a new branch representing the feature (a feature branch) and open a PR towards the release
branch. Optionally add the `Prerelease` label on the PR for the release branch, to release preview versions before merging and releasing a published
version of the PowerShell module.

### Colocation of concerns

Colocate concerns for long-term maintainability. For example, `#Requires -Modules` statements belong in the function files that use them, not in a
central manifest β€” this makes it immediately visible which functions drive each external dependency, and avoids silent drift between the manifest and
the actual code. Another example is how parameter descriptions are placed as comments in the `param()` block directly above each parameter
declaration, rather than in the comment-based help at the top of the function β€” this keeps the description next to the code it documents.

### Compatibility

The process is compatible with:

Expand Down
Loading