refactor: Extract github platform resolver
This commit is contained in:
@@ -3,6 +3,8 @@ import {DiffInfo} from "../pr-collector/commits";
|
||||
import {Options} from "../pr-collector/prCollector";
|
||||
import moment from "moment/moment";
|
||||
import {PullRequestInfo} from "../pr-collector/pullRequests";
|
||||
import * as core from "@actions/core";
|
||||
import {createCommandManager} from "../pr-collector/gitHelper";
|
||||
|
||||
export abstract class BaseRepository {
|
||||
proxy?: string;
|
||||
@@ -11,7 +13,7 @@ export abstract class BaseRepository {
|
||||
// Define an abstract getter for the default URL
|
||||
abstract get defaultUrl(): string;
|
||||
|
||||
protected constructor(protected token: string, protected url?: string) {
|
||||
protected constructor(protected token: string, protected url: string | undefined,protected repositoryPath:string) {
|
||||
this.proxy = process.env.https_proxy || process.env.HTTPS_PROXY
|
||||
const noProxy = process.env.no_proxy || process.env.NO_PROXY
|
||||
this.noProxyArray = []
|
||||
@@ -34,4 +36,24 @@ export abstract class BaseRepository {
|
||||
abstract getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]>
|
||||
|
||||
abstract getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void>
|
||||
|
||||
|
||||
protected async getTagByCreateTime(repositoryPath: string, tagInfo: TagInfo) {
|
||||
core.info(`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`)
|
||||
const gitHelper = await createCommandManager(repositoryPath)
|
||||
const creationTimeString = await gitHelper.tagCreation(tagInfo.name)
|
||||
const creationTime = moment(creationTimeString)
|
||||
if (creationTimeString !== null && creationTime.isValid()) {
|
||||
tagInfo.date = creationTime
|
||||
core.info(
|
||||
`ℹ️ Resolved tag creation time (${creationTimeString}) from 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}`
|
||||
)
|
||||
} else {
|
||||
core.info(
|
||||
`⚠️ Could not retrieve tag creation time via git cli 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}'`
|
||||
)
|
||||
}
|
||||
return tagInfo
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,16 +4,13 @@ import {HttpsProxyAgent} from "https-proxy-agent";
|
||||
import * as core from "@actions/core";
|
||||
import {TagInfo} from "../pr-collector/tags";
|
||||
import moment from "moment/moment";
|
||||
import {createCommandManager} from "../pr-collector/gitHelper";
|
||||
import {DiffInfo} from "../pr-collector/commits";
|
||||
import {
|
||||
CommentInfo,
|
||||
fetchedEnough,
|
||||
mapComment,
|
||||
mapPullRequest,
|
||||
CommentInfo, PullData,
|
||||
PullRequestInfo,
|
||||
PullReviewsData, PullsListData
|
||||
} from "../pr-collector/pullRequests";
|
||||
import {Unpacked} from "../pr-collector/utils";
|
||||
|
||||
export class GithubRepository extends BaseRepository {
|
||||
|
||||
@@ -90,11 +87,12 @@ export class GithubRepository extends BaseRepository {
|
||||
const prs: PullsListData = response.data as PullsListData
|
||||
|
||||
for (const pr of prs) {
|
||||
mergedPRs.push(mapPullRequest(pr, pr.merged_at ? 'merged' : 'open'))
|
||||
mergedPRs.push(this.mapPullRequest(pr, pr.merged_at ? 'merged' : 'open'))
|
||||
}
|
||||
}
|
||||
return mergedPRs
|
||||
}
|
||||
|
||||
async getBetweenDates(owner: string, repo: string, fromDate: moment.Moment, toDate: moment.Moment, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||
const mergedPRs: PullRequestInfo[] = []
|
||||
const options = this.octokit.pulls.list.endpoint.merge({
|
||||
@@ -109,13 +107,13 @@ export class GithubRepository extends BaseRepository {
|
||||
const prs: PullsListData = response.data as PullsListData
|
||||
|
||||
for (const pr of prs.filter(p => !!p.merged_at)) {
|
||||
mergedPRs.push(mapPullRequest(pr, 'merged'))
|
||||
mergedPRs.push(this.mapPullRequest(pr, 'merged'))
|
||||
}
|
||||
if (mergedPRs.length >= maxPullRequests) {
|
||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests} (1)`)
|
||||
break // bail out early to not keep iterating forever
|
||||
} else if (prs.length > 0) {
|
||||
if (fetchedEnough(prs, fromDate)) {
|
||||
if (this.fetchedEnough(prs, fromDate)) {
|
||||
return mergedPRs // bail out early to not keep iterating on PRs super old
|
||||
}
|
||||
} else {
|
||||
@@ -125,6 +123,7 @@ export class GithubRepository extends BaseRepository {
|
||||
}
|
||||
return mergedPRs
|
||||
}
|
||||
|
||||
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||
const openPrs: PullRequestInfo[] = []
|
||||
const options = this.octokit.pulls.list.endpoint.merge({
|
||||
@@ -140,7 +139,7 @@ export class GithubRepository extends BaseRepository {
|
||||
const prs: PullsListData = response.data as PullsListData
|
||||
|
||||
for (const pr of prs) {
|
||||
openPrs.push(mapPullRequest(pr, 'open'))
|
||||
openPrs.push(this.mapPullRequest(pr, 'open'))
|
||||
}
|
||||
|
||||
const firstPR = prs[0]
|
||||
@@ -153,6 +152,7 @@ export class GithubRepository extends BaseRepository {
|
||||
}
|
||||
return openPrs
|
||||
}
|
||||
|
||||
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
||||
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
||||
owner,
|
||||
@@ -166,17 +166,20 @@ export class GithubRepository extends BaseRepository {
|
||||
const comments: PullReviewsData = response.data as PullReviewsData
|
||||
|
||||
for (const comment of comments) {
|
||||
prReviews.push(mapComment(comment))
|
||||
prReviews.push(this.mapComment(comment))
|
||||
}
|
||||
}
|
||||
pr.reviews = prReviews
|
||||
}
|
||||
|
||||
get defaultUrl(): string {
|
||||
return "https://api.example.com";
|
||||
return "https://api.github.com";
|
||||
}
|
||||
private octokit:Octokit
|
||||
constructor(token: string, url?: string) {
|
||||
super(token, url);
|
||||
|
||||
private octokit: Octokit
|
||||
|
||||
constructor(token: string, url: string|undefined,repositoryPath:string) {
|
||||
super(token, url,repositoryPath);
|
||||
this.url = url || this.defaultUrl
|
||||
|
||||
// load octokit instance
|
||||
@@ -240,23 +243,57 @@ export class GithubRepository extends BaseRepository {
|
||||
tagInfo.date = moment(release.created_at)
|
||||
core.info(`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the GitHub API`)
|
||||
} catch (error) {
|
||||
core.info(`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`)
|
||||
const gitHelper = await createCommandManager(repositoryPath)
|
||||
const creationTimeString = await gitHelper.tagCreation(tagInfo.name)
|
||||
const creationTime = moment(creationTimeString)
|
||||
if (creationTimeString !== null && creationTime.isValid()) {
|
||||
tagInfo.date = creationTime
|
||||
core.info(
|
||||
`ℹ️ Resolved tag creation time (${creationTimeString}) from 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}`
|
||||
)
|
||||
} else {
|
||||
core.info(
|
||||
`⚠️ Could not retrieve tag creation time via git cli 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}'`
|
||||
)
|
||||
}
|
||||
tagInfo = await this.getTagByCreateTime(repositoryPath, tagInfo)
|
||||
}
|
||||
return tagInfo
|
||||
}
|
||||
|
||||
// helper function to add a special open label to prs not merged.
|
||||
private attachSpecialLabels(status: 'open' | 'merged', labels: string[]): string[] {
|
||||
labels.push(`--rcba-${status}`)
|
||||
return labels
|
||||
}
|
||||
|
||||
private mapPullRequest = (pr: PullData | Unpacked<PullsListData>, status: 'open' | 'merged' = 'open'): PullRequestInfo => ({
|
||||
number: pr.number,
|
||||
title: pr.title,
|
||||
htmlURL: pr.html_url,
|
||||
baseBranch: pr.base.ref,
|
||||
branch: pr.head.ref,
|
||||
createdAt: moment(pr.created_at),
|
||||
mergedAt: pr.merged_at ? moment(pr.merged_at) : undefined,
|
||||
mergeCommitSha: pr.merge_commit_sha || '',
|
||||
author: pr.user?.login || '',
|
||||
repoName: pr.base.repo.full_name,
|
||||
labels: this.attachSpecialLabels(status, pr.labels?.map(lbl => lbl.name?.toLocaleLowerCase('en') || '') || []),
|
||||
milestone: pr.milestone?.title || '',
|
||||
body: pr.body || '',
|
||||
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
||||
requestedReviewers: pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
||||
approvedReviewers: [],
|
||||
reviews: undefined,
|
||||
status
|
||||
})
|
||||
|
||||
private mapComment = (comment: Unpacked<PullReviewsData>): CommentInfo => ({
|
||||
id: comment.id,
|
||||
htmlURL: comment.html_url,
|
||||
submittedAt: comment.submitted_at ? moment(comment.submitted_at) : undefined,
|
||||
author: comment.user?.login || '',
|
||||
body: comment.body,
|
||||
state: comment.state
|
||||
})
|
||||
private fetchedEnough(pullRequests: PullsListData, fromDate: moment.Moment): boolean {
|
||||
for (let i = 0; i < Math.min(pullRequests.length, 3); i++) {
|
||||
const firstPR = pullRequests[i]
|
||||
if (!firstPR.merged_at) {
|
||||
continue // no merged_at timestamp -> look for the next
|
||||
} else if (fromDate.isAfter(moment(firstPR.merged_at))) {
|
||||
return true
|
||||
} else {
|
||||
break // not enough PRs yet, go further
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user