A while ago I had come across this cool blog post (and cool blog in general) on signing PowerShell scripts via GitHub actions. Before that I was signing scripts manually, and I think I was Googling on whether there’s a way to do this via GitHub actions and luckily came across that blog post. Ever since I’ve been using it.
I had modified it a bit to suit my needs – such as have the zip file name be a mix of the repo name, branch name, and so on. Easy to know what is what when I have a bunch of these lying around. Unfortunately, today I ran into an issue wherein I named a branch as “feature/something” and the slash caused and issue in the file name. Wanted to see if there’s a way to remove the branch and came across the find-and-replace strings action. Combined the two and here’s my workflow:
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 |
name: Sign Runbook and make available for download on: workflow_dispatch: push: paths: - 'Runbooks/*.ps1' jobs: sign_runbooks: runs-on: windows-2019 steps: - name: Import code signing certificate shell: powershell run: | $pfxCertFilePath = Join-Path -Path $PSScriptRoot -ChildPath "CodeSigningCertificate.pfx" Set-Content -Value $([System.Convert]::FromBase64String($env:BASE64_PFX)) -Path $pfxCertFilePath -Encoding Byte $codeSigningCert = Import-PfxCertificate -FilePath $pfxCertFilePath -Password $($env:PFX_PASSWORD | ConvertTo-SecureString -AsPlainText -Force) -CertStoreLocation Cert:\CurrentUser\My env: BASE64_PFX: ${{ secrets.BASE64_PFX }} PFX_PASSWORD: ${{ secrets.PFX_PASSWORD }} - name: Check out repository uses: actions/checkout@v2 - name: Sign PowerShell Runbooks shell: powershell run: | $scripts = Get-ChildItem -Path .\Runbooks\ -Filter "*.ps1" -Recurse -ErrorAction Stop $codeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1 foreach ($script in $scripts) { try { $scriptContent = Get-Content -Path $script.FullName Write-Output "Signing script `"$($script.Name)`" with certificate `"$($codeSigningCert.Thumbprint)`"" # sign script $null = Set-AuthenticodeSignature -Certificate $codeSigningCert -FilePath $script.FullName -TimestampServer "http://timestamp.comodoca.com/rfc3161" } catch { Write-Error $_ } } - name: Fix Branch name if needed uses: mad9000/actions-find-and-replace-string@2 with: source: ${{ github.ref_name }} # The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature/branch-1. find: '/' # We want to remove / from source replace: '' # and replace it with a blank string (ie. removing it) id: fixbranchname - name: Publish artifacts uses: actions/upload-artifact@v2 with: name: ${{ env.ARTIFACT_NAME }} path: .\Runbooks env: ARTIFACT_NAME: SignedRunbooks-${{ github.event.repository.name }}-${{ steps.fixbranchname.outputs.value }} # More variables at https://docs.github.com/en/actions/learn-github-actions/contexts#github-context |
Just putting it here in case it helps anyone else. This one runs on any push to the repo, as long as there’s changes to the .ps1
files in the Runbooks
folder. I could have targetted specific branches too, for instance, by modifying this section:
1 2 3 4 5 6 7 |
on: workflow_dispatch: push: branches: - 'prod' paths: - 'Runbooks/*.ps1' |