-
Notifications
You must be signed in to change notification settings - Fork 5
164 lines (144 loc) · 6.91 KB
/
release-pipeline.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Azure CAC Release
env:
ARTIFACT_NAME: PowerShell.Workflows.Release.ScriptSigning
jobs:
sign_scripts:
name: Sign, validate, test and publish PowerShell scripts as pipeline artifacts
runs-on: windows-2019
environment: test
permissions:
id-token: write
contents: read
steps:
- name: Check out repository
uses: actions/checkout@v2
- name: Install AzureSignTool
run: dotnet tool install --no-cache --global AzureSignTool --version 4.0.1
- name: AZ Login
uses: azure/login@v1
with:
client-id: ${{ secrets.ENT_AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.ENT_AZURE_TENANT_ID }}
subscription-id: ${{ secrets.ENT_AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
- name: Azure token
run: |
$az_token=$(az account get-access-token --scope https://vault.azure.net/.default --query accessToken --output tsv)
echo "::add-mask::$az_token"
echo "AZ_TOKEN=$az_token" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Sign pwsh scripts and modules
shell: powershell
run: |
$scripts = Get-ChildItem -Path . -Include *.ps1,*.psm1,*.psd1 -Recurse -ErrorAction Stop
$vaultName = $env:VAULTNAME
foreach ($script in $scripts) {
try {
# sign script
azuresigntool.exe sign --verbose -kvu https://$vaultName.vault.azure.net/ -kvc $env:CERTNAME -kva ${{ env.AZ_TOKEN }} -fd sha256 -tr "http://timestamp.comodoca.com/rfc3161" $script.FullName
}
catch {
Write-Error $_
}
}
env:
CERTNAME: ${{ secrets.ENT_VAULTSECRETNAME }}
VAULTNAME: ${{ secrets.ENT_VAULTNAME }}
- name: Validate Signature
shell: powershell
run: |
$signatureStatuses = Get-ChildItem -r -i *.ps* | Get-AuthenticodeSignature
Foreach ($signatureStatus in $signatureStatuses) {
If ($signatureStatus.Status -eq 'HashMismatch') {
throw "File '$($signatureStatus.Path)' has a hash status of '$($signatureStatus.status)'"
}
ElseIf ($signatureStatus.Status -eq 'NotSigned') {
Write-Warning "File '$($signatureStatus.Path)' has a hash status of '$($signatureStatus.status)'"
}
ElseIf ($signatureStatus.Status -eq 'Valid') {
Write-Host "File '$($signatureStatus.Path)' has a hash status of '$($signatureStatus.status)'"
}
Else {
throw "File '$($signatureStatus.Path)' has an unhandled hash status of '$($signatureStatus.status)'"
}
}
- name: Test Module Imports
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$moduleFiles = Get-ChildItem -path ./* -recurse -include *.psm1
Write-Host "Count of module files: $($moduleFiles.count)"
try {
ForEach ($moduleFile in $moduleFiles) {
Import-Module $moduleFile.Fullname -ErrorAction Stop
}
}
catch {
throw "Failed test import module '$moduleFile' with error: $_"
}
$importedModules = Get-Module
Write-Host "Imported modules: `n $($importedModules.Path | Out-String)"
$missingModules = $moduleFiles | Where-object {$_ -inotin ($importedModules).Path}
If ($missingModules) {
throw "The following modules failed import test: $missingModules"
}
- name: Zip Signed Modules
shell: powershell
run: |
$moduleCodeFilesObjs = Get-ChildItem -Path .\src -Recurse -Include *.psm1 -Exclude '*-GSA*','*GuardrailsSolutionAcceleratorSetup*','*Deploy-GuardrailsSolutionAccelerator*'
Write-Host "'$($moduleCodeFilesObjs.count)' module manifest files "
ForEach ($moduleCodeFile in $moduleCodeFilesObjs) {
$moduleManifestFile = Get-Item -Path $moduleCodeFile.FullName.replace('psm1','psd1')
If ($moduleCodeFilesObjs.FullName -icontains $moduleCodeFile.FullName -or $moduleCodeFilesObjs.FullName -icontains $moduleManifestFile.FullName) {
Write-Host "Module '$($moduleCodeFile.BaseName)' found, zipping module files..."
$destPath = "./psmodules/$($moduleCodeFile.BaseName).zip"
If ($moduleCodeFile.DIrectory.Name -eq 'Guardrails-Localization') {
Compress-Archive -Path "$($moduleCodeFile.Directory)/*" -DestinationPath $destPath -Force
}
Else {
$filesToZip = $moduleManifestFile,$moduleCodeFile
Compress-Archive -Path $filesToZip -DestinationPath $destPath -Force
}
}
Else {
Write-Host "Neither the manifest '$($moduleCodeFile.FullName.toLower())' or script file '$($moduleManifestFile.FullName.ToLower())' for module '$($moduleCodeFile.BaseName)' was changed, skipping zipping..."
}
}
- name: Publish artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ github.workspace }}
create_release:
name: Create Release
needs: sign_scripts
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download signed ps scripts and zipped modules
uses: actions/download-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: .
- id: archive-code
name: Archive code
run: |
mkdir -p release_assets
releaseName=$(basename ${{ github.ref }})
# Create a tarball (tgz) and a zip file of your code
tar --exclude='release_assets' --exclude='.git' --exclude='.github' -czvf release_assets/azure-cac-solution-$releaseName.tar.gz .
zip -r release_assets/azure-cac-solution-$releaseName.zip . -x "release_assets/*" -x ".git/*" -x ".github/*"
echo "releasename=$releaseName" >> $GITHUB_OUTPUT
- name: Create Release
run: |
if [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref_type }}" == "tag" ]; then
gh release create ${{ github.ref }} --generate-notes --latest "./release_assets/azure-cac-solution-$RELEASE_NAME.tar.gz#Azure CAC Solution (tar.gz)" "./release_assets/azure-cac-solution-$RELEASE_NAME.zip#Azure CAC Solution (zip)"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_NAME: ${{ steps.archive-code.outputs.releasename }}