# CI/CD Certificate Setup Guide This guide explains how to set up code signing certificates for automated builds in your CI/CD pipeline. ## Prerequisites 1. **Certificate Created**: Run `.\create_certificate.ps1` to create your certificate 2. **Local Testing**: Verify signing works locally with `.\build_windows.ps1 -Release` ## Step 1: Encode Certificate Run the encoding script to prepare your certificate for CI/CD: ```powershell .\encode_certificate.ps1 ``` This creates `certificate_base64.txt` containing your certificate encoded as base64. ## Step 2: Add Action Secrets ### For Gitea Actions: 1. Go to your repository settings 2. Navigate to "Secrets and Variables" → "Actions" 3. Add these secrets: | Secret Name | Value | Description | |-------------|-------|-------------| | `CERT_BASE64` | Contents of `certificate_base64.txt` | Base64 encoded certificate | | `CERT_PASSWORD` | `rmtPocketWatcher2024!` | Certificate password | ### For GitHub Actions: 1. Go to repository "Settings" → "Secrets and variables" → "Actions" 2. Click "New repository secret" 3. Add the same secrets as above ## Step 3: Security Cleanup **IMPORTANT**: After adding the secrets, delete the local files: ```powershell Remove-Item certificate_base64.txt -Force ``` ## Step 4: Verify Setup 1. Push a change to trigger the workflow 2. Check the build logs for: - "✅ Certificate installed successfully" - "✅ Executable signed successfully" - "✅ MSIX installer signed successfully" ## How It Works ### Certificate Installation The workflow automatically: 1. Decodes the base64 certificate 2. Saves it as `certificates/rmtPocketWatcher.pfx` 3. Uses it for signing during the build process ### Signing Process The build script signs: - **Standalone executable**: `rmtpocketwatcher.exe` - **MSIX installer**: `*.msix` file ### Environment Variables - `CERT_PASSWORD`: Used by signing scripts - `MSIX_CERTIFICATE_PASSWORD`: Used by MSIX creation ## Troubleshooting ### "Certificate not found" Error - Verify `CERT_BASE64` secret is set correctly - Check the base64 encoding is complete (no line breaks) ### "Invalid certificate password" Error - Verify `CERT_PASSWORD` secret matches your certificate password - Default password is `rmtPocketWatcher2024!` ### "SignTool not found" Error - This should not occur in GitHub/Gitea runners - Windows runners include Windows SDK by default ### Unsigned Executables - Check workflow logs for certificate setup messages - Verify both secrets are set correctly - Ensure certificate is valid and not expired ## Security Best Practices ### Certificate Protection - Never commit `.pfx` files to version control - Use repository secrets for sensitive data - Regularly rotate certificate passwords ### Access Control - Limit repository access to trusted contributors - Use branch protection rules - Require reviews for workflow changes ### Monitoring - Monitor build logs for signing failures - Set up notifications for failed builds - Regularly verify certificate expiration dates ## Commercial Certificate Migration When upgrading to a commercial certificate: 1. **Obtain Certificate**: Purchase from DigiCert, Sectigo, etc. 2. **Update Secrets**: Replace `CERT_BASE64` with new certificate 3. **Update Password**: Change `CERT_PASSWORD` if different 4. **Test Build**: Verify signing works with new certificate ## Certificate Lifecycle ### Monitoring Expiration Add this to your workflow to check certificate expiration: ```yaml - name: Check Certificate Expiration shell: pwsh run: | if (Test-Path "certificates\rmtPocketWatcher.pfx") { $cert = Get-PfxCertificate -FilePath "certificates\rmtPocketWatcher.pfx" $daysUntilExpiry = ($cert.NotAfter - (Get-Date)).Days Write-Host "Certificate expires in $daysUntilExpiry days" if ($daysUntilExpiry -lt 30) { Write-Warning "Certificate expires soon!" } } ``` ### Renewal Process 1. Create new certificate (self-signed or commercial) 2. Encode with `.\encode_certificate.ps1` 3. Update `CERT_BASE64` secret 4. Update `CERT_PASSWORD` if changed 5. Test with a new build ## Support For issues with certificate setup: 1. Check workflow logs for detailed error messages 2. Verify certificate validity locally first 3. Test encoding/decoding process manually 4. Consult the main Certificate Guide for certificate creation issues