diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 57cae2979696..0c2decab5b04 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,3 +8,8 @@ /bindings/nodejs/ @suyanhanx /bindings/python/ @messense @Zheaoli /bindings/ruby/ @PsiACE + +# This is a place holder for all committers who what to join the review of not owned code. +# +# More details could be found at +COMMITTERS_PLACEHOLDER @Xuanwo @Ji-Xinyou @morristai @dqhl76 @ClSlaid @Young-Flash @G-XD @oowl @silver-ymz diff --git a/.github/scripts/assign_reviewers.js b/.github/scripts/assign_reviewers.js new file mode 100644 index 000000000000..15089ba90568 --- /dev/null +++ b/.github/scripts/assign_reviewers.js @@ -0,0 +1,67 @@ +/* + * 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. + */ + +async function run(github, context, core, fs) { + try { + // Pick two reviewers from list + const numberOfReviewers = 2; + const repo = context.repo; + + // Read CODEOWNERS + const codeownersContent = fs.readFileSync('.github/CODEOWNERS', 'utf8'); + const lines = codeownersContent.split('\n'); + + // Search COMMITTERS + const placeholderLine = lines.find(line => line.startsWith('COMMITTERS_PLACEHOLDER')); + if (!placeholderLine) { + throw new Error("No COMMITTERS found in CODEOWNERS"); + } + + // Extract committers from placeholder line + const committers = placeholderLine.match(/@[\w-]+/g).map(u => u.substring(1)); + if (committers.length === 0) { + throw new Error("No committer found in COMMITTERS_PLACEHOLDER"); + } + + // Pick reviewers + const selectedReviewers = []; + while (selectedReviewers.length < numberOfReviewers && committers.length > 0) { + const randomIndex = Math.floor(Math.random() * committers.length); + selectedReviewers.push(committers.splice(randomIndex, 1)[0]); + } + + // Assign reviewers Pull Request + if (context.payload.pull_request) { + const pullRequestNumber = context.payload.pull_request.number; + await github.rest.pulls.requestReviewers({ + owner: repo.owner, + repo: repo.repo, + pull_number: pullRequestNumber, + reviewers: selectedReviewers, + }); + console.log(`Assigned reviewers: ${selectedReviewers.join(', ')}`); + } + } catch (error) { + core.setFailed(`Action failed with error: ${error}`); + } +} + +module.exports = ({github, context, core, fs}) => { + return run(github, context, core, fs) +} diff --git a/.github/workflows/ci_review.yml b/.github/workflows/ci_review.yml new file mode 100644 index 000000000000..8f31a0a6a917 --- /dev/null +++ b/.github/workflows/ci_review.yml @@ -0,0 +1,38 @@ +# 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: Assign Reviewers + +on: + pull_request_target: + types: [opened, reopened] + +jobs: + assign-reviewers: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Assign Reviewers + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const script = require('.github/scripts/assign_reviewers.js') + script({github, context, core, fs}) + github-token: ${{ secrets.GITHUB_TOKEN }}