code signing assemblies with GitHub Actions

image by archi-lab

If you are working in the AEC space you probably get annoyed by the fact that Revit constantly warns you about the unsafe assemblies that you want to load into the application.


It’s the same old code signing issue that we had to deal with for the last few years. I think I wrote about this before here: playing with Power Shell commands and Post Build events, and here: code signing of your revit plug-ins. These two posts explain how to get the Code Signing Certificate and then use the Post Build Event in Visual Studio to sign your DLLs, before they are copied to Revit Add-ins folder. Nothing new here. However, since I wrote recently about using GitHub Actions to automate creation of Releases, I decided to follow up to let you know how to setup Code Signing for GitHub Actions so that we can sign our DLLs “in the cloud”. Sounds fancy. I know. It’s not.

I am going to make an assumption that you already have your PFX file (code signing certificate), and we will go from there. First we have to convert that file into a base64 string. We will do that because I want to store that certificate in something called GitHub Secrets. Secrets is basically GitHub storage for things like access tokens, and passwords. It allows us to store strings, so if we convert our certificate into a string, we can store it there. It’s also accessible from GitHub Actions so it makes perfect sense to put it up there. Here’s how to convert a PFX file into a base64 string.

The above line can be executed from Power Shell. It will convert the PFX input file into TXT base64 string and save it out somewhere on your drive. Take contents of that file, and store it in GitHub Secrets. My variable name was: CERTIFICATE but you can name it something else.

Note that a properly exported PFX file will start with “—–BEGIN CERTIFICATE—–“ and end with “—–END CERTIFICATE—–“.

Ok, next up create a new secret for the PFX password. Mine was CERTIFICATE_PASS. Store your password. You should have two variables like that:

Now we can add the following code to your GitHub Actions to make that certificate available to us:

Just to quickly explain these three lines of code:

  1. We first create a new directory on the build server called “certificate”.
  2. Then we write the contents of the CERTIFICATE secret into a file in that directory called certificate.txt
  3. Finally we use the certutil tool to decode a base64 string into a PFX file and save that file in certificate\certificate.pfx file.

Now we can use the above file to sign an actual DLL. Please make sure to sign your dlls after they were build so put the code signing code after build action, but before the releases.

This should get our assemblies signed. Please notice how we disabled rebuilding of project references for the MSI build action. We want to avoid our DLLs getting overridden by another build action which WIX would normally do. /p:BuildProjectReferences=false is the trick here. You don’t have to worry about this if you are only Zipping them up.

This is it! We did it. With these actions in place, we can now automate our CD pipeline.


Support archi-lab on Patreon!


  1. Tim Cartwright says:

    I really liked your solution, but implemented a module to enter developer powershell that I used for this instead of hard coding the path to the signtool. DISCLOSURE: I am the author of the module.

    – name: Code Sign The DLL
    shell: powershell
    run: |
    $moduleName = “EnterDeveloperPowerShell”

    $module = Get-InstalledModule $moduleName -ErrorAction SilentlyContinue
    if (-not $module) {
    Write-Host “Installing module: $moduleName”
    Install-Module -Name $moduleName -Force

    Import-Module $moduleName
    . signtool.exe sign /f certificate\certificate.pfx /p ‘${{ secrets.CODE_SIGN_PASSWORD }}’ /t “$env:binary_path”

Leave a Comment