2019-08-19 10:46:32 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
/* eslint-disable */
|
|
|
|
|
|
|
|
const requestPromise = require( 'request-promise' );
|
|
|
|
const chalk = require( 'chalk' );
|
|
|
|
const octokit = require( '@octokit/rest' )();
|
|
|
|
const promptly = require( 'promptly' );
|
|
|
|
|
|
|
|
const REPO = 'woocommerce/woocommerce-gutenberg-products-block';
|
|
|
|
|
|
|
|
const headers = {
|
|
|
|
'Content-Type': 'application/json;charset=UTF-8',
|
2019-09-05 15:09:31 +00:00
|
|
|
Authorization: `token ${ process.env.GH_API_TOKEN }`,
|
|
|
|
Accept: 'application/vnd.github.inertia-preview+json',
|
|
|
|
'User-Agent': 'request',
|
2019-08-19 10:46:32 +00:00
|
|
|
};
|
|
|
|
|
2019-09-05 15:09:31 +00:00
|
|
|
const getPullRequestType = ( labels ) => {
|
2019-09-09 10:52:48 +00:00
|
|
|
const typeLabel = labels.find( ( label ) =>
|
|
|
|
label.name.includes( 'type:' )
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
if ( ! typeLabel ) {
|
|
|
|
return 'dev';
|
|
|
|
}
|
|
|
|
return typeLabel.name.replace( 'type: ', '' );
|
|
|
|
};
|
|
|
|
|
|
|
|
const isCollaborator = async ( username ) => {
|
|
|
|
return requestPromise( {
|
|
|
|
url: `https://api.github.com/orgs/woocommerce/members/${ username }`,
|
|
|
|
headers,
|
2019-09-05 15:09:31 +00:00
|
|
|
resolveWithFullResponse: true,
|
2019-08-19 10:46:32 +00:00
|
|
|
} )
|
2019-09-05 15:09:31 +00:00
|
|
|
.then( ( response ) => {
|
|
|
|
return response.statusCode === 204;
|
|
|
|
} )
|
|
|
|
.catch( ( err ) => {
|
2019-08-19 10:46:32 +00:00
|
|
|
if ( err.statusCode !== 404 ) {
|
|
|
|
console.log( '🤯' );
|
|
|
|
console.log( err.message );
|
|
|
|
}
|
2019-09-05 15:09:31 +00:00
|
|
|
} );
|
|
|
|
};
|
2019-08-19 10:46:32 +00:00
|
|
|
|
|
|
|
const isMergedPullRequest = async ( pullRequestUrl ) => {
|
|
|
|
const options = {
|
|
|
|
url: pullRequestUrl,
|
|
|
|
headers,
|
|
|
|
json: true,
|
|
|
|
};
|
|
|
|
return requestPromise( options )
|
2019-09-05 15:09:31 +00:00
|
|
|
.then( ( data ) => data.merged )
|
|
|
|
.catch( ( err ) => {
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '🤯' );
|
|
|
|
console.log( err.message );
|
2019-09-05 15:09:31 +00:00
|
|
|
} );
|
|
|
|
};
|
2019-08-19 10:46:32 +00:00
|
|
|
|
|
|
|
const getEntry = async ( data ) => {
|
|
|
|
if ( ! data.pull_request ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isMerged = await isMergedPullRequest( data.pull_request.url );
|
2019-09-05 15:09:31 +00:00
|
|
|
const skipChangelog = data.labels.find(
|
|
|
|
( label ) => label.name === 'skip-changelog'
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
|
|
|
|
if ( ! isMerged || skipChangelog ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const collaborator = await isCollaborator( data.user.login );
|
|
|
|
const type = getPullRequestType( data.labels );
|
|
|
|
const authorTag = collaborator ? '' : `👏 @${ data.user.login }`;
|
|
|
|
let title;
|
|
|
|
if ( /### Changelog\r\n\r\n> /.test( data.body ) ) {
|
|
|
|
const bodyParts = data.body.split( '### Changelog\r\n\r\n> ' );
|
|
|
|
const note = bodyParts[ bodyParts.length - 1 ];
|
|
|
|
title = note
|
|
|
|
// Remove comment prompt
|
|
|
|
.replace( /<!---(.*)--->/gm, '' )
|
|
|
|
// Remove new lines and whitespace
|
|
|
|
.trim();
|
|
|
|
if ( ! title.length ) {
|
|
|
|
title = `${ type }: ${ data.title }`;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
title = `${ type }: ${ data.title }`;
|
|
|
|
}
|
|
|
|
return `- ${ title } #${ data.number } ${ authorTag }`;
|
|
|
|
};
|
|
|
|
|
2019-09-05 15:09:31 +00:00
|
|
|
const makeChangelog = async ( version ) => {
|
2019-08-19 10:46:32 +00:00
|
|
|
const results = await octokit.search.issuesAndPullRequests( {
|
|
|
|
q: `milestone:${ version }+type:pr+repo:${ REPO }`,
|
|
|
|
sort: 'reactions',
|
|
|
|
per_page: 100,
|
|
|
|
} );
|
2019-09-05 15:09:31 +00:00
|
|
|
const entries = await Promise.all(
|
|
|
|
results.data.items.map( async ( pr ) => await getEntry( pr ) )
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
|
|
|
|
if ( ! entries || ! entries.length ) {
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow( "This version doesn't have any associated PR." )
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const filteredEntries = entries.filter( Boolean );
|
|
|
|
|
|
|
|
if ( ! entries || ! entries.length ) {
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow(
|
|
|
|
'None of the PRs of this version are eligible for the changelog.'
|
|
|
|
)
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log( filteredEntries.join( '\n' ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
( async () => {
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow(
|
|
|
|
'This program requires an api token. You can create one here: '
|
|
|
|
) + 'https://github.com/settings/tokens'
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow(
|
|
|
|
'Token scope will require read permissions on public_repo, admin:org, and user.'
|
|
|
|
)
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow(
|
|
|
|
'Export the token as variable called GH_API_TOKEN from your bash profile.'
|
|
|
|
)
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
|
|
|
|
|
|
|
const ready = await promptly.confirm( 'Are you ready to continue? ' );
|
|
|
|
|
|
|
|
if ( ready ) {
|
|
|
|
console.log( '' );
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow(
|
|
|
|
'In order to generate the changelog, you will have to provide a version number to retrieve the PRs from.'
|
|
|
|
)
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.yellow( 'Write it as it appears in the milestones page: ' ) +
|
|
|
|
'https://github.com/woocommerce/woocommerce-gutenberg-products-block/milestones'
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
|
|
|
const version = await promptly.prompt( 'Version number: ' );
|
|
|
|
console.log( '' );
|
2019-09-05 15:09:31 +00:00
|
|
|
console.log(
|
|
|
|
chalk.green(
|
|
|
|
'Here is the generated changelog. Be sure to remove entries ' +
|
|
|
|
'not intended for a WooCommerce Blocks release.'
|
|
|
|
)
|
|
|
|
);
|
2019-08-19 10:46:32 +00:00
|
|
|
console.log( '' );
|
|
|
|
makeChangelog( version );
|
|
|
|
} else {
|
|
|
|
console.log( '' );
|
|
|
|
console.log( chalk.yellow( 'Ok, see you soon.' ) );
|
|
|
|
console.log( '' );
|
|
|
|
}
|
|
|
|
} )();
|