UNPKG

@ossjs/release

Version:

Minimalistic, opinionated, and predictable release automation tool.

83 lines (68 loc) 2.33 kB
import createIssueParser from 'issue-parser' import { getInfo, type GitInfo } from '#/src/utils/git/get-info.js' import type { ParsedCommitWithHash } from '#/src/utils/git/parse-commits.js' const parser = createIssueParser('github') function extractIssueIds(text: string, repo: GitInfo): Set<string> { const ids = new Set<string>() const parsed = parser(text) for (const action of parsed.actions.close) { if (action.slug == null || action.slug === `${repo.owner}/${repo.name}`) { ids.add(action.issue) } } return ids } export async function getReleaseRefs( commits: ParsedCommitWithHash[], ): Promise<Set<string>> { const repo = await getInfo() const issueIds = new Set<string>() for (const commit of commits) { // Extract issue ids from the commit messages. for (const ref of commit.references) { if (ref.issue) { issueIds.add(ref.issue) } } // Extract issue ids from the commit bodies. if (commit.body) { const bodyIssueIds = extractIssueIds(commit.body, repo) bodyIssueIds.forEach((id) => issueIds.add(id)) } } // Fetch issue detail from each issue referenced in the commit message // or commit body. Those may include pull request ids that reference // other issues. const issuesFromCommits = await Promise.all( Array.from(issueIds).map(fetchIssue), ) // Extract issue ids from the pull request descriptions. for (const issue of issuesFromCommits) { // Ignore regular issues as they may not close/fix other issues // by reference (at least on GitHub). if (!issue.pull_request || !issue.body) { continue } const descriptionIssueIds = extractIssueIds(issue.body, repo) descriptionIssueIds.forEach((id) => issueIds.add(id)) } return issueIds } export interface IssueOrPullRequest { html_url: string pull_request: Record<string, string> | null body: string | null } async function fetchIssue(id: string): Promise<IssueOrPullRequest> { const repo = await getInfo() const response = await fetch( `https://api.github.com/repos/${repo.owner}/${repo.name}/issues/${id}`, { headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, }, }, ) const resource = (await response.json()) as Promise<IssueOrPullRequest> return resource }