Skip to content

Commit 28558a4

Browse files
brandom-msftCopilot
andcommitted
fix: use cascading org checks for PR redirect workflow
Replace the single 'microsoft' org membership check with a multi-signal cascade that catches internal contributors with private org membership: 1. Check microsoft-foundry org membership (full GITHUB_TOKEN visibility) 2. Check repo collaborator status 3. Check microsoft org membership (public members fallback) Also adds members: read permission and debug logging. Fixes misidentification of internal contributors like #574 where a Microsoft docs writer was incorrectly treated as an external contributor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 195fdf0 commit 28558a4

1 file changed

Lines changed: 50 additions & 6 deletions

File tree

.github/workflows/redirect-pull-requests.yml

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66

77
permissions:
88
pull-requests: write
9+
members: read
910

1011
jobs:
1112
redirect:
@@ -25,21 +26,64 @@ jobs:
2526
return;
2627
}
2728
28-
// Check if author is a member of the microsoft org
29-
let isOrgMember = false;
29+
// Check if author is a Microsoft contributor using multiple signals.
30+
// The GITHUB_TOKEN can only see *public* members of the 'microsoft' org
31+
// (since this repo is in the 'microsoft-foundry' org), so we cascade
32+
// through several checks to catch contributors with private membership.
33+
let isInternal = false;
34+
let matchedSignal = null;
35+
36+
// Signal 1: Check microsoft-foundry org membership (full visibility via GITHUB_TOKEN)
3037
try {
3138
const res = await github.rest.orgs.checkMembershipForUser({
32-
org: 'microsoft',
39+
org: 'microsoft-foundry',
3340
username: author,
3441
});
35-
isOrgMember = res.status === 204;
42+
if (res.status === 204) {
43+
isInternal = true;
44+
matchedSignal = 'microsoft-foundry org member';
45+
}
3646
} catch {
3747
// 404 or 302 means not a member
38-
isOrgMember = false;
3948
}
4049
50+
// Signal 2: Check if author is a collaborator on this repo
51+
if (!isInternal) {
52+
try {
53+
const res = await github.rest.repos.checkCollaborator({
54+
owner: context.repo.owner,
55+
repo: context.repo.repo,
56+
username: author,
57+
});
58+
if (res.status === 204) {
59+
isInternal = true;
60+
matchedSignal = 'repo collaborator';
61+
}
62+
} catch {
63+
// 404 means not a collaborator
64+
}
65+
}
66+
67+
// Signal 3: Check microsoft org membership (catches public members only)
68+
if (!isInternal) {
69+
try {
70+
const res = await github.rest.orgs.checkMembershipForUser({
71+
org: 'microsoft',
72+
username: author,
73+
});
74+
if (res.status === 204) {
75+
isInternal = true;
76+
matchedSignal = 'microsoft org member (public)';
77+
}
78+
} catch {
79+
// 404 or 302 means not a member (or private membership not visible)
80+
}
81+
}
82+
83+
console.log(`Author: ${author}, isInternal: ${isInternal}, signal: ${matchedSignal || 'none'}`);
84+
4185
let body;
42-
if (isOrgMember) {
86+
if (isInternal) {
4387
body = [
4488
`👋 Thanks for your contribution, @${author}!`,
4589
'',

0 commit comments

Comments
 (0)