ci: deduplicate PR runs and serialize live E2E#1888
Conversation
📝 WalkthroughWalkthroughThe CI workflow now deduplicates pull request runs, preserves push and manual runs, and serializes the shared live E2E resource pool. Shell tests validate the workflow-level and job-level concurrency settings. ChangesCI concurrency controls
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@005870047779f652cf1fee3ecf80bf136a6f7a74🧩 Skill updatenpx skills add larksuite/cli#ci/serialize-live-e2e -y -g |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/ci.yml:
- Around line 13-15: Update the workflow concurrency configuration around the
top-level concurrency group so the e2e-live job is not governed by the
pull_request cancellation group. Exclude that job from the shared group or move
it into a separate workflow, while preserving cancellation for other pull
request jobs.
- Around line 321-325: Update the actionlint version or its configuration used
for the CI workflow so the valid concurrency.queue setting under the
lark-cli-e2e-live-shared-bot group is accepted. If upgrading is not feasible,
add a narrowly scoped ignore targeting this workflow’s concurrency.queue
diagnostic without suppressing unrelated actionlint errors.
🪄 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: 74d4493b-1852-4a03-85a5-e789c67e30ed
📒 Files selected for processing (2)
.github/workflows/ci.ymlscripts/ci-workflow.test.sh
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} | ||
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the workflow and any actionlint configuration.
git ls-files '.github/workflows/ci.yml' '.github/*actionlint*' '.github/**/actionlint*' 'actionlint*' '.editorconfig' '.github/**/*.yml' | sed 's#^`#FILE` #'
echo
echo '--- ci.yml outline ---'
ast-grep outline .github/workflows/ci.yml --view expanded || true
echo
echo '--- actionlint references ---'
rg -n --hidden --glob '.github/**' --glob '.github/workflows/**' --glob '.github/**.yml' 'actionlint|queue:|cancel-in-progress|concurrency:' . || trueRepository: larksuite/cli
Length of output: 1098
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the relevant sections of the workflow with line numbers.
sed -n '1,120p' .github/workflows/ci.yml | cat -n
echo
sed -n '300,360p' .github/workflows/ci.yml | cat -nRepository: larksuite/cli
Length of output: 8224
🌐 Web query:
GitHub Actions workflow-level concurrency cancel-in-progress cancels previous run including jobs job-level cancel-in-progress false cannot override workflow-level cancellation
💡 Result:
In GitHub Actions, the concurrency setting at the job level is independent of the workflow-level concurrency setting [1][2]. If you define concurrency at both levels using the same concurrency group name, the job-level configuration will override the workflow-level configuration for that specific job [2]. However, the workflow-level cancel-in-progress behavior remains active for any other parts of the workflow that are not overridden by a job-level concurrency configuration [1][2]. Regarding your specific scenario: 1. Workflow-level concurrency does not have a global mechanism that forces a "cancel-in-progress: true" behavior upon all child jobs if they attempt to define their own conflicting "cancel-in-progress: false" configuration [1][2]. 2. If a workflow has concurrency configured at the top level, it governs the workflow run as a whole [1][3]. If you specify a job-level concurrency group, that job will follow its own concurrency rules [1]. If the job-level group is the same as the workflow-level group, the job-level setting effectively takes over for that job [2]. 3. Because these settings operate on the defined concurrency group, a job-level configuration of "cancel-in-progress: false" will prevent that specific job from canceling other in-progress jobs within that group, even if the workflow-level setting for the same group is set to "cancel-in-progress: true" [1][2]. In summary, you cannot use a workflow-level setting to forcibly override a job-level "cancel-in-progress: false" configuration if that job is explicitly managing its own concurrency within that group [1][2]. The job-level definition acts as the final authority for that specific job's concurrency behavior [2].
Citations:
- 1: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
- 2: https://christosgalano.github.io/github-actions-concurrency/
- 3: https://docs.github.com/en/actions/concepts/workflows-and-actions/concurrency
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- actionlint files ---'
git ls-files | rg '(^|/)actionlint(\.ya?ml|\.json|\.toml|\.sh)?$|actionlint' || true
echo
echo '--- actionlint references anywhere ---'
rg -n --hidden -g '!*node_modules/*' -g '!*dist/*' -g '!*build/*' 'actionlint' . || true
echo
echo '--- queue usage anywhere ---'
rg -n --hidden -g '.github/**' 'queue:\s*max|queue:' . || trueRepository: larksuite/cli
Length of output: 294
Don't put e2e-live behind the cancelable workflow group. A new pull_request run cancels the previous workflow run, so this job can still be terminated even with cancel-in-progress: false. Move live E2E to a separate workflow or exclude it from the PR-cancelled concurrency group.
🤖 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/ci.yml around lines 13 - 15, Update the workflow
concurrency configuration around the top-level concurrency group so the e2e-live
job is not governed by the pull_request cancellation group. Exclude that job
from the shared group or move it into a separate workflow, while preserving
cancellation for other pull request jobs.
| # All live runs share one bot credential and remote resource pool. | ||
| concurrency: | ||
| group: lark-cli-e2e-live-shared-bot | ||
| cancel-in-progress: false | ||
| queue: max |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n 'actionlint|1\.7\.12' --glob '!**/.git/**' .
if command -v actionlint >/dev/null 2>&1; then
actionlint .github/workflows/ci.yml
fiRepository: larksuite/cli
Length of output: 151
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Locate workflow and actionlint config/pins.
rg -n --hidden --glob '!**/.git/**' 'actionlint|1\.7\.12|concurrency:|queue:' .github . || true
# Show the relevant workflow section with line numbers.
sed -n '300,340p' .github/workflows/ci.yml
# If the initial log file is still available, inspect it for the actual failure.
if [ -f /tmp/coderabbit-shell-logs/shell-output-a0VKx7 ]; then
echo '--- initial log ---'
cat /tmp/coderabbit-shell-logs/shell-output-a0VKx7
fiRepository: larksuite/cli
Length of output: 2443
🌐 Web query:
actionlint 1.7.12 concurrency.queue max support release notes
💡 Result:
As of July 14, 2026, actionlint version 1.7.12 does not provide support for the concurrency.queue property [1]. The concurrency.queue feature was introduced in GitHub Actions to allow pending workflow runs to queue instead of being cancelled, using values such as "max" or "single" [2][3]. While this feature is recognized by GitHub's own language services and other tooling [4][3], actionlint version 1.7.12 explicitly lacks knowledge of the "queue" key [1]. Consequently, workflows using this configuration will trigger an "Unknown Property" or "unexpected key" error when linted with actionlint 1.7.12 [5][1][6]. Support for this feature in actionlint is tracked in issue #657 and has been addressed in subsequent pull requests (such as #661) which were developed after the release of version 1.7.12 [2][5][7]. Users currently using actionlint 1.7.12 have been required to implement ignore patterns to suppress these false-positive linting errors [1][6].
Citations:
- 1: pulumi/ci-mgmt@8433bb2
- 2: concurrency: Add support for
queuekey rhysd/actionlint#654 - 3: Add concurrency queue support actions/languageservices#355
- 4: Add
concurrency.queuesupport and queue-aware conclusion job defaults github/gh-aw#31764 - 5: Actionlint does not know about
queue:key for concurrency rhysd/actionlint#657 - 6: Fix
gh aw lintfalse positives breakingmake lint-lockgithub/gh-aw#31916 - 7: feat: support concurrency queue and job.workflow_* contexts rhysd/actionlint#661
🌐 Web query:
actionlint queue support version 1.7.12 GitHub Actions concurrency.queue release notes
💡 Result:
Actionlint version 1.7.12 does not include support for the GitHub Actions concurrency.queue configuration [1][2]. While GitHub Actions introduced the concurrency.queue key to allow workflow runs to queue instead of being cancelled [3], actionlint version 1.7.12 (released March 30, 2026) does not recognize this key [1][2]. Consequently, using concurrency.queue in a workflow file at this version will result in a linting error (specifically, an unexpected key error for the concurrency section) [4]. Support for this feature was addressed in subsequent development through pull requests (such as #654 and #661) [3][5], but it was not present in the 1.7.12 release [1].
Citations:
- 1: https://github.com/rhysd/actionlint/releases/tag/v1.7.12
- 2: https://github.com/rhysd/actionlint/blob/main/CHANGELOG.md
- 3: concurrency: Add support for
queuekey rhysd/actionlint#654 - 4: Fix
gh aw lintfalse positives breakingmake lint-lockgithub/gh-aw#31916 - 5: feat: support concurrency queue and job.workflow_* contexts rhysd/actionlint#661
Align the actionlint pin with concurrency.queue. queue: max is valid GitHub Actions syntax, but actionlint 1.7.12 still flags concurrency.queue as an unknown key. Update the pin/configuration or add a narrow ignore for this workflow.
🧰 Tools
🪛 actionlint (1.7.12)
[error] 325-325: unexpected key "queue" for "concurrency" section. expected one of "cancel-in-progress", "group"
(syntax-check)
🤖 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/ci.yml around lines 321 - 325, Update the actionlint
version or its configuration used for the CI workflow so the valid
concurrency.queue setting under the lark-cli-e2e-live-shared-bot group is
accepted. If upgrading is not feasible, add a narrowly scoped ignore targeting
this workflow’s concurrency.queue diagnostic without suppressing unrelated
actionlint errors.
Source: Linters/SAST tools
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1888 +/- ##
=======================================
Coverage 74.66% 74.66%
=======================================
Files 878 878
Lines 91764 91764
=======================================
Hits 68520 68520
Misses 17930 17930
Partials 5314 5314 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Controlled runtime validation completed on the PR head:
This proves the scheduler behavior and one successful serialized execution. It does not yet constitute a statistically significant before/after failure-rate comparison; that requires post-merge observation across multiple runs. |
Summary
A single pull request head can currently start overlapping full CI runs from
synchronizeandeditedevents, while every live E2E run shares the same bot credentials and remote resource pool. This PR keeps only the newest full CI run for each pull request and serializes live E2E across the repository, reducing duplicate API traffic, rate limits, and resource contention. The trade-off is that live E2E may queue; GitHub Actions retains up to 100 pending runs, and superseded runs for the same pull request are intentionally cancelled.Changes
.github/workflows/ci.ymlwhile preserving independent push and manual runs.e2e-livejob without changing existingeditedevent coverage or required checks.scripts/ci-workflow.test.shto pin run deduplication, live serialization, non-cancellation, and queue retention.Test Plan
bash scripts/ci-workflow.test.shmake script-testgo vet ./...go mod tidyproduced nogo.modorgo.sumchangesqueue: maxmake unit-testnot repeated locally: this PR changes only workflow and shell contract files; the exact base commit passedunit-test,lint, andscript-teston main CIRelated Issues
N/A
Summary by CodeRabbit