Sampler Module
This project is used to scaffold a PowerShell module project, complete with PowerShell build and deploy pipeline automation.
The Sampler module in itself serves several purposes:
- Quickly scaffold a PowerShell module project that can build and enforce some good practices.
- Provide a minimum set of InvokeBuild tasks that help you build, test, pack and publish your module.
- Help building your module by adding elaborate sample elements like classes, MOF-based DSC resources, class-based DSC resources, helper modules, embedded helper modules, and more.
- Avoid the "it works on my machine" and remove the dependence on specific tools (such as a CI tool).
- Ensures the build process can be run anywhere the same way (whether behind a firewall, on a developers workstation, or in a build agent).
- Assume nothing is set up, and you don't have local administrator rights.
- Works on Windows, Linux and MacOS.
Check the video for a quick intro:
Note: The video was made when Sampler was in early stages. Since that time there have been a lot of improvements and changes, so please read the _ documentation below._
Prerequisites
PowerShellGet
Because we resolve dependencies from a nuget feed, whether the public PowerShellGallery or your private repository, a working version of PowerShellGet is required. We recommend the latest version of PowerShellGet v2 (PowerShellGet v3 will be supported when it is released).
Managing the Module versions (optional)
Managing the versions of your module is tedious, and is hard to maintain
consistency over time. The usual tricks like checking what the latest version on
PowerShell Gallery is, or use the BuildNumber
to increment a 0.0.x
version
works but isn't ideal, especially if we want to stick to semver.
While you can manage the version by updating the module manifest manually or by
letting your CI tool update the ModuleVersion
environment variable, we think
the best method is to rely on the cross-platform tool GitVersion
.
GitVersion
will generate the version based on
the git history. You control what version to deploy using git tags.
Generally, GitVersion will look at the latest version tag, the branch names, commit
messages, to try to determine the Major/Minor/Patch (semantic versioning) based
on detected change (configurable in the file GitVersion.yml
that is part of your project).
Therefore, it is recommended that you install GitVersion
on your development environment
and on your CI environment build agents.
There are various ways to install GitVersion on your development environment. If you use Chocolatey (install and upgrade):
C:\> choco upgrade gitversion.portable
This describes how to install GitVersion in your CI environment build agents if you plan to use the deploy pipelines in the CI.
Usage
How to create a new project
To create a new project the command New-SampleModule
should be used. Depending
on the template used with the command the content in project will contain
different sample content while some also adds additional pipeline jobs. But all
templates (except one) will have the basic tasks to have a working pipeline including
build, test and deploy stages.
The sections below show how to use each template. The templates are:
SimpleModule
- Creates a module with minimal structure and pipeline automation.SimpleModule_NoBuild
- Creates a simple module without the build automation.CompleteSample
- Creates a module with complete structure and example files.dsccommunity
- Creates a DSC module according to the DSC Community baseline with a pipeline for build, test, and release automation.CustomModule
- Will prompt you for more details as to what you'd like to scaffold.GCPackage
- Creates a module that can be deployed to be used with Azure Policy Guest Configuration.
As per the video above, you can create a new module project with all files and
pipeline scripts. Once the project is created, the build.ps1
inside the new
project folder is how you interact with the built-in pipeline automation, and
the file build.yaml
is where you configure and customize it.
SimpleModule
Creates a module with minimal structure and pipeline automation.
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
$newSampleModuleParameters = @{
DestinationPath = 'C:\source'
ModuleType = 'SimpleModule'
ModuleName = 'MySimpleModule'
ModuleAuthor = 'My Name'
ModuleDescription = 'MySimpleModule Description'
}
New-SampleModule @newSampleModuleParameters
SimpleModule_NoBuild
Creates a simple module without the build automation.
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
$newSampleModuleParameters = @{
DestinationPath = 'C:\source'
ModuleType = 'SimpleModule_NoBuild'
ModuleName = 'MySimpleModuleNoBuild'
ModuleAuthor = 'My Name'
ModuleDescription = 'MySimpleModuleNoBuild Description'
}
New-SampleModule @newSampleModuleParameters
CompleteSample
Creates a module with complete structure and example files.
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
$newSampleModuleParameters = @{
DestinationPath = 'C:\source'
ModuleType = 'CompleteSample'
ModuleName = 'MyCompleteSample'
ModuleAuthor = 'My Name'
ModuleDescription = 'MyCompleteSample Description'
}
New-SampleModule @newSampleModuleParameters
dsccommunity
Creates a DSC module according to the DSC Community baseline with a pipeline for build, test, and release automation.
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
$newSampleModuleParameters = @{
DestinationPath = 'C:\source'
ModuleType = 'dsccommunity'
ModuleName = 'MyDscModule'
ModuleAuthor = 'My Name'
ModuleDescription = 'MyDscModule Description'
}
New-SampleModule @newSampleModuleParameters
CustomModule
Will prompt you for more details as to what you'd like to scaffold.
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
$samplerModule = Import-Module -Name Sampler -PassThru
$invokePlasterParameters = @{
TemplatePath = Join-Path -Path $samplerModule.ModuleBase -ChildPath 'Templates/Sampler'
DestinationPath = 'C:\source'
ModuleType = 'CustomModule'
ModuleName = 'MyCustomModule'
ModuleAuthor = 'My Name'
ModuleDescription = 'MyCustomModule Description'
}
Invoke-Plaster @invokePlasterParameters
GCPackage
Note: The
GCPackage
template is not yet available, but can be created using thedsccommunity
template with modifications, see the section GCPackage scaffolding.
How to download dependencies for the project
To be able to build the project, all the dependencies listed in the file
RequiredModules.psd1
must first be available. This is the beginning of
the build process so that anyone doing a git clone can 're-hydrate' the
project and start testing and producing the build artefact locally with
minimal environmental dependencies.
The following command will resolve dependencies:
cd C:\source\MySimpleModule
./build.ps1 -ResolveDependency -Tasks noop
The dependencies will be downloaded (or updated) from the PowerShell Gallery (unless
another repository is specified) and saved in the project folder under
./output/RequiredModules
.
By default, each repository should not rely on your personal development environment, so that it's easier to repeat on any machine or build agent.
Normally this command only needs to be run once, but the command can be run
anytime to update to a newer version of a required module (if one is available),
or if the required modules have changed in the file RequiredModules.psd1
.
Note: If a required module is removed in the file
RequiredModules.psd1
that module will not be automatically removed from the folder./output/RequiredModules
.
How to build the project
The following command will build the project:
cd C:\source\MySimpleModule
./build.ps1 -Tasks build
It is also possible to resolve dependencies and build the project at the same time using the command:
./build.ps1 -ResolveDependency -Tasks build
If there are any errors during build they will be shown in the output and the build will stop. If it is successful the output should end with:
Build succeeded. 7 tasks, 0 errors, 0 warnings 00:00:06.1049394
NOTE: The number of tasks can differ depending on which template that was used to create the project.
How to set up the build environment in the current PowerShell session
If you only want to make sure the environment is configured, or you only want
to resolve the dependencies, you can call the built-in task noop
("no operation")
which won't do anything other than a quick way to run the bootstrap script (there
is no code that executes in the noop
task).
./build.ps1 -Tasks noop
Note: For the built-in
noop
task to work, the dependencies must first have been resolved.
How to run tests
NOTE: Which tests are run is determined by the paths configured by a key in the Pester configuration in the file
build.yml
. The key differs depending on the version of Pester being used. The key isScript
when using Pester v4, andPath
when using Pester v5.
If running (or debugging) tests in Visual Studio Code you should first make sure
the session environment is set correctly. This is normally done when you build
the project. But if there is no need to rebuild the project it is faster to run
the built-in task noop
in the PowerShell Integrated Console.
How to run the default workflow
It is possible to do all of the above (resolve dependencies, build, and run tests) in just one line by running the following:
./build -ResolveDependency
The parameter Task
is not used which means this will run the default workflow
(.
). The tasks for the default workflow are configured in the file build.yml
.
Normally the default workflow builds the project and runs all the configured test.
This means by running this it will build and run all configured tests:
./build.ps1
How to list all available tasks
Because the build tasks are InvokeBuild
tasks, we can discover them using
the ?
task. So to list the available tasks in a project, run the following
command:
./build.ps1 -Tasks ?
NOTE: If it is not already done, first make sure to resolve dependencies. Dependencies can also hold tasks that are used in the pipeline.
build.ps1
)
About the bootstrap process (The build.ps1
is the entry point to invoke any task, or a list of build
tasks (workflow), leveraging the Invoke-Build
task runner.
The script does not assume your environment has the required PowerShell modules,
so the bootstrap is done by the project's script file build.ps1
, and can
resolve the dependencies listed in the project's file RequiredModules.psd1
using PSDepend
.
Invoking build.ps1
with the -ResolveDependency
parameter will prepare your
environment like so:
- Updates the session environment variable (
$env:PSModulePath
) to resolve the built module (.\output
) and the modules in the folder./output/RequiredModules
by prepending those paths to$env:PSModulePath
. By prepending the paths to the session$env:PSModulePath
the build process will make those dependencies available in your session for module discovery and auto-loading, and also make it possible to use one or more of those modules as part of your built module. - Making sure you have a compatible version of the modules PowerShellGet and
PackageManagement (
version -gt 1.6
). If not, these will be installed from the configured repository. - Download or install the
PowerShell-yaml
andPSDepend
modules needed for further dependency management. - Read the
build.yaml
configuration. - If the Nuget package provider is not present, install and import Nuget PackageProvider (proxy enabled).
- Invoke PSDepend on
the file
RequiredModules.psd1
. It will not install required modules to your environment, it will save them to your project's folder./output/RequiredModules
. - Hand over the task execution to
Invoke-Build
to run the configured workflow.
About Sampler build workflow
Let's look at the pipeline of the Sampler
module itself to better understand
how the pipeline automation is configured for a project created using a
template from the Sampler module.
NOTE: Depending on the Sampler template used when creating a new project there can be additional configuration options - but they can all be added manually when those options are needed. The Sampler project itself does not use all features available (an example is DSC resources documentation generation).
Default Workflow Currently configured
As seen in the bootstrap process above, the different workflows can be configured
by editing the build.psd1
: new tasks can be loaded, and the sequence can be
added under the BuildWorkflow
key by listing the names.
In our case, the build.yaml defines several workflows (.
,
build
, pack
, hqrmtest
, test
, and publish
) that can be called by using:
.\build.ps1 -Tasks <Workflow_or_task_Name>
The detail of the default workflow is as follow (InvokeBuild defaults to the workflow named '.' when no tasks is specified):
BuildWorkflow:
'.':
- build
- test
The tasks build
and tests
are meta-tasks or workflow calling other tasks:
build:
- Clean
- Build_Module_ModuleBuilder
- Build_NestedModules_ModuleBuilder
- Create_changelog_release_output
test:
- Pester_Tests_Stop_On_Fail
- Pester_if_Code_Coverage_Under_Threshold
- hqrmtest
Those tasks are imported from a module, in this case from
the .build/
folder, from this Sampler
module,
but for another module you would use this line in your build.yml
config:
ModuleBuildTasks:
Sampler:
- '*.build.Sampler.ib.tasks' # this means: import (dot source) all aliases ending with .ib.tasks exported by 'Sampler' module
You can edit your build.yml
to change the workflow, add a custom task,
create repository-specific task in a .build/
folder named *.build.ps1
.
MyTask: {
# do something with some PowerShellCode
Write-Host "Doing something in a task"
}
build:
- Clean
- MyTask
- call_another_task
GCPackage scaffolding
Creates a module that can be deployed to be used with Azure Policy Guest Configuration. This process will be replaced with a Plaster template.
-
Start by creating a new project using the template
dsccommunity
.Install-Module -Name 'Sampler' -Scope 'CurrentUser' $newSampleModuleParameters = @{ DestinationPath = 'C:\source' ModuleType = 'dsccommunity' ModuleName = 'MyGCPackages' ModuleAuthor = 'My Name' ModuleDescription = 'MyGCPackages Description' } New-SampleModule @newSampleModuleParameters
-
In the file
build.yaml
add the following top-level key:BuiltModuleSubdirectory: module
-
In the file
build.yaml
modify thepack
key under the top-level keyBuildWorkflow
by adding the taskgcpack
:pack: - build - package_module_nupkg - gcpack
-
In the file
build.yaml
modify theGitHubConfig
top-level key as follows:GitHubConfig: GitHubFilesToAdd: - 'CHANGELOG.md' ReleaseAssets: - output/GCPolicyPackages/UserAmyNotPresent*.zip GitHubConfigUserName: myGitHubUserName GitHubConfigUserEmail: [email protected] UpdateChangelogOnPrerelease: false
-
In the file
RequiredModules.psd1
add the module GuestConfiguration andxPSDesiredStateConfiguration
to the list of dependency modules.@{ # ... current dependencies xPSDesiredStateConfiguration = 'latest' GuestConfiguration = @{ Version = 'latest' Parameters = @{ AllowPrerelease = $true } } }
-
Modify the
azure-pipelines.yml
as follows:- Replace build image with
windows-latest
. - In the job
Package_Module
after the jobgitversion
and before the jobpackage
add this new job:- task: PowerShell@2 name: Exp_Feature displayName: 'Enable Experimental features' inputs: pwsh: true targetType: inline continueOnError: true script: | ./build.ps1 -Tasks noop -ResolveDependency Import-Module GuestConfiguration Enable-ExperimentalFeature -Name GuestConfiguration.Pester Enable-ExperimentalFeature -Name GuestConfiguration.SetScenario Enable-ExperimentalFeature -Name PSDesiredStateConfiguration.InvokeDscResource -ErrorAction SilentlyContinue env: ModuleVersion: $(gitVersion.NuGetVersionV2)
- Remove the job
Test_HQRM
. - Remove the job
Test_Integration
. - Remove the job
Code_Coverage
. - Update deploy condition to use the Azure DevOps organization name:
contains(variables['System.TeamFoundationCollectionUri'], 'myorganizationname')
- In the job
Deploy_Module
for both the deploy taskspublishRelease
andsendChangelogPR
add the following environment variables:ReleaseBranch: main MainGitBranch: main
- Replace build image with
-
Create a new folder
GCPackages
under the foldersource
. -
Create a new folder
UserAmyNotPresent
under the new folderGCPackages
. -
Under the folder
UserAmyNotPresent
create a new fileUserAmyNotPresent.config.ps1
. -
In the file
UserAmyNotPresent.config.ps1
add the following:Configuration UserAmyNotPresent { Import-DSCResource -ModuleName 'xPSDesiredStateConfiguration' Node UserAmyNotPresent { xUser 'UserAmyNotPresent' { Ensure = 'Absent' UserName = 'amy' } } }
-
Now resolve dependencies and run the task
gcpack
:build.ps1 -task gcpack -ResolveDependency
-
The built Guest Configuration package can be found in the folder
output\GCPolicyPackages\UserAmyNotPresent
.
Commands
Refer to the comment-based help for more information about these commands.
Add-Sample
This command is used to invoke a plaster template built-in the Sampler module. With this function you can bootstrap your module project by adding classes, functions and associated tests, examples and configuration elements.
Syntax
Add-Sample [[-Sample] <String>] [[-DestinationPath] <String>] [<CommonParameters>]
Outputs
None.
Example
Add-Sample -Sample PublicFunction -PublicFunctionName Get-MyStuff
This example adds a public function to the module (in the current folder), with a sample unit test that test the public function.
Invoke-SamplerGit
This command executes git with the provided arguments and throws an error if the call failed.
Syntax
Invoke-SamplerGit [-Argument] <string[]> [<CommonParameters>]
Outputs
[System.String]
Example
Invoke-SamplerGit -Argument @('config', 'user.name', 'MyName')
Calls git to set user name in the git config.
New-SampleModule
This command helps you scaffold your PowerShell module project by creating the folder structure of your module, and optionally add the pipeline files to help with compiling the module, publishing to a repository like PowerShell Gallery and GitHub, and testing quality and style such as per the DSC Community guidelines.
Syntax
New-SampleModule -DestinationPath <String> [-ModuleType <String>] [-ModuleAuthor <String>]
-ModuleName <String> [-ModuleDescription <String>] [-CustomRepo <String>]
[-ModuleVersion <String>] [-LicenseType <String>] [-SourceDirectory <String>]
[<CommonParameters>]
New-SampleModule -DestinationPath <String> [-ModuleAuthor <String>] -ModuleName <String>
[-ModuleDescription <String>] [-CustomRepo <String>] [-ModuleVersion <String>]
[-LicenseType <String>] [-SourceDirectory <String>] [-Features <String[]>]
[<CommonParameters>]
Outputs
None.
Example
See section Usage.
Commands for Build Tasks
These commands are primarily meant to be used in tasks that exist either in Sampler or in third-party modules.
Refer to the comment-based help for more information about these commands.
Convert-SamplerHashtableToString
Convert a Hashtable to a string representation. For instance, calling the function with this hashtable:
@{a=1;b=2; c=3; d=@{dd='abcd'}}
will return:
a=1; b=2; c=3; d={dd=abcd}
Syntax
Convert-SamplerHashtableToString [[-Hashtable] <Hashtable>] [<CommonParameters>]
Outputs
[System.String]
Example
Convert-SamplerhashtableToString -Hashtable @{a=1;b=2; c=3; d=@{dd='abcd'}}
This example will return the string representation of the provided hashtable.
Get-BuiltModuleVersion
Will read the properties ModuleVersion
and PrivateData.PSData.Prerelease
tag
of the module manifest for a module that has been built by Sampler. The command
looks into the OutputDirectory where the project's module should have been
built.
Syntax
Get-BuiltModuleVersion [-OutputDirectory] <String> [[-BuiltModuleSubdirectory] <String>]
[-ModuleName] <String> [-VersionedOutputDirectory] [<CommonParameters>]
Outputs
[System.String]
Example
Get-BuiltModuleVersion -OutputDirectory 'output' -ProjectName 'MyModuleName'
This example will return the module version of the built module 'MyModuleName'.
Get-ClassBasedResourceName
This command returns all the class-based DSC resource names in a script file.
The script file is parsed for classes with the [DscResource()]
attribute.
Note: For MOF-based DSC resources, look at the command
Get-MofSchemaName
.
Syntax
Get-ClassBasedResourceName [-Path] <String> [<CommonParameters>]
Outputs
[System.String]
Example
Get-ClassBasedResourceName -Path 'source/Classes/MyDscResource.ps1'
This example will return the class-based DSC resource names in the script file MyDscResource.ps1.
Import-Module -Name 'MyResourceModule'
$module = Get-Module -Name 'MyResourceModule'
Get-ClassBasedResourceName -Path (Join-Path -Path $module.ModuleBase -ChildPath $module.RootModule)
This example will return the class-based DSC resource names in built module script file for the module named 'MyResourceModule'.
Get-CodeCoverageThreshold
This command returns the CodeCoverageThreshold from the build configuration
(or overridden if the parameter RuntimeCodeCoverageThreshold
is passed).
Syntax
Get-CodeCoverageThreshold [[-RuntimeCodeCoverageThreshold] <String>]
[[-BuildInfo] <PSObject>] [<CommonParameters>]
Outputs
[System.Int]
Example
Get-CodeCoverageThreshold -RuntimeCodeCoverageThreshold 0
This example will override the code coverage threshold in the build configuration and return the value pass in the parameter RuntimeCodeCoverageThreshold.
Get-MofSchemaName
This command looks within a DSC resource's .MOF schema file to find the name and friendly name of the class.
Syntax
Get-MofSchemaName [-Path] <String> [<CommonParameters>]
Outputs
[System.Collections.Hashtable]
Property Name | Type | Description |
---|---|---|
Name | [System.String] |
The name of class |
FriendlyName | [System.String] |
The friendly name of the class |
Example
Get-MofSchemaName -Path Source/DSCResources/MyResource/MyResource.schema.mof
This example will return a hashtable containing the name and friendly name of the MOF-based resource MyResource.
Get-OperatingSystemShortName
This command tells what the platform is; Windows
, Linux
, or MacOS
.
Syntax
Get-OperatingSystemShortName [<CommonParameters>]
Outputs
[System.String]
Example
Get-OperatingSystemShortName
This example will return what platform it is run on.
Get-PesterOutputFileFileName
This command creates a file name to be used as Pester output XML file name.
The file name will be composed in the format:
${ProjectName}_v${ModuleVersion}.${OsShortName}.${PowerShellVersion}.xml
Syntax
Get-OperatingSystemShortName [<CommonParameters>]
Outputs
[System.String]
Example
Get-PesterOutputFileFileName -ProjectName 'Sampler' -ModuleVersion '0.110.4-preview001' -OsShortName 'Windows' -PowerShellVersion '5.1'
This example will return the string Sampler_v0.110.4-preview001.Windows.5.1.xml
.
Get-SamplerAbsolutePath
This command will resolve the absolute value of a path, whether it's potentially relative to another path, relative to the current working directory, or it's provided with an absolute path.
The path does not need to exist, but the command will use the right
[System.Io.Path]::DirectorySeparatorChar
for the OS, and adjust the
..
and .
of a path by removing parts of a path when needed.
Note: When the root drive is omitted on Windows, the path is not considered absolute.
Syntax
Get-SamplerAbsolutePath [[-Path] <String>] [[-RelativeTo] <String>] [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerAbsolutePath -Path '/src' -RelativeTo 'C:\Windows'
This example will return the string C:\src
on Windows.
Get-SamplerAbsolutePath -Path 'MySubFolder' -RelativeTo '/src'
This example will return the string C:\src\MySubFolder
on Windows.
Get-SamplerBuiltModuleBase
This command returns the module base of the built module.
Syntax
Get-SamplerBuiltModuleBase [-OutputDirectory] <String> [[-BuiltModuleSubdirectory] <String>]
[-ModuleName] <String> [-VersionedOutputDirectory] [[-ModuleVersion] <String>]
[<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerBuiltModuleBase -OutputDirectory 'C:\src\output' -BuiltModuleSubdirectory 'Module' -ModuleName 'stuff' -ModuleVersion '3.1.2-preview001'
This example will return the string C:\src\output\Module\stuff\3.1.2
.
Get-SamplerBuiltModuleManifest
This command returns the path to the built module's manifest.
Syntax
Get-SamplerBuiltModuleManifest [-OutputDirectory] <String> [[-BuiltModuleSubdirectory] <String>]
[-ModuleName] <String> [-VersionedOutputDirectory] [[-ModuleVersion] <String>] [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerBuiltModuleManifest -OutputDirectory 'C:\src\output' -BuiltModuleSubdirectory 'Module' -ModuleName 'stuff' -ModuleVersion '3.1.2-preview001'
This example will return the string C:\src\output\Module\stuff\3.1.2\stuff.psd1
.
Get-SamplerCodeCoverageOutputFile
This command resolves the code coverage output file path from the project's build configuration.
Syntax
Get-SamplerCodeCoverageOutputFile [-BuildInfo] <PSObject> [-PesterOutputFolder] <String>
[<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerCodeCoverageOutputFile -BuildInfo $buildInfo -PesterOutputFolder 'C:\src\MyModule\Output\testResults'
This example will return the code coverage output file path.
Get-SamplerCodeCoverageOutputFileEncoding
This command resolves the code coverage output file encoding from the project's build configuration.
Syntax
Get-SamplerCodeCoverageOutputFileEncoding [-BuildInfo] <PSObject> [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerCodeCoverageOutputFileEncoding -BuildInfo $buildInfo
This example will return the code coverage output file encoding.
Get-SamplerModuleInfo
This command loads a module manifest and returns the hashtable.
This implementation works around the issue where Windows PowerShell has
issues with the pwsh $env:PSModulePath
such as in VS Code with the VS Code
PowerShell extension.
Syntax
Get-SamplerModuleInfo [-ModuleManifestPath] <String> [<CommonParameters>]
Outputs
[System.Collections.Hashtable]
Example
Get-SamplerModuleInfo -ModuleManifestPath 'C:\src\MyProject\output\MyProject\MyProject.psd1'
This example will return the module manifest's hashtable.
Get-SamplerModuleRootPath
This command reads the module manifest (.psd1) and if the ModuleRoot
property
is defined it will resolve its absolute path based on the module manifest's
path. If there is no ModuleRoot
property defined, then this function will
return $null
.
Syntax
Get-SamplerModuleRootPath [-ModuleManifestPath] <String> [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerModuleRootPath -ModuleManifestPath C:\src\MyModule\output\MyModule\2.3.4\MyModule.psd1
This example will return the path to module script file, e.g. C:\src\MyModule\output\MyModule\2.3.4\MyModule.psm1
.
Get-SamplerProjectName
This command returns the project name based on the module manifest, if no
module manifest is available it will return $null
.
Syntax
Get-SamplerProjectName [-BuildRoot] <String> [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerProjectName -BuildRoot 'C:\src\MyModule'
This example will return the project name of the module in the path C:\src\MyModule
.
Get-SamplerSourcePath
This command returns the project's source path based on the module manifest,
if no module manifest is available it will return $null
.
Syntax
Get-SamplerSourcePath [-BuildRoot] <String> [<CommonParameters>]
Outputs
[System.String]
Example
Get-SamplerSourcePath -BuildRoot 'C:\src\MyModule'
This example will return the project's source path of the module in the
path C:\src\MyModule
.
Merge-JaCoCoReport
This command merges two JaCoCo reports and return the resulting merged JaCoCo report.
Note: Also see the command Update-JaCoCoStatistic.
Syntax
Merge-JaCoCoReport [-OriginalDocument] <XmlDocument> [-MergeDocument] <XmlDocument>
[<CommonParameters>]
Outputs
[System.Xml.XmlDocument]
Example
Merge-JaCoCoReport -OriginalDocument 'C:\src\MyModule\Output\JaCoCoRun_linux.xml' -MergeDocument 'C:\src\MyModule\Output\JaCoCoRun_windows.xml'
This example will merge the JaCoCo report JaCoCoRun_windows.xml
into the
JaCoCo report JaCoCoRun_linux.xml
and then return the resulting JaCoCo report.
New-SamplerJaCoCoDocument
This command creates a new JaCoCo XML document based on the provided missed
and hit lines. This command is usually used together with the output object
from Pester that also have been passed through ModuleBuilder's command
Convert-LineNumber
.
Syntax
New-SamplerJaCoCoDocument [-MissedCommands] <Object[]> [-HitCommands] <Object[]>
[-PackageName] <String> [[-PackageDisplayName] <String>] [<CommonParameters>]
Outputs
[System.Xml.XmlDocument]
Example
# Assuming Pester 4, for Pester 5 change the commands accordingly.
$pesterObject = Invoke-Pester ./tests/unit -CodeCoverage -PassThru
$pesterObject.CodeCoverage.MissedCommands |
Convert-LineNumber -ErrorAction 'Stop' -PassThru | Out-Null
$pesterObject.CodeCoverage.HitCommands |
Convert-LineNumber -ErrorAction 'Stop' -PassThru | Out-Null
New-SamplerJaCoCoDocument `
-MissedCommands $pesterObject.CodeCoverage.MissedCommands `
-HitCommands $pesterObject.CodeCoverage.HitCommands `
-PackageName 'source'
This example will create a new JaCoCo report based on the commands that
was hit or missed from the Pester run. It will use the ModuleBuilder's
command Convert-LineNumber
to correlate the correct line number from
the built module script file to the source script files.
New-SamplerJaCoCoDocument `
-MissedCommands @{
Class = 'ResourceBase'
Function = 'Compare'
HitCount = 0
SourceFile = '.\Classes\001.ResourceBase.ps1'
SourceLineNumber = 4
} `
-HitCommands @{
Class = 'ResourceBase'
Function = 'Compare'
HitCount = 2
SourceFile = '.\Classes\001.ResourceBase.ps1'
SourceLineNumber = 3
} `
-PackageName 'source'
This example will create a new JaCoCo report based on the two hashtables containing hit or missed line.
Out-SamplerXml
This command outputs an XML document to the file specified in the parameter Path.
Syntax
Out-SamplerXml [-XmlDocument] <XmlDocument> [-Path] <String> [[-Encoding] <String>]
[<CommonParameters>]
Outputs
None.
Example
Out-SamplerXml -Path 'C:\temp\my.xml' -XmlDocument '<?xml version="1.0"?><a><b /></a>' -Encoding 'UTF8'
This example will create a new XML file based on the XML document passed in the parameter XmlDocument.
Set-SamplerTaskVariable
This is an alias that points to a script file that is meant to be dot-sourced from (in) a build task. The script will set common task variables for a build task. This function should normally never be called outside of a build task, but an exception can be tests; tests can call the alias to set the values prior to running tests.
Note: Running the command
Get-Help -Name 'Set-SamplerTaskVariable'
will only return help for the alias. To see the comment-based help for the script, run:Import-Module -Name Sampler Get-Help -Name (Get-Alias -Name 'Set-SamplerTaskVariable').Definition -Detailed
Syntax
Set-SamplerTaskVariable [-AsNewBuild] [<CommonParameters>]
Outputs
None. Sets variables in the current PowerShell session. See comment-based help for more information about the variables that are set.
Example
. Set-SamplerTaskVariable
Call the scriptblock and tells the script to evaluate the module version by not checking after the module manifest in the built module.
. Set-SamplerTaskVariable -AsNewBuild
Call the scriptblock set script variables. The parameter AsNewBuild tells the script to skip variables that can only be set when the module has been built.
Split-ModuleVersion
This command parses a SemVer2 version string, and also a version string returned by a certain property of GitVersion (containing additional metadata).
Syntax
Split-ModuleVersion [[-ModuleVersion] <String>] [<CommonParameters>]
Outputs
[System.Management.Automation.PSCustomObject]
Property Name | Type | Description |
---|---|---|
Version | [System.String] |
The module version (without prerelease string) |
PreReleaseString | [System.String] |
The prerelease string part |
ModuleVersion | [System.String] |
The full semantic version |
Example
Split-ModuleVersion -ModuleVersion '1.15.0-pr0224-0022+Sha.47ae45eb2cfed02b249f239a7c55e5c71b26ab76.Date.2020-01-07'
This example will return a hashtable with the different parts of the module version for a version string that was returned by GitVersion.
Update-JaCoCoStatistic
This command updates statistics of a JaCoCo report. This is meant to be
run after the command Merge-JaCoCoReport
has been
used.
Syntax
Update-JaCoCoStatistic [-Document] <XmlDocument> [<CommonParameters>]
Outputs
[System.Xml.XmlDocument]
Example
Update-JaCoCoStatistic -Document (Merge-JaCoCoReport OriginalDocument $report1 -MergeDocument $report2)
This example will return a XML document containing the JaCoCo report with the updated statistics.
Build Task Variables
A task variable is used in a build task and it can be added as a script parameter to build.ps1 or set as as an environment variable. It can often be used if defined in parent scope or read from the $BuildInfo properties defined in the configuration file.
BuildModuleOutput
This is the path where the module will be built. The path will, for example,
be used for the parameter OutputDirectory
when calling the cmdlet
Build-Module
of the PowerShell module Invoke-Build. Defaults to
the path for OutputDirectory
, and concatenated with BuiltModuleSubdirectory
if it is set.
BuiltModuleSubdirectory
An optional path that will suffix the OutputDirectory
to build the
default path in variable BuildModuleOutput
.
ModuleVersion
The module version of the built module. Defaults to the property NuGetVersionV2
returned by the executable gitversion
, or if the executable gitversion
is not available the the variable defaults to an empty string, and the
build module task will use the version found in the Module Manifest.
It is also possible to set the session environment variable $env:ModuleVersion
in the PowerShell session or set the variable $ModuleVersion
in the
PowerShell session (the parent scope to Invoke-Build
) before running the
task build
This ModuleVersion
task variable can be overridden by using the key SemVer
in the file build.yml
, e.g. SemVer: '99.0.0-preview1'
. This can be used
if the preferred method of using GitVersion is not available.
The order that the module version is determined is as follows:
- the parameter
ModuleVersion
is set from the command line (passing parameter to build task) - if no parameter was passed it defaults to using the property from the
environment variable
$env:ModuleVersion
or parent scope variable$ModuleVersion
- if the
ModuleVersion
is still not found it will try to useGitVersion
if it is available - if
GitVersion
is not available the module version is set from the module manifest in the source path using the propertiesModuleVersion
andPrivateData.PSData.Prerelease
- if module version is set using key
SemVer
inbuild.yml
it will override 1), 2), 3), and 4) ifSemVar
is set through parameter from the command line then it willoverride 1), 2), 3), 4), and 5). This is not yet supported.
OutputDirectory
The base directory of all output from the build tasks. This is the path
where artifacts will be built or saved such as the built module, required
modules downloaded at build time, test results, etc. This folder should
be ignored by git as its content is ephemeral. It defaults to the folder
'output', a path relative to the root of the repository (same as Invoke-Build
's
$BuildRoot
).
You can override this setting with an absolute path should you need to.
ProjectPath
The root path to the project. Defaults to $BuildRoot
.
ProjectName
The project name. Defaults to the BaseName of the module manifest it finds in either the folder 'source', 'src, or a folder with the same name as the module.
ReleaseNotesPath
THe path to the release notes markdown file. Defaults to the path for
OutputDirectory
concatenated with ReleaseNotes.md
.
SourcePath
The path to the source folder. Defaults to the same path where the module manifest is found in either the folder 'source', 'src', or a folder with the same name as the module.
Tasks
Create_Changelog_Branch
This build task creates pushes a branch with the changelog updated with the current release version.
This is an example of how to use the task in the azure-pipelines.yml file:
- task: PowerShell@2
name: sendChangelogPR
displayName: 'Send Changelog PR'
inputs:
filePath: './build.ps1'
arguments: '-tasks Create_Changelog_Branch'
pwsh: true
env:
MainGitBranch: 'main'
BasicAuthPAT: $(BASICAUTHPAT)
This can be use in conjunction with the Create_Release_Git_Tag
task
that creates the release tag.
publish:
- Create_Release_Git_Tag
- Create_Changelog_Branch
Task parameters
Some task parameters are vital for the resource to work. See comment based help for the description for each available parameter. Below is the most important.
Task configuration
The build configuration (build.yaml) can be used to control the behavior of the build task.
####################################################
# Changelog Configuration #
####################################################
ChangelogConfig:
FilesToAdd:
- 'CHANGELOG.md'
UpdateChangelogOnPrerelease: false
####################################################
# Git Configuration #
####################################################
GitConfig:
UserName: bot
UserEmail: [email protected]
Section ChangelogConfig
Property FilesToAdd
This specifies one or more files to add to the commit when creating the PR branch. If left out it will default to the one file CHANGELOG.md.
Property UpdateChangelogOnPrerelease
true
: Always create a changelog PR, even on preview releases.false
: Only create a changelog PR for full releases. Default.
Section GitConfig
This configures git. user name and e-mail address of the user before task pushes the tag.
Property UserName
User name of the user that should push the tag.
Property UserEmail
E-mail address of the user that should push the tag.
Create_Release_Git_Tag
This build task creates and pushes a preview release tag to the default branch.
Note: This task is primarily meant to be used for SCM's that does not have releases that connects to tags like GitHub does with GitHub Releases, but this task can also be used as an alternative when using GitHub as SCM.
This is an example of how to use the task in the build.yaml file:
publish:
- Create_Release_Git_Tag
Task parameters
Some task parameters are vital for the resource to work. See comment based help for the description for each available parameter. Below is the most important.
Task configuration
The build configuration (build.yaml) can be used to control the behavior of the build task.
####################################################
# Git Configuration #
####################################################
GitConfig:
UserName: bot
UserEmail: [email protected]
Section GitConfig
This configures git. user name and e-mail address of the user before task pushes the tag.
Property UserName
User name of the user that should push the tag.
Property UserEmail
E-mail address of the user that should push the tag.
Set_PSModulePath
This task sets the PSModulePath
according to the configuration in the build.yml
file.
This task can be important when compiling DSC resource modules or DSC composite resource modules. When a DSC resource module is available in 'Program Files' and the Required Modules folder, DSC sees this as a conflict.
Note: The paths
$BuiltModuleSubdirectory
and$RequiredModulesDirectory
are always prepended to thePSModulePath
.
This sequence sets the PSModulePath
before starting the tests.
test:
- Set_PSModulePath
- Pester_Tests_Stop_On_Fail
- Pester_If_Code_Coverage_Under_Threshold
Task parameters
Some task parameters are vital for the resource to work. See comment based help for the description for each available parameter. Below is the most important.
Task configuration
The build configuration (build.yaml) can be used to control the behavior of the build task.
####################################################
# Setting Sampler PSModulePath #
####################################################
SetPSModulePath:
PSModulePath: C:\Users\Install\OneDrive\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;c:\Users\Install\.vscode\extensions\ms-vscode.powershell-2022.5.1\modules;
RemovePersonal: false
RemoveProgramFiles: false
RemoveWindows: false
SetSystemDefault: false
Section SetPSModulePath
Property SetPSModulePath
Sets the PSModulePath
to the specified value.
Property RemovePersonal
Removed the personal path from PSModulePath
, like C:\Users\Install\Documents\WindowsPowerShell\Modules
.
Section RemoveProgramFiles
Removed the 'Program Files' path from PSModulePath
, like C:\Program Files\WindowsPowerShell\Modules
.
Property RemoveWindows
Removed the Windows path from PSModulePath
, like C:\Windows\system32\WindowsPowerShell\v1.0\Modules
.
Note: It is not recommended to remove the Windows path from
PSModulePath
.
Property SetSystemDefault
Sets the module path to what is defined for the machine. The machines PSModulePath
is retrieved with this call:
[System.Environment]::GetEnvironmentVariable('PSModulePath', 'Machine')