feat(ci): poll merged locale-fix PRs and auto-refresh data - #213
Conversation
Adds a lightweight workflow that runs every 30 minutes, checks if any locale-fix or translation PRs were merged since the last data update, and triggers a data refresh if so. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 35 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a scheduled and manually triggered workflow that detects merged locale-fix and translation PRs. It dispatches data refreshes when no active update exists. Documentation and FAQs describe refresh triggers, the issues route, and the tracked-skill submission process. ChangesReactive refresh and workflow documentation
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant GitHubSearch
participant UpdateDataWorkflow
GitHubActions->>GitHubSearch: Search recently merged locale-fix and translation PRs
GitHubSearch-->>GitHubActions: Return matching PR count
GitHubActions->>UpdateDataWorkflow: Dispatch data refresh on dev when no active run exists
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
.github/workflows/poll_merged_fixes.yml (1)
12-15: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDisable unnecessary checkout credential persistence.
This job authenticates
ghexplicitly throughGH_TOKEN, so it does not need checkout to persist credentials. Setpersist-credentials: falseto reduce token exposure to later processes. (github.com)Proposed hardening
with: ref: dev fetch-depth: 10 + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/poll_merged_fixes.yml around lines 12 - 15, Update the actions/checkout configuration in the poll merged fixes job to set persist-credentials to false, while preserving the existing ref and fetch-depth settings.Sources: MCP tools, Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 32-43: Update the COUNT and TX_COUNT gh search commands in the
workflow to stop converting command failures into zero matches; remove the
fallback that echoes “0” and allow authentication, rate-limit, or API errors to
fail the job or be surfaced separately, while preserving zero for successful
searches with no results.
- Around line 48-58: Prevent duplicate dispatches from the “Trigger data update”
step by adding a shared concurrency policy covering both this poller and
update_data.yml, or by checking for an existing queued or in-progress dev run
before invoking gh workflow run. Ensure at most one update_data.yml run for dev
can be queued or running.
- Around line 54-58: Add a job-level permissions block for the job containing
the “Trigger data update” step, granting actions: write and retaining contents:
read for checkout. Keep the existing workflow dispatch command unchanged.
In `@docs/whitepaper.md`:
- Line 104: Update the pipeline trigger description in the whitepaper to include
changes under scripts/** and ovos_localize/** on the dev branch alongside
skills.txt, matching the triggers documented in update_data.yml and
docs/index.md.
In `@FAQ.md`:
- Around line 69-70: Update the “How do I add a new skill to the tracked list?”
section in FAQ.md to clarify that the add_skill workflow reads the
ADD_SKILL_META block from the issue body, while duplicate-submission validation
is performed by the frontend in index.html before submission. Keep the remaining
submission and pull-request flow unchanged.
---
Nitpick comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 12-15: Update the actions/checkout configuration in the poll
merged fixes job to set persist-credentials to false, while preserving the
existing ref and fetch-depth settings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b9a14ec5-1d3e-42c9-86cd-e0dcaf4b8c13
📒 Files selected for processing (4)
.github/workflows/poll_merged_fixes.ymlFAQ.mddocs/index.mddocs/whitepaper.md
| ### How do I add a new skill to the tracked list? | ||
| Click the "Submit a skill" button in the UI. Enter the GitHub repository URL. This opens a GitHub issue with a machine-readable `ADD_SKILL_META` block. The `add_skill` workflow parses the URL, appends it to `skills.txt`, and opens a PR. The UI checks for duplicate submissions before allowing a new one. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== FAQ.md context ==\n'
nl -ba FAQ.md | sed -n '60,85p'
printf '\n== Workflow context ==\n'
nl -ba .github/workflows/add_skill.yml | sed -n '1,240p'
printf '\n== Search for UI and duplicate-check references ==\n'
rg -n --hidden --glob '!**/.git/**' -e 'Submit a skill|ADD_SKILL_META|duplicate|skills\.txt|add_skill' .Repository: OpenVoiceOS/ovos-localize
Length of output: 225
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== FAQ.md context ==\n'
sed -n '60,85p' FAQ.md | cat -n
printf '\n== Workflow context ==\n'
sed -n '1,240p' .github/workflows/add_skill.yml | cat -n
printf '\n== Search for UI and duplicate-check references ==\n'
rg -n --hidden --glob '!**/.git/**' -e 'Submit a skill|ADD_SKILL_META|duplicate|skills\.txt|add_skill' .Repository: OpenVoiceOS/ovos-localize
Length of output: 50383
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Files mentioning submit-skill UI or duplicate checks ==\n'
rg -n --hidden --glob '!**/.git/**' \
-e 'Submit a skill|duplicate submission|already tracked|ADD_SKILL_META|skill-submission|add_skill' \
. \
| head -n 300
printf '\n== Candidate UI/templates/docs files ==\n'
fd -HI -t f 'add_skill|faq|issue|submit|skill' .Repository: OpenVoiceOS/ovos-localize
Length of output: 4271
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== index.html add-skill flow ==\n'
sed -n '3090,3215p' index.html | cat -n
printf '\n== issue template ==\n'
sed -n '1,220p' .github/ISSUE_TEMPLATE/add_skill.yml | cat -nRepository: OpenVoiceOS/ovos-localize
Length of output: 7021
Update the add-skill FAQ wording. The workflow reads ADD_SKILL_META from the issue body; the pre-submit duplicate check happens in the frontend (index.html), not in .github/workflows/add_skill.yml. Keep the description aligned with that split.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@FAQ.md` around lines 69 - 70, Update the “How do I add a new skill to the
tracked list?” section in FAQ.md to clarify that the add_skill workflow reads
the ADD_SKILL_META block from the issue body, while duplicate-submission
validation is performed by the frontend in index.html before submission. Keep
the remaining submission and pull-request flow unchanged.
Surface real gh search failures instead of masking them as zero matches, skip re-dispatching update_data.yml when a run is already queued or in progress for dev, grant the job explicit actions:write permission for workflow_dispatch, and document all push-triggered refresh paths (scripts/**, ovos_localize/**) in the whitepaper. AI-Generated Change: - Model: claude-sonnet-4-6 - Intent: address 5 unresolved CodeRabbit review threads on PR #213 - Impact: poll_merged_fixes.yml no longer swallows gh API errors as "0 matches"; adds a queued/in-progress check before dispatching update_data.yml; adds job-level permissions (contents: read, actions: write); whitepaper.md now lists all three push-trigger paths matching update_data.yml - Skipped: FAQ.md add-skill wording (thread on FAQ.md:70) — already correct in current source; it already states the add_skill workflow reads the issue body and the UI (index.html) performs the duplicate check, matching what CodeRabbit asked for - Verified via: python3 -m pytest test/ -q (169 passed); yaml.safe_load on poll_merged_fixes.yml
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/poll_merged_fixes.yml (1)
15-18: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winFetch full history for the marker lookup.
fetch-depth: 10limits the commits available togit log --all .. 'chore: update translation data'. If more than ten newer commits reachdev, the lookup can return empty and the poll will trigger a refresh on every run. Usefetch-depth: 0, or querychore: update translation datathrough GitHub instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/poll_merged_fixes.yml around lines 15 - 18, Update the actions/checkout step in the poll workflow to use fetch-depth: 0, ensuring the marker lookup against dev can inspect the full Git history and does not repeatedly trigger refreshes when the marker is older than ten commits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 66-76: Make duplicate prevention atomic by adding the same
workflow-level concurrency group to both the poller workflow and
update_data.yml, configured with cancel-in-progress: false, so poller and
refresh runs share a server-side lock and serialize dispatches. Preserve the
existing polling behavior while ensuring concurrent scheduled or manual runs
cannot both dispatch a refresh.
---
Outside diff comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 15-18: Update the actions/checkout step in the poll workflow to
use fetch-depth: 0, ensuring the marker lookup against dev can inspect the full
Git history and does not repeatedly trigger refreshes when the marker is older
than ten commits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b9b1a951-7781-4907-a6e3-b9732c19ee71
📒 Files selected for processing (2)
.github/workflows/poll_merged_fixes.ymldocs/whitepaper.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/whitepaper.md
| run: | | ||
| set -euo pipefail | ||
| # Skip dispatch if update_data.yml already has a queued or | ||
| # in-progress run for dev, to avoid piling up duplicate refreshes. | ||
| PENDING=$(gh run list --workflow update_data.yml --branch dev \ | ||
| --json status --jq '[.[] | select(.status == "queued" or .status == "in_progress")] | length') | ||
| if [ "$PENDING" -gt 0 ]; then | ||
| echo "update_data.yml already queued/running for dev ($PENDING run(s)), skipping dispatch" | ||
| exit 0 | ||
| fi | ||
| gh workflow run update_data.yml --ref dev |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Make duplicate prevention atomic.
The gh run list check and gh workflow run dispatch are separate operations. Two scheduled or manual poller runs can both observe PENDING=0 and dispatch update_data.yml. The filter also ignores requested, waiting, and pending statuses. (docs.github.com)
Add the same workflow-level concurrency group to this workflow and .github/workflows/update_data.yml, with cancel-in-progress: false, or use another server-side lock. A shared group serializes the poller and refresh workflow. (docs.github.com)
Proposed serialization
+concurrency:
+ group: translation-data-refresh-dev
+ cancel-in-progress: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/poll_merged_fixes.yml around lines 66 - 76, Make duplicate
prevention atomic by adding the same workflow-level concurrency group to both
the poller workflow and update_data.yml, configured with cancel-in-progress:
false, so poller and refresh runs share a server-side lock and serialize
dispatches. Preserve the existing polling behavior while ensuring concurrent
scheduled or manual runs cannot both dispatch a refresh.
Address CodeRabbit re-review: - shared concurrency group (cancel-in-progress: false) across the poller and update_data.yml — the gh-run-list check then dispatch was not atomic, two pollers could both observe zero pending runs - fetch-depth: 0 so the last-update marker lookup still finds the 'chore: update translation data' commit when it is >10 commits back; a missing marker made every poll trigger a refresh - persist-credentials: false on checkout; gh auths via GH_TOKEN AI-Generated Change: - Model: claude-fable-5 - Intent: address CodeRabbit review on PR #213 - Impact: no duplicate/looping data refreshes - Skipped: FAQ.md:70 thread — stale, text already corrected in 0955a77 - Verified via: python3 -m pytest test/ -q (169 passed)
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/poll_merged_fixes.yml (1)
49-60: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftAdvance the refresh watermark even when data generation produces no diff.
update_data.ymlonly commitsdata/**, andgit-auto-commit-actionwill not create achore: update translation datacommit when no matched files changed.poll_merged_fixes.ymluses that commit timestamp as the only checkpoint, so merged PRs stay in the search window until a future data diff occurs. Persist a separate successful-refresh marker or always update a marker file.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/poll_merged_fixes.yml around lines 49 - 60, The refresh checkpoint in the poll workflow must advance even when no translation data changes. Update the workflow around the COUNT/TX_COUNT search logic and its downstream refresh handling to persist a successful-refresh marker (or always modify a dedicated marker file), and use that marker as the next watermark instead of relying solely on the data commit timestamp.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 8-12: Change the shared concurrency policy from the default single
pending slot to queue all pending runs, using queue: max or an equivalent atomic
lock policy. Apply the same change to the concurrency blocks in
.github/workflows/poll_merged_fixes.yml lines 8-12 and
.github/workflows/update_data.yml lines 13-16, preserving the
translation-data-refresh-dev group and cancel-in-progress: false.
- Around line 24-27: Limit the marker lookup in the workflow to the checked-out
dev ref rather than all refs: update the git log command that computes
LAST_UPDATE to remove all-branch traversal and search only from HEAD, while
preserving the full fetch history required to find old markers.
---
Outside diff comments:
In @.github/workflows/poll_merged_fixes.yml:
- Around line 49-60: The refresh checkpoint in the poll workflow must advance
even when no translation data changes. Update the workflow around the
COUNT/TX_COUNT search logic and its downstream refresh handling to persist a
successful-refresh marker (or always modify a dedicated marker file), and use
that marker as the next watermark instead of relying solely on the data commit
timestamp.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 27e46e57-a7e7-4327-afc0-e23feff0b0e6
📒 Files selected for processing (2)
.github/workflows/poll_merged_fixes.yml.github/workflows/update_data.yml
| # Shared with update_data.yml so the poller and the refresh serialize on a | ||
| # server-side lock instead of racing the check-then-dispatch below. | ||
| concurrency: | ||
| group: translation-data-refresh-dev | ||
| cancel-in-progress: false |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -A3 '^concurrency:' \
.github/workflows/poll_merged_fixes.yml \
.github/workflows/update_data.yml
gh run list --workflow update_data.yml --branch dev \
--json status,event,createdAt --limit 100Repository: OpenVoiceOS/ovos-localize
Length of output: 8359
🌐 Web query:
GitHub Actions concurrency default cancel-new-workflows queue in-progress runs queue replacement one pending run
💡 Result:
In GitHub Actions, concurrency groups allow you to control how workflow runs execute. The behavior of pending runs depends on your configuration of the queue property [1][2]. Default Behavior: By default, GitHub Actions uses queue: single [1][2]. In this mode, a concurrency group can have at most one job or workflow run in progress and one pending run [1][3]. When a new workflow run is triggered: 1. If a run is already in progress, the new run enters a pending state [1][2]. 2. If another run is already pending, that existing pending run is canceled and replaced by the new one [1][2]. Configuring Queuing: To allow multiple runs to wait in line rather than being canceled, you can set the queue property to max [1][4]. - queue: max: Allows up to 100 jobs or workflow runs to be in a pending state within the same concurrency group [1][2]. Runs are processed sequentially as the in-progress slot becomes available [4]. - When the queue reaches its limit (100 runs), any additional runs triggered are canceled [1][2]. Important Considerations: - You cannot combine queue: max with cancel-in-progress: true, as they represent conflicting strategies for handling workflow runs; attempting this will result in a validation error [1][2]. - The cancel-in-progress property specifically governs whether the currently running job should be terminated when a new run enters the concurrency group [1][2]. If cancel-in-progress is set to true, the currently running job is stopped, while queue: single (the default) continues to handle the pending slot by replacing any existing waiting run [1][2].
Citations:
- 1: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- 3: https://docs.github.com/en/actions/concepts/workflows-and-actions/concurrency
- 4: https://github.blog/changelog/2026-05-07-github-actions-concurrency-groups-now-allow-larger-queues/
Preserve pending translation refresh runs in the shared concurrency group.
cancel-in-progress: false only protects the currently running run. Both workflows still use the default queue: single, so a new workflow run can cancel and replace a pending run in translation-data-refresh-dev, delaying update_data.yml. Use queue: max or a separate atomic lock policy in both .github/workflows/poll_merged_fixes.yml#L8-L12 and .github/workflows/update_data.yml#L13-L16.
📍 Affects 2 files
.github/workflows/poll_merged_fixes.yml#L8-L12(this comment).github/workflows/update_data.yml#L13-L16
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/poll_merged_fixes.yml around lines 8 - 12, Change the
shared concurrency policy from the default single pending slot to queue all
pending runs, using queue: max or an equivalent atomic lock policy. Apply the
same change to the concurrency blocks in .github/workflows/poll_merged_fixes.yml
lines 8-12 and .github/workflows/update_data.yml lines 13-16, preserving the
translation-data-refresh-dev group and cancel-in-progress: false.
- the watermark is now the last successful update_data.yml run; a refresh that changes no data makes no commit, and the old commit-timestamp watermark then re-matched the same merged PRs and re-dispatched a refresh every 30 minutes - the commit-marker fallback (first run / expired run history) searches only the checked-out dev history, not --all refs, so stale branches cannot supply the marker AI-Generated Change: - Model: claude-fable-5 - Intent: address CodeRabbit follow-up review on PR #213 - Impact: poller converges after no-op refreshes; marker from dev only - Skipped: concurrency 'queue: max' suggestion — no such key exists in GitHub Actions concurrency syntax (group/cancel-in-progress only); losing a superseded pending poll run is harmless for an idempotent 30-minute cron - Verified via: yaml parse + python3 -m pytest test/ -q
Adds
poll_merged_fixes.yml: when a locale-fix PR is merged, refresh the generated browse data so the SPA reflects it. Documents the polling + skill-submission flow in FAQ/docs.Scope: one workflow + its docs. No data, no unrelated files.
Split out of the previously-tangled PR stack (was leaking into #210/#211/#212).
Summary by CodeRabbit
New Features
#/issuesroute.Documentation