Signer votre application Windows Store avec un certificat autogénéré dans un agent de build VSTS Hosted
Dans un précédent article nous avons vu comment créer un certificat auto-signé pour vos packages Windows / UWP de longue durée. Il est facile de l'utiliser directement sur votre PC mais il est encore plus intéressant d'utiliser ce certificat dans une build automatisée VSTS pour signer votre package.
Demander la signature du package
La première étape consiste à demander à la tâche de compilation de générer vos packages. Pour cela vous aurez à ajouter les arguments suivants à MsBuild :
- AppxBundlePlatforms : architecture des packages à générer.
- AppxPackageDir : emplacement de sortie des packages.
- AppxBundle : génération ou non de bundle.
Une fois votre build lancée, vous aurez alors sûrement cette erreur de build :
Cannot import the key file 'MON_CERTIFICAT.pfx'. The key file may be password protected. To correct this, try to import the certificate manually into the current user's personal certificate store. error APPX0102: A certificate with thumbprint '9ACB9676737198CCB6707rrr0' that is specified in the project cannot be found in the certificate store. Please specify a valid thumbprint in the project file. error APPX0107: The certificate specified is not valid for signing. For more information about valid certificates, see http://go.microsoft.com/fwlink/?LinkID=241478.
L'erreur est claire : il faut installer votre certificat sur l'agent hosted de VSTS.
Installer votre certificat sur l'agent Hosted
C'est en réalité très simple.. une fois que vous avez trouvé la solution (par vous-même, je ne l'ai vu nulle part :(). Il faut utiliser un script PowerShell pour installer le certificat de signature avant la tâche de compilation.
$pwd= ConvertTo-SecureString $args[1] -AsPlainText -Force Add-Type -AssemblyName System.Security $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import($args[0],$pwd , [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"UserKeySet") $s = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", CurrentUser $s.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite") $s.Add($cert) $s.Close()
Le script ci-dessus utilise les arguments passés en paramètre du PowerShell par la build. Cela permet notamment de définir et utiliser une variable de Build. En premier nous passons le nom du certificat et son mot de passe en second. Il est aussi intéressant de noter que je définis l'emplacement d'exécution au dossier où se trouve le certificat pour des raisons de simplicité.
Signer votre package dans une tâche
La solution ci-dessus fonctionne très bien mais il peut être intéressant de ne pas avoir votre certificat final dans le code source. Dans ce cas, vous devrez re-signer le package après sa génération par la tâche de compilation du SLN.
Bonne nouvelle cela est encore possible avec un script Powershell. Celui-ci va utiliser l'outil signtool présent sur les agents Hosted pour re-signer le package :
$appxName= Get-ChildItem -recurse -Filter *.appx | Select-Object -First 1 |Select -ExpandProperty FullName Set-Alias signToolPath 'C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe' signToolPath sign /fd SHA256 /a /f MON_CERT.pfx /p $args[0] $appxName
Je passe encore une fois le mot de passe comme variable de build et je vais chercher le nom complet du package avec la commande Get-ChildItem. Aussi je pars du principe que le certificat est présent sur le disque à l'emplacement d'exécution du PowerShell sous le nom "MON_CERT.pfx". Il est assez facile d'écrire un script PowerShell dumpant une chaîne en base64 représentant votre certificat passée en variable de build au bon endroit.
Happy coding !
Commentaires