Skip to content

Commit e78a220

Browse files
Initial version
1 parent 87cc452 commit e78a220

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1820
-3
lines changed

.gitattributes

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Needed for publishing of examples, build worker defaults to core.autocrlf=input.
2+
* text eol=autocrlf
3+
4+
*.mof text eol=crlf
5+
*.sh text eol=lf
6+
*.svg eol=lf
7+
8+
# Ensure any exe files are treated as binary
9+
*.exe binary
10+
*.jpg binary
11+
*.xl* binary
12+
*.pfx binary
13+
*.png binary
14+
*.dll binary
15+
*.so binary

.github/linters/.markdown-lint.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
###########################
2+
## Markdown Linter rules ##
3+
###########################
4+
5+
# Linter rules doc:
6+
# - https://github.com/DavidAnson/markdownlint
7+
8+
###############
9+
# Rules by id #
10+
###############
11+
MD004: false # Unordered list style
12+
MD007:
13+
indent: 2 # Unordered list indentation
14+
MD013:
15+
line_length: 808 # Line length
16+
MD026:
17+
punctuation: ".,;:!。,;:" # List of not allowed
18+
MD029: false # Ordered list item prefix
19+
MD033: false # Allow inline HTML
20+
MD036: false # Emphasis used instead of a heading
21+
22+
#################
23+
# Rules by tags #
24+
#################
25+
blank_lines: false # Error on blank lines

.github/release.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes
2+
3+
changelog:
4+
categories:
5+
- title: Breaking Changes
6+
labels:
7+
- Major
8+
- Breaking
9+
- title: New Features
10+
labels:
11+
- Minor
12+
- Feature
13+
- Improvement
14+
- Enhancement
15+
- title: Other Changes
16+
labels:
17+
- '*'

.github/workflows/Action-Test.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Action-Test
2+
3+
run-name: "Action-Test - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"
4+
5+
on: [pull_request]
6+
7+
env:
8+
GH_TOKEN: ${{ github.token }}
9+
10+
jobs:
11+
ActionTestDefault:
12+
name: Action-Test - [Default]
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repo
16+
uses: actions/checkout@v4
17+
18+
- name: Initialize environment
19+
uses: PSModule/Initialize-PSModule@main
20+
21+
- name: Action-Test
22+
uses: ./
23+
with:
24+
Name: PSModule
25+
Path: tests/src
26+
ModulesOutputPath: tests/outputs/modules
27+
DocsOutputPath: tests/outputs/docs

.github/workflows/Auto-Release.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Auto-Release
2+
3+
run-name: "Auto-Release - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"
4+
5+
on:
6+
pull_request_target:
7+
branches:
8+
- main
9+
types:
10+
- closed
11+
- opened
12+
- reopened
13+
- synchronize
14+
- labeled
15+
16+
concurrency:
17+
group: ${{ github.workflow }}
18+
19+
permissions:
20+
contents: write
21+
pull-requests: write
22+
23+
jobs:
24+
Auto-Release:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout Code
28+
uses: actions/checkout@v4
29+
30+
- name: Auto-Release
31+
uses: PSModule/Auto-Release@v1
32+
env:
33+
GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication
34+
with:
35+
IncrementalPrerelease: false

.github/workflows/Linter.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Linter
2+
3+
run-name: "Linter - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"
4+
5+
on: [pull_request]
6+
7+
jobs:
8+
Lint:
9+
name: Lint code base
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout repo
13+
uses: actions/checkout@v4
14+
15+
- name: Lint code base
16+
uses: github/super-linter@latest
17+
env:
18+
GITHUB_TOKEN: ${{ github.token }}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Ignore Visual Studio Code temporary files, build results, and
2+
## files generated by popular Visual Studio Code add-ons.
3+
##
4+
## Get latest from https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore
5+
.vscode/*
6+
!.vscode/settings.json
7+
!.vscode/extensions.json
8+
*.code-workspace
9+
10+
# Local History for Visual Studio Code
11+
.history/

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2023 PSModule
3+
Copyright (c) 2024 PSModule
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 178 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,178 @@
1-
# build
2-
Action that is used to build a PowerShell module
1+
# Build-PSModule
2+
3+
This action "compiles" the module source code into a efficient PowerShell module that is ready to be published to the PowerShell Gallery.
4+
5+
This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule). It is recommended to use the [Process-PSModule workflow](https://github.com/PSModule/Process-PSModule) to automate the whole process of managing the PowerShell module.
6+
7+
## Supported module types
8+
9+
- Script module type
10+
- Manifest module type
11+
12+
## Supported practices and principles
13+
14+
- [PowerShellGallery Publishing Guidelines and Best Practices](https://learn.microsoft.com/powershell/gallery/concepts/publishing-guidelines) are followed as much as possible.
15+
16+
## How it works
17+
18+
During the build process the following steps are performed:
19+
20+
1. Copies the source code of the module to an output folder.
21+
1. Builds the module manifest file based of info on the GitHub repository and source code. Read the [Module Manifest](#module-manifest) section for more information.
22+
1. Builds the root module (.psm1) file by combining source code and adding automation into the root module file. Read the [Root module](#root-module) section for more information.
23+
1. Builds the module documentation using platyPS and comment based help in the source code. Read the [Module documentation](#module-documentation) section for more information.
24+
25+
## Usage
26+
27+
| Name | Description | Required | Default |
28+
| --- | --- | --- | --- |
29+
| `Name` | Name of the module to process. | `false` | |
30+
| `Path` | Path to the folder where the modules are located. | `false` | `src` |
31+
| `ModulesOutputPath` | Path to the folder where the built modules are outputted. | `false` | `outputs/modules` |
32+
| `DocsOutputPath` | Path to the folder where the built docs are outputted. | `false` | `outputs/docs` |
33+
34+
## Root module
35+
36+
The root module file is the main file that is loaded when the module is imported.
37+
It is built from the source code files in the module folder in the following order:
38+
39+
1. Adds module headers from `header.ps1`.
40+
1. Adds data loader automation that loads files from the `data` folder as variables in the module scope. The variables are available using the ´$script:<filename>´ syntax.
41+
1. Adds content from subfolders, in the order:
42+
- Init
43+
- Private
44+
- Public
45+
- *.ps1 on module root
46+
1. Adds the Export-ModuleMember function to the end of the file, to make sure that only the functions, cmdlets, variables and aliases that are defined in the module are exported.
47+
48+
### The root module in the `src` folder
49+
50+
The root module file that is included in the source files contains the same functionality but is not optimized for performance.
51+
The goal with this is to have a quick way to import and test the module without having to build it.
52+
53+
## Module manifest
54+
55+
The module manifest file is the file that describes the module and its content. It is used by PowerShell to load the module and its prerequisites.
56+
The file also contains important metadata that is used by the PowerShell Gallery.
57+
58+
During the module manifest build process the following steps are performed:
59+
60+
1. Get the manifest file from the source code. Content from this file overrides any value that would be calculated based on the source code.
61+
1. Find and set the `RootModule` based on filename and extension.
62+
1. Set a temporary `ModuleVersion`, as this is set during the release process by [Publish-PSModule](https://github.com/PSModule/Publish-PSModule).
63+
1. Set the `Author` and `CompanyName` based on GitHub Owner.
64+
1. Set the `Copyright` information based on a default text (`(c) 2024 >>OwnerName<<. All rights reserved.`) and adds either the `Author`, `CompanyName` or both (`Author | CompanyName`) when these are different.
65+
1. Set the `Description` based on the GitHub repository description.
66+
1. Set various properties in the manifest such as `PowerShellHostName`, `PowerShellHostVersion`, `DotNetFrameworkVersion`, `ClrVersion`, and `ProcessorArchitecture`. There is currently no automation for these properties.
67+
1. Get the list of files in the module source folder and set the `FileList` property in the manifest.
68+
1. Get the list of required assemblies (`*.dll` files) from the `assemblies` folder and set the `RequiredAssemblies` property in the manifest.
69+
1. Get the list of nested modules (`*.psm1` files) from the `modules` folder and set the `NestedModules` property in the manifest.
70+
1. Get the list of scripts to process (`*.ps1` files) from the `classes` and `scripts` folders and set the `ScriptsToProcess` property in the manifest. This ensures that the scripts are loaded to the caller session (parent of module session).
71+
1. Get the list of types to process by searching for `*.Types.ps1xml` files in the entire module source folder and set the `TypesToProcess` property in the manifest.
72+
1. Get the list of formats to process by searching for `*.Format.ps1xml` files in the entire module source folder and set the `FormatsToProcess` property in the manifest.
73+
1. Get the list of DSC resources to export by searching for `*.psm1` files in the `resources` folder and set the `DscResourcesToExport` property in the manifest.
74+
1. Get the list of functions, cmdlets, aliases, and variables to export and set the respective properties in the manifest.
75+
1. Get the list of modules by searching for all `*.psm1` files in the entire module source folder, excluding the root module and set the `ModuleList` property in the manifest.
76+
1. Gather information about required modules, PowerShell version, and compatible PS editions from the module source files and set the respective properties in the manifest.
77+
1. The following values are gathered from the GitHub repository:
78+
- `Tags` are generated from Repository topics in addition to compatability tags gathered from the source code.
79+
- `LicenseUri` is generated assuming there is a `LICENSE` file on the root of the repository.
80+
- `ProjectUri` is the URL to the GitHub repository
81+
- `IconUri` is generated assuming there is a `icon.png` file in the `icon` folder on the repository root.
82+
1. `ReleaseNotes` currently not automated, but could be the PR description or release description.
83+
1. `PreRelease` is not managed here, but is managed from [Publish-PSModule](https://github.com/PSModule/Publish-PSModule)
84+
1. `RequireLicenseAcceptance` is not automated and defaults to `false`, and
85+
1. `ExternalModuleDependencies` is currenlty not automated.
86+
1. `HelpInfoURI` is not automated.
87+
1. Create a new manifest file in the output folder with the gathered info above. This also generates a new `GUID` for the module.
88+
1. Format the manifest file using the `Set-ModuleManifest` function from the [Utilities](https://github.com/PSModule/Utilities) module.
89+
90+
Linking the description to the module manifest file might show more how this works:
91+
92+
```powershell
93+
@{
94+
RootModule = 'Utilities.psm1' # Get files from root of folder wher name is same as the folder and file extension is .psm1, .ps1, .psd1, .dll, .cdxml, .xaml. Error if there are multiple files that meet the criteria.
95+
ModuleVersion = '0.0.1' # Set during release using Publish-PSModule.
96+
CompatiblePSEditions = @() # Get from source files, REQUIRES -PSEdition <PSEdition-Name>, null if not provided.
97+
GUID = '<GUID>' # Generated when finally saving the manifest using New-ModuleManifest.
98+
Author = 'PSModule' # Get from GitHub Owner, else use info from source manifest file.
99+
CompanyName = 'PSModule' # Get from GitHub Owner, else use info from source manifest file.
100+
Copyright = '(c) 2024 PSModule. All rights reserved.' # Generated from the current year and Author and Company values.
101+
Description = 'This is a module.' # Get from the repository description, else use info from source manifest file.
102+
PowerShellVersion = '' # Get from source files, REQUIRES -Version <N>[.<n>], null if not provided.
103+
PowerShellHostName = '' # Get from manifest file, null if not provided.
104+
PowerShellHostVersion = '' # Get from manifest file, null if not provided.
105+
DotNetFrameworkVersion = '' # Get from manifest file, null if not provided.
106+
ClrVersion = '' # Get from manifest file, null if not provided.
107+
ProcessorArchitecture = '' # Get from manifest file, null if not provided.
108+
RequiredModules = @() # Get from source files, REQUIRES -Modules <Module-Name> | <Hashtable> -> Need to be installed and loaded on build time. Will be installed in global session state during installtion.
109+
RequiredAssemblies = @() # Get from assemblies\*.dll.
110+
ScriptsToProcess = @() # Get from scripts\*.ps1 and classes\*.ps1 ordered by name. These are loaded to the caller session (parent of module session).
111+
TypesToProcess = @() # Get from *.Types.ps1xml anywhere in the source module folder.
112+
FormatsToProcess = @() # Get from *.Format.ps1xml anywhere in the source module folder.
113+
NestedModules = @() # Get from modules\*.psm1.
114+
FunctionsToExport = @() # Get from public\*.ps1.
115+
CmdletsToExport = @() # Get from manifest file, @() if not provided.
116+
VariablesToExport = @() # To be automated, currently adds '@()' to the manifest file.
117+
AliasesToExport = '*' # To be automated, currently adds '*' to the manifest file.
118+
DscResourcesToExport = @() # Get from resources\*.psm1.
119+
ModuleList = @() # Get from listing all .\*.psm1 files - Informational only.
120+
FileList = @() # Get from listing all .\* files - Informational only.
121+
PrivateData = @{ # <https://learn.microsoft.com/en-us/powershell/gallery/concepts/package-manifest-affecting-ui?view=powershellget-2.x>
122+
PSData = @{
123+
Tags = @() # Get from repository topics + compatability tags collected from source files.
124+
LicenseUri = '' # Generate public link to .\LICENSE.
125+
ProjectUri = '' # Generate public link to GitHub Repository.
126+
IconUri = '' # Get from .\icon\icon.png.
127+
ReleaseNotes = '' # Update during release -> PR description or release description.
128+
Prerelease = '' # Update during release -> uses a normalized version of the branch name.
129+
RequireLicenseAcceptance = $false ## Get from manifest file, default is $false.
130+
ExternalModuleDependencies = @() # Get from source manifest file
131+
ExperimentalFeatures = @( # Get from source manifest file
132+
@{
133+
Name = "SomeExperimentalFeature"
134+
Description = "This is an experimental feature."
135+
}
136+
)
137+
}
138+
OtherKeys = @{} # Get from manifest file
139+
}
140+
HelpInfoURI = '' # Get from source manifest file
141+
DefaultCommandPrefix = '' # Get from source manifest file
142+
}
143+
```
144+
145+
### The module manifest in the `src` folder
146+
147+
The module manifest file that is included in the source files contains the same functionality but is not optimized for performance and does not automatically gather all the information that is gathered during the build process.
148+
The goal with this is to have a quick way to import and test the module without having to build it.
149+
150+
The source module manifest is also the only place where some of the values can be controlled. These values are typically difficult to calculate and are not automated.
151+
152+
## Module documentation
153+
154+
The module documentation is built using platyPS and comment based help in the source code.
155+
The documentation is currently not published anywhere, but should be published to GitHub Pages in a future release.
156+
157+
## Sources
158+
159+
Module manifest:
160+
161+
- [about_Module_Manifests](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_module_manifests)
162+
- [How to write a PowerShell module manifest](https://learn.microsoft.com/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest)
163+
- [New-ModuleManifest](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/new-modulemanifest)
164+
- [Update-ModuleManifest](https://learn.microsoft.com/powershell/module/powershellget/update-modulemanifest)
165+
- [Package metadata values that impact the PowerShell Gallery UI](https://learn.microsoft.com/powershell/gallery/concepts/package-manifest-affecting-ui#powershell-gallery-feature-elements-controlled-by-the-module-manifest)
166+
- [PowerShellGallery Publishing Guidelines and Best Practices](https://learn.microsoft.com/en-us/powershell/gallery/concepts/publishing-guidelines#tag-your-package-with-the-compatible-pseditions-and-platforms)
167+
168+
Modules:
169+
170+
- [PowerShell scripting performance considerations](https://learn.microsoft.com/powershell/scripting/dev-cross-plat/performance/script-authoring-considerations)
171+
- [PowerShell module authoring considerations](https://learn.microsoft.com/powershell/scripting/dev-cross-plat/performance/module-authoring-considerations):
172+
173+
Documentation:
174+
175+
- [platyPS reference](https://learn.microsoft.com/powershell/module/platyps/?source=recommendations)
176+
- [PlatyPS overview](https://learn.microsoft.com/powershell/utility-modules/platyps/overview?view=ps-modules)
177+
- [about_Comment_Based_Help](https://go.microsoft.com/fwlink/?LinkID=123415)
178+
- [Supporting Updatable Help](https://learn.microsoft.com/powershell/scripting/developer/help/supporting-updatable-help)

action.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Build-PSModule (by PSModule)
2+
description: Build a PowerShell module to the PowerShell Gallery.
3+
author: PSModule
4+
branding:
5+
icon: package
6+
color: gray-dark
7+
8+
inputs:
9+
Name:
10+
description: Name of the module to process.
11+
required: false
12+
Path:
13+
description: Path to the folder where the modules are located.
14+
required: false
15+
default: src
16+
ModulesOutputPath:
17+
description: Path to the folder where the built modules are outputted.
18+
required: false
19+
default: outputs/modules
20+
DocsOutputPath:
21+
description: Path to the folder where the built docs are outputted.
22+
required: false
23+
default: outputs/docs
24+
25+
runs:
26+
using: composite
27+
steps:
28+
- name: Run Build-PSModule
29+
shell: pwsh
30+
env:
31+
GITHUB_ACTION_INPUT_Name: ${{ inputs.Name }}
32+
GITHUB_ACTION_INPUT_Path: ${{ inputs.Path }}
33+
GITHUB_ACTION_INPUT_ModulesOutputPath: ${{ inputs.ModulesOutputPath }}
34+
GITHUB_ACTION_INPUT_DocsOutputPath: ${{ inputs.DocsOutputPath }}
35+
run: |
36+
# Build-PSModule
37+
. "$env:GITHUB_ACTION_PATH\scripts\main.ps1" -Verbose

0 commit comments

Comments
 (0)