Copilot commented on code in PR #4885: URL: https://github.com/apache/texera/pull/4885#discussion_r3179211406
########## .github/workflows/pr-assignment.yml: ########## @@ -0,0 +1,205 @@ +# 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: PR assignment +on: + pull_request_target: + types: [opened, edited, closed] + +permissions: + issues: write + pull-requests: write + +jobs: + # All three behaviors live as steps under one job so the PR Checks + # tab shows a single entry per event instead of two-or-three skipped + # siblings. Step-level if-guards keep the actual work scoped. + pr-assignment: + runs-on: ubuntu-latest + steps: + - name: Self-assign PR author to the PR + if: >- + github.event.action == 'opened' + && github.event.pull_request.user.type != 'Bot' + && github.event.pull_request.assignees[0] == null + uses: actions/github-script@v8 + with: + script: | + const pr = context.payload.pull_request; + core.info(`PR #${pr.number} opened by ${pr.user.login}; self-assigning.`); + try { + await github.rest.issues.addAssignees({ + ...context.repo, + issue_number: pr.number, + assignees: [pr.user.login], + }); + core.info(`Assigned ${pr.user.login} to PR #${pr.number}`); + } catch (e) { + core.warning(`Self-assign on PR #${pr.number} failed: ${e.message}`); + } + + - name: Sync PR opener as assignee on linked issues + # Mirror the PR opener as an assignee on each same-repo issue listed + # in closingIssuesReferences. On body edits, also drop the opener + # from issues whose closing keyword was removed. Other manual + # assignees are never touched here, so this never fights with the + # merge-time credit step or human triage decisions. + if: >- + contains(fromJSON('["opened","edited"]'), github.event.action) + && github.event.pull_request.state == 'open' + && github.event.pull_request.user.type != 'Bot' + uses: actions/github-script@v8 Review Comment: The workflow assigns the PR opener to linked issues on `opened`/`edited`, but there’s no corresponding cleanup when a PR is closed without being merged. That can leave the opener assigned (and `triage` removed) even though the PR was abandoned. If the intent is to sync assignees with *active* PR closing refs, consider handling `closed` events where `merged == false` by removing the opener from same-repo closing issues. ########## .github/workflows/pr-assignment.yml: ########## @@ -0,0 +1,205 @@ +# 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: PR assignment +on: + pull_request_target: + types: [opened, edited, closed] + +permissions: + issues: write + pull-requests: write + +jobs: + # All three behaviors live as steps under one job so the PR Checks + # tab shows a single entry per event instead of two-or-three skipped + # siblings. Step-level if-guards keep the actual work scoped. + pr-assignment: + runs-on: ubuntu-latest + steps: + - name: Self-assign PR author to the PR + if: >- + github.event.action == 'opened' + && github.event.pull_request.user.type != 'Bot' + && github.event.pull_request.assignees[0] == null + uses: actions/github-script@v8 + with: + script: | + const pr = context.payload.pull_request; + core.info(`PR #${pr.number} opened by ${pr.user.login}; self-assigning.`); + try { + await github.rest.issues.addAssignees({ + ...context.repo, + issue_number: pr.number, + assignees: [pr.user.login], + }); + core.info(`Assigned ${pr.user.login} to PR #${pr.number}`); + } catch (e) { + core.warning(`Self-assign on PR #${pr.number} failed: ${e.message}`); + } + + - name: Sync PR opener as assignee on linked issues + # Mirror the PR opener as an assignee on each same-repo issue listed + # in closingIssuesReferences. On body edits, also drop the opener + # from issues whose closing keyword was removed. Other manual + # assignees are never touched here, so this never fights with the + # merge-time credit step or human triage decisions. + if: >- + contains(fromJSON('["opened","edited"]'), github.event.action) + && github.event.pull_request.state == 'open' + && github.event.pull_request.user.type != 'Bot' + uses: actions/github-script@v8 + with: + script: | + const { owner, repo } = context.repo; + const pr = context.payload.pull_request; + const opener = pr.user.login; + core.info(`Event ${context.payload.action} on PR #${pr.number} by ${opener}; syncing closing-issue assignees.`); + + const { repository: { pullRequest: prq } } = await github.graphql(` + query($owner: String!, $repo: String!, $pr: Int!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: $pr) { + closingIssuesReferences(first: 50) { + nodes { number repository { nameWithOwner } } + } + } + } + }`, { owner, repo, pr: pr.number }); + + const sameRepo = `${owner}/${repo}`; + const allRefs = prq.closingIssuesReferences.nodes; + const linked = allRefs + .filter((n) => n.repository.nameWithOwner === sameRepo) + .map((n) => n.number); + const crossRepo = allRefs.filter((n) => n.repository.nameWithOwner !== sameRepo); + core.info(`Found ${linked.length} same-repo closing reference(s): ${linked.join(', ') || '(none)'}`); + if (crossRepo.length) { + core.info(`Skipping ${crossRepo.length} cross-repo reference(s): ${crossRepo.map((n) => `${n.repository.nameWithOwner}#${n.number}`).join(', ')}`); + } + + for (const issue_number of linked) { + try { + await github.rest.issues.addAssignees({ + owner, repo, issue_number, assignees: [opener], + }); + core.info(`Assigned ${opener} to issue #${issue_number}`); + } catch (e) { + core.warning(`addAssignees on #${issue_number} failed: ${e.message}`); + } + } + + // On body edit, find closing refs that disappeared from the body + // and remove the opener from those issues. closingIssuesReferences + // is a snapshot of the *new* state, so we need text-diff to detect + // removals. Cross-repo refs are intentionally skipped. + if ( + context.payload.action === 'edited' && + context.payload.changes && + context.payload.changes.body && + typeof context.payload.changes.body.from === 'string' + ) { + const re = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi; + const oldBody = context.payload.changes.body.from || ''; + const newBody = pr.body || ''; + const oldRefs = new Set([...oldBody.matchAll(re)].map((m) => Number(m[1]))); + const newRefs = new Set([...newBody.matchAll(re)].map((m) => Number(m[1]))); + const removed = [...oldRefs].filter((n) => !newRefs.has(n)); Review Comment: The body-diff regex used to detect removed closing references only matches `closes #123`-style patterns (whitespace before `#`). GitHub also recognizes forms like `Closes: #123` and `Closes #1, #2`; in those cases `oldRefs/newRefs` may miss linked issues and the workflow won’t unassign the opener when the closing reference is removed. Consider broadening the parser to cover the supported closing-reference syntax (e.g., allow optional `:` and additional `#NNN` refs on the same line) so removals are detected reliably. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
