Skip to content

Commit bff8e7a

Browse files
authored
Merge pull request #133 from PoshCode/joel/Rebuild
Fix the test matrix
2 parents b715cf6 + 9d06dd8 commit bff8e7a

23 files changed

+1007
-887
lines changed

.github/workflows/build.yml

+37-26
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,18 @@ jobs:
4242
name: TestResults
4343
path: Modules/ModuleBuilder-TestResults
4444

45-
- uses: actions/upload-artifact@v4
46-
with:
47-
name: Packages
48-
path: Modules/ModuleBuilder-Packages
49-
45+
# These ones are just for the test matrix
5046
- name: Upload Tests
5147
uses: actions/upload-artifact@v4
5248
with:
5349
name: PesterTests
5450
path: ${{github.workspace}}/Tests
55-
- name: Upload RequiredModules.psd1
51+
52+
- name: Upload build.requires.psd1
5653
uses: actions/upload-artifact@v4
5754
with:
58-
name: RequiredModules
59-
path: ${{github.workspace}}/RequiredModules.psd1
55+
name: build.requires.psd1
56+
path: ${{github.workspace}}/build.requires.psd1
6057
test:
6158
needs: build
6259
runs-on: ${{ matrix.os }}
@@ -69,29 +66,43 @@ jobs:
6966
uses: actions/download-artifact@v4
7067
with:
7168
name: ModuleBuilder
72-
path: Modules/ModuleBuilder
69+
path: Modules/ModuleBuilder # /home/runner/work/ModuleBuilder/ModuleBuilder/Modules/ModuleBuilder
7370
- name: Download Pester Tests
7471
uses: actions/download-artifact@v4
7572
with:
7673
name: PesterTests
7774
path: PesterTests
78-
- name: Download RequiredModules
75+
- name: Download build.requires.psd1
7976
uses: actions/download-artifact@v4
8077
with:
81-
name: RequiredModules
82-
83-
- uses: PoshCode/Actions/install-requiredmodules@v1
84-
- uses: PoshCode/Actions/pester@v1
85-
with:
86-
codeCoveragePath: Modules/ModuleBuilder
87-
moduleUnderTest: ModuleBuilder
88-
additionalModulePaths: ${{github.workspace}}/Modules
89-
- name: Publish Test Results
90-
uses: zyborg/dotnet-tests-report@v1
78+
name: build.requires.psd1
79+
- name: ⚡ Install PowerShell Modules
80+
uses: JustinGrote/[email protected]
81+
- name: Put Build output in PATH
82+
shell: pwsh
83+
run: | # PowerShell
84+
Convert-Path Modules -OutVariable BuiltModules
85+
Add-Content -Path $env:GITHUB_PATH -Value $BuiltModules -Encoding utf8
86+
# Uninstall the "installed" copy of ModuleBuilder
87+
Get-Module -Name ModuleBuilder -List | Where ModuleBase -notmatch ([regex]::escape($pwd)) | Split-Path | Remove-Item -Recurse -Force
88+
- name: Put Build output in PATH
89+
shell: pwsh
90+
run: | # PowerShell
91+
$Env:PATH -split ([IO.Path]::PathSeparator) | Out-Host
92+
- name: Invoke Pester Tests
93+
id: pester
94+
uses: zyborg/pester-tests-report@v1
9195
with:
92-
test_results_path: results.xml
93-
- name: Upload Results
94-
uses: actions/upload-artifact@v2
95-
with:
96-
name: Pester Results
97-
path: ${{github.workspace}}/*.xml
96+
# include_paths: tests
97+
# exclude_paths: tests/powershell1,tests/powershell2
98+
# exclude_tags: skip_ci
99+
report_name: module_tests
100+
report_title: My Module Tests
101+
github_token: ${{ secrets.GITHUB_TOKEN }}
102+
- name: dump test results
103+
shell: pwsh
104+
run: | # PowerShell
105+
Write-Host 'Total Tests Executed...: ${{ steps.pester.outputs.total_count }}'
106+
Write-Host 'Total Tests PASSED.....: ${{ steps.pester.outputs.passed_count }}'
107+
Write-Host 'Total Tests FAILED.....: ${{ steps.pester.outputs.failed_count }}'
108+

.github/workflows/dotnet-tools.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"gitversion.tool": {
6+
"version": "5.6.0",
7+
"commands": [
8+
"dotnet-gitversion"
9+
]
10+
}
11+
}
12+
}

Build.build.ps1

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ param(
1616
# Add the clean task before the default build
1717
[switch]$Clean,
1818

19-
# Collect code coverage when tests are run
20-
[switch]$CollectCoverage,
19+
# A minimum code coverage percentage to accept as a double: 0.85
20+
[double]$RequiredCodeCoverage = 0.85,
2121

2222
# Which projects to build
2323
[Alias("Projects")]

Earthfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
VERSION 0.7
22
IMPORT github.com/poshcode/tasks
3-
FROM mcr.microsoft.com/dotnet/sdk:7.0
3+
FROM mcr.microsoft.com/dotnet/sdk:9.0
44
WORKDIR /work
55

66
ARG --global EARTHLY_GIT_ORIGIN_URL
@@ -25,9 +25,9 @@ worker:
2525
COPY tasks+tasks/* /Tasks
2626
# Dealing with dependencies first allows docker to cache packages for us
2727
# So the dependency cach only re-builds when you add a new dependency
28-
COPY RequiredModules.psd1 .
28+
COPY build.requires.psd1 .
2929
# COPY *.csproj .
30-
RUN ["pwsh", "-File", "/Tasks/_Bootstrap.ps1", "-RequiredModulesPath", "RequiredModules.psd1"]
30+
RUN ["pwsh", "-File", "/Tasks/_Bootstrap.ps1", "-RequiresPath", "build.requires.psd1"]
3131

3232
build:
3333
FROM +worker

GitVersion.yml

+40-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,46 @@
1-
mode: Mainline
2-
assembly-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILDCOUNT ?? 0}'
3-
assembly-informational-format: '{NuGetVersionV2}+Build.{env:BUILDCOUNT ?? 0}.Date.{CommitDate}.Branch.{env:SAFEBRANCHNAME ?? unknown}.Sha.{Sha}'
4-
major-version-bump-message: '\+?semver:\s?(breaking|major)'
5-
minor-version-bump-message: '\+?semver:\s?(feature|minor)'
6-
patch-version-bump-message: '\+?semver:\s?(fix|patch)'
7-
no-bump-message: '\+?semver:\s?(none|skip)'
1+
mode: mainline
2+
commit-date-format: "yyyyMMddTHHmmss"
3+
assembly-file-versioning-format: "{Major}.{Minor}.{Patch}.{env:GITHUB_RUN_NUMBER ?? 0}"
4+
5+
# This repo needs to use NuGetVersionV2 for compatibility with PowerShellGallery
6+
assembly-informational-format: "{NuGetVersionV2}+Build.{env:GITHUB_RUN_NUMBER ?? local}.Branch.{EscapedBranchName}.Sha.{Sha}.Date.{CommitDate}"
7+
major-version-bump-message: 'semver:\s?(breaking|major)'
8+
minor-version-bump-message: 'semver:\s?(feature|minor)'
9+
patch-version-bump-message: 'semver:\s?(fix|patch)'
10+
no-bump-message: 'semver:\s?(none|skip)'
11+
commit-message-incrementing: Enabled
12+
813
branches:
9-
master:
14+
main:
15+
tag: "" # explicitly no tag for main builds
16+
regex: ^main$
1017
increment: Patch
11-
pull-request:
18+
is-mainline: true
19+
tracks-release-branches: true
20+
hotfix:
21+
tag: rc
22+
regex: hotfix(es)?/\d+\.\d+\.\d+
23+
increment: None
24+
is-release-branch: true
25+
prevent-increment-of-merged-branch-version: true
26+
source-branches: [ "main" ]
27+
release:
1228
tag: rc
29+
regex: releases?/\d+\.\d+\.\d+
30+
increment: None
31+
is-release-branch: true
32+
prevent-increment-of-merged-branch-version: true
33+
source-branches: [ "main" ]
34+
pull-request:
35+
regex: pull/
36+
tag: pr
37+
tag-number-pattern: '[/-](?<number>\d+)'
1338
increment: Patch
39+
source-branches: [ "main", "feature", "release", "hotfix" ]
1440
feature:
41+
regex: .*/
42+
tag: useBranchName
43+
source-branches: [ "main", "feature" ]
44+
track-merge-target: true
45+
tracks-release-branches: true
1546
increment: Patch
16-
regex: .*?/
17-
source-branches:
18-
- master
19-
- feature

ReadMe.md

+27-39
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,59 @@
1-
# The Module Builder Project
1+
# Module Builder - Simplifying Authoring PowerShell (Script) Modules
22

3-
This project is an attempt by a group of PowerShell MVPs and module authors to:
3+
This module makes it easier to break up your module source into several files for organization, even though you need to ship it as one big psm1 file.
44

5-
1. Build a common set of [tools for module authoring](#whats-in-the-module-so-far)
6-
2. Encourage a common pattern for [organizing PowerShell module projects](#organizing-your-module)
7-
3. Promote best practices for authoring functions and modules
5+
There are still some issues in Visual Studio Code and PSScriptAnalyzer when authoring modules as multiple files, but if you want to break up your module into multiple files for organization and maintainability, and still need to ship it as one big file for performance and compatibility reasons, this module is for you.
86

9-
In short, we want to make it easier for people to write great code and produce great modules.
7+
## You should ship your module as one big file!
108

11-
In service of this goal, we intend to produce:
9+
PowerShell expects script modules to be all in one file. A module in a single `.psm1` script file results in the best performance, natural "script" scope, and full support for classes and "using" statements.
1210

13-
1. Guidance on using the best of the existing tools: dotnet, Pester, PSDepends, etc.
14-
2. Module templates demonstrating best practices for organization
15-
3. Function templates demonstrating best practices for common parameters and error handling
16-
4. ModuleBuilder module - a set of tools for building modules following these best practices
11+
The single file option is particularly important for performance if you are signing your module (or your end users want to be able to code-sign it), because each file's signature must be checked, and each certificate must be checked against CRLs. It's also critical if you are using PowerShell classes (the `using` statement only supports classes defined in the root psm1 file). It's basically required if you want to use module-scope variables to share state between functions in your module.
1712

18-
## The ModuleBuilder module
13+
## What's in the ModuleBuilder module so far?
1914

20-
This module is the main output of the project, consisting of one primary command: `Build-Module` and a few helpers to translate input and output line numbers. It represents the collaboration of several module authors who had each written their own version of these tools for themselves, and have now decided to collaborate on creating a shared tool set. We are each using the patterns and tools that are represented here, and are committed to helping others to succeed at doing so.
15+
This module is the main output of the project, consisting of one primary command: `Build-Module` and a few helpers to translate input and output line numbers so you can trouble-shoot error messages from your module against the source files.
2116

22-
### What's in the module so far
23-
24-
#### Build-Module
17+
### Build-Module
2518

2619
Builds a script module from a source project containing one file per function in `Public` and `Private` folders.
2720

2821
The `Build-Module` command is a build task for PowerShell script modules that supports [incremental builds](https://docs.microsoft.com/en-us/visualstudio/msbuild/incremental-builds).
2922

30-
#### Convert-CodeCoverage
23+
### Convert-CodeCoverage
3124

3225
Takes the output from `Invoke-Pester -Passthru` run against the build output, and converts the code coverage report to the source lines.
3326

34-
#### ConvertFrom-SourceLineNumber
27+
### ConvertFrom-SourceLineNumber
3528

3629
Converts a line number from a source file to the corresponding line number in the built output.
3730

38-
#### ConvertTo-SourceLineNumber
31+
### ConvertTo-SourceLineNumber
3932

4033
Converts a line number from the built output to the corresponding file and line number in the source.
4134

42-
#### Convert-Breakpoint
35+
### Convert-Breakpoint
4336

4437
Convert any breakpoints on source files to module files _and vice-versa_.
4538

4639
## Organizing Your Module
4740

48-
For best results, you need to organize your module project similarly to how this project is organized. It doesn't have to be exact, because nearly all of our conventions can be overriden, but the module _is_ opinionated, so if you follow the conventions, it should feel wonderfully automatic.
41+
For best results, you need to organize your module project similarly to how this project is organized. It doesn't have to be exact, because you can override nearly all of our conventions, but the module _is_ opinionated, so if you follow the conventions, it should feel wonderfully automatic.
4942

50-
1. Create a `source` folder with a `build.psd1` file and your module manifest in it
43+
1. Create a `source` (or `src`) folder with a `build.psd1` file and your module manifest in it
5144
2. In the `build.psd1` specify the relative **Path** to your module's manifest, e.g. `@{ Path = "ModuleBuilder.psd1" }`
5245
3. In your manifest, make sure a few values are not commented out. You can leave them empty, because they'll be overwritten:
5346
- `FunctionsToExport` will be updated with the _file names_ that match the `PublicFilter`
5447
- `AliasesToExport` will be updated with the values from `[Alias()]` attributes on commands
5548
- `Prerelease` and `ReleaseNotes` in the `PSData` hash table in `PrivateData`
5649

57-
Once you start working on the module, you'll create sub-folders in source, and put script files in them with only **one** function in each file. You should name the files with _the same name_ as the function that's in them -- especially in the public folder, where we use the file name (without the extension) to determine the exported functions.
50+
Once you start working on the module, you'll create sub-folders in source, and put script files in them with only **one** function in each file. You should name the files with _the same name_ as the function that's in them -- especially in the `source\public` folder, where we use the file names to determine the exported functions.
5851

59-
1. By convention, use folders named "Classes" (and/or "Enum"), "Private", and "Public"
60-
2. By convention, the functions in "Public" will be exported from the module (you can override the `PublicFilter`)
52+
1. By convention, use SourceDirectories named "Classes" (and/or "Enum"), "Private", and "Public"
53+
2. By convention, the PublicFilter is all of the functions in the "Public" directory.
6154
3. To force classes to be in a certain order, you can prefix their file names with numbers, like `01-User.ps1`
6255

63-
There are a _lot_ of conventions in `Build-Module`, expressed as default values for its parameters. These defaults are documented in the help for Build-Module. You can override any parameter defaults by adding keys to the `build.psd1` file with your preferences, or by passing the values to the `Build-Module` command directly.
56+
There are a _lot_ of conventions in `Build-Module`, expressed as default values for its parameters. These defaults are documented in the help for Build-Module, and you can override any parameter defaults by adding keys to the `build.psd1` file with your preferences, or by passing the values to the `Build-Module` command directly. So in other words, you can override the default `SourceDirectories` and `PublicFilters` (and any others) by adding them to the `build.psd1` file.
6457

6558
## A note on build tools
6659

@@ -93,7 +86,7 @@ git clone https://github.com/PoshCode/ModuleBuilder.git
9386
git clone https://github.com/PoshCode/Tasks.git
9487
```
9588

96-
Once you've cloned both, the `Build.build.ps1` script will use the shared [Tasks\_Bootstrap.ps1](https://github.com/PoshCode/Tasks/blob/main/_Bootstrap.ps1) to install the other dependencies (see [RequiredModules.psd1](https://github.com/PoshCode/ModuleBuilder/blob/main/RequiredModules.psd1)), including [dotnet](https://dot.net), and will use [Invoke-Build](https://github.com/nightroman/Invoke-Build) and [Pester](https://github.com/Pester/Pester) to build and test the module.
89+
Once you've cloned both, the `Build.build.ps1` script will use the shared [Tasks\_Bootstrap.ps1](https://github.com/PoshCode/Tasks/blob/main/_Bootstrap.ps1) to install the other dependencies (see [build.requires.psd1](https://github.com/PoshCode/ModuleBuilder/blob/main/build.requires.psd1)), including [dotnet](https://dot.net), and will use [Invoke-Build](https://github.com/nightroman/Invoke-Build) and [Pester](https://github.com/Pester/Pester) to build and test the module.
9790

9891
```powershell
9992
cd ModuleBuilder
@@ -102,23 +95,18 @@ cd ModuleBuilder
10295

10396
This _should_ work on Windows, Linux, or MacOS. I test the build process on Windows, and in CI we run it in the Linux containers via earthly, and we run the full Pester test suit on all three platforms.
10497

105-
#### The old-fashioned way
98+
## Most recent releases
10699

107-
You _can_ build the module without any additional tools (and without running tests), by using the old `build.ps1` bootstrap script. You'll need to pass a version number in, and if you have [Pester](https://github.com/Pester/Pester) and [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer), you can run the 'test.ps1' script to run the tests.
100+
### 3.2.0 - Script Generators
108101

109-
```powershell
110-
./build.ps1 -Semver 5.0.0-prerelease | Split-Path | Import-Module -Force
111-
./test.ps1
112-
```
102+
Script Generators let developers modify their module's source code as it is being built. A generator can create new script functions on the fly, such that whole functions are added to the built module. A generator can also inject boilerplate code like error handling, logging, tracing and timing at build-time, so this code can be maintained once, and be automatically added (and updated) in all the places where it's needed when the module is built. The generators run during the build and can inspect existing functions, data files, or even data from an API, and produce code that is output into the module (and clearly marked as generated).
103+
104+
### 3.1.0 - Supports help outside the top of script commands
113105

114-
## Changelog
106+
Starting with this release, ModuleBuilder adds an empty line between the `#REGION filename` comment lines it injects, and the content of the files. This allows PowerShell to recognize help comments that are at the top of each file (outside the function block).
115107

116-
### 3.0.0 - Now with better alias support
108+
### 3.0.0 - Better alias support
117109

118110
Starting with this release, ModuleBuilder will automatically export aliases from `New-Alias` and `Set-Alias` as well as the `[Alias()]` attributes on commands. This is (probably not) a breaking change, but because it can change the aliases exported by existing modules that use ModuleBuilder, I've bumped the major version number as a precaution (if you're reading this, mission accomplished).
119111

120112
Additionally, the `Build-Module` command now _explicitly sorts_ the source files into alphabetical order, to ensure consistent behavior regardless of the native order of the underlying file system. This is technically also a breaking change, but it's unlikely to affect anyone except the people whose builds didn't work on non-Windows systems because of the previous behavior.
121-
122-
### 3.1.0 - Now allows help outside the top of script commands
123-
124-
Starting with this release, ModuleBuilder adds an empty line between the `#REGION filename` comment lines it injects, and the content of the files. This allows PowerShell to recognize help comments that are at the top of each file (outside the function block).

RequiredModules.psd1

-10
This file was deleted.

0 commit comments

Comments
 (0)