@@ -91,29 +91,58 @@ jobs:
9191 }
9292 }
9393
94+ let assigned = false;
9495 if (assignedTeams.size > 0) {
9596 const teamReviewers = Array.from(assignedTeams);
9697 console.log(`PR contains changes matching specific routes. Requesting review from: ${teamReviewers.join(', ')}`);
97- await github.rest.pulls.requestReviewers({
98- owner: context.repo.owner,
99- repo: context.repo.repo,
100- pull_number: context.payload.pull_request.number,
101- team_reviewers: teamReviewers,
102- });
103- } else {
104- // Route to cloud-sdk-nodejs-team members with load balancing
105- console.log("Requesting review from a member of cloud-sdk-nodejs-team using load balancing.");
10698 try {
107- const { data: members } = await github.rest.teams.listMembersInOrg({
108- org: 'googleapis',
109- team_slug: 'cloud-sdk-nodejs-team',
99+ await github.rest.pulls.requestReviewers({
100+ owner: context.repo.owner,
101+ repo: context.repo.repo,
102+ pull_number: context.payload.pull_request.number,
103+ team_reviewers: teamReviewers,
110104 });
111-
112- const memberLogins = members
113- .map(m => m.login)
114- .filter(login => login !== author);
105+ assigned = true;
106+ } catch (err) {
107+ console.error(`Failed to assign route-specific team reviewers (${teamReviewers.join(', ')}):`, err.message || err);
108+ console.log("Falling back to default team members.");
109+ }
110+ }
111+
112+ if (!assigned) {
113+ console.log("Fetching .github/CODEOWNERS to identify default reviewers...");
114+ let defaultReviewers = [];
115+ try {
116+ const { data: codeownersData } = await github.rest.repos.getContent({
117+ owner: context.repo.owner,
118+ repo: context.repo.repo,
119+ path: '.github/CODEOWNERS',
120+ ref: context.payload.pull_request.head.sha,
121+ });
122+ const content = Buffer.from(codeownersData.content, 'base64').toString('utf-8');
123+ const lines = content.split('\n');
124+ for (const line of lines) {
125+ const trimmed = line.trim();
126+ if (trimmed.startsWith('#')) {
127+ const commentContent = trimmed.substring(1).trim();
128+ if (commentContent.startsWith('team_members:')) {
129+ const listPart = commentContent.substring('team_members:'.length).trim();
130+ const parts = listPart.split(/\s+/);
131+ defaultReviewers = parts
132+ .filter(p => p.startsWith('@'))
133+ .map(p => p.substring(1))
134+ .filter(login => login !== author);
135+ break;
136+ }
137+ }
138+ }
139+ } catch (err) {
140+ console.error("Failed to read or parse CODEOWNERS:", err);
141+ }
115142
116- if (memberLogins.length > 0) {
143+ if (defaultReviewers.length > 0) {
144+ console.log(`Found default reviewers: ${defaultReviewers.join(', ')}. Load balancing among them.`);
145+ try {
117146 // Retrieve active open PRs to calculate load
118147 const { data: openPRs } = await github.rest.pulls.list({
119148 owner: context.repo.owner,
@@ -123,7 +152,7 @@ jobs:
123152 });
124153
125154 const loadMap = {};
126- for (const member of memberLogins ) {
155+ for (const member of defaultReviewers ) {
127156 loadMap[member] = 0;
128157 }
129158
@@ -151,7 +180,7 @@ jobs:
151180 // Find members with the minimum load
152181 let minLoad = Infinity;
153182 let selectedReviewers = [];
154- for (const member of memberLogins ) {
183+ for (const member of defaultReviewers ) {
155184 const load = loadMap[member];
156185 if (load < minLoad) {
157186 minLoad = load;
@@ -169,25 +198,11 @@ jobs:
169198 repo: context.repo.repo,
170199 pull_number: context.payload.pull_request.number,
171200 reviewers: [leastLoadedReviewer],
172- team_reviewers: ['cloud-sdk-nodejs-team'],
173- });
174- } else {
175- console.log("No other members found in cloud-sdk-nodejs-team. Requesting team review only.");
176- await github.rest.pulls.requestReviewers({
177- owner: context.repo.owner,
178- repo: context.repo.repo,
179- pull_number: context.payload.pull_request.number,
180- team_reviewers: ['cloud-sdk-nodejs-team'],
181201 });
202+ } catch (err) {
203+ console.error("Failed to assign reviewers using load balancing:", err);
182204 }
183- } catch (err) {
184- console.error("Failed to fetch team members or assign reviewers:", err);
185- // Fallback to just requesting the team review
186- await github.rest.pulls.requestReviewers({
187- owner: context.repo.owner,
188- repo: context.repo.repo,
189- pull_number: context.payload.pull_request.number,
190- team_reviewers: ['cloud-sdk-nodejs-team'],
191- });
205+ } else {
206+ console.warn("No default reviewers found in CODEOWNERS (or they only contained teams/author).");
192207 }
193208 }
0 commit comments