This is an automated email from the ASF dual-hosted git repository.

mfordjody pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git


The following commit(s) were added to refs/heads/master by this push:
     new 72ab0d54 Add /lgtm merge docs and automatic project labels (#973)
72ab0d54 is described below

commit 72ab0d547fcc3b353bb396a50c1e2d4fd5c99405
Author: mfordjody <[email protected]>
AuthorDate: Mon Jul 20 14:34:27 2026 +0800

    Add /lgtm merge docs and automatic project labels (#973)
    
    * Document lgtm merge authorization
    
    * Add automatic project labels
    
    * Use native auto merge for lgtm
    
    * Reset lgtm label after new commits
---
 .asf.yaml                         |   2 +
 .github/labeler.yml               | 128 ++++++++++++++++++++++++++++++++++++++
 .github/pull_request_template.md  |   3 +
 .github/workflows/ci.yml          |   2 +-
 .github/workflows/commands.yml    | 124 +++---------------------------------
 .github/workflows/labels.yml      |  40 ++++++++++++
 .github/workflows/review-gate.yml |  14 +++++
 7 files changed, 197 insertions(+), 116 deletions(-)

diff --git a/.asf.yaml b/.asf.yaml
index 32f23cb0..9368bdf1 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -21,6 +21,8 @@ notifications:
 github:
   homepage: "https://kdubbo.github.io";
   description: "Build a native mesh using gRPC and xDS"
+  pull_requests:
+    allow_auto_merge: true
   labels:
     - dubbo
     - consul
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 00000000..e91a89a2
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,128 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+bug:
+  - head-branch:
+      - '^bug/'
+      - '^bugfix/'
+      - '^fix/'
+
+feature:
+  - head-branch:
+      - '^feat/'
+      - '^feature/'
+
+dependencies:
+  - any:
+      - head-branch:
+          - '^dependabot/'
+      - changed-files:
+          - any-glob-to-any-file:
+              - '**/go.mod'
+              - '**/go.sum'
+              - '.github/dependabot.yml'
+
+github_actions:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '.github/actions/**'
+          - '.github/workflows/**'
+
+go:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '**/*.go'
+          - '**/go.mod'
+          - '**/go.sum'
+
+python:
+  - changed-files:
+      - any-glob-to-any-file: '**/*.py'
+
+cni:
+  - changed-files:
+      - any-glob-to-any-file:
+          - 'cni/**'
+          - 'pkg/cni/**'
+
+dubboctl:
+  - changed-files:
+      - any-glob-to-any-file:
+          - 'cli/**'
+          - 'dubboctl/**'
+
+dubbod:
+  - changed-files:
+      - any-glob-to-any-file: 'dubbod/**'
+
+operator:
+  - changed-files:
+      - any-glob-to-any-file: 'operator/**'
+
+helm:
+  - changed-files:
+      - any-glob-to-any-file: 'manifests/charts/**'
+
+documentation:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '**/*.md'
+          - 'site/**'
+
+testing:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '**/*_test.go'
+          - 'tests/**'
+
+performance:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '**/*benchmark*'
+          - '**/benchmark/**'
+          - '.github/workflows/benchmark.yml'
+
+security:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '**/security/**'
+          - 'tools/govulncheck.py'
+          - '.github/workflows/security.yml'
+
+networking:
+  - changed-files:
+      - any-glob-to-any-file:
+          - 'dubbod/discovery/pkg/networking/**'
+          - 'pkg/adsc/**'
+          - 'pkg/xds/**'
+
+samples:
+  - changed-files:
+      - any-glob-to-any-file: 'samples/**'
+
+build:
+  - changed-files:
+      - any-glob-to-any-file:
+          - 'Makefile'
+          - 'tools/make/**'
+          - 'tools/ci/**'
+          - '**/Dockerfile*'
+          - '**/dockerfile*'
+
+release:
+  - changed-files:
+      - any-glob-to-any-file:
+          - '.github/workflows/release.yaml'
+          - 'tools/release/**'
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 4de780b5..8ca27b42 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -31,6 +31,9 @@ limitations under the License.
 
 <!-- List exact commands, environments, and results. Add screenshots or 
cluster evidence when behavior is user-visible. -->
 
+> Merge authorization: after required checks pass, only an `/lgtm` comment
+> from `@mfordjody` authorizes the automatic squash merge.
+
 ## Compatibility and rollout
 
 <!-- Describe upgrade, downgrade, API, configuration, performance, security, 
and rollback implications. Write "None" when not applicable. -->
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0af3edaf..c5539223 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-name: Dubbo Kubernetes CI
+name: CI
 
 on:
   push:
diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml
index d5db43db..8c45f579 100644
--- a/.github/workflows/commands.yml
+++ b/.github/workflows/commands.yml
@@ -20,8 +20,8 @@
 #   /unassign [@user ...]  remove assignees
 #   /lgtm                  (PR only) only an approver in the root OWNERS file
 #                          can record Maintainer Approval. The PR is squash
-#                          merged immediately when CI is green, or by the
-#                          workflow-run handler when CI finishes.
+#                          merged immediately when CI is green, or queued with
+#                          GitHub Auto-merge while required checks finish.
 #   /lgtm cancel           remove the `lgtm` label and reset approval
 #   /close                 close the issue/PR (author or write access)
 #   /reopen                reopen the issue/PR (author or write access)
@@ -41,20 +41,8 @@ on:
   issue_comment:
     types:
       - created
-  workflow_run:
-    workflows:
-      - Dubbo Kubernetes CI
-    types:
-      - completed
-  workflow_dispatch:
-    inputs:
-      pr_number:
-        description: Pull request to reconsider for an approved merge
-        required: true
-        type: number
 
 permissions:
-  checks: read
   contents: write
   issues: write
   pull-requests: write
@@ -273,14 +261,13 @@ jobs:
                   await reply(`Merged on behalf of @${commenter} via 
\`/lgtm\`.`);
                 } catch (mergeErr) {
                   core.info(`Merge deferred until CI finishes: 
${mergeErr.message}`);
-                  await github.rest.actions.createWorkflowDispatch({
-                    owner,
-                    repo,
-                    workflow_id: 'commands.yml',
-                    ref: pr.base.ref,
-                    inputs: {pr_number: String(pr.number)},
-                  });
-                  await reply(`\`/lgtm\` recorded by @${commenter}. The PR 
will be squash merged automatically after required CI passes.`);
+                  if (!pr.auto_merge) {
+                    await github.graphql(
+                      `mutation($id: ID!) { enablePullRequestAutoMerge(input: 
{pullRequestId: $id, mergeMethod: SQUASH}) { pullRequest { number } } }`,
+                      {id: pr.node_id},
+                    );
+                  }
+                  await reply(`\`/lgtm\` recorded by @${commenter}. GitHub 
Auto-merge will squash merge the PR after required CI passes.`);
                 }
                 return;
               }
@@ -329,96 +316,3 @@ jobs:
                 return;
               }
             }
-
-  merge-approved:
-    name: Merge Approved Pull Request
-    runs-on: ubuntu-latest
-    timeout-minutes: 5
-    if: |
-      github.repository == 'apache/dubbo-kubernetes' &&
-      (github.event_name == 'workflow_dispatch' ||
-       (github.event_name == 'workflow_run' &&
-        github.event.workflow_run.event == 'pull_request' &&
-        github.event.workflow_run.conclusion == 'success'))
-    steps:
-      - name: Merge current-head pull request approved via /lgtm
-        uses: actions/github-script@v7
-        with:
-          script: |
-            const {owner, repo} = context.repo;
-            let headSha;
-            let candidates;
-            if (context.eventName === 'workflow_dispatch') {
-              const pullNumber = Number(context.payload.inputs.pr_number);
-              const {data: pr} = await github.rest.pulls.get({owner, repo, 
pull_number: pullNumber});
-              headSha = pr.head.sha;
-              candidates = [pr];
-            } else {
-              headSha = context.payload.workflow_run.head_sha;
-              const {data: associated} = await 
github.rest.repos.listPullRequestsAssociatedWithCommit({
-                owner,
-                repo,
-                commit_sha: headSha,
-              });
-              candidates = associated.filter((pr) =>
-                pr.state === 'open' &&
-                pr.head.sha === headSha &&
-                ['master', 'main'].includes(pr.base.ref),
-              );
-            }
-
-            for (const candidate of candidates) {
-              const {data: pr} = await github.rest.pulls.get({
-                owner,
-                repo,
-                pull_number: candidate.number,
-              });
-              const labels = new Set(pr.labels.map((label) => label.name));
-              if (pr.state !== 'open' || pr.head.sha !== headSha ||
-                  !['master', 'main'].includes(pr.base.ref) || 
!labels.has('lgtm')) {
-                core.info(`#${pr.number}: missing lgtm label`);
-                continue;
-              }
-
-              const {data: combined} = await 
github.rest.repos.getCombinedStatusForRef({
-                owner,
-                repo,
-                ref: headSha,
-              });
-              const approval = combined.statuses.find((status) =>
-                status.context === 'Maintainer Approval Gate',
-              );
-              if (approval?.state !== 'success') {
-                core.info(`#${pr.number}: maintainer approval is 
${approval?.state || 'missing'}`);
-                continue;
-              }
-
-              const {data: checks} = await github.rest.checks.listForRef({
-                owner,
-                repo,
-                ref: headSha,
-                per_page: 100,
-              });
-              const requiredCI = checks.check_runs.find((check) =>
-                check.name === 'CI Required' && check.app?.slug === 
'github-actions',
-              );
-              if (requiredCI?.conclusion !== 'success') {
-                core.info(`#${pr.number}: CI Required is 
${requiredCI?.conclusion || requiredCI?.status || 'missing'}`);
-                continue;
-              }
-
-              try {
-                const {data: result} = await github.rest.pulls.merge({
-                  owner,
-                  repo,
-                  pull_number: pr.number,
-                  merge_method: 'squash',
-                  sha: headSha,
-                });
-                if (!result.merged) {
-                  core.setFailed(`#${pr.number}: ${result.message}`);
-                }
-              } catch (error) {
-                core.setFailed(`#${pr.number}: ${error.message}`);
-              }
-            }
diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml
new file mode 100644
index 00000000..9de471b0
--- /dev/null
+++ b/.github/workflows/labels.yml
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: Labels
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - reopened
+      - synchronize
+      - ready_for_review
+
+permissions:
+  contents: read
+  pull-requests: write
+
+jobs:
+  changed-files:
+    name: Apply PR Labels
+    runs-on: ubuntu-latest
+    timeout-minutes: 5
+    if: github.repository == 'apache/dubbo-kubernetes'
+    steps:
+      - name: Apply labels from changed paths
+        uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
+        with:
+          repo-token: ${{ github.token }}
diff --git a/.github/workflows/review-gate.yml 
b/.github/workflows/review-gate.yml
index 855c8bab..e18c2eec 100644
--- a/.github/workflows/review-gate.yml
+++ b/.github/workflows/review-gate.yml
@@ -34,6 +34,7 @@ on:
 
 permissions:
   contents: read
+  issues: write
   pull-requests: read
   statuses: write
 
@@ -81,6 +82,19 @@ jobs:
               return;
             }
 
+            if (context.eventName === 'pull_request_target' && 
context.payload.action === 'synchronize') {
+              try {
+                await github.rest.issues.removeLabel({
+                  owner,
+                  repo,
+                  issue_number: pr.number,
+                  name: 'lgtm',
+                });
+              } catch (error) {
+                if (error.status !== 404) throw error;
+              }
+            }
+
             await publish(
               pr.head.sha,
               'pending',

Reply via email to