Skip to content

ci: deduplicate PR runs and serialize live E2E#1888

Open
luozhixiong01 wants to merge 1 commit into
mainfrom
ci/serialize-live-e2e
Open

ci: deduplicate PR runs and serialize live E2E#1888
luozhixiong01 wants to merge 1 commit into
mainfrom
ci/serialize-live-e2e

Conversation

@luozhixiong01

@luozhixiong01 luozhixiong01 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

A single pull request head can currently start overlapping full CI runs from synchronize and edited events, 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

  • Add pull-request-scoped workflow concurrency in .github/workflows/ci.yml while preserving independent push and manual runs.
  • Add a repository-wide FIFO queue for the shared e2e-live job without changing existing edited event coverage or required checks.
  • Extend scripts/ci-workflow.test.sh to pin run deduplication, live serialization, non-cancellation, and queue retention.

Test Plan

  • bash scripts/ci-workflow.test.sh
  • make script-test
  • go vet ./...
  • go mod tidy produced no go.mod or go.sum changes
  • Negative contract checks fail when workflow-level concurrency, live concurrency, or queue retention is removed
  • GitHub Actions documentation confirms workflow/job concurrency, conditional cancellation, fallback run IDs, and queue: max
  • make unit-test not repeated locally: this PR changes only workflow and shell contract files; the exact base commit passed unit-test, lint, and script-test on main CI

Related Issues

N/A

Summary by CodeRabbit

  • CI Improvements
    • Prevented duplicate pull request workflow runs from executing simultaneously.
    • Automatically cancels outdated pull request runs while preserving push and manual runs.
    • Queues live end-to-end test runs to ensure shared testing resources are used safely.
    • Added validation to maintain these workflow execution and queuing behaviors.

@github-actions github-actions Bot added the size/M Single-domain feat or fix with limited business impact label Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The 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.

Changes

CI concurrency controls

Layer / File(s) Summary
Workflow concurrency policies
.github/workflows/ci.yml
Adds workflow-level concurrency for run grouping and pull-request cancellation, plus non-cancelling queueing for the shared e2e-live resource pool.
Concurrency conformance checks
scripts/ci-workflow.test.sh
Parses and validates workflow-level and e2e-live concurrency settings, including grouping, cancellation, and queueing behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: yxzhaao, hanshaoshuai-k, evandance

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise, specific, and accurately summarizes the main change: deduplicating PR runs and serializing live E2E.
Description check ✅ Passed The description follows the template and includes complete Summary, Changes, Test Plan, and Related Issues sections.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/serialize-live-e2e

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@005870047779f652cf1fee3ecf80bf136a6f7a74

🧩 Skill update

npx skills add larksuite/cli#ci/serialize-live-e2e -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between ac2508d and 0058700.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • scripts/ci-workflow.test.sh

Comment thread .github/workflows/ci.yml
Comment on lines +13 to +15
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:' . || true

Repository: 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 -n

Repository: 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:


🏁 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:' . || true

Repository: 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.

Comment thread .github/workflows/ci.yml
Comment on lines +321 to +325
# 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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
fi

Repository: 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
fi

Repository: 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:


🌐 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:


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

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.66%. Comparing base (ac2508d) to head (0058700).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@luozhixiong01

Copy link
Copy Markdown
Collaborator Author

Controlled runtime validation completed on the PR head:

  • PR-run deduplication: three rapid pull_request.edited events produced runs 29332388260, 29332389362, and 29332391514. The two superseded runs were cancelled and only the latest run continued. An earlier CodeRabbit body edit also cancelled the original run as intended. The PR body was restored unchanged after the check.
  • Live E2E serialization: while PR run 29332391514 / e2e-live was in_progress, an independent manual run 29332433625 / e2e-live remained pending in the shared concurrency group. No overlap occurred.
  • No execution regression: the retained live E2E job completed successfully. The extra manual run was cancelled immediately after the queue state was captured.

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.

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

Labels

size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant