woocommerce/tools/release-posts/lib/github-api.ts

146 lines
3.0 KiB
TypeScript

/**
* External dependencies
*/
import { Octokit } from '@octokit/rest';
import shuffle from 'lodash.shuffle';
/**
* Internal dependencies
*/
import { getEnvVar } from './environment';
export type ContributorData = {
totalCommits: number;
contributors: Record< string, unknown >[];
org: string;
repo: string;
baseRef: string;
headRef: string;
};
const filterUniqBy = ( arr: Record< string, unknown >[], key: string ) => {
const seen = new Set();
return arr.filter( ( item ) => {
const k = item[ key ];
if ( seen.has( k ) ) {
return false;
}
seen.add( k );
return true;
} );
};
const PAGE_SIZE = 100;
export const getContributorData = async (
orgName: string,
repoName: string,
baseRef: string,
headRef: string
) => {
const octokit = new Octokit( {
auth: getEnvVar( 'GITHUB_ACCESS_TOKEN', true ),
} );
const {
data: { total_commits, commits },
} = await octokit.repos.compareCommitsWithBasehead( {
owner: orgName,
repo: repoName,
basehead: `${ baseRef }...${ headRef }`,
per_page: PAGE_SIZE,
} );
const pages = Math.ceil( total_commits / PAGE_SIZE );
const allAuthors = [];
// add page 1 commits
allAuthors.push(
...commits
.filter( ( commit ) => {
return (
!! commit.author && ! commit.author.login.includes( 'bot' )
);
} )
.map( ( commit ) => commit.author )
);
for ( let i = 2; i <= pages; i++ ) {
const {
data: { commits: pageCommits },
} = await octokit.repos.compareCommitsWithBasehead( {
owner: orgName,
repo: repoName,
basehead: `${ baseRef }...${ headRef }`,
per_page: PAGE_SIZE,
page: i,
} );
allAuthors.push(
...pageCommits
.filter( ( commit ) => {
return (
!! commit.author &&
! commit.author.login.includes( 'bot' )
);
} )
.map( ( commit ) => commit.author )
);
}
return {
totalCommits: total_commits,
contributors: shuffle(
filterUniqBy(
allAuthors as Array< Record< string, unknown > >,
'login'
)
),
org: orgName,
repo: repoName,
baseRef,
headRef,
} as ContributorData;
};
export const getMostRecentFinal = async () => {
const octokit = new Octokit( {
auth: getEnvVar( 'GITHUB_ACCESS_TOKEN', true ),
} );
const release = await octokit.repos.getLatestRelease( {
owner: 'woocommerce',
repo: 'woocommerce',
} );
return release.data;
};
export const getMostRecentBeta = async () => {
const octokit = new Octokit( {
auth: getEnvVar( 'GITHUB_ACCESS_TOKEN', true ),
} );
const { data: releases } = await octokit.repos.listReleases( {
owner: 'woocommerce',
repo: 'woocommerce',
} );
const betaReleases = releases.filter(
( release ) =>
release?.name && release.name.toLowerCase().includes( 'beta' )
);
if ( betaReleases.length === 0 ) {
throw new Error( 'No beta releases found' );
}
const latestBetaRelease = betaReleases.reduce( ( latest, current ) => {
const latestDate = new Date( latest.created_at );
const currentDate = new Date( current.created_at );
return currentDate > latestDate ? current : latest;
} );
return latestBetaRelease;
};