mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
ci: use GitHub App for community label org membership check (#24149)
Supersedes #23343. ## Problem `author_association` on `pull_request_target` events is unreliable: - Returns `CONTRIBUTOR` instead of `MEMBER` when both apply ([actions/github-script#643](https://github.com/actions/github-script/issues/643)). - Returns `NONE` for members with private org visibility ([community#18690](https://github.com/orgs/community/discussions/18690)). This causes org members to incorrectly receive the `community` label. ## Approach Replace the `author_association` check with an explicit `orgs.checkMembershipForUser()` API call, which reliably detects both public and private org members. Uses a dedicated **GitHub App** via `actions/create-github-app-token` instead of a PAT. The App only needs **Organization > Members: Read** permission. Installation tokens are short-lived (1 hour) and auto-rotated — no long-lived secrets to worry about. ### Setup required A repo/org admin needs to: 1. Create a GitHub App with only **Organization > Members: Read** permission. 2. Install it on the `coder` org. 3. Store the App ID as a repository variable: `ORG_MEMBERSHIP_APP_ID`. 4. Store the App's private key as a repository secret: `ORG_MEMBERSHIP_APP_PRIVATE_KEY`. > [!NOTE] > Generated by Coder Agents --------- Co-authored-by: Jakub Domeracki <jakub@coder.com>
This commit is contained in:
co-authored by
Jakub Domeracki
parent
b78eba9f9d
commit
079dc48ba0
@@ -30,16 +30,28 @@ jobs:
|
||||
if: >-
|
||||
${{
|
||||
github.event_name == 'pull_request_target' &&
|
||||
github.event.action == 'opened' &&
|
||||
github.event.pull_request.author_association != 'MEMBER' &&
|
||||
github.event.pull_request.author_association != 'COLLABORATOR' &&
|
||||
github.event.pull_request.author_association != 'OWNER'
|
||||
github.event.action == 'opened'
|
||||
}}
|
||||
steps:
|
||||
- name: Generate app token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||
with:
|
||||
app-id: ${{ vars.ORG_MEMBERSHIP_APP_ID }}
|
||||
private-key: ${{ secrets.ORG_MEMBERSHIP_APP_PRIVATE_KEY }}
|
||||
- name: Add community label
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
APP_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
with:
|
||||
# Default GITHUB_TOKEN handles label writes via the
|
||||
# `github` object (needs pull-requests: write). The App
|
||||
# token is scoped to members: read only and used via a
|
||||
# separate Octokit client for the membership check.
|
||||
script: |
|
||||
const { Octokit } = require("@octokit/rest")
|
||||
const orgClient = new Octokit({ auth: process.env.APP_TOKEN })
|
||||
|
||||
const params = {
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
@@ -52,10 +64,27 @@ jobs:
|
||||
return
|
||||
}
|
||||
|
||||
console.log(
|
||||
'Adding "community" label for author association "%s".',
|
||||
context.payload.pull_request.author_association,
|
||||
)
|
||||
// author_association can be unreliable: it returns
|
||||
// CONTRIBUTOR instead of MEMBER when both apply, and
|
||||
// returns NONE for members with private org visibility.
|
||||
// Use the org membership API as the source of truth.
|
||||
// See: https://github.com/actions/github-script/issues/643
|
||||
const author = context.payload.pull_request.user.login
|
||||
try {
|
||||
await orgClient.orgs.checkMembershipForUser({
|
||||
org: context.repo.owner,
|
||||
username: author,
|
||||
})
|
||||
console.log('Author "%s" is an org member, skipping.', author)
|
||||
return
|
||||
} catch (error) {
|
||||
if (error.status !== 404 && error.status !== 302) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Adding "community" label for author "%s".', author)
|
||||
// Uses the default GITHUB_TOKEN via the `github` object.
|
||||
await github.rest.issues.addLabels({
|
||||
...params,
|
||||
labels: ["community"],
|
||||
|
||||
Reference in New Issue
Block a user