Skip to content

Commit

Permalink
Implement support for creating draft PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
greglockwood committed Jan 9, 2021
1 parent 724a04b commit b1233f6
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ If you run with `--create-prs` again, `pr-train` will only override the Table of

**Pro-tip**: If you want to udpate the ToCs in your GitHub PRs, just update the PR titles and re-run pr train with `--create-prs` - it will do the right thing.

### Draft PRs

To create PRs in draft mode ([if your repo allows](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests)),
pass the `-d` or `--draft` argument on the command line (instead of, or in addition to, `-c`/`--create-prs`).

You can also configure PRs to be created in draft mode by default if you add the following section to your `.pr-train.yml` file:

```yaml
prs:
draft-by-default: true

trains:
# etc
```

Specifying this option will allow you to omit the `-d`/`--draft` parameter (though you still need to specify `-c`/`--create-prs`) when you want to create/update PRs.

## Example with explanation

You finished coding a feature and now you have a patch that is over 1000 SLOCs long. That's a big patch. As a good citizen, you want to split the diff into multiple PRs, e.g.:
Expand Down
4 changes: 4 additions & 0 deletions cfg_template.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
prs:
# Change this if you use a different name for your default branch (e.g. main)
main-branch-name: master
# Create new PRs in draft mode by default. This will prevent them from notifying anybody
# until you are ready. This option can be overridden on the command line using the
# -d/--draft or --no-draft options, which set draft mode to true or false, respectively.
draft-by-default: true

trains:
# This is an example. This PR train would have 4 branches plus 1 "combined" branch to run tests etc on.
Expand Down
9 changes: 7 additions & 2 deletions github.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ function checkAndReportInvalidBaseError(e, base) {
* @param {simpleGit.SimpleGit} sg
* @param {Array.<string>} allBranches
* @param {string} combinedBranch
* @param {boolean} draft
* @param {string} remote
* @param {string} baseBranch
*/
async function ensurePrsExist({
sg,
allBranches,
combinedBranch,
draft,
remote = DEFAULT_REMOTE,
baseBranch = DEFAULT_MAIN_BRANCH
}) {
Expand Down Expand Up @@ -131,8 +133,10 @@ async function ensurePrsExist({
body: '',
});

const prText = draft ? 'draft PR' : 'PR';

console.log();
console.log('This will create (or update) PRs for the following branches:');
console.log(`This will create (or update) ${prText}s for the following branches:`);
await allBranches.reduce(async (memo, branch) => {
await memo;
const {
Expand Down Expand Up @@ -185,9 +189,10 @@ async function ensurePrsExist({
base,
title,
body,
draft,
};
const baseMessage = base === baseBranch ? colors.dim(` (against ${base})`) : '';
process.stdout.write(`Creating PRs for branch "${branch}"${baseMessage}...`);
process.stdout.write(`Creating ${prText} for branch "${branch}"${baseMessage}...`);
try {
prResponse = (await ghRepo.prAsync(payload))[0];
} catch (e) {
Expand Down
25 changes: 21 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ const fs = require('fs');
const yaml = require('js-yaml');
const { ensurePrsExist, readGHKey, checkGHKeyExists } = require('./github');
const colors = require('colors');
const { DEFAULT_REMOTE, DEFAULT_MAIN_BRANCH, MERGE_STEP_DELAY_MS, MERGE_STEP_DELAY_WAIT_FOR_LOCK } = require('./consts');
const {
DEFAULT_REMOTE,
DEFAULT_MAIN_BRANCH,
MERGE_STEP_DELAY_MS,
MERGE_STEP_DELAY_WAIT_FOR_LOCK,
} = require('./consts');
const path = require('path');
// @ts-ignore
const package = require('./package.json');
Expand Down Expand Up @@ -130,10 +135,11 @@ function getBranchesInCurrentTrain(branchConfig) {
*/
function getCombinedBranch(branchConfig) {
const combinedBranch = /** @type {Object<string, {combined: boolean}>} */ branchConfig.find(cfg => {
if (typeof cfg === 'string') {
if (!cfg || typeof cfg === 'string') {
return false;
}
const branchName = Object.keys(cfg)[0];
// console.log(`cfg = ${JSON.stringify(cfg)}, branchName = ${branchName}`);
return cfg[branchName].combined;
});
if (!combinedBranch) {
Expand Down Expand Up @@ -223,6 +229,8 @@ async function main() {
.option('--push-merged', 'Push all branches (including those that have already been merged into the base branch)')
.option('--remote <remote>', 'Set remote to push to. Defaults to "origin"')
.option('-b, --base <base>', `Specify the base branch to use for the first and combined PRs.`, defaultBase)
.option('-d, --draft', 'Create PRs in draft mode. Implies --create-prs.')
.option('--no-draft', 'Do not create PRs in draft mode. Implies --create-prs.')
.option('-c, --create-prs', 'Create GitHub PRs from your train branches');

program.on('--help', () => {
Expand All @@ -249,9 +257,17 @@ async function main() {

program.parse(process.argv);

program.createPrs && checkGHKeyExists();
const createPrs = program.draft != null || program.createPrs;

createPrs && checkGHKeyExists();

const baseBranch = program.base; // will have default value if one is not supplied

// if there is no `-d`/`--draft`/`--no-draft` option specified, try to extract it from the config file
const draft = program.draft != null
? program.draft
: !!getConfigOption(ymlConfig, 'prs.draft-by-default');

const { current: currentBranch, all: allBranches } = await sg.branchLocal();
const trainCfg = await getBranchesConfigInCurrentTrain(sg, ymlConfig);
if (!trainCfg) {
Expand Down Expand Up @@ -306,13 +322,14 @@ async function main() {

// If we're creating PRs, don't combine branches (that might change branch HEADs and consequently
// the PR titles and descriptions). Just push and create the PRs.
if (program.createPrs) {
if (createPrs) {
await findAndPushBranches();
await ensurePrsExist({
sg,
allBranches: sortedTrainBranches,
combinedBranch: combinedTrainBranch,
remote: program.remote,
draft,
baseBranch,
});
return;
Expand Down

0 comments on commit b1233f6

Please sign in to comment.