Skip to content

A project containing the necessary tools to ease publishing of PowerShell modules.

License

Notifications You must be signed in to change notification settings

theohbrothers/PSModulePublisher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PSModulePublisher

github-workflows github-release powershellgallery-version

A project containing the necessary tools to ease publishing of PowerShell modules.

Introduction

This project provides PowerShell cmdlets and CI remote templates that other projects can utilize for building, testing, and publishing PowerShell modules.

Directory structure

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]

Installation

PSModulePublisher can either be installed as a PowerShell module, or used as a submodule with provided CI remote templates.

PowerShell module

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.

Submodule

PSModulePublisher can be used as submodule together with provided CI remote template(s).

Adding the submodule

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'

Configuration

Script module file

Ensure the main project contains the script module file at the location src/MyPowershellModule/MyPowershellModule.psm1.

Module manifest definition file

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.

CI remote templates

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.

Test files (Optional)

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.

CI settings

Secrets

PSGallery API Key

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.

Environment variables

Project directory

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.

Module version

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.

Usage

Development

The PowerShell cmdlet Invoke-PSModulePublisher is used for executing the project's build, test, and publish steps for PowerShell modules.

Parameters

Invoke-PSModulePublisher [[-Repository] <string>] [-DryRun] [<CommonParameters>]

Commands

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.

VSCode

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.

Continuous Integration (CI)

The project provides PowerShell cmdlets, as well as CI remote templates for executing the project's build, test, and publish steps for PowerShell modules.

via Cmdlets

The following are the parameters and environment variables supported by the provided PowerShell cmdlets for building, testing, and publishing PowerShell modules.

Parameters
Invoke-Build [<CommonParameters>]
Invoke-Test [[-ModuleManifestPath] <string>] [<CommonParameters>]
Invoke-Publish [[-ModuleManifestPath] <string>] [-Repository] <string> [-DryRun] [<CommonParameters>]
Environment variables
Build, Test, Publish
Name Example value Mandatory Type
PROJECT_DIRECTORY /path/to/my-project false string
MODULE_VERSION x.x.x false, true (Build + Publish) string
Publish
Name Example value Mandatory Type
NUGET_API_KEY xxx true string
Commands

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.

via Submodule and CI remote templates

The provided CI remote templates is composed of the following CI process:

Build
  1. Display system info
  2. Get PowerShell version
  3. Process build variables
  4. Generate module manifest
Test
  1. Test module via module's manifest
Publish
  1. Install publish dependencies (if applicable)
  2. 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.

Use cases

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.

Maintenance

Submodule

Using a specific tag

# 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'

Best practices

  • 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 the PSModulePublisher submodule used in your main project.