Skip to content

fix(ci): select nightly first-party submodules by URL, not by name - #1457

Merged
ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/nightly-first-party-url-filter
Sep 18, 2026
Merged

ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/nightly-first-party-url-filter

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Follow-up from #1448, closes #1456.

Change

Replace the name-based exclusion list (grep -vx awatcher) with a URL-based property check. A submodule is first-party iff its URL is under github.com/ActivityWatch/ (case-insensitive). This makes the boundary:

  1. Self-maintaining — a new third-party submodule is excluded automatically without touching the filter
  2. Visible — the excluded set is printed in every job run so maintainers can see the boundary without reading the script

The logic walks top-level submodule paths and queries .gitmodules via git config -f .gitmodules for each URL. All current submodules classify correctly: the 10 ActivityWatch-org ones become first-party; awatcher (github.com/2e3s/awatcher) becomes excluded.

Verification

Manual classification check against current .gitmodules:

  • aw-core, aw-client, aw-server, aw-watcher-afk, aw-qt, aw-watcher-window, aw-server-rust, aw-watcher-input, aw-tauri, aw-notify → all under github.com/ActivityWatch/first-party
  • awatchergithub.com/2e3s/awatcherexcluded

The empty-list guard (exits 1 if $firstparty is empty) is preserved so the nightly can't silently promote all submodules including third-party if the URL lookup ever fails.

Filter by whether the URL is under github.com/ActivityWatch/ (case-
insensitive) instead of hard-coding a name exclusion list. This ensures
newly added third-party submodules are excluded automatically, and
prints the excluded set in every job run so the boundary stays visible.

Closes ActivityWatch#1456
Follow-up from ActivityWatch#1448

Git-Session-Id: dc09
@greptile-apps

greptile-apps Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the prior URL-boundary and section-name lookup issues are fully fixed with no new actionable failures.

Findings

  1. P2 Security URL Host Is Unverified
  2. P2 Path Used As Name

Summary

The PR updates nightly release automation to classify first-party submodules using anchored ActivityWatch GitHub URLs rather than submodule names.

  • Reads each top-level submodule’s section name and path directly from .gitmodules.
  • Uses the section name for URL lookup and the path for updates.
  • Excludes and reports third-party submodules while retaining the fail-closed empty-list guard.
  • The latest changes fully address both previous findings by anchoring accepted URL forms and no longer assuming section names equal paths.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  G[Read name and path from .gitmodules] --> U[Look up submodule URL by section name]
  U --> C{URL has accepted GitHub ActivityWatch prefix?}
  C -- Yes --> F[Add path to first-party list]
  C -- No --> E[Add path to excluded list]
  F --> N{First-party list empty?}
  E --> P[Print excluded paths]
  P --> N
  N -- Yes --> X[Fail closed]
  N -- No --> R[Update first-party submodules with --remote]
Loading

Reviews (2) · Last reviewed commit: "fix(ci): anchor first-party URL match an..."

Comment thread .github/workflows/release.yml Outdated
[ -z "$sm" ] && continue
url=$(git config -f .gitmodules --get "submodule.$sm.url" 2>/dev/null || true)
case "${url,,}" in
*github.com/activitywatch/*) firstparty="${firstparty:+$firstparty }$sm" ;;

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.

P2 security URL Host Is Unverified

The glob checks for github.com/activitywatch/ anywhere in the URL instead of verifying the URL's host and organization. An external URL such as https://mirror.example/github.com/ActivityWatch/component.git would therefore be classified as first-party, advanced to its remote tip, and built downstream in jobs carrying the Tauri signing key. Parse or anchor the accepted GitHub URL forms so that only repositories actually hosted under the ActivityWatch organization cross this boundary.

How this was verified: The matched submodule is advanced with --remote, propagated through the SHA output, and checked out and built downstream with the signing key in the job environment.

Knowledge Base Used: Build and distribution

Comment thread .github/workflows/release.yml Outdated
firstparty=$(git submodule --quiet foreach 'echo $sm_path' | grep -vx awatcher || true)
while IFS= read -r sm; do
[ -z "$sm" ] && continue
url=$(git config -f .gitmodules --get "submodule.$sm.url" 2>/dev/null || true)

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.

P2 Path Used As Name

$sm comes from $sm_path, but .gitmodules is keyed by the submodule section name, which Git permits to differ from its path. For such a submodule, this lookup silently returns an empty URL because errors are suppressed. A first-party component is then reported as third-party and left pinned; if every section name differs from its path, the nightly job fails its empty-list guard. Carry both $name and $sm_path from git submodule foreach, using the name for the configuration lookup and the path for the update.

….gitmodules

Two review findings on the URL-based classifier:

- The `*github.com/activitywatch/*` glob matched the string anywhere in
  the URL, so a mirror like `https://mirror.example/github.com/ActivityWatch/x`
  would classify as first-party and get built with the signing key. Anchor
  the match against known URL prefixes instead.
- `$sm` was populated from `git submodule foreach`'s `$sm_path`, but
  `.gitmodules` is keyed by submodule *name*, which git permits to differ
  from path. Read name/path pairs directly from `.gitmodules` instead of
  reusing the path as the name for the url lookup.

Git-Session-Id: 1083368a-3a3e-5b8c-ac1e-c999007d3dc1
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@TimeToBuildBob

TimeToBuildBob commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

🤖 AI code review

The PR replaces the name-based exclusion of the awatcher submodule in the nightly-submodules job with a URL-based classification. It reads submodule name/path pairs from .gitmodules, looks up each URL, and classifies a submodule as first-party only if its URL matches github.com/ActivityWatch/ (case-insensitive). The excluded set is printed to the log, and the empty-list guard is preserved.

Safe to merge — no P0/P1 findings

Confidence 5/5

⚠️ 1 of 1 changed files were not fully read. Claims that an identifier is never assigned, used, or called are discarded unless verification names only fully preloaded files. This coverage describes the bounded context preload; the diff was reviewed.

No thread-worthy findings. Advisory notes follow; they are retained without opening review threads.

1 advisory finding (summary-only, not scored)

These P2 guard, heuristic, trade-off, or documentation claims are retained for judgment without opening review threads.

⚠️ P2 medium.github/workflows/release.yml

This is a fix(...) PR but no test files are included in the diff. Erik's feedback: 'where is the repro & fixes they are supposed to catch' (gptme#3441), 'that measurement should come with a regression test' (gptme#3446). Add a test that would have caught this bug. (Advisory: Erik merged all such PRs but consistently requested tests.)

Add a test file that reproduces the bug before the fix and passes after it.

How this was verified: static preflight: fix-commit + touched-files scan (rule 7)

Files changed (1) — the diff as I read it
  • .github/workflows/release.yml — Replaces the grep -vx awatcher filter with a .gitmodules URL-based first-party classification loop and adds an excluded-set log line.

Reviewed c4d0c4b5a73c · openrouter/deepseek/deepseek-v4-flash-0731 · llm engine · 22s · about this reviewer

Maintainer commands

@TimeToBuildBob review (own line) — fresh review · @TimeToBuildBob fix — a worker acts on the findings. Once per comment; 👀 = received.

@ErikBjare
ErikBjare merged commit be7d6b1 into ActivityWatch:master Sep 18, 2026
22 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.

nightly submodule build: select first-party submodules by URL, not by name

2 participants