Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface ResponseNode {
export interface PrNode {
createdAt: string
mergedAt: string | null
closedAt: string | null
author: { login: string } | null
comments: { nodes: ResponseNode[] }
reviews: { nodes: ResponseNode[] }
Expand Down
77 changes: 19 additions & 58 deletions services/apps/packages_worker/src/enricher/fetchActivitySnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,11 @@ async function graphqlRequest<T>(
return json.data as T
}

function toDateString(date: Date): string {
return date.toISOString().slice(0, 10)
}

function buildDateWindows(): {
since12m: Date
since6m: Date
since12mIso: string
since6mIso: string
since12mDate: string
since6mDate: string
} {
const now = new Date()

Expand All @@ -91,10 +86,9 @@ function buildDateWindows(): {

return {
since12m,
since6m,
since12mIso: since12m.toISOString(),
since6mIso: since6m.toISOString(),
since12mDate: toDateString(since12m),
since6mDate: toDateString(since6m),
}
}

Expand All @@ -104,10 +98,6 @@ interface RateLimit {
resetAt: string
}

interface IssueCount {
issueCount: number
}

interface CommitHistory {
totalCount: number
}
Expand All @@ -127,14 +117,8 @@ interface SummaryQueryResult {
commitsPrior6m?: CommitHistory
}
}
openIssues: { totalCount: number }
}
prsOpened: IssueCount
prsMerged: IssueCount
prsClosedUnmerged: IssueCount
issuesOpened: IssueCount
issuesClosed: IssueCount
issuesOpened6m: IssueCount
issuesOpenNow: IssueCount
}

interface PrPageQueryResult {
Expand All @@ -158,14 +142,7 @@ interface IssuePageQueryResult {
}

const SUMMARY_QUERY = `
query(
$owner: String!, $name: String!,
$since12m: GitTimestamp!, $since6m: GitTimestamp!,
$searchPrsOpened: String!, $searchPrsMerged: String!,
$searchPrsClosedUnmerged: String!,
$searchIssuesOpened: String!, $searchIssuesClosed: String!,
$searchIssuesOpened6m: String!, $searchIssuesOpenNow: String!
) {
query($owner: String!, $name: String!, $since12m: GitTimestamp!, $since6m: GitTimestamp!) {
rateLimit { cost remaining resetAt }
repository(owner: $owner, name: $name) {
defaultBranchRef {
Expand All @@ -177,14 +154,8 @@ const SUMMARY_QUERY = `
}
}
}
openIssues: issues(states: OPEN) { totalCount }
}
prsOpened: search(query: $searchPrsOpened, type: ISSUE) { issueCount }
prsMerged: search(query: $searchPrsMerged, type: ISSUE) { issueCount }
prsClosedUnmerged: search(query: $searchPrsClosedUnmerged, type: ISSUE) { issueCount }
issuesOpened: search(query: $searchIssuesOpened, type: ISSUE) { issueCount }
issuesClosed: search(query: $searchIssuesClosed, type: ISSUE) { issueCount }
issuesOpened6m: search(query: $searchIssuesOpened6m, type: ISSUE) { issueCount }
issuesOpenNow: search(query: $searchIssuesOpenNow, type: ISSUE) { issueCount }
}
`

Expand All @@ -197,6 +168,7 @@ const PR_PAGE_QUERY = `
nodes {
createdAt
mergedAt
closedAt
author { login }
comments(first: ${RESPONSES_PER_NODE}) { nodes { createdAt author { login } } }
reviews(first: ${RESPONSES_PER_NODE}) { nodes { createdAt author { login } } }
Expand Down Expand Up @@ -325,24 +297,11 @@ export async function fetchActivitySnapshot(
token: string,
timeoutMs: number,
): Promise<RepoActivitySnapshot> {
const { since12m, since12mIso, since6mIso, since12mDate, since6mDate } = buildDateWindows()
const repoFilter = `repo:${owner}/${name}`
const { since12m, since6m, since12mIso, since6mIso } = buildDateWindows()

const summaryData = await graphqlRequest<SummaryQueryResult>(
SUMMARY_QUERY,
{
owner,
name,
since12m: since12mIso,
since6m: since6mIso,
searchPrsOpened: `${repoFilter} is:pr created:>=${since12mDate}`,
searchPrsMerged: `${repoFilter} is:pr is:merged created:>=${since12mDate}`,
searchPrsClosedUnmerged: `${repoFilter} is:pr is:unmerged is:closed created:>=${since12mDate}`,
searchIssuesOpened: `${repoFilter} is:issue created:>=${since12mDate}`,
searchIssuesClosed: `${repoFilter} is:issue is:closed created:>=${since12mDate}`,
searchIssuesOpened6m: `${repoFilter} is:issue created:>=${since6mDate}`,
searchIssuesOpenNow: `${repoFilter} is:issue is:open`,
},
{ owner, name, since12m: since12mIso, since6m: since6mIso },
token,
timeoutMs,
)
Expand Down Expand Up @@ -378,6 +337,9 @@ export async function fetchActivitySnapshot(

const prMedians = computePrMedians(prResult.nodes)
const issueMedians = computeIssueMedians(issueResult.nodes)
const issuesOpenedLast6m = issueResult.nodes.filter(
(n) => new Date(n.createdAt) >= since6m,
).length
Comment on lines +340 to +342

// Lowest remaining across all requests — remaining only decreases within a reset window
const lastRateLimit = [summaryData.rateLimit, prResult.rateLimit, issueResult.rateLimit]
Expand All @@ -391,17 +353,16 @@ export async function fetchActivitySnapshot(
commitsLast12m,
commitsLast6m,
commitsPrior6m,
prsOpenedLast12m: summaryData.prsOpened.issueCount,
prsMergedLast12m: summaryData.prsMerged.issueCount,
prsClosedUnmerged12m: summaryData.prsClosedUnmerged.issueCount,
prsOpenedLast12m: prResult.nodes.length,
prsMergedLast12m: prResult.nodes.filter((n) => n.mergedAt).length,
prsClosedUnmerged12m: prResult.nodes.filter((n) => n.closedAt && !n.mergedAt).length,
prMedianTimeToMergeHours: prMedians.medianTimeToMergeHours,
prMedianTimeToFirstResponseHours: prMedians.medianTimeToFirstResponseHours,
issuesOpenedLast12m: summaryData.issuesOpened.issueCount,
issuesClosedLast12m: summaryData.issuesClosed.issueCount,
issuesOpenedLast6m: summaryData.issuesOpened6m.issueCount,
issuesOpenedPrior6m:
summaryData.issuesOpened.issueCount - summaryData.issuesOpened6m.issueCount,
issuesOpenNow: summaryData.issuesOpenNow.issueCount,
issuesOpenedLast12m: issueResult.nodes.length,
issuesClosedLast12m: issueResult.nodes.filter((n) => n.closedAt).length,
issuesOpenedLast6m,
issuesOpenedPrior6m: issueResult.nodes.length - issuesOpenedLast6m,
issuesOpenNow: summaryData.repository.openIssues.totalCount,
issueMedianTimeToCloseHours: issueMedians.medianTimeToCloseHours,
issueMedianTimeToFirstResponseHours: issueMedians.medianTimeToFirstResponseHours,
httpRequestCount: totalHttpRequests,
Expand Down
Loading