Skip to content

Commit 3240ab2

Browse files
🩹 [Patch]: Co-locate EVERYTHING :) (#131)
## Description The actions within the PSModule framework are closely interconnected, each serving a critical function. However, developing and testing both individual actions and their integration within the framework has become increasingly inefficient due to their scattered nature. Additionally, issue tracking was fragmented across multiple repositories, making management more cumbersome. To improve efficiency, I have consolidated everything into a single reusable workflow repository. This centralization simplifies development, testing, and issue tracking, providing a unified view of the entire process. ### Motivation The actions within the PSModule framework are tightly connected, each playing a crucial role. However, developing and testing both individual actions and their integration with the whole has become inefficient due to their scattered nature. Additionally, issue tracking was spread across multiple repositories, further complicating the process. To streamline development, testing, and issue tracking, I’ve opted to consolidate everything into a single reusable workflow repository. This will provide a unified view of the entire process and improve efficiency. ### Documentation Moving forward, the documentation for the PSModule framework will be hosted on GitHub Pages using Material for MkDocs. As a result, the README in this workflow repository will be minimal, serving primarily as a pointer to the official documentation. ### What has moved where | Old location | New location | | - | - | | [Initialize-PSModule](https://github.com/PSModule/Initialize-PSModule) | [Initialize](.github/actions/Initialize) | | [Test-PSModule](https://github.com/PSModule/Test-PSModule) | [Test](.github/actions/Test)| | [Publish-PSModule](https://github.com/PSModule/Publish-PSModule) | [Publish](.github/actions/Publish)| | [Build-PSModule](https://github.com/PSModule/Build-PSModule) | [Build](.github/actions/Build)| | [Document-PSModule](https://github.com/PSModule/Document-PSModule) | [Document](.github/actions/Document)| ### Testing All testing workflows have been consolidated into this repository to ensure that both individual actions and the overall workflow are tested as changes are developed. This improves cycle time and enhances confidence in the stability of changes before they are released. ## Type of change <!-- Use the check-boxes [x] on the options that are relevant. --> - [ ] 📖 [Docs] - [ ] 🪲 [Fix] - [x] 🩹 [Patch] - [ ] ⚠️ [Security fix] - [ ] 🚀 [Feature] - [ ] 🌟 [Breaking change] ## Checklist <!-- Use the check-boxes [x] on the options that are relevant. --> - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas Here’s an improved version with clearer wording, better structure, and more fluid readability:
1 parent ae2797d commit 3240ab2

File tree

143 files changed

+5993
-156
lines changed

Some content is hidden

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

143 files changed

+5993
-156
lines changed

Diff for: .github/actions/Build/action.yml

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
ModuleArtifactName:
25+
description: Name of the module artifact to upload.
26+
required: false
27+
default: module
28+
DocsArtifactName:
29+
description: Name of the docs artifact to upload.
30+
required: false
31+
default: docs
32+
Debug:
33+
description: Enable debug output.
34+
required: false
35+
default: 'false'
36+
Verbose:
37+
description: Enable verbose output.
38+
required: false
39+
default: 'false'
40+
Version:
41+
description: Specifies the version of the GitHub module to be installed. The value must be an exact version.
42+
required: false
43+
Prerelease:
44+
description: Allow prerelease versions if available.
45+
required: false
46+
default: 'false'
47+
48+
runs:
49+
using: composite
50+
steps:
51+
- name: Run Build-PSModule
52+
uses: PSModule/GitHub-Script@v1
53+
env:
54+
GITHUB_ACTION_INPUT_Name: ${{ inputs.Name }}
55+
GITHUB_ACTION_INPUT_Path: ${{ inputs.Path }}
56+
GITHUB_ACTION_INPUT_ModulesOutputPath: ${{ inputs.ModulesOutputPath }}
57+
GITHUB_ACTION_INPUT_DocsOutputPath: ${{ inputs.DocsOutputPath }}
58+
with:
59+
Debug: ${{ inputs.Debug }}
60+
Prerelease: ${{ inputs.Prerelease }}
61+
Verbose: ${{ inputs.Verbose }}
62+
Version: ${{ inputs.Version }}
63+
Script: |
64+
# Build-PSModule
65+
. "${{ github.action_path }}\scripts\main.ps1"
66+
67+
- name: Upload module artifact
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: ${{ inputs.ModuleArtifactName }}
71+
path: ${{ inputs.ModulesOutputPath }}
72+
if-no-files-found: error
73+
retention-days: 1
74+
75+
- name: Upload docs artifact
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: ${{ inputs.DocsArtifactName }}
79+
path: ${{ inputs.DocsOutputPath }}
80+
if-no-files-found: error
81+
retention-days: 1
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#Requires -Modules @{ ModuleName = 'GitHub'; ModuleVersion = '0.13.2' }
2+
#Requires -Modules @{ ModuleName = 'Utilities'; ModuleVersion = '0.3.0' }
3+
4+
function Build-PSModule {
5+
<#
6+
.SYNOPSIS
7+
Builds a module.
8+
9+
.DESCRIPTION
10+
Builds a module.
11+
#>
12+
[CmdletBinding()]
13+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
14+
'PSReviewUnusedParameter', '', Scope = 'Function',
15+
Justification = 'LogGroup - Scoping affects the variables line of sight.'
16+
)]
17+
param(
18+
# Name of the module.
19+
[Parameter(Mandatory)]
20+
[string] $ModuleName,
21+
22+
# Path to the folder where the modules are located.
23+
[Parameter(Mandatory)]
24+
[string] $ModuleSourceFolderPath,
25+
26+
# Path to the folder where the built modules are outputted.
27+
[Parameter(Mandatory)]
28+
[string] $ModulesOutputFolderPath,
29+
30+
# Path to the folder where the documentation is outputted.
31+
[Parameter(Mandatory)]
32+
[string] $DocsOutputFolderPath
33+
)
34+
35+
LogGroup "Building module [$ModuleName]" {
36+
Write-Host "Source path: [$ModuleSourceFolderPath]"
37+
if (-not (Test-Path -Path $ModuleSourceFolderPath)) {
38+
Write-Error "Source folder not found at [$ModuleSourceFolderPath]"
39+
exit 1
40+
}
41+
$moduleSourceFolder = Get-Item -Path $ModuleSourceFolderPath
42+
Write-Host "Module source folder: [$moduleSourceFolder]"
43+
44+
$moduleOutputFolder = New-Item -Path $ModulesOutputFolderPath -Name $ModuleName -ItemType Directory -Force
45+
Write-Host "Module output folder: [$moduleOutputFolder]"
46+
47+
$docsOutputFolder = New-Item -Path $DocsOutputFolderPath -ItemType Directory -Force
48+
Write-Host "Docs output folder: [$docsOutputFolder]"
49+
}
50+
51+
Build-PSModuleBase -ModuleName $ModuleName -ModuleSourceFolder $moduleSourceFolder -ModuleOutputFolder $moduleOutputFolder
52+
Build-PSModuleManifest -ModuleName $ModuleName -ModuleOutputFolder $moduleOutputFolder
53+
Build-PSModuleRootModule -ModuleName $ModuleName -ModuleOutputFolder $moduleOutputFolder
54+
Update-PSModuleManifestAliasesToExport -ModuleName $ModuleName -ModuleOutputFolder $moduleOutputFolder
55+
Build-PSModuleDocumentation -ModuleName $ModuleName -ModuleSourceFolder $moduleSourceFolder -DocsOutputFolder $docsOutputFolder
56+
57+
LogGroup 'Build manifest file - Final Result' {
58+
$outputManifestPath = Join-Path -Path $ModuleOutputFolder -ChildPath "$ModuleName.psd1"
59+
Show-FileContent -Path $outputManifestPath
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
function Add-ContentFromItem {
2+
<#
3+
.SYNOPSIS
4+
Add the content of a folder or file to the root module file.
5+
6+
.DESCRIPTION
7+
This function will add the content of a folder or file to the root module file.
8+
9+
.EXAMPLE
10+
Add-ContentFromItem -Path 'C:\MyModule\src\MyModule' -RootModuleFilePath 'C:\MyModule\src\MyModule.psm1' -RootPath 'C:\MyModule\src'
11+
#>
12+
param(
13+
# The path to the folder or file to process.
14+
[Parameter(Mandatory)]
15+
[string] $Path,
16+
17+
# The path to the root module file.
18+
[Parameter(Mandatory)]
19+
[string] $RootModuleFilePath,
20+
21+
# The root path of the module.
22+
[Parameter(Mandatory)]
23+
[string] $RootPath
24+
)
25+
# Get the path separator for the current OS
26+
$pathSeparator = [System.IO.Path]::DirectorySeparatorChar
27+
28+
$relativeFolderPath = $Path -Replace $RootPath, ''
29+
$relativeFolderPath = $relativeFolderPath -Replace $file.Extension, ''
30+
$relativeFolderPath = $relativeFolderPath.TrimStart($pathSeparator)
31+
$relativeFolderPath = $relativeFolderPath -Split $pathSeparator | ForEach-Object { "[$_]" }
32+
$relativeFolderPath = $relativeFolderPath -Join ' - '
33+
34+
Add-Content -Path $RootModuleFilePath -Force -Value @"
35+
#region $relativeFolderPath
36+
Write-Debug "[`$scriptName] - $relativeFolderPath - Processing folder"
37+
"@
38+
39+
$files = $Path | Get-ChildItem -File -Force -Filter '*.ps1' | Sort-Object -Property FullName
40+
foreach ($file in $files) {
41+
$relativeFilePath = $file.FullName -Replace $RootPath, ''
42+
$relativeFilePath = $relativeFilePath -Replace $file.Extension, ''
43+
$relativeFilePath = $relativeFilePath.TrimStart($pathSeparator)
44+
$relativeFilePath = $relativeFilePath -Split $pathSeparator | ForEach-Object { "[$_]" }
45+
$relativeFilePath = $relativeFilePath -Join ' - '
46+
47+
Add-Content -Path $RootModuleFilePath -Force -Value @"
48+
#region $relativeFilePath
49+
Write-Debug "[`$scriptName] - $relativeFilePath - Importing"
50+
"@
51+
Get-Content -Path $file.FullName | Add-Content -Path $RootModuleFilePath -Force
52+
Add-Content -Path $RootModuleFilePath -Value @"
53+
Write-Debug "[`$scriptName] - $relativeFilePath - Done"
54+
#endregion $relativeFilePath
55+
"@
56+
}
57+
58+
$subFolders = $Path | Get-ChildItem -Directory -Force | Sort-Object -Property Name
59+
foreach ($subFolder in $subFolders) {
60+
Add-ContentFromItem -Path $subFolder.FullName -RootModuleFilePath $RootModuleFilePath -RootPath $RootPath
61+
}
62+
Add-Content -Path $RootModuleFilePath -Force -Value @"
63+
Write-Debug "[`$scriptName] - $relativeFolderPath - Done"
64+
#endregion $relativeFolderPath
65+
"@
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#Requires -Modules @{ ModuleName = 'GitHub'; ModuleVersion = '0.13.2' }
2+
3+
function Build-PSModuleBase {
4+
<#
5+
.SYNOPSIS
6+
Compiles the base module files.
7+
8+
.DESCRIPTION
9+
This function will compile the base module files.
10+
It will copy the source files to the output folder and remove the files that are not needed.
11+
12+
.EXAMPLE
13+
Build-PSModuleBase -SourceFolderPath 'C:\MyModule\src\MyModule' -OutputFolderPath 'C:\MyModule\build\MyModule'
14+
#>
15+
[CmdletBinding()]
16+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
17+
'PSReviewUnusedParameter', '', Scope = 'Function',
18+
Justification = 'LogGroup - Scoping affects the variables line of sight.'
19+
)]
20+
param(
21+
# Name of the module.
22+
[Parameter(Mandatory)]
23+
[string] $ModuleName,
24+
25+
# Path to the folder where the module source code is located.
26+
[Parameter(Mandatory)]
27+
[System.IO.DirectoryInfo] $ModuleSourceFolder,
28+
29+
# Path to the folder where the built modules are outputted.
30+
[Parameter(Mandatory)]
31+
[System.IO.DirectoryInfo] $ModuleOutputFolder
32+
)
33+
34+
LogGroup 'Build base' {
35+
Write-Host "Copying files from [$ModuleSourceFolder] to [$ModuleOutputFolder]"
36+
Copy-Item -Path "$ModuleSourceFolder\*" -Destination $ModuleOutputFolder -Recurse -Force -Verbose -Exclude "$ModuleName.psm1"
37+
New-Item -Path $ModuleOutputFolder -Name "$ModuleName.psm1" -ItemType File -Force -Verbose
38+
}
39+
40+
LogGroup 'Build base - Result' {
41+
(Get-ChildItem -Path $ModuleOutputFolder -Recurse -Force).FullName | Sort-Object
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#Requires -Modules @{ ModuleName = 'GitHub'; ModuleVersion = '0.13.2' }
2+
#Requires -Modules @{ ModuleName = 'platyPS'; ModuleVersion = '0.14.2' }
3+
#Requires -Modules @{ ModuleName = 'Utilities'; ModuleVersion = '0.3.0' }
4+
5+
function Build-PSModuleDocumentation {
6+
<#
7+
.SYNOPSIS
8+
Compiles the module documentation.
9+
10+
.DESCRIPTION
11+
This function will compile the module documentation.
12+
It will generate the markdown files for the module help and copy them to the output folder.
13+
14+
.EXAMPLE
15+
Build-PSModuleDocumentation -ModuleOutputFolder 'C:\MyModule\src\MyModule' -DocsOutputFolder 'C:\MyModule\build\MyModule'
16+
#>
17+
[CmdletBinding()]
18+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
19+
'PSReviewUnusedParameter', '', Scope = 'Function',
20+
Justification = 'LogGroup - Scoping affects the variables line of sight.'
21+
)]
22+
param(
23+
# Name of the module.
24+
[Parameter(Mandatory)]
25+
[string] $ModuleName,
26+
27+
# Path to the folder where the module source code is located.
28+
[Parameter(Mandatory)]
29+
[System.IO.DirectoryInfo] $ModuleSourceFolder,
30+
31+
# Folder where the documentation for the modules should be outputted. 'outputs/docs/MyModule'
32+
[Parameter(Mandatory)]
33+
[System.IO.DirectoryInfo] $DocsOutputFolder
34+
)
35+
36+
LogGroup 'Build docs - Generate markdown help' {
37+
$ModuleName | Remove-Module -Force
38+
Import-Module -Name $ModuleName -Force -RequiredVersion '999.0.0'
39+
Write-Host ($ModuleName | Get-Module)
40+
$null = New-MarkdownHelp -Module $ModuleName -OutputFolder $DocsOutputFolder -Force -Verbose
41+
}
42+
43+
LogGroup 'Build docs - Fix markdown code blocks' {
44+
Get-ChildItem -Path $DocsOutputFolder -Recurse -Force -Include '*.md' | ForEach-Object {
45+
$content = Get-Content -Path $_.FullName
46+
$fixedOpening = $false
47+
$newContent = @()
48+
foreach ($line in $content) {
49+
if ($line -match '^```$' -and -not $fixedOpening) {
50+
$line = $line -replace '^```$', '```powershell'
51+
$fixedOpening = $true
52+
} elseif ($line -match '^```.+$') {
53+
$fixedOpening = $true
54+
} elseif ($line -match '^```$') {
55+
$fixedOpening = $false
56+
}
57+
$newContent += $line
58+
}
59+
$newContent | Set-Content -Path $_.FullName
60+
}
61+
}
62+
63+
LogGroup 'Build docs - Fix markdown escape characters' {
64+
Get-ChildItem -Path $DocsOutputFolder -Recurse -Force -Include '*.md' | ForEach-Object {
65+
$content = Get-Content -Path $_.FullName -Raw
66+
$content = $content -replace '\\`', '`'
67+
$content = $content -replace '\\\[', '['
68+
$content = $content -replace '\\\]', ']'
69+
$content = $content -replace '\\\<', '<'
70+
$content = $content -replace '\\\>', '>'
71+
$content = $content -replace '\\\\', '\'
72+
$content | Set-Content -Path $_.FullName
73+
}
74+
}
75+
76+
LogGroup 'Build docs - Structure markdown files to match source files' {
77+
$PublicFunctionsFolder = Join-Path $ModuleSourceFolder.FullName 'functions\public' | Get-Item
78+
Get-ChildItem -Path $DocsOutputFolder -Recurse -Force -Include '*.md' | ForEach-Object {
79+
$file = $_
80+
Write-Host "Processing: $file"
81+
82+
# find the source code file that matches the markdown file
83+
$scriptPath = Get-ChildItem -Path $PublicFunctionsFolder -Recurse -Force | Where-Object { $_.Name -eq ($file.BaseName + '.ps1') }
84+
Write-Host "Found script path: $scriptPath"
85+
$docsFilePath = ($scriptPath.FullName).Replace($PublicFunctionsFolder.FullName, $DocsOutputFolder.FullName).Replace('.ps1', '.md')
86+
Write-Host "Doc file path: $docsFilePath"
87+
$docsFolderPath = Split-Path -Path $docsFilePath -Parent
88+
New-Item -Path $docsFolderPath -ItemType Directory -Force
89+
Move-Item -Path $file.FullName -Destination $docsFilePath -Force
90+
}
91+
# Get the MD files that are in the public functions folder and move them to the same place in the docs folder
92+
Get-ChildItem -Path $PublicFunctionsFolder -Recurse -Force -Include '*.md' | ForEach-Object {
93+
$file = $_
94+
Write-Host "Processing: $file"
95+
$docsFilePath = ($file.FullName).Replace($PublicFunctionsFolder.FullName, $DocsOutputFolder.FullName)
96+
Write-Host "Doc file path: $docsFilePath"
97+
$docsFolderPath = Split-Path -Path $docsFilePath -Parent
98+
New-Item -Path $docsFolderPath -ItemType Directory -Force
99+
Move-Item -Path $file.FullName -Destination $docsFilePath -Force
100+
}
101+
}
102+
103+
Get-ChildItem -Path $DocsOutputFolder -Recurse -Force -Include '*.md' | ForEach-Object {
104+
$fileName = $_.Name
105+
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash
106+
LogGroup " - [$fileName] - [$hash]" {
107+
Show-FileContent -Path $_
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)