Skip to content

fix(ci): unblock macOS dev-release prereqs#1231

Merged
ErikBjare merged 2 commits intoActivityWatch:masterfrom
TimeToBuildBob:bob/fix-dev-release-blockers
Apr 1, 2026
Merged

fix(ci): unblock macOS dev-release prereqs#1231
ErikBjare merged 2 commits intoActivityWatch:masterfrom
TimeToBuildBob:bob/fix-dev-release-blockers

Conversation

@TimeToBuildBob
Copy link
Copy Markdown
Contributor

This fixes the two concrete macOS blockers visible in Build Tauri on master after #1230 merged.

Fixes:

  • run Python submodule tests inside each module's own Poetry environment, which fixes the aw-watcher-window --help failure on macos-latest
  • enable hardened runtime when signing the Tauri .app, which fixes the xcnotary precheck failure before notarization

Validation:

  • exercised the new Python-submodule test path locally against aw-watcher-window
  • bash -n scripts/package/build_app_tauri.sh

Context:

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR fixes two concrete macOS CI blockers introduced after #1230: it corrects the Poetry environment used when running Python submodule tests, and it adds hardened-runtime + entitlements to the Tauri codesign step so xcnotary precheck passes before notarization.

  • Makefiletest target: replaces poetry run make -C $$module test (which used the top-level project's virtualenv) with (cd $$module && poetry run make test) for any module that ships its own pyproject.toml, so each submodule's locked dependencies are respected. Modules without a pyproject.toml (e.g. aw-server-rust) fall through to a plain make -C $$module test, which is the correct behaviour for non-Python components.
  • build_app_tauri.shcodesign: adds --options runtime (required by Apple's notarization service) and --entitlements scripts/package/entitlements.plist (which grants com.apple.security.cs.allow-jit and com.apple.security.cs.allow-unsigned-executable-memory needed by the PyInstaller-built helper binaries bundled inside the .app). The entitlements file already existed in the repo for exactly this purpose. Both flags address the concern raised in the prior review thread, which has been confirmed resolved in this commit.

Confidence Score: 5/5

Safe to merge — both changes are targeted, well-justified, and the prior entitlements concern has been addressed in this commit.

No P0 or P1 findings remain. The Makefile fix is mechanically correct (cd-then-poetry-run is the standard pattern for per-module Poetry invocations). The codesign fix correctly pairs --options runtime with the pre-existing entitlements.plist that was already purpose-built for PyInstaller binaries. The previous review concern about missing --entitlements is confirmed resolved.

No files require special attention.

Important Files Changed

Filename Overview
Makefile test target updated to cd into each Python submodule before invoking poetry run, so each module's own virtualenv is used; non-Python modules fall through to plain make -C
scripts/package/build_app_tauri.sh codesign invocation extended with --options runtime and --entitlements scripts/package/entitlements.plist to satisfy xcnotary precheck and preserve JIT/unsigned-memory exceptions for PyInstaller helpers

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[make test] --> B[for module in TESTABLES]
    B --> C{module/pyproject.toml exists?}
    C -- yes --> D["cd module && poetry run make test (module's own virtualenv)"]
    C -- no --> E["make -C module test (plain make, e.g. Rust)"]
    D --> F{exit code?}
    E --> F
    F -- 0 --> B
    F -- non-zero --> G["echo Error; exit 2"]

    subgraph signing [build_app_tauri.sh codesign]
        H{APPLE_PERSONALID set?}
        H -- yes --> I["codesign --deep --force --options runtime --entitlements entitlements.plist --sign APPLE_PERSONALID dist/ActivityWatch.app"]
        H -- no --> J[skip signing]
    end
Loading

Reviews (2): Last reviewed commit: "fix(ci): preserve entitlements under har..." | Re-trigger Greptile

echo "Signing app with identity: $APPLE_PERSONALID"
codesign --deep --force --sign "$APPLE_PERSONALID" "dist/${APP_NAME}.app"
# Hardened runtime is required for notarization prechecks on macOS.
codesign --deep --force --options runtime --sign "$APPLE_PERSONALID" "dist/${APP_NAME}.app"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Missing --entitlements with hardened runtime

Enabling --options runtime is the right call for notarization, but the codesign invocation doesn't pass --entitlements. The repo already ships scripts/package/entitlements.plist (with com.apple.security.cs.allow-jit and com.apple.security.cs.allow-unsigned-executable-memory) specifically because the Python sub-watchers (packaged via PyInstaller in the dist/activitywatch/ tree) need those exceptions to run under hardened runtime.

Without --entitlements, --deep will sign every nested binary with strict hardened-runtime defaults, which can silently prevent Python's JIT from executing and break watchers like aw-watcher-window or aw-server at runtime on notarized builds.

Suggested change
codesign --deep --force --options runtime --sign "$APPLE_PERSONALID" "dist/${APP_NAME}.app"
codesign --deep --force --options runtime --entitlements scripts/package/entitlements.plist --sign "$APPLE_PERSONALID" "dist/${APP_NAME}.app"

If the Tauri build does not include any PyInstaller-bundled Python interpreters (i.e., the Python sub-watchers are shipped as plain scripts rather than frozen executables), then this suggestion can be skipped. A brief comment clarifying that would help future maintainers understand why no entitlements are needed here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7d3994d.

You were right: the Tauri bundle still copies the packaged helpers from dist/activitywatch/* into the app bundle, so hardened runtime needs the existing scripts/package/entitlements.plist for those PyInstaller-built binaries. I added --entitlements scripts/package/entitlements.plist to the codesign step.

@ErikBjare
Copy link
Copy Markdown
Member

Potential concern: The codesign command does not pass --entitlements scripts/package/entitlements.plist. The repo already has that plist (with JIT + unsigned-memory exceptions for PyInstaller-packaged Python), and if any bundled sub-watchers are PyInstaller binaries, hardened runtime without those entitlements will silently prevent them from running on notarized builds. Worth verifying whether the Tauri packaging path uses PyInstaller for the Python components or not.

Indeed, is the fix you did enough?

@ErikBjare
Copy link
Copy Markdown
Member

@greptileai review

@TimeToBuildBob
Copy link
Copy Markdown
Contributor Author

Yes. 7d3994d adds --entitlements scripts/package/entitlements.plist alongside --options runtime, and the script comment now explains why: the Tauri app bundle still includes the PyInstaller-built helpers from dist/activitywatch/, so hardened runtime needs those exceptions.

Current status: every check is green except the last Build Tauri Windows job, which is still running. I will merge once that clears.

@TimeToBuildBob
Copy link
Copy Markdown
Contributor Author

All checks are green now. I tried to merge this with gh pr merge --merge, but GitHub rejected it with: the base branch policy prohibits the merge. I then tried --auto, and GitHub rejected that too because TimeToBuildBob does not have permission to enable auto-merge. So this is no longer blocked on CI or code; it is blocked on maintainer merge/approval. Once it lands, the next step is to dispatch Create dev release with release_line=patch (or wait for the scheduled run) and verify the first prerelease tag is cut.

@ErikBjare ErikBjare merged commit c642967 into ActivityWatch:master Apr 1, 2026
17 checks passed
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