A project containing the necessary tools to ease publishing of PowerShell modules.
This project provides PowerShell cmdlets and CI remote templates that other projects can utilize for building, testing, and publishing PowerShell modules.
PSModulePublisher
sets the following convention of directory structure for PowerShell projects to adopt for building, testing, and publishing PowerShell modules.
/build/ # Build directory
/build/PSModulePublisher/ # PSModulePublisher as a submodule [optional]
/build/definitions/modulemanifest.ps1 # The module manifest definition file
/src/MyPowershellModule/ # The module's root directory
/src/MyPowershellModule/MyPowershellModule.psm1 # The script module file (.psm1)
/src/MyPowershellModule/MyPowershellModule.psd1 # The module manifest file (.psd1) [optional]
/test/ # Test directory [optional]
/test/test.ps1 # The test entrypoint script [optional]
PSModulePublisher
can either be installed as a PowerShell module, or used as a submodule with provided CI remote templates.
To use PSModulePublisher
as a PowerShell module, simply perform an installation of the module in development or CI environment(s) prior to executing provided cmdlets to perform their respective functions.
# Latest version
Install-Module -Name PSModulePublisher -Repository PSGallery -Scope CurrentUser -Verbose
# Specific version
Install-Module -Name PSModulePublisher -Repository PSGallery -RequiredVersion x.x.x -Scope CurrentUser -Verbose
If prompted to trust the repository, type Y
and enter
.
PSModulePublisher
can be used as submodule together with provided CI remote template(s).
Add PSModulePublisher
as a submodule under the directory build
in your main project:
# Add the submodule
git submodule add https://github.com/theohbrothers/PSModulePublisher.git build/PSModulePublisher
# Checkout ref to use
git --git-dir build/PSModulePublisher/.git checkout vx.x.x
# Commit the submodule
git commit -am 'Add submodule PSModulePublisher vx.x.x'
Ensure the main project contains the script module file at the location src/MyPowershellModule/MyPowershellModule.psm1
.
The project sources from a definition file to generate the module manifest file (.psd1
) used for publishing the module. Ensure that the file exists in your main project at the location build/definitions/modulemanifest.ps1
and that it contains the right properties and values relevant to your PowerShell module. Remember to update the definition file prior to publishing your module.
The definition template can be found here.
Note: This section only applies if using the project as a submodule.
Decide on which CI provider to use in your main project based on those supported by this project. Then setup the CI file(s) for your main project, referencing relevant CI remote template(s) of this project from your main project's CI file(s).
Sample CI files can be found here.
The project optionally runs an entrypoint script for tests at the location test/test.ps1
. You can add the module's main tests steps in this file for tests to be run.
Sample test files can be found here.
Add a secret variable NUGET_API_KEY
containing your PSGallery API key to your main project's CI settings for publishing your module on PowerShell Gallery.
By default, PSModulePublisher
uses the main project's root directory as the path for execution. To override the default location, set the environment variable PROJECT_DIRECTORY
to contain a custom directory value before executing PSModulePublisher
.
The default module version is 0.0.0
which prevents a module from being published. To publish a module, simply create a tag for a desired commit and push the tag. Tags must follow Semantic Versioning and be prepended with a lowercase v
:
# Tag the commit to publish
git tag v1.0.12
# Push the tag
git push remotename v1.0.12 # MODULE_VERSION will be 1.0.12
The environment variable MODULE_VERSION
will automatically be populated with the equivalent PowerShell module version based on the semver tag pushed.
The PowerShell cmdlet Invoke-PSModulePublisher
is used for executing the project's build, test, and publish steps for PowerShell modules.
Invoke-PSModulePublisher [[-Repository] <string>] [-DryRun] [<CommonParameters>]
To perform the project's build, test, and publish steps for a given Powershell module, simply define applicable environment variables for the project before executing the cmdlet.
# Process applicable environment variables
$env:PROJECT_DIRECTORY = git rev-parse --show-toplevel
# Build and Test steps (Generates module manifest, Tests module via module manifest)
Invoke-PSModulePublisher
# Publish steps (Publishes module as a dry run)
Invoke-PSModulePublisher -Repository MyPSRepository -DryRun
# Publish steps (Publishes module)
Invoke-PSModulePublisher -Repository MyPSRepository
Note: Ensure the environment variable NUGET_API_KEY
is defined prior to publishing PowerShell modules.
The individual cmdlets may also be used for executing the project's build, test, and publish steps independently.
The project includes samples of .vscode/tasks.json
for executing build, test, and publish steps with the included cmdlets via Build Tasks in VSCode. Simply execute relevant build task(s) while entering custom or default values per variable prompt.
The project provides PowerShell cmdlets, as well as CI remote templates for executing the project's build, test, and publish steps for PowerShell modules.
The following are the parameters and environment variables supported by the provided PowerShell cmdlets for building, testing, and publishing PowerShell modules.
Invoke-Build [<CommonParameters>]
Invoke-Test [[-ModuleManifestPath] <string>] [<CommonParameters>]
Invoke-Publish [[-ModuleManifestPath] <string>] [-Repository] <string> [-DryRun] [<CommonParameters>]
Name | Example value | Mandatory | Type |
---|---|---|---|
PROJECT_DIRECTORY |
/path/to/my-project |
false | string |
MODULE_VERSION |
x.x.x |
false, true (Build + Publish) | string |
Name | Example value | Mandatory | Type |
---|---|---|---|
NUGET_API_KEY |
xxx |
true | string |
To execute build, test, and publish steps for a project, simply define applicable environment variables before executing the individual cmdlets within the CI environment to perform their respective functions.
# Process applicable environment variables
export PROJECT_DIRECTORY=$( git rev-parse --show-toplevel )
export MODULE_VERSION=$( echo "$GITHUB_REF" | sed -rn 's/^refs\/tags\/v(.*)/\1/p' )
# Install PSModulePublisher
pwsh -NoLogo -NonInteractive -NoProfile -Command 'Install-Module -Name PSModulePublisher -Repository PSGallery -Scope CurrentUser -Force -Verbose'
# Build (Generates module manifest)
pwsh -NoLogo -NonInteractive -NoProfile -Command '$VerbosePreference = "Continue"; Invoke-Build'
# Test (Tests module via module manifest)
pwsh -NoLogo -NonInteractive -NoProfile -Command '$VerbosePreference = "Continue"; Invoke-Test'
# Publish (Publishes module)
pwsh -NoLogo -NonInteractive -NoProfile -Command '$VerbosePreference = "Continue"; Invoke-Publish -Repository PSGallery'
Note: Ensure the environment variable NUGET_API_KEY
is defined prior to publishing PowerShell modules.
Sample CI files demonstrating use of this approach can be found here.
The provided CI remote templates is composed of the following CI process:
- Display system info
- Get PowerShell version
- Process build variables
- Generate module manifest
- Test module via module's manifest
- Install publish dependencies (if applicable)
- Publish module
Build, Test, and Publish steps can be executed for all refs. Simply configure your main project's CI file(s) and/or settings to allow so.
Publish steps default to simulating publishing of the module. The module is published only for tag refs. Simply configure your main project's CI file(s) and/or settings to allow so.
For a basic use case, the CI process could simply comprise a single stage containing all the steps from Build, Test, and Publish.
In cases where the module needs to be tested across multiple operating systems and/or versions of PowerShell, two stages can be configured: The 1st stage containing multiple jobs executing Build and Test steps for building and testing the module; the 2nd stage containing a single job executing Build and Publish steps for publishing the module.
Sample CI files demonstrating use of this approach can be found here.
# Update the submodule
git submodule update --remote build/PSModulePublisher
# Checkout ref to use
git --git-dir build/PSModulePublisher/.git checkout vx.x.x
# Bump PSModulePublisher to the same ref in CI file
vi azure-pipelines.yml
# Commit the submodule and CI file
git commit -am 'Bump PSModulePublisher to vx.x.x'
- Use only tag refs of
PSModulePublisher
in your main project. - If using the project as a Submodule with CI remote templates, ensure your main project's CI file(s) is configured to use the CI remote templates of
PSModulePublisher
, and that the ref matches that of thePSModulePublisher
submodule used in your main project.