Skip to content
Merged
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
15 changes: 15 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Needed for publishing of examples, build worker defaults to core.autocrlf=input.
* text eol=autocrlf

*.mof text eol=crlf
*.sh text eol=lf
*.svg eol=lf

# Ensure any exe files are treated as binary
*.exe binary
*.jpg binary
*.xl* binary
*.pfx binary
*.png binary
*.dll binary
*.so binary
25 changes: 25 additions & 0 deletions .github/linters/.markdown-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
###########################
## Markdown Linter rules ##
###########################

# Linter rules doc:
# - https://github.com/DavidAnson/markdownlint

###############
# Rules by id #
###############
MD004: false # Unordered list style
MD007:
indent: 2 # Unordered list indentation
MD013:
line_length: 808 # Line length
MD026:
punctuation: ".,;:!。,;:" # List of not allowed
MD029: false # Ordered list item prefix
MD033: false # Allow inline HTML
MD036: false # Emphasis used instead of a heading

#################
# Rules by tags #
#################
blank_lines: false # Error on blank lines
17 changes: 17 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes

changelog:
categories:
- title: Breaking Changes
labels:
- Major
- Breaking
- title: New Features
labels:
- Minor
- Feature
- Improvement
- Enhancement
- title: Other Changes
labels:
- '*'
35 changes: 35 additions & 0 deletions .github/workflows/Auto-Release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Auto-Release

run-name: "Auto-Release - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"

on:
pull_request_target:
branches:
- main
types:
- closed
- opened
- reopened
- synchronize
- labeled

concurrency:
group: ${{ github.workflow }}

permissions:
contents: write
pull-requests: write

jobs:
Auto-Release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Auto-Release
uses: PSModule/Auto-Release@v1
env:
GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication
with:
IncrementalPrerelease: false
18 changes: 18 additions & 0 deletions .github/workflows/Linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Linter

run-name: "Linter - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"

on: [pull_request]

jobs:
Lint:
name: Lint code base
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Lint code base
uses: github/super-linter@latest
env:
GITHUB_TOKEN: ${{ github.token }}
13 changes: 13 additions & 0 deletions .github/workflows/Workflow-Test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Workflow-Test

run-name: "Workflow-Test - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}"

on: [pull_request]

jobs:
WorkflowTestDefault:
uses: ./.github/workflows/workflow.yml
secrets: inherit
with:
Name: PSModule
TestProcess: true
69 changes: 69 additions & 0 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Process-PSModule

on:
workflow_call:
secrets:
APIKey:
description: The API key to use when publishing modules
required: true
inputs:
Name:
type: string
description: The name of the module to process. Scripts default to the repository name if nothing is specified.
required: false
SkipTests:
type: boolean
description: Whether to skip tests.
required: false
default: false
TestProcess:
type: boolean
description: Whether to test the process.
required: false
default: false

env:
GITHUB_TOKEN: ${{ github.token }} # Used for GitHub CLI authentication

jobs:
Process-PSModule:
name: Process module
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Initialize environment
uses: PSModule/Initialize-PSModule@v1

- name: Test source code
uses: PSModule/Test-PSModule@v1
if: ${{ inputs.SkipTests != true }}
with:
Name: ${{ inputs.Name }}
Path: src
RunModuleTests: false

- name: Build module
uses: PSModule/Build-PSModule@v1
with:
Name: ${{ inputs.Name }}
Path: src
ModulesOutputPath: outputs/modules
DocsOutputPath: outputs/docs

- name: Test built module
uses: PSModule/Test-PSModule@v1
if: ${{ inputs.SkipTests != true }}
with:
Name: ${{ inputs.Name }}
Path: outputs/modules

- name: Publish module
uses: PSModule/Publish-PSModule@v1
with:
Name: ${{ inputs.Name }}
ModulePath: outputs/modules
DocsPath: outputs/docs
APIKey: ${{ secrets.APIKEY }}
WhatIf: ${{ inputs.TestProcess }}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Ignore Visual Studio Code temporary files, build results, and
## files generated by popular Visual Studio Code add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore
.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
*.code-workspace

# Local History for Visual Studio Code
.history/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 PSModule

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
113 changes: 111 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,111 @@
# Actions
Repo for GitHub actions and workflows
# Process-PSModule

A workflow for the PSModule process, stitching together the `Initialize`, `Build`, `Test`, and `Publish` actions to create a complete
CI/CD pipeline for PowerShell modules. The workflow is used by all PowerShell modules in the PSModule organization.

## Specifications and practices

Process-PSModule follows:

- [Test-Driven Development](https://testdriven.io/test-driven-development/) using [Pester](https://pester.dev) and [PSScriptAnalyzer](https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules)
- [GitHub Flow specifications](https://docs.github.com/en/get-started/using-github/github-flow)
- [SemVer 2.0.0 specifications](https://semver.org)
- [Continiuous Delivery practices](https://en.wikipedia.org/wiki/Continuous_delivery)

## How it works

The workflow is designed to be trigger on pull requests to the repository's default branch.
When a pull request is opened, closed, reopened, synchronized (push), or labeled, the workflow will run.
Depending on the labels in the pull requests, the workflow will result in different outcomes.

- [Initialize-PSModule](https://github.com/PSModule/Initialize-PSModule/) - To prepare the runner for all requirements of the framework.
- [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Testing the source code using only PSScriptAnalyzer and the PSModule test suites.
- [Build-PSModule](https://github.com/PSModule/Build-PSModule/) - To compile the repository into an efficient PowerShell module.
- [Test-PSModule](https://github.com/PSModule/Test-PSModule/) - Testing the compiled module using PSScriptAnalyzer, PSModule test suites and custom module tests.
- [Publish-PSModule](https://github.com/PSModule/Publish-PSModule/) - Publish the module to the PowerShell Gallery, publish docs to GitHub Pages, and create a release on the GitHub repository.

To use the workflow, create a new file in the `.github/workflows` directory of the module repository and add the following content.
<details>
<summary>Workflow suggestion</summary>

```yaml
name: Process-PSModule

on:
pull_request:
branches:
- main
types:
- closed
- opened
- reopened
- synchronize
- labeled

concurrency:
group: ${{ github.workflow }}

permissions:
contents: write
pull-requests: write

jobs:
Process-PSModule:
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v1
secrets: inherit

```
</details>

## Usage

### Inputs

| Name | Type | Description | Required | Default |
| ---- | ---- | ----------- | -------- | ------- |
| `Name` | `string` | The name of the module to process. This defaults to the repository name if nothing is specified. | `false` | N/A |
| `SkipTests` | `boolean` | Whether to skip the tests. | false | `false` |
| `TestProcess` | `boolean` | Whether to test the process. | false | `false` |

### Secrets

The following secrets are **required** for the workflow to run:

| Name | Location | Description | Default |
| ---- | -------- | ----------- | ------- |
| `GITHUB_TOKEN` | `github` context | The token used to authenticate with GitHub. | `${{ secrets.GITHUB_TOKEN }}` |
| `APIKey` | GitHub secrets | The API key for the PowerShell Gallery. | N/A |

## In detail

The following steps will be run when the workflow triggers:

- Checkout Code [actions/checkout](https://github.com/actions/checkout/)
- Checks out the code of the repository to the runner.
- Initialize environment [PSModule/Initialize-PSModule](https://github.com/PSModule/Initialize-PSModule/)
- Test source code [PSModule/Test-PSModule](https://github.com/PSModule/Test-PSModule/)
- Looks for the module in the `src` directory and runs the PSScriptAnalyzer and PSModule testing suite on the code.
- Build module [PSModule/Build-PSModule](https://github.com/PSModule/Build-PSModule/)
- Build the manifest file for the module.
- Compiles the `src` directory into a PowerShell module and docs.
- The compiled module is output to the `outputs/modules` directory.
- The compiled docs are output to the `outputs/docs` directory.
- Test built module [PSModule/Test-PSModule](https://github.com/PSModule/Test-PSModule/)
- Looks for the module in the `outputs/modules` directory and runs the PSScriptAnalyzer, PSModule testing suite and the custom module tests from the `tests` directory on the code.
- Publish module [PSModule/Publish-PSModule](https://github.com/PSModule/Publish-PSModule/)
- Calculates the next version of the module based on the latest release and labels on the PR.
- Publishes the module to the PowerShell Gallery using the API key stored in as a secret named `APIKey`.
- Publishes the docs to GitHub Pages from the `outputs/docs` directory.
- Creates a release on the GitHub repository with the source code.

## Permissions

The action requires the following permissions:

If running the action in a restrictive mode, the following permissions needs to be granted to the action:

```yaml
permissions:
contents: write # Required to create releases
pull-requests: write # Required to create comments on the PRs
```
5 changes: 5 additions & 0 deletions src/PSModule/PSModule.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@{
ModuleVersion = '0.0.1'
RootModule = 'PSModule.psm1'
Description = 'PSModule Framework Test Module'
}
32 changes: 32 additions & 0 deletions src/PSModule/PSModule.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[Cmdletbinding()]
param()

Write-Verbose 'Importing subcomponents'
$Folders = 'classes', 'private', 'public'
# Import everything in these folders
Foreach ($Folder in $Folders) {
$Root = Join-Path -Path $PSScriptRoot -ChildPath $Folder
Write-Verbose "Processing folder: $Root"
if (Test-Path -Path $Root) {
Write-Verbose "Getting all files in $Root"
$Files = $null
$Files = Get-ChildItem -Path $Root -Include '*.ps1', '*.psm1' -Recurse
# dot source each file
foreach ($File in $Files) {
Write-Verbose "Importing $($File)"
Import-Module $File
Write-Verbose "Importing $($File): Done"
}
}
}

$Param = @{
Function = (Get-ChildItem -Path "$PSScriptRoot\public" -Include '*.ps1' -Recurse).BaseName
Variable = '*'
Cmdlet = '*'
Alias = '*'
}

Write-Verbose 'Exporting module members'

Export-ModuleMember @Param
Loading