Build and Release Module #279
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#https://scriptingchris.tech/2021/05/16/how-to-setup-a-github-actions-pipeline-for-publishing-your-powershell-module/ | |
name: Build and Release Module | |
on: | |
pull_request: # Only trigger the workflow if there is a pull request to the main branch | |
branches: [ main ] | |
workflow_dispatch: # Enables the possibility to trigger the workflow manually | |
push: | |
tags: | |
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 | |
env: | |
BUILD_NUMBER: ${{ vars.BUILD_NUMBER }} | |
MODULE_NAME: ${{ vars.MODULE_NAME }} | |
VERSION_NUMBER: ${{ vars.VERSION_NUMBER }} | |
jobs: | |
# 1st Job -- Building the module | |
build: | |
name: Build Module | |
runs-on: windows-latest | |
steps: | |
# Checkout the main branch | |
- name: Checkout Repository | |
uses: actions/checkout@v2 | |
- name: Get Module Name | |
shell: pwsh | |
run: | | |
$Tags = @( | |
'Windows', | |
'ActiveDirectory', | |
'ActiveDirectory_Delegation', | |
'ActiveDirectory_Security', | |
'AD_Security', | |
'Security', | |
'Delegation', | |
'AD_Delegation', | |
'DelegationModel', | |
'TierModel', | |
'RBACmodel', | |
'RoleBasedAccessControl_model', | |
'DelegationModel', | |
'TierModel', | |
'RBACmodel', | |
'Infrastructure', | |
'Testing', | |
'Checks', | |
'Audits', | |
'Checklist', | |
'Validation', | |
'CredentialTheaf', | |
'Pass-the-Hash', | |
'Pass-the-Ticket', | |
'Golden_Ticket', | |
'Silver_Ticket' | |
) | |
$ModuleName = (Test-ModuleManifest -Path '.\*.psd1').Name | |
$oldModuleVersion = (Test-ModuleManifest -Path ".\*.psd1").Version | |
[System.Collections.ArrayList]$publicFunctions = (Get-ChildItem -Path '.\Public\*.ps1' -recurse).BaseName | |
[System.Collections.ArrayList]$privateFunctions = (Get-ChildItem -Path '.\Private\*.ps1' -recurse).BaseName | |
$ClassesFunctions = (Get-ChildItem -Path '.\Classes\*.ps1' -recurse).BaseName | |
[System.Collections.ArrayList]$EnumsFunctions = (Get-ChildItem -Path '.\Enums\*.ps1' -recurse).BaseName | |
$totalFunctions = $publicFunctions.count + $privateFunctions.count + $ClassesFunctions.count + $EnumsFunctions.count | |
$ModuleBuildNumber = $oldModuleVersion.Build + 1 | |
While($totalFunctions -lt $oldModuleVersion.Minor) { $totalFunctions++ } | |
$ModuleVersion = "$($oldModuleVersion.Major).$($totalFunctions).$($ModuleBuildNumber)" | |
Update-ModuleManifest -Path ".\$($ModuleName).psd1" -ModuleVersion $ModuleVersion -Tags $Tags -FunctionsToExport $publicFunctions | |
if (!(Get-PackageProvider | Where-Object { $_.Name -eq 'NuGet' })) { | |
Install-PackageProvider -Name NuGet -force | Out-Null | |
} | |
Import-PackageProvider -Name NuGet -force | Out-Null | |
if ((Get-PSRepository -Name PSGallery).InstallationPolicy -ne 'Trusted') { | |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | |
} | |
Write-Output "BUILD_NUMBER=$ModuleVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "MODULE_NAME=$ModuleName" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
env: | |
MODULE_NAME: ${{ env.MODULE_NAME }} | |
BUILD_NUMBER: ${{ env.BUILD_NUMBER }} | |
- name: Install PSScriptAnalyzer module | |
shell: pwsh | |
run: | | |
Set-PSRepository PSGallery -InstallationPolicy Trusted | |
Install-Module PSScriptAnalyzer -ErrorAction Stop | |
- name: Lint with PSScriptAnalyzer | |
shell: pwsh | |
run: | | |
Invoke-ScriptAnalyzer -Path .\Public -recurse | |
Invoke-ScriptAnalyzer -Path .\Private -recurse | |
Invoke-ScriptAnalyzer -Path .\Enums -recurse | |
Invoke-ScriptAnalyzer -Path .\Classes -recurse | |
# Pushing the changes from InvokeBuild to the main branch | |
- name: Push changes to Git Repository | |
run: | | |
git config --global user.name 'vreguibar' | |
git config --global user.email 'vicente@eguibarIT.com' | |
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} | |
git add . | |
git commit -m "Build Module" | |
git push | |
# 2nd Job -- Releasing the module | |
release: | |
name: Release Module | |
needs: build | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v2 | |
- name: Read exported variable | |
id: Read_Var | |
shell: pwsh | |
run: | | |
$ModuleVersion = (Test-ModuleManifest -Path ".\*.psd1").Version | |
$PS_Module_Version = ('v{0}' -f $ModuleVersion) | |
$ModuleName = (Test-ModuleManifest -Path '.\*.psd1').Name | |
Write-Output "MODULE_NAME=$ModuleName" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "BUILD_NUMBER=$ModuleVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "VERSION_NUMBER=$PS_Module_Version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
env: | |
MODULE_NAME: ${{ env.MODULE_NAME }} | |
BUILD_NUMBER: ${{ env.BUILD_NUMBER }} | |
VERSION_NUMBER: ${{ env.VERSION_NUMBER }} | |
- name: Check if Release Exists | |
id: check_release | |
uses: actions/github-script@v4 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const tagName = process.env.MODULE_VERSION; | |
const { data: releases } = await github.repos.listReleases({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
}); | |
const releaseExists = releases.some(release => release.tag_name === tagName); | |
console.log(`Release ${tagName} exists: ${releaseExists}`); | |
console.log(`::set-output name=exists::${releaseExists}`); | |
# Create a release to github | |
- name: Create Release | |
if: steps.check_release.outputs.exists != 'true' | |
uses: actions/create-release@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: ${{ env.VERSION_NUMBER }} | |
release_name: Release ${{ env.BUILD_NUMBER }} | |
draft: false | |
prerelease: false | |
- name: Publish module to PowerShell Gallery | |
id: Publish_Module | |
shell: pwsh | |
run: | | |
$ModuleName = "${{ env.MODULE_NAME }}" | |
$NugetAPIKey = "${{ secrets.PS_GALLERY_KEY }}" | |
$PublishParams = @{ | |
NuGetApiKey = $NugetAPIKey | |
Path = '.' | |
Tags = @( | |
'Windows', | |
'ActiveDirectory', | |
'ActiveDirectory_Delegation', | |
'ActiveDirectory_Security', | |
'AD_Security', | |
'Security', | |
'Delegation', | |
'AD_Delegation', | |
'DelegationModel', | |
'TierModel', | |
'RBACmodel', | |
'RoleBasedAccessControl_model', | |
'DelegationModel', | |
'TierModel', | |
'RBACmodel', | |
'Infrastructure', | |
'Testing', | |
'Checks', | |
'Audits', | |
'Checklist', | |
'Validation', | |
'CredentialTheaf', | |
'Pass-the-Hash', | |
'Pass-the-Ticket', | |
'Golden_Ticket', | |
'Silver_Ticket' | |
) | |
Verbose = $true | |
} | |
Publish-Module @PublishParams |