Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
paths:
.github/workflows/*.yml:
# actionlint does not yet know the `job.workflow_repository` / `job.workflow_sha` contexts
# (https://docs.github.com/actions/reference/contexts-reference#job-context). GitHub Actions
# itself resolves and runs them correctly; this is a central, one-time ignore instead of an
# inline suppression on every `uses: actions/checkout` self-checkout step that reads them.
ignore:
- 'property "workflow_repository" is not defined in object type'
- 'property "workflow_sha" is not defined in object type'
53 changes: 53 additions & 0 deletions .github/actions/Build-PSModule/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Build-PSModule
description: Build a PowerShell module to the PowerShell Gallery.
author: PSModule

inputs:
Name:
description: Name of the module to build. Defaults to the repository name.
required: false
OutputFolder:
description: Path to the folder where the built module is outputted.
required: false
default: 'outputs/module'
Version:
description: Module version to stamp into the manifest.
required: true
Prerelease:
description: Prerelease tag to stamp into the manifest's `PrivateData.PSData.Prerelease`. When empty, no prerelease tag is written.
required: false
ArtifactName:
description: Name of the artifact to upload.
required: false
default: module
WorkingDirectory:
description: The working directory where the script will run from.
required: false
default: '.'

runs:
using: composite
steps:
- name: Install-PSModuleHelpers
uses: ./_wf/.github/actions/Install-PSModuleHelpers

- name: Run Build-PSModule
shell: pwsh
id: build
working-directory: ${{ inputs.WorkingDirectory }}
env:
PSMODULE_BUILD_PSMODULE_INPUT_Name: ${{ inputs.Name }}
PSMODULE_BUILD_PSMODULE_INPUT_OutputFolder: ${{ inputs.OutputFolder }}
PSMODULE_BUILD_PSMODULE_INPUT_Version: ${{ inputs.Version }}
PSMODULE_BUILD_PSMODULE_INPUT_Prerelease: ${{ inputs.Prerelease }}
run: |
# Build-PSModule
${{ github.action_path }}/src/main.ps1

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ github.action_path }
, which may be controlled by an external user.

- name: Upload module artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ inputs.ArtifactName }}
path: ${{ steps.build.outputs.ModuleOutputFolderPath }}
if-no-files-found: error
retention-days: 1
60 changes: 60 additions & 0 deletions .github/actions/Build-PSModule/src/helpers/Build-PSModule.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function Build-PSModule {
<#
.SYNOPSIS
Builds a module.

.DESCRIPTION
Builds a module.
#>
[OutputType([void])]
[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSReviewUnusedParameter', '', Scope = 'Function',
Justification = 'LogGroup - Scoping affects the variables line of sight.'
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', '', Scope = 'Function',
Justification = 'Want to just write to the console, not the pipeline.'
)]
param(
# Name of the module.
[Parameter(Mandatory)]
[string] $ModuleName,

# Path to the folder where the modules are located.
[Parameter(Mandatory)]
[string] $ModuleSourceFolderPath,

# Path to the folder where the built modules are outputted.
[Parameter(Mandatory)]
[string] $ModuleOutputFolderPath,

# Module version to stamp into the manifest.
[Parameter(Mandatory)]
[string] $ModuleVersion,

# Prerelease tag to stamp into the manifest. When empty, no prerelease tag is written.
[Parameter()]
[string] $ModulePrerelease
)

Set-GitHubLogGroup "Building module [$ModuleName]" {
$moduleSourceFolder = Get-Item -Path $ModuleSourceFolderPath
$moduleOutputFolder = New-Item -Path $ModuleOutputFolderPath -Name $ModuleName -ItemType Directory -Force
[pscustomobject]@{
ModuleSourceFolderPath = $moduleSourceFolder
ModuleOutputFolderPath = $moduleOutputFolder
} | Format-List | Out-String
}

Build-PSModuleBase -ModuleName $ModuleName -ModuleSourceFolder $moduleSourceFolder -ModuleOutputFolder $moduleOutputFolder
Build-PSModuleManifest -ModuleName $ModuleName -ModuleOutputFolder $moduleOutputFolder `
-ModuleVersion $ModuleVersion -ModulePrerelease $ModulePrerelease
Build-PSModuleRootModule -ModuleName $ModuleName -ModuleOutputFolder $moduleOutputFolder
Update-PSModuleManifestAliasesToExport -ModuleName $ModuleName -ModuleSourceFolder $moduleSourceFolder -ModuleOutputFolder $moduleOutputFolder

Set-GitHubLogGroup 'Build manifest file - Final Result' {
$outputManifestPath = Join-Path -Path $ModuleOutputFolder -ChildPath "$ModuleName.psd1"
Show-FileContent -Path $outputManifestPath
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
function Add-ContentFromItem {
<#
.SYNOPSIS
Add the content of a folder or file to the root module file.

.DESCRIPTION
This function will add the content of a folder or file to the root module file.

.EXAMPLE
Add-ContentFromItem -Path 'C:\MyModule\src\MyModule' -RootModuleFilePath 'C:\MyModule\src\MyModule.psm1' -RootPath 'C:\MyModule\src'
#>
param(
# The path to the folder or file to process.
[Parameter(Mandatory)]
[string] $Path,

# The path to the root module file.
[Parameter(Mandatory)]
[string] $RootModuleFilePath,

# The root path of the module.
[Parameter(Mandatory)]
[string] $RootPath
)
# Get the path separator for the current OS
$pathSeparator = [System.IO.Path]::DirectorySeparatorChar

$relativeFolderPath = $Path -replace $RootPath, ''
$relativeFolderPath = $relativeFolderPath -replace $file.Extension, ''
$relativeFolderPath = $relativeFolderPath.TrimStart($pathSeparator)
$relativeFolderPath = $relativeFolderPath -split $pathSeparator | ForEach-Object { "[$_]" }
$relativeFolderPath = $relativeFolderPath -join ' - '

Add-Content -Path $RootModuleFilePath -Force -Value @"
#region $relativeFolderPath
Write-Debug "[`$scriptName] - $relativeFolderPath - Processing folder"
"@

$files = $Path | Get-ChildItem -File -Force -Filter '*.ps1' | Sort-Object -Property FullName
foreach ($file in $files) {
$relativeFilePath = $file.FullName -replace $RootPath, ''
$relativeFilePath = $relativeFilePath -replace $file.Extension, ''
$relativeFilePath = $relativeFilePath.TrimStart($pathSeparator)
$relativeFilePath = $relativeFilePath -split $pathSeparator | ForEach-Object { "[$_]" }
$relativeFilePath = $relativeFilePath -join ' - '

Add-Content -Path $RootModuleFilePath -Force -Value @"
#region $relativeFilePath
Write-Debug "[`$scriptName] - $relativeFilePath - Importing"
"@
Get-Content -Path $file.FullName | Add-Content -Path $RootModuleFilePath -Force
Add-Content -Path $RootModuleFilePath -Value @"
Write-Debug "[`$scriptName] - $relativeFilePath - Done"
#endregion $relativeFilePath
"@
}

$subFolders = $Path | Get-ChildItem -Directory -Force | Sort-Object -Property Name
foreach ($subFolder in $subFolders) {
Add-ContentFromItem -Path $subFolder.FullName -RootModuleFilePath $RootModuleFilePath -RootPath $RootPath
}
Add-Content -Path $RootModuleFilePath -Force -Value @"
Write-Debug "[`$scriptName] - $relativeFolderPath - Done"
#endregion $relativeFolderPath
"@
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function Build-PSModuleBase {
<#
.SYNOPSIS
Compiles the base module files.

.DESCRIPTION
This function will compile the base module files.
It will copy the source files to the output folder and remove the files that are not needed.

.EXAMPLE
Build-PSModuleBase -SourceFolderPath 'C:\MyModule\src\MyModule' -OutputFolderPath 'C:\MyModule\build\MyModule'
#>
[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSReviewUnusedParameter', '', Scope = 'Function',
Justification = 'LogGroup - Scoping affects the variables line of sight.'
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidUsingWriteHost', '', Scope = 'Function',
Justification = 'Want to just write to the console, not the pipeline.'
)]
param(
# Name of the module.
[Parameter(Mandatory)]
[string] $ModuleName,

# Path to the folder where the module source code is located.
[Parameter(Mandatory)]
[System.IO.DirectoryInfo] $ModuleSourceFolder,

# Path to the folder where the built modules are outputted.
[Parameter(Mandatory)]
[System.IO.DirectoryInfo] $ModuleOutputFolder
)

Set-GitHubLogGroup 'Build base' {
$relModuleSourceFolder = $ModuleSourceFolder | Resolve-Path -Relative
$relModuleOutputFolder = $ModuleOutputFolder | Resolve-Path -Relative
Write-Host "Copying files from [$relModuleSourceFolder] to [$relModuleOutputFolder]"
Copy-Item -Path "$ModuleSourceFolder\*" -Destination $ModuleOutputFolder -Recurse -Force -Exclude "$ModuleName.psm1"
$null = New-Item -Path $ModuleOutputFolder -Name "$ModuleName.psm1" -ItemType File -Force
}

Set-GitHubLogGroup 'Build base - Result' {
Get-ChildItem -Path $ModuleOutputFolder -Recurse -Force | Resolve-Path -Relative | Sort-Object
}
}
Loading
Loading