Skip to content

Commit 31267ea

Browse files
authored
Merge pull request #20 from evwilkin/fix/19-gh-403
2 parents f39e57c + ed5680f commit 31267ea

File tree

3 files changed

+89
-24
lines changed

3 files changed

+89
-24
lines changed

.github/workflows/daily_run.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ jobs:
3939
# Step 4: Run GitHub-Jira sync
4040
- name: Execute GitHub-Jira Sync
4141
env:
42+
# PF-org token
4243
GH_TOKEN: ${{ secrets.GH_TOKEN }}
44+
# RH-UXD org token
45+
GH_JIRA_SYNC_RHUXD_PAT: ${{ secrets.GH_JIRA_SYNC_RHUXD_PAT }}
46+
# Jira token
4347
JIRA_PAT: ${{ secrets.JIRA_PAT }}
4448
run: |
4549
if [[ "${{ github.event.inputs.since_date }}" != "" ]]; then

src/helpers.js

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,49 @@ import { errorCollector } from './index.js';
44
import j2m from 'jira2md';
55

66
// Initialize Octokit with GraphQL support
7+
// @deprecated Use getOctokitForOwner() instead for multi-org support
78
export const octokit = new Octokit({
89
auth: process.env.GH_TOKEN,
910
baseUrl: 'https://api.github.com',
1011
});
1112

13+
// Cache for Octokit instances by owner
14+
const octokitInstances = new Map();
15+
16+
/**
17+
* Get an Octokit instance for the specified owner
18+
* @param {string} owner - Repository owner (e.g., 'patternfly', 'rh-uxd')
19+
* @returns {Octokit} Cached Octokit instance with appropriate token
20+
*/
21+
export function getOctokitForOwner(owner) {
22+
// Return cached instance if available
23+
if (octokitInstances.has(owner)) {
24+
return octokitInstances.get(owner);
25+
}
26+
27+
// Determine which token to use based on owner
28+
let token;
29+
if (owner === 'rh-uxd') {
30+
token = process.env.GH_JIRA_SYNC_RHUXD_PAT;
31+
} else {
32+
// Default to patternfly token for 'patternfly' and any other owners
33+
token = process.env.GH_TOKEN;
34+
}
35+
36+
if (!token) {
37+
throw new Error(`Missing GitHub token for owner: ${owner}`);
38+
}
39+
40+
// Create and cache new instance
41+
const instance = new Octokit({
42+
auth: token,
43+
baseUrl: 'https://api.github.com',
44+
});
45+
46+
octokitInstances.set(owner, instance);
47+
return instance;
48+
}
49+
1250
// Initialize Jira client
1351
export const jiraClient = axios.create({
1452
baseURL: 'https://issues.redhat.com/',
@@ -283,6 +321,10 @@ export const availableComponents = [
283321
{
284322
name: 'github-jira-sync',
285323
owner: 'rh-uxd'
324+
},
325+
{
326+
name: 'jira-weekly-report',
327+
owner: 'rh-uxd'
286328
}
287329
];
288330

@@ -354,9 +396,12 @@ export const buildJiraIssueData = (githubIssue, isUpdateIssue = false) => {
354396
};
355397

356398
// Helper function to execute GraphQL queries
357-
export async function executeGraphQLQuery(query, variables) {
399+
export async function executeGraphQLQuery(query, variables, owner = null) {
358400
try {
359-
const response = await octokit.graphql(query, variables);
401+
// Extract owner from variables if not provided directly
402+
const ownerToUse = owner || variables?.owner || 'patternfly';
403+
const octokitInstance = getOctokitForOwner(ownerToUse);
404+
const response = await octokitInstance.graphql(query, variables);
360405
return response;
361406
} catch (error) {
362407
errorCollector.addError('HELPERS: GraphQL query execution', error);
@@ -587,7 +632,7 @@ export async function getRepoIssues(repo, ghOwner = 'patternfly', since) {
587632
repo,
588633
issuesCursor: cursor,
589634
since,
590-
});
635+
}, ghOwner);
591636

592637
// Validate response structure
593638
if (!response?.repository?.issues) {
@@ -786,7 +831,8 @@ export function shouldSyncFromJira(githubIssue, jiraIssue) {
786831
export async function updateGitHubIssue(owner, repo, issueNumber, updates) {
787832
await delay();
788833
try {
789-
const response = await octokit.rest.issues.update({
834+
const octokitInstance = getOctokitForOwner(owner);
835+
const response = await octokitInstance.rest.issues.update({
790836
owner,
791837
repo,
792838
issue_number: issueNumber,
@@ -805,7 +851,8 @@ export async function updateGitHubIssue(owner, repo, issueNumber, updates) {
805851
export async function addGitHubIssueComment(owner, repo, issueNumber, body) {
806852
await delay();
807853
try {
808-
const response = await octokit.rest.issues.createComment({
854+
const octokitInstance = getOctokitForOwner(owner);
855+
const response = await octokitInstance.rest.issues.createComment({
809856
owner,
810857
repo,
811858
issue_number: issueNumber,
@@ -824,7 +871,8 @@ export async function addGitHubIssueComment(owner, repo, issueNumber, body) {
824871
export async function createGitHubIssue(owner, repo, issueData) {
825872
await delay();
826873
try {
827-
const response = await octokit.rest.issues.create({
874+
const octokitInstance = getOctokitForOwner(owner);
875+
const response = await octokitInstance.rest.issues.create({
828876
owner,
829877
repo,
830878
...issueData,
@@ -850,7 +898,8 @@ export async function createGitHubIssue(owner, repo, issueData) {
850898
export async function closeGitHubIssue(owner, repo, issueNumber) {
851899
await delay();
852900
try {
853-
const response = await octokit.rest.issues.update({
901+
const octokitInstance = getOctokitForOwner(owner);
902+
const response = await octokitInstance.rest.issues.update({
854903
owner,
855904
repo,
856905
issue_number: issueNumber,

src/syncJiraToGitHub.js

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
octokit,
2+
getOctokitForOwner,
33
delay,
44
jiraToGitHubUserMapping,
55
extractUpstreamUrl,
@@ -127,19 +127,27 @@ export async function syncAssigneeToGitHub(jiraIssue, githubIssue) {
127127
}
128128

129129
// Remove existing assignees and add the Jira assignee
130-
if (currentAssignees.length > 0) {
131-
await octokit.rest.issues.removeAssignees({
132-
owner: parseGitHubUrl(githubIssue.url).owner,
133-
repo: parseGitHubUrl(githubIssue.url).repo,
134-
issue_number: parseGitHubUrl(githubIssue.url).issueNumber,
135-
assignees: currentAssignees,
136-
});
130+
const parsed = parseGitHubUrl(githubIssue.url);
131+
if (!parsed) {
132+
console.log(` - Could not parse GitHub URL: ${githubIssue.url}`);
133+
return false;
137134
}
138-
139-
await octokit.rest.issues.addAssignees({
140-
owner: parseGitHubUrl(githubIssue.url).owner,
141-
repo: parseGitHubUrl(githubIssue.url).repo,
142-
issue_number: parseGitHubUrl(githubIssue.url).issueNumber,
135+
const { owner, repo, issueNumber } = parsed;
136+
const octokitInstance = getOctokitForOwner(owner);
137+
138+
// if (currentAssignees.length > 0) {
139+
// await octokitInstance.rest.issues.removeAssignees({
140+
// owner,
141+
// repo,
142+
// issue_number: issueNumber,
143+
// assignees: currentAssignees,
144+
// });
145+
// }
146+
147+
await octokitInstance.rest.issues.addAssignees({
148+
owner,
149+
repo,
150+
issue_number: issueNumber,
143151
assignees: [githubAssignee],
144152
});
145153

@@ -218,7 +226,8 @@ export async function reopenGitHubIssueIfJiraReopened(jiraIssue, githubIssue) {
218226
try {
219227
// Get current GitHub issue state (to verify it's still closed and get updated timestamp)
220228
await delay();
221-
const { data: ghIssue } = await octokit.rest.issues.get({
229+
const octokitInstance = getOctokitForOwner(owner);
230+
const { data: ghIssue } = await octokitInstance.rest.issues.get({
222231
owner,
223232
repo,
224233
issue_number: issueNumber,
@@ -301,7 +310,8 @@ export async function closeGitHubIssueIfJiraClosed(jiraIssue, githubIssue) {
301310
try {
302311
// Get current GitHub issue state (to verify it's still open and get updated timestamp)
303312
await delay();
304-
const { data: ghIssue } = await octokit.rest.issues.get({
313+
const octokitInstance = getOctokitForOwner(owner);
314+
const { data: ghIssue } = await octokitInstance.rest.issues.get({
305315
owner,
306316
repo,
307317
issue_number: issueNumber,
@@ -396,7 +406,8 @@ export async function checkAndHandleArchivedJiraIssue(githubIssue) {
396406
try {
397407
// Get GitHub issue to check if it's already closed
398408
await delay();
399-
const { data: ghIssue } = await octokit.rest.issues.get({
409+
const octokitInstance = getOctokitForOwner(owner);
410+
const { data: ghIssue } = await octokitInstance.rest.issues.get({
400411
owner,
401412
repo,
402413
issue_number: issueNumber,
@@ -466,7 +477,8 @@ export async function closeGitHubIssuesForClosedJira(closedJiraIssues) {
466477
try {
467478
// Get GitHub issue to check if it's already closed
468479
await delay();
469-
const { data: ghIssue } = await octokit.rest.issues.get({
480+
const octokitInstance = getOctokitForOwner(owner);
481+
const { data: ghIssue } = await octokitInstance.rest.issues.get({
470482
owner,
471483
repo,
472484
issue_number: issueNumber,

0 commit comments

Comments
 (0)