From 81ed441c7a81401c0f21bd063706a4bc59c27577 Mon Sep 17 00:00:00 2001 From: alan Date: Sat, 13 Jan 2024 02:57:58 -0500 Subject: [PATCH] Cleanup and improvements --- src/index.ts | 105 ++++++++++++++++++++++++++++-------------------- src/requests.ts | 22 +++++++++- 2 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/index.ts b/src/index.ts index f0fe65c..8eb8667 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,6 @@ -import fs from 'fs' -import https from 'https' -import bodyParser from 'body-parser' import _ from 'lodash' -import express from 'express' -import fetch from 'node-fetch' +// import bodyParser from 'body-parser' +// import express from 'express' import Issue from './issue'; @@ -11,56 +8,76 @@ import Issue from './issue'; import CONFIG from '../config/server.json'; import SECRETS from '../config/secrets.json'; import uGiteaToJira from '../config/user_remap.json'; -import { jiraFetch } from './requests' - -// BUILD OAUTH -const OAUTH_JIRA = `${SECRETS['jira-email']}:${SECRETS['jira-token']}`; -const OAUTH_GITEA = `token=${SECRETS['gitea-token']}`; - -const URL_GITEA = `${CONFIG['gitea']}/api/v1`; - -const url = `${URL_GITEA}/repos/${CONFIG['repositories']['bot']}/issues?state=all&${OAUTH_GITEA}` +import { fetchGitea, fetchJira } from './requests' const database: Issue[] = []; -// Copy issues over from Gitea to Jira -fetch(url).then((res) => { - res.json().then((data) => { - _.forEach(data, (ticket) => { - const issue = Issue.fromGitea(ticket, CONFIG['repository-default']); - database.push(issue); - // Now, search Jira issues to make sure this isn't already duplicated - const jiraIssueSearch = `project = "${SECRETS['jira-project']}" and summary ~ "${issue.title_jira}"\nORDER BY created DESC` +// GOAL: Copy issues over from Gitea to Jira +// First, iterate through all relevant Gitea repositories and corresponding keys +_.forEach(CONFIG['repositories'], (repoURL, repoName) => { + // Perform a search for all open issues + fetchGitea(`repos/${repoURL}/issues?state=open`) + .then((giteaSearchData) => { + // Convert search results to JSON for indexing + giteaSearchData.json().then((giteaSearch) => { + console.log(`Indexxing repository "${repoURL}" -----------`); - jiraFetch(`issue/picker?currentJQL=${jiraIssueSearch}`, 'GET').then((jiraSearch) => { - jiraSearch.json().then((searchJSON) => { - let issueFound: any = null; + // For each search result, parse out an issue + _.forEach(giteaSearch, (ticket) => { + // Generate issue from ticket JSON + const issue = Issue.fromGitea(ticket, repoName); + database.push(issue); // Save to our database for posterity - _.forEach(searchJSON['sections'], (searchSection) => { - const issueList: any[] = searchSection['issues'] - if (issueList.length > 0) { // If any issues were found - issueFound = issueList[0]; // Select the first one (probably matches best) - } - }) - - // If the issue does not exist... - if (issueFound === null) { - // ...then create one! - console.log(`Issue "${issue.title_jira}" not found on Jira, creating one...`); + // Now, search Jira issues (using JQL) to make sure this isn't already duplicated + // To do this, we need to search for issues using our given Project key + // ...then search for a matching title + const jiraIssueSearch = `project = "${SECRETS['jira-project']}" and summary ~ "${issue.title_jira}"\nORDER BY created DESC` - jiraFetch('issue', 'POST', issue.toJira(uGiteaToJira, SECRETS['jira-project'])).then((res) => { - res.json().then((createdIssue) => { - console.log(createdIssue); - issue.id_jira = createdIssue['key']; + fetchJira(`issue/picker?currentJQL=${jiraIssueSearch}`) + .then((jiraSearchData) => { + // Convert search results to JSON for indexing + jiraSearchData.json().then((jiraSearch) => { + let issueFound: any = null; + + // Look through all sections of the Jira search + _.forEach(jiraSearch['sections'], (searchSection) => { + const issueList: any[] = searchSection['issues'] + if (issueList.length > 0) { // If any issues were found + issueFound = issueList[0]; // Select the first one (probably matches best) + } + }) + + // If the issue does NOT exist... + if (issueFound === null) { + // ...then create one! + console.log(`\tIssue "${issue.title_jira}" not found on Jira, creating one...`); + + return; // WOOPS DO NOT ALLOW CRASH AND BURN + // Send POST request to Jira, asking to create the issue + fetchJira('issue', 'POST', issue.toJira(uGiteaToJira, SECRETS['jira-project'])) + .then((jiraIssueData) => { + // Convert our response back to JSON + jiraIssueData.json().then((jiraIssue) => { + issue.id_jira = jiraIssue['key']; // Store relevant information of newly created issue + }) + }) + .catch((reason) => { + console.error(`\tFailed to create issue "${issue.title_jira}" on Jira, for reason ${reason}`); + }) + } else { + console.log(`\tIssue "${issue.title_jira}" already existed, skipping`); + } }) }) - } else { - console.log(`Issue "${issue.title_jira}" already existed, skipping`); - } + .catch((reason) => { + console.error(`\tFailed to fetch issues from Jira project for reason ${reason}`); + }) }) }) }) - }) + .catch((reason) => { + console.error(`\tFailed to fetch issues from Gitea repository "${repoURL}" for reason ${reason}`); + }) }) /* diff --git a/src/requests.ts b/src/requests.ts index 45b86aa..13d04e9 100644 --- a/src/requests.ts +++ b/src/requests.ts @@ -1,11 +1,29 @@ import fetch from 'node-fetch' +import CONFIG from '../config/server.json'; import SECRETS from '../config/secrets.json'; const OAUTH_JIRA = `${SECRETS['jira-email']}:${SECRETS['jira-token']}`; const OAUTH_GITEA = `token=${SECRETS['gitea-token']}`; -function jiraFetch(protocol: string, method: string = 'POST', body: any = null) { +function fetchGitea(protocol: string, method: string = 'GET', body: any = null) { + const options: RequestInit = { + method: method, + headers: { + 'Authorization': SECRETS['gitea-token'], + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + }; + + if (body !== null) { + options.body = JSON.stringify(body); + } + + return fetch(`${CONFIG['gitea']}/api/v1/${protocol}`, options) +} + +function fetchJira(protocol: string, method: string = 'GET', body: any = null) { const options: RequestInit = { method: method, headers: { @@ -22,4 +40,4 @@ function jiraFetch(protocol: string, method: string = 'POST', body: any = null) return fetch(`https://${SECRETS['jira-site']}.atlassian.net/rest/api/3/${protocol}`, options); } -export { jiraFetch }; +export { fetchGitea, fetchJira };