This is an automated email from the ASF dual-hosted git repository. hello-stephen pushed a commit to branch agent/fix-comment-trigger-queue in repository https://gitbox.apache.org/repos/asf/doris.git
commit 0bd2d275ec2eb5a8ea920213c3ecd63a5cb0693f Author: lidongyang <[email protected]> AuthorDate: Tue Jul 28 22:29:30 2026 +0800 [fix](ci) deduplicate comment-triggered TeamCity builds --- .github/workflows/comment-to-trigger-teamcity.yml | 50 +++++++++++++++- regression-test/pipeline/common/teamcity-utils.sh | 73 +++++++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/.github/workflows/comment-to-trigger-teamcity.yml b/.github/workflows/comment-to-trigger-teamcity.yml index 6227490e559..c6bac078b9f 100644 --- a/.github/workflows/comment-to-trigger-teamcity.yml +++ b/.github/workflows/comment-to-trigger-teamcity.yml @@ -29,8 +29,54 @@ permissions: jobs: check-comment-if-need-to-trigger-teamcity: - # This job only runs for pull request comments, and comment body contains 'run' - if: ${{ github.event.issue.pull_request && (contains(github.event.comment.body, 'run') || contains(github.event.comment.body, 'skip buildall') || contains(github.event.comment.body, 'skip check_coverage')) }} + # Keep this server-side filter aligned with the supported commands parsed below. + # A generic "run" match also catches performance reports such as "Total hot run time". + if: >- + ${{ + github.event.issue.pull_request && + ( + contains(github.event.comment.body, 'run buildall') || + contains(github.event.comment.body, 'run compile') || + contains(github.event.comment.body, 'run beut') || + contains(github.event.comment.body, 'run feut') || + contains(github.event.comment.body, 'run cloudut') || + contains(github.event.comment.body, 'run p0') || + contains(github.event.comment.body, 'run p1') || + contains(github.event.comment.body, 'run external') || + contains(github.event.comment.body, 'run cloud_p0') || + contains(github.event.comment.body, 'run cloud_p1') || + contains(github.event.comment.body, 'run vault_p0') || + contains(github.event.comment.body, 'run nonConcurrent') || + contains(github.event.comment.body, 'run check_coverage') || + contains(github.event.comment.body, 'run performance') || + contains(github.event.comment.body, 'skip buildall') || + contains(github.event.comment.body, 'skip check_coverage') + ) + }} + + # Serialize duplicate commands for one PR. The next run then sees the build + # queued by the previous run and can safely skip an identical PR revision. + concurrency: + group: >- + comment-to-trigger-teamcity-${{ github.event.issue.number }}-${{ + contains(github.event.comment.body, 'run buildall') && 'buildall' || + contains(github.event.comment.body, 'run compile') && 'compile' || + contains(github.event.comment.body, 'run beut') && 'beut' || + contains(github.event.comment.body, 'run feut') && 'feut' || + contains(github.event.comment.body, 'run cloudut') && 'cloudut' || + contains(github.event.comment.body, 'run p0') && 'p0' || + contains(github.event.comment.body, 'run p1') && 'p1' || + contains(github.event.comment.body, 'run external') && 'external' || + contains(github.event.comment.body, 'run cloud_p0') && 'cloud-p0' || + contains(github.event.comment.body, 'run cloud_p1') && 'cloud-p1' || + contains(github.event.comment.body, 'run vault_p0') && 'vault-p0' || + contains(github.event.comment.body, 'run nonConcurrent') && 'non-concurrent' || + contains(github.event.comment.body, 'run check_coverage') && 'check-coverage' || + contains(github.event.comment.body, 'run performance') && 'performance' || + contains(github.event.comment.body, 'skip buildall') && 'skip-buildall' || + 'skip-check-coverage' + }} + cancel-in-progress: false runs-on: ubuntu-latest env: diff --git a/regression-test/pipeline/common/teamcity-utils.sh b/regression-test/pipeline/common/teamcity-utils.sh index c9b61c6fb54..2ac5e00d726 100644 --- a/regression-test/pipeline/common/teamcity-utils.sh +++ b/regression-test/pipeline/common/teamcity-utils.sh @@ -159,6 +159,64 @@ get_queue_build_of_pr() { } # get_queue_build_of_pr "$1" "$2" +get_active_builds_of_revision() { + # Return active build IDs for the same PR, pipeline, and revision. + # Return 0 when a duplicate exists, 1 when none exists, and 2 when lookup fails. + local PULL_REQUEST_NUM="${PULL_REQUEST_NUM:-$1}" + local COMMENT_TRIGGER_TYPE="${COMMENT_TRIGGER_TYPE:-$2}" + local COMMIT_ID_FROM_TRIGGER="${COMMIT_ID_FROM_TRIGGER:-$3}" + if [[ -z "${PULL_REQUEST_NUM}" || + -z "${COMMENT_TRIGGER_TYPE}" || + -z "${COMMIT_ID_FROM_TRIGGER}" ]]; then + echo "Usage: get_active_builds_of_revision PULL_REQUEST_NUM COMMENT_TRIGGER_TYPE COMMIT_ID_FROM_TRIGGER" >&2 + return 2 + fi + + local PIPELINE="${comment_to_pipeline[${COMMENT_TRIGGER_TYPE}]}" + local teamcity_rest_url="http://43.132.222.7:8111/app/rest" + local queue_response + local running_response + if ! queue_response=$( + curl -sSf -X GET \ + -u OneMoreChance:OneMoreChance \ + -H "Accept: application/json" \ + "${teamcity_rest_url}/buildQueue?locator=buildType:(id:${PIPELINE})&fields=build(id,branchName,revisions(revision(version)))" + ); then + echo "WARNING: failed to get queued builds for duplicate check" >&2 + return 2 + fi + if ! running_response=$( + curl -sSf -X GET \ + -u OneMoreChance:OneMoreChance \ + -H "Accept: application/json" \ + "${teamcity_rest_url}/builds?locator=buildType:(id:${PIPELINE}),branch:(name:pull/${PULL_REQUEST_NUM}),running:true&fields=build(id,branchName,revisions(revision(version)))" + ); then + echo "WARNING: failed to get running builds for duplicate check" >&2 + return 2 + fi + + local build_ids + if ! build_ids=$( + printf '%s\n%s\n' "${queue_response}" "${running_response}" | + jq -s -r \ + --arg branch "pull/${PULL_REQUEST_NUM}" \ + --arg revision "${COMMIT_ID_FROM_TRIGGER}" \ + '.[] | .build[]? | + select(.branchName == $branch and .revisions.revision[0].version == $revision) | + .id' + ); then + echo "WARNING: failed to parse active builds for duplicate check" >&2 + return 2 + fi + + if [[ -n "${build_ids}" ]]; then + echo "${build_ids}" + return 0 + fi + return 1 +} +# get_active_builds_of_revision "$1" "$2" "$3" + cancel_running_build() { local PULL_REQUEST_NUM="${PULL_REQUEST_NUM:-$1}" local COMMENT_TRIGGER_TYPE="${COMMENT_TRIGGER_TYPE:-$2}" @@ -300,6 +358,21 @@ trigger_or_skip_build() { fi if [[ "${FILE_CHANGED:-"true"}" == "true" ]]; then + local duplicate_build_ids + local duplicate_lookup_status=0 + duplicate_build_ids=$( + get_active_builds_of_revision \ + "${PULL_REQUEST_NUM}" \ + "${COMMENT_TRIGGER_TYPE}" \ + "${COMMIT_ID_FROM_TRIGGER}" + ) || duplicate_lookup_status=$? + if [[ ${duplicate_lookup_status} -eq 0 ]]; then + echo "INFO: active build(s) ${duplicate_build_ids//$'\n'/,} already exist for PR ${PULL_REQUEST_NUM}, pipeline ${COMMENT_TRIGGER_TYPE}, revision ${COMMIT_ID_FROM_TRIGGER}; skip duplicate trigger" + return 0 + elif [[ ${duplicate_lookup_status} -ne 1 ]]; then + echo "WARNING: duplicate lookup failed for PR ${PULL_REQUEST_NUM}, pipeline ${COMMENT_TRIGGER_TYPE}; continue with the existing trigger flow" + fi + cancel_running_build "${PULL_REQUEST_NUM}" "${COMMENT_TRIGGER_TYPE}" cancel_queue_build "${PULL_REQUEST_NUM}" "${COMMENT_TRIGGER_TYPE}" trigger_build "${PULL_REQUEST_NUM}" "${COMMIT_ID_FROM_TRIGGER}" "${COMMENT_TRIGGER_TYPE}" "${COMMENT_REPEAT_TIMES}" --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
