Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write unit tests for build and sign release #1521

Open
wants to merge 60 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5ba46c8
move sign code into function
james-garriss Dec 16, 2024
021a9d8
fix lint
james-garriss Dec 16, 2024
43da682
fix path
james-garriss Dec 16, 2024
9cd0bb1
fix path
james-garriss Dec 16, 2024
aa00717
fix path
james-garriss Dec 16, 2024
31f5706
remove commented out code
james-garriss Dec 16, 2024
1e35e16
run test release method
james-garriss Dec 18, 2024
6bc8651
Add debugging
james-garriss Dec 18, 2024
db57541
Add temp pester test
james-garriss Dec 18, 2024
b21b053
test file
james-garriss Dec 18, 2024
ee43e3c
add more debug
james-garriss Dec 18, 2024
a9bfb11
debug path
james-garriss Dec 18, 2024
348bf9f
use copy instead of move
james-garriss Dec 18, 2024
6699668
remove debug
james-garriss Dec 18, 2024
73ce101
Back to move
james-garriss Dec 18, 2024
703f157
restore
james-garriss Dec 18, 2024
6676866
create Pester test for installing AST
james-garriss Dec 18, 2024
7250133
install before checking for install
james-garriss Dec 18, 2024
426f4b2
verify commands
james-garriss Dec 18, 2024
2f900fd
Spell toolpath with a L
james-garriss Dec 18, 2024
55a2a38
Spell $true as $true
james-garriss Dec 18, 2024
84ed7c8
remove debug
james-garriss Dec 19, 2024
09e5c71
fix lint
james-garriss Dec 19, 2024
23d0b07
test for dotnet
james-garriss Dec 19, 2024
1c02f37
Replace env
james-garriss Dec 19, 2024
9580ab2
test azure login
james-garriss Dec 19, 2024
046f12d
Remove dead code, test copy folder again
james-garriss Dec 19, 2024
0822608
Restore code for a test
james-garriss Dec 19, 2024
41391b4
Restore login
james-garriss Dec 19, 2024
e42dddc
restore env
james-garriss Dec 19, 2024
a103a41
try copy item again
james-garriss Dec 19, 2024
5e3bc2c
restore move
james-garriss Dec 20, 2024
abf8012
set to copy
james-garriss Dec 24, 2024
41951fc
test for zip
james-garriss Dec 24, 2024
e5885f6
add debug
james-garriss Dec 24, 2024
f4ac865
Return to move
james-garriss Dec 24, 2024
3bfe37a
improve tests
james-garriss Dec 24, 2024
ce7096d
fix path errors
james-garriss Dec 24, 2024
158cd49
fix path
james-garriss Dec 24, 2024
71842f1
add root folder name
james-garriss Dec 24, 2024
29410e4
fix root folder name
james-garriss Dec 24, 2024
f4776bd
add bad input checks
james-garriss Jan 8, 2025
69a7798
fix unused variable
james-garriss Jan 8, 2025
bba4576
change root folder name
james-garriss Jan 8, 2025
46b0155
Test for root
james-garriss Jan 8, 2025
dd40f78
add resolve
james-garriss Jan 8, 2025
220f6ad
fix root folder name
james-garriss Jan 8, 2025
932bca3
Throw exception for missing dir
james-garriss Jan 8, 2025
96cca59
added function doc
james-garriss Jan 8, 2025
a4cb084
remove the remove-item
james-garriss Jan 9, 2025
7c2c843
set root to repo
james-garriss Jan 9, 2025
e786cbd
add remove-item back
james-garriss Jan 9, 2025
c99f5b7
clarify comments
james-garriss Jan 9, 2025
28dfeb5
Cleanup
james-garriss Jan 17, 2025
c0ec264
add exception test
james-garriss Jan 17, 2025
2568231
add scriptblock
james-garriss Jan 17, 2025
430a3c1
Comments
james-garriss Jan 17, 2025
cfb9af2
remove outdated comments
james-garriss Jan 17, 2025
c5a09b5
Add comment
james-garriss Jan 21, 2025
a6ecb8d
Lint
james-garriss Jan 21, 2025
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
42 changes: 18 additions & 24 deletions .github/workflows/build_sign_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ on:
description: "Release Name"
required: true
type: string
# Note: This is NOT the ACTUAL release version for ScubaGear.
# That value is found in ScubaGear.psd1.
# This is only used for things like the release file name.
# Yes, this is a disconnect that violates DRY.
# Note: It's possible that this value could be retrieved from ScubaGear.psd1
# using a function similar to Set-ScubaGearVersionManifest in
# utils/workflow/Set-ScubaGearModuleVersion.psm1.
version:
description: "Release Version (e.g., 1.2.4)"
required: true
Expand All @@ -27,8 +34,6 @@ jobs:
name: Build and Draft Release
runs-on: windows-latest
environment: Development
env:
RELEASE_VERSION: ${{ inputs.version }}
permissions:
id-token: write
contents: write
Expand All @@ -44,9 +49,10 @@ jobs:
path: repo
- name: Install Azure Signing Tool
run: |
dotnet --version
dotnet tool install --global AzureSignTool --version 5.0.0
# OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
# Source the function
. repo/utils/workflow/Install-AzureSignTool.ps1
Install-AzureSignTool
# OpenID Connect (OIDC) login to Azure Public Cloud with AzPowershell
- name: Login to Azure
uses: azure/login@v2
with:
Expand All @@ -64,25 +70,13 @@ jobs:
echo "KeyVaultCertificateName=$($KeyVaultInfo.KeyVault.CertificateName)" >> $env:GITHUB_OUTPUT
- name: Sign Module
run: |
# Source the deploy utilities so the functions in it can be called.
. repo/utils/workflow/Publish-ScubaGear.ps1
# Remove non-release files
Remove-Item -Recurse -Force repo -Include .git*
Write-Output "Creating an array of the files to sign..."
$ArrayOfFilePaths = New-ArrayOfFilePaths `
-ModuleDestinationPath repo
Write-Output "Creating a file with a list of the files to sign..."
$FileListFileName = New-FileList `
-ArrayOfFilePaths $ArrayOfFilePaths
Write-Output "Calling AzureSignTool function to sign scripts, manifest, and modules..."
$AzureKeyVaultUrl = '${{ steps.key-vault-info.outputs.KeyVaultUrl }}'
$CertificateName = '${{ steps.key-vault-info.outputs.KeyVaultCertificateName }}'
Use-AzureSignTool `
-AzureKeyVaultUrl $AzureKeyVaultUrl `
-CertificateName $CertificateName `
-FileList $FileListFileName
Move-Item -Path repo -Destination "ScubaGear-${env:RELEASE_VERSION}" -Force
Compress-Archive -Path "ScubaGear-${env:RELEASE_VERSION}" -DestinationPath "ScubaGear-${env:RELEASE_VERSION}.zip"
# Source the function.
. repo/utils/workflow/Build-SignRelease.ps1
New-ModuleSignature `
-AzureKeyVaultUrl ${{ steps.key-vault-info.outputs.KeyVaultUrl }} `
-CertificateName ${{ steps.key-vault-info.outputs.KeyVaultCertificateName }} `
-ReleaseVersion ${{ inputs.version }} `
-RootFolderName "repo"
- name: Create Release
uses: softprops/action-gh-release@v1
id: create-release
Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/publish_private_package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ jobs:
path: repo
- name: Install Azure Signing Tool
run: |
dotnet --version
dotnet tool install --global AzureSignTool --version 5.0.0
# OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
# Source the function
. repo/utils/workflow/Install-AzureSignTool.ps1
Install-AzureSignTool
# OIDC Login to Azure Public Cloud with AzPowershell
- name: Login to Azure
uses: azure/login@v2
with:
Expand All @@ -60,13 +61,13 @@ jobs:
echo "KeyVaultCertificateName=$($KeyVaultInfo.KeyVault.CertificateName)" >> $env:GITHUB_OUTPUT
- name: Create Private Gallery
run: |
# Source the deploy utilities so the functions in it can be called.
# Source the function.
. repo/utils/workflow/Publish-ScubaGear.ps1
cd repo
New-PrivateGallery -GalleryName $env:GalleryName -Trusted
- name: Sign and Publish Module
run: |
# Source the deploy utilities so the functions in it can be called.
# Source the function.
. repo/utils/workflow/Publish-ScubaGear.ps1
# Remove non-release files
Remove-Item -Recurse -Force repo -Include .git*
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/publish_public_package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ jobs:
path: repo
- name: Install Azure Signing Tool
run: |
dotnet --version
dotnet tool install --global AzureSignTool --version 5.0.0
# OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
# Source the function
. repo/utils/workflow/Install-AzureSignTool.ps1
Install-AzureSignTool
# OIDC Login to Azure Public Cloud with AzPowershell
- name: Login to Azure
uses: azure/login@v2
with:
Expand All @@ -66,7 +67,7 @@ jobs:
echo "KeyVaultCertificateName=$($KeyVaultInfo.KeyVault.CertificateName)" >> $env:GITHUB_OUTPUT
- name: Sign and Publish Module
run: |
# Source the deploy utilities so the functions in it can be called.
# Source the function.
. repo/utils/workflow/Publish-ScubaGear.ps1
# Remove non-release files
Remove-Item -Recurse -Force repo -Include .git*
Expand Down
18 changes: 18 additions & 0 deletions Testing/workflow/Build-SignRelease.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# The purpose of this test to ensure that the function fails
# gracefully if the root folder name does not exist.
# Note: Functional testing (not unit testing) should be used
# to verify that AST itself actually works.

Describe "Bad Inputs Check" {
It "The root folder name should exist" {
$ScriptPath = Join-Path -Path $PSScriptRoot -ChildPath '../../utils/workflow/Build-SignRelease.ps1' -Resolve
# Source the function
. $ScriptPath
# The function should throw an exception if the root folder name does not exist.
{ New-ModuleSignature `
-AzureKeyVaultUrl "https://www.cisa.gov" `
-CertificateName "certificate name" `
-ReleaseVersion "0.0.1" `
-RootFolderName "nonexistantfoldername" } | Should -Throw
}
}
21 changes: 21 additions & 0 deletions Testing/workflow/Install-AzureSignTool.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The purpose of this test is to verify that Azure Sign Tool is working.

BeforeDiscovery {
$ScriptPath = Join-Path -Path $PSScriptRoot -ChildPath '../../utils/workflow/Install-AzureSignTool.ps1' -Resolve
# Source the function
. $ScriptPath
Install-AzureSignTool
}
Comment on lines +3 to +8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question.
Is this unit test ever meant to be run locally?

If yes, then would it beneficial to check if the AzureSignInTool is already installed before attempting to do another installation?
If no, disregard question.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions that are in /utils are intended to be used and reused by any code. Functions that are in /utils/workflow, however, are only intended to be used by workflows. As we would not expect AST to already be installed on the runner, there doesn't seem to be a need to add a Pester test for that. If we moved this function up into /utils, then I think your idea would be smart.

Can you think of any other (non-workflow) code that would want to use the Install-AzureSignTool function?


Describe "AST Check" {
It "Dotnet should be installed" {
$ToolPath = (Get-Command dotnet).Path
Write-Warning "The path to dotnet is $ToolPath"
Test-Path -Path $ToolPath | Should -Be $true
}
It "AST should be installed" {
$ToolPath = (Get-Command AzureSignTool).Path
Write-Warning "The path to AzureSignTool is $ToolPath"
Test-Path -Path $ToolPath | Should -Be $true
}
}
65 changes: 65 additions & 0 deletions utils/workflow/Build-SignRelease.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
function New-ModuleSignature {
<#
.SYNOPSIS
Sign the ScubaGear module.
.PARAMETER $AzureKeyVaultUrl
The URL for the KeyVault in Azure.
.PARAMETER $CertificateName
The name of the certificate stored in the KeyVault.
.PARAMETER $ReleaseVersion
The version number of the release (e.g., 1.5.1).
.PARAMETER $RootFolderName
The name of the root folder.
.EXCEPTIONS
System.IO.DirectoryNotFoundException
Thrown if $RootFolderName does not exist.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]
$AzureKeyVaultUrl,
[Parameter(Mandatory = $true)]
[string]
$CertificateName,
[Parameter(Mandatory = $true)]
[string]
$ReleaseVersion,
[Parameter(Mandatory = $true)]
[string]
$RootFolderName
)

Write-Warning "Signing the module with AzureSignTool..."

# Verify that $RootFolderName exists
Write-Warning "The root folder name is $RootFolderName"
if (Test-Path -Path $RootFolderName) {
Write-Warning "Directory exists"
} else {
Write-Warning "Directory does not exist; throwing an exception..."
throw [System.IO.DirectoryNotFoundException] "Directory not found: $RootFolderName"
}

# Source the deploy utilities so the functions in it can be called.
$PublishPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\utils\workflow\Publish-ScubaGear.ps1' -Resolve
. $PublishPath

# Remove non-release files, like the .git dir, required for non-Windows machines
Remove-Item -Recurse -Force $RootFolderName -Include .git*
Write-Warning "Creating an array of the files to sign..."
$ArrayOfFilePaths = New-ArrayOfFilePaths `
-ModuleDestinationPath $RootFolderName

Write-Warning "Creating a file with a list of the files to sign..."
$FileListFileName = New-FileList `
-ArrayOfFilePaths $ArrayOfFilePaths

Write-Warning "Calling AzureSignTool function to sign scripts, manifest, and modules..."
Use-AzureSignTool `
-AzureKeyVaultUrl $AzureKeyVaultUrl `
-CertificateName $CertificateName `
-FileList $FileListFileName
Move-Item -Path $RootFolderName -Destination "ScubaGear-$ReleaseVersion" -Force
Compress-Archive -Path "ScubaGear-$ReleaseVersion" -DestinationPath "ScubaGear-$ReleaseVersion.zip"
}
10 changes: 10 additions & 0 deletions utils/workflow/Install-AzureSignTool.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function Install-AzureSignTool {
<#
.SYNOPSIS
Install Azure Signing Tool
#>

Write-Warning "Installing AST..."

dotnet tool install --global AzureSignTool --version 5.0.0
}
3 changes: 1 addition & 2 deletions utils/workflow/Publish-ScubaGear.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ function New-FileList {

function Use-AzureSignTool {
<#
.DESCRIPTION
.SYNOPSIS
AzureSignTool is a utility for signing code that is used to secure ScubaGear.
https://github.com/vcsjones/AzureSignTool
Throws an error if there was an error signing the files.
Expand Down Expand Up @@ -429,7 +429,6 @@ function Use-AzureSignTool {
Write-Warning "The path to AzureSignTool is $ToolPath"
# & is the call operator that executes a command, script, or function.
$Results = & $ToolPath $SignArguments

# Test the results for failures.
# If there are no failures, the $SuccessPattern string will be the last
# line in the results.
Expand Down
Loading