Skip to main content

CI Configuration

The Agent-Up CI workflow runs on every push. This page documents the repository secrets and variables that control CI behavior. Signing and release steps degrade gracefully when their credentials are absent; the Codecov upload token is required for the .NET coverage job.

Secrets are set under Settings → Secrets and variables → Actions → Secrets. Variables are set under the Variables tab in the same location.

Code coverage

SecretValue
CODECOV_TOKENRepository upload token from Codecov

The .NET coverage job uploads each test project's Cobertura output separately. Each upload has a test-project-specific Codecov flag, such as agentup-server-tests, so Codecov can filter the production-project coverage contributed by an individual test module. AgentUp.Tests combines its regular and headless E2E coverage under the agentup-tests flag.

Signing — macOS

Requires an Apple Developer Program membership ($99/year).

You need two separate certificates from the Apple Developer portal: a Developer ID Application certificate (signs the individual Mach-O binaries inside the package) and a Developer ID Installer certificate (signs the .pkg itself). Export each as a .p12 file with a password, then base64-encode it: base64 -i cert.p12 | pbcopy.

Notarization uses an app-specific password, not your Apple ID login password. Create one at appleid.apple.com under Sign-In and Security → App-Specific Passwords.

SecretValue
MACOS_APP_CERTIFICATEBase64-encoded Developer ID Application .p12
MACOS_APP_CERTIFICATE_PASSWORDPassword for the Developer ID Application .p12
MACOS_INSTALLER_CERTIFICATEBase64-encoded Developer ID Installer .p12
MACOS_INSTALLER_CERTIFICATE_PASSWORDPassword for the Developer ID Installer .p12
MACOS_NOTARIZE_APPLE_IDApple ID email associated with the developer account
MACOS_NOTARIZE_APP_SPECIFIC_PASSWORDApp-specific password from appleid.apple.com
MACOS_NOTARIZE_TEAM_IDTeam ID from the Apple Developer portal (top-right of the Certificates page)
KEYCHAIN_PASSWORDAny random string — used to protect the temporary keychain created on the runner

Enable macOS signing by setting the repository variable MACOS_SIGNING_ENABLED to true.

Signing — Windows

Requires an Azure Trusted Signing account. This is Microsoft's HSM-backed cloud signing service — no hardware token required. Identity validation (same process as a traditional OV code-signing certificate) takes 1–5 business days.

Setup steps:

  1. Create an Azure subscription and a Trusted Signing account resource (Microsoft.CodeSigning/codeSigningAccounts).
  2. Complete identity validation in the Azure portal.
  3. Create a Certificate Profile (choose Public Trust).
  4. Create a Service Principal (App Registration) and assign it the Trusted Signing Certificate Profile Signer role on the account.
  5. Generate a client secret for the service principal.
SecretValue
AZURE_TENANT_IDAzure AD directory (tenant) ID
AZURE_CLIENT_IDService principal application (client) ID
AZURE_CLIENT_SECRETService principal client secret
AZURE_TRUSTED_SIGNING_ENDPOINTAccount endpoint URL, e.g. https://eus.codesigning.azure.net/
AZURE_TRUSTED_SIGNING_ACCOUNTTrusted Signing account resource name
AZURE_TRUSTED_SIGNING_CERT_PROFILECertificate profile name

Enable Windows signing by setting the repository variable AZURE_SIGNING_ENABLED to true.

Signing — Linux

Linux packages are GPG-signed. No external account is required — generate a dedicated key pair locally.

gpg --full-gen-key # RSA 4096, set a long expiry or none
gpg --list-secret-keys --keyid-format LONG # note the key ID
gpg --export-secret-keys --armor <KEY_ID> # copy the output into the secret
gpg --export --armor <KEY_ID> > packaging/linux/agent-up-signing.asc # commit the public key
SecretValue
GPG_SIGNING_PRIVATE_KEYArmored private key (--export-secret-keys --armor)
GPG_SIGNING_PASSPHRASEGPG key passphrase

Enable Linux signing by setting the repository variable LINUX_SIGNING_ENABLED to true.

The signing step produces a detached agent-up-ubuntu-linux-x64.deb.asc signature file alongside the .deb. Users can verify with:

gpg --import agent-up-signing.asc
gpg --verify agent-up-ubuntu-linux-x64.deb.asc agent-up-ubuntu-linux-x64.deb

Release

The release job uses GITHUB_TOKEN, which GitHub provides automatically. No setup required.

Releases only run on main when semantic-release determines a new version is warranted based on Conventional Commits.

The same release publishes the Server image and agent-up-helm chart to Docker Hub. Create the public repositories themassiveone/agent-up-server and themassiveone/agent-up-helm on Docker Hub, then add a token with write access.

SecretValue
DOCKERHUB_USERNAMEDocker Hub username or organization account used to push
DOCKERHUB_TOKENDocker Hub access token with write access to those repositories

If those secrets are missing, the GitHub release still succeeds until semantic-release reaches the container and chart publish steps, which then fail.

LocalInstaller NuGet publishing is optional. Add NUGET_API_KEY to publish LocalInstaller.Core, LocalInstaller.App, LocalInstaller.Packaging, and LocalInstaller.Smoke packages from the localinstaller.yml release job; when the secret is absent, the GitHub release still publishes the NuGet package files and separately labeled sample installer assets.

Sentry product telemetry

The GitOps sentry-configurator Job creates agent-up-server, agent-up-desktop, agent-up-cli, and agent-up-mobile on the self-hosted Sentry and writes their DSNs to Secret agent-up-sentry-dsn. Copy the packaged Desktop, CLI, and Server keys into GitHub Actions secrets. Cluster Helm Server does not use a GitHub secret: it reads SENTRY_DSN from that generated Secret. Mobile production web builds read SENTRY_DSN_MOBILE from Cloudflare Pages, not GitHub Actions.

CI passes SENTRY_DSN_DESKTOP and SENTRY_DSN_CLI into .NET publish, and SENTRY_DSN_SERVER into native packaging. Unset secrets leave those binaries as SDK no-ops.

SecretValue
SENTRY_DSN_SERVERagent-up-server DSN for packaged Server service env at package time
SENTRY_DSN_DESKTOPagent-up-desktop DSN for native Desktop publish (/p:SentryDsn=...)
SENTRY_DSN_CLIagent-up-cli DSN for native CLI publish (/p:SentryDsn=...)
SENTRY_AUTH_TOKENOptional org auth token for later sentry-cli debug-file or source-map upload; not used by apps or the cluster

Do not put a DSN in Helm values or in Docker images. Unset DSN means the SDK is a no-op. Inbound filters and rate limits on the public Desktop, CLI, and Mobile projects mitigate DSN spam.

Event tags, error-only SDK policy, and injection paths are documented in Product telemetry.

JetBrains Marketplace

JetBrains Marketplace publishing is optional. Create the Agent-Up plugin entry in JetBrains Marketplace once, then add a Marketplace token from the vendor profile. The release job publishes Plugins/Jetbrains through Gradle after the GitHub release succeeds, using the same planned release version that was injected into the release ZIP.

SecretValue
JETBRAINS_MARKETPLACE_TOKENJetBrains Marketplace publishing token
JETBRAINS_PLUGIN_CERTIFICATE_CHAINOptional Base64-encoded plugin signing certificate chain
JETBRAINS_PLUGIN_PRIVATE_KEYOptional Base64-encoded plugin signing private key
JETBRAINS_PLUGIN_PRIVATE_KEY_PASSWORDOptional private-key password

If JETBRAINS_MARKETPLACE_TOKEN is not configured, CI still builds the plugin ZIP and attaches it to the GitHub release, but skips Marketplace publishing.

Repository Variables

Variables control which signing steps run. They are not secrets and can be read freely in workflow if: conditions.

VariableEffect when set to true
MACOS_SIGNING_ENABLEDEnables real macOS signing (requires the macOS secrets above)
AZURE_SIGNING_ENABLEDEnables real Windows signing via Azure Trusted Signing (requires the Azure secrets above)
LINUX_SIGNING_ENABLEDEnables real Linux GPG signing (requires the GPG secrets above)
SIGNING_SMOKE_TESTRuns a credential-free signing dry run on all platforms: ad-hoc codesign on macOS, self-signed certificate via signtool on Windows, throwaway GPG key on Linux. Useful for validating the signing pipeline before real credentials are available.

SIGNING_SMOKE_TEST and the platform-specific *_SIGNING_ENABLED variables are mutually exclusive in intent. Setting both at the same time would sign files twice.