Files
rmtPocketWatcher/flutter_app/CI_CD_CERTIFICATE_SETUP.md
HRiggs 110c5d99a1
Some checks failed
Flutter Release / get-version (push) Successful in 7s
Flutter Release / build-windows (push) Failing after 9s
Flutter Release / create-release (push) Has been cancelled
Flutter Release / build-android (push) Has been cancelled
Signing, Installer, New Workflows
2025-12-15 00:05:29 -05:00

4.3 KiB

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:

.\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:

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:

- 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