Skip to content

[codex] fix(ci): resolve macOS codesign identity from imported cert#1337

Merged
ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:codex/fix-macos-codesign-identity
Jul 1, 2026
Merged

[codex] fix(ci): resolve macOS codesign identity from imported cert#1337
ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:codex/fix-macos-codesign-identity

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

What changed

  • resolve the macOS codesigning identity from the certificate that was actually imported into the temporary keychain
  • harden scripts/ci/import-macos-p12.sh for current macos-latest runners by recreating the keychain, setting the search list, and printing discovered codesigning identities for debugging
  • stop pre-populating APPLE_PERSONALID from APPLE_TEAMID, since the packaging step now derives the real signing identity after import

Why

master release CI started failing on July 1, 2026 in both macOS release jobs. The failing step was codesign during Package dmg, with errors like no identity found and The specified item could not be found in the keychain.

The existing workflow depended on a brittle APPLE_PERSONALID value and an old keychain import flow. This patch makes the workflow use the identity that macOS actually exposes after import, which is what codesign needs.

Impact

This should unblock the Release workflow on master for both Qt and Tauri macOS builds without changing Linux or Windows packaging.

Validation

  • git diff --check
  • bash -n scripts/ci/import-macos-p12.sh
  • inspected failing runs 28523138998 and 28523116461

Local end-to-end signing was not possible here because the Apple certificate secrets and a macOS runner are only available in GitHub Actions.

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes broken macOS release CI by deriving the codesigning identity dynamically from the certificate that was actually imported into the temporary keychain, rather than relying on a hard-coded Team ID that codesign cannot use directly. The shell script is also hardened: keychain is recreated on every run, all variables are properly quoted, and set -eu catches unexpected failures early.

  • Identity resolution: both "Package dmg" steps now run security find-identity after import and fail fast with a clear error if no identity is found, replacing the old APPLE_PERSONALID=${{ secrets.APPLE_TEAMID }} approach that was never a valid codesign identity.
  • Script hardening: import-macos-p12.sh gains set -eu, printf '%s' instead of echo for safe base64 decoding, explicit keychain deletion before recreation, and a set-keychain-settings timeout — all standard hygiene for ephemeral CI keychains.

Confidence Score: 5/5

Safe to merge; the identity resolution, quoting fix, and script hardening are all correct and directly address the documented CI failures.

The sed BRE capture-group syntax is correct (single backslashes in single-quoted shell strings), APPLE_PERSONALID is now double-quoted before being passed to codesign, and the fast-fail guard prevents silent no-op signing. The one open question is whether security list-keychains tolerates the legacy login.keychain name on the latest GitHub macOS runners, but it does not affect the core identity-resolution path.

scripts/ci/import-macos-p12.sh — the login.keychain entry in the search-list call is worth a second look given set -eu.

Important Files Changed

Filename Overview
scripts/ci/import-macos-p12.sh Hardened with set -eu, proper quoting, keychain recreation, and identity verification; including login.keychain in the search list alongside login.keychain-db may fail on newer macOS runners where that legacy name is absent.
.github/workflows/release.yml Both macOS Package dmg steps correctly resolve the codesigning identity from the imported cert and guard against an empty result; APPLE_PERSONALID is now properly quoted in codesign.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant GHA as GitHub Actions
    participant Script as import-macos-p12.sh
    participant KC as macOS Keychain
    participant Workflow as release.yml run block
    participant CS as codesign

    GHA->>Script: ./scripts/ci/import-macos-p12.sh
    Script->>KC: delete-keychain build.keychain-db idempotent
    Script->>KC: create-keychain + unlock + set-keychain-settings
    Script->>KC: list-keychains -s add to search list
    Script->>KC: security import cert.p12
    Script->>KC: set-key-partition-list
    Script->>GHA: find-identity output debug print

    GHA->>Workflow: continue run block
    Workflow->>KC: security find-identity -v -p codesigning build.keychain-db
    KC-->>Workflow: Apple Distribution Company TEAMID
    Workflow->>Workflow: sed + head -1 to APPLE_PERSONALID
    Note over Workflow: exit 1 if APPLE_PERSONALID is empty

    Workflow->>CS: codesign -s APPLE_PERSONALID dist/ActivityWatch.dmg
    CS-->>Workflow: signed DMG
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant GHA as GitHub Actions
    participant Script as import-macos-p12.sh
    participant KC as macOS Keychain
    participant Workflow as release.yml run block
    participant CS as codesign

    GHA->>Script: ./scripts/ci/import-macos-p12.sh
    Script->>KC: delete-keychain build.keychain-db idempotent
    Script->>KC: create-keychain + unlock + set-keychain-settings
    Script->>KC: list-keychains -s add to search list
    Script->>KC: security import cert.p12
    Script->>KC: set-key-partition-list
    Script->>GHA: find-identity output debug print

    GHA->>Workflow: continue run block
    Workflow->>KC: security find-identity -v -p codesigning build.keychain-db
    KC-->>Workflow: Apple Distribution Company TEAMID
    Workflow->>Workflow: sed + head -1 to APPLE_PERSONALID
    Note over Workflow: exit 1 if APPLE_PERSONALID is empty

    Workflow->>CS: codesign -s APPLE_PERSONALID dist/ActivityWatch.dmg
    CS-->>Workflow: signed DMG
Loading

Reviews (2): Last reviewed commit: "fix(ci): quote macOS codesign identity" | Re-trigger Greptile

Comment thread .github/workflows/release.yml Outdated
run: |
if [ -n "$APPLE_EMAIL" ]; then
./scripts/ci/import-macos-p12.sh
APPLE_PERSONALID=$(security find-identity -v -p codesigning "${KEY_CHAIN:-build.keychain-db}" | sed -n 's/.*"\\(.*\\)"/\\1/p' | head -1)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Broken sed regex — identity extraction always fails

In a YAML literal block scalar (|), backslashes are not escape sequences, so \\( reaches the shell as two characters: \ and (. Inside single quotes, the shell passes them literally to sed. In POSIX BRE, \\( means "literal backslash then literal (", not a capture group — so the pattern never matches an identity like Apple Distribution: Company (TEAMID). APPLE_PERSONALID will always be empty, and the explicit exit 1 guard will fire on every run. Single backslashes are needed: 's/.*"\(.*\)"/\1/p'. The same bug is present at line 595.

@TimeToBuildBob TimeToBuildBob marked this pull request as ready for review July 1, 2026 17:22
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Verified the fix on the active PR build (run 28534522833). Both macOS release jobs that were previously failing with "no identity found" / "Code signing identity: None" are now green:

  • Build Qt artifacts (macos-latest) — pass (16m3s)
  • Build Tauri artifacts (macos-latest) — pass (16m10s)

Linux x86_64, Linux arm64, and the lint/CodeQL/Greptile checks are also green; only Windows is still running. Promoting from draft so this is visible to reviewers.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@ErikBjare ErikBjare merged commit b32338d into ActivityWatch:master Jul 1, 2026
16 checks passed
@TimeToBuildBob

TimeToBuildBob commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Correction after re-checking the actual runs on July 1, 2026:

The merged workflow change in #1337 did not validate or fix macOS signing on master.

What the logs now show:

  • The macOS signing break already existed before #1337 merged.
    • 28523116461 (18a234b) and 28523138998 (2715937) both failed on push with Apple secrets present.
    • Those failures happened during in-app signing inside the build, with errors like ***: no identity found and The specified item could not be found in the keychain.
  • The PR Release run I previously cited as validation (28534522833) was a pull_request run where the Apple signing secrets were empty.
    • APPLE_EMAIL: empty
    • APPLE_PERSONALID: empty
    • CERTIFICATE_MACOS_P12_BASE64: empty
    • So that run only proved unsigned macOS packaging, not signing/notarization.
  • After merge, master still fails (28548184603), but earlier in the same lane:
    • certificate import succeeds
    • security find-identity -v -p codesigning build.keychain-db returns 0 valid identities found
    • workflow aborts before the later codesign step

So the current evidence points to a macOS signing credential / secret-state problem on push runs, not an ActivityWatch app-code regression and not a validated workflow fix.

I opened #1339 to track the exact evidence and the next action:

The practical next step is to refresh/re-upload the working macOS signing .p12 + password (and verify the actual codesigning identity on a macOS machine), then rerun Release on master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants