refactor: start moving tasks to operations dir (#88)

This commit is contained in:
Shelley Vohr 2019-04-16 03:58:18 +03:00 коммит произвёл Samuel Attard
Родитель 456a18a0d8
Коммит f76980c3f7
5 изменённых файлов: 87 добавлений и 53 удалений

Просмотреть файл

@ -4,7 +4,7 @@ import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as simpleGit from 'simple-git/promise'; import * as simpleGit from 'simple-git/promise';
import { initRepo, setUpRemotes } from '../runner'; import { initRepo, setupRemotes } from '../../operations/task-runner';
let dirObject: { dir?: string } | null = null; let dirObject: { dir?: string } | null = null;
@ -57,7 +57,7 @@ describe('runner', () => {
}); });
it('should set new remotes correctly', async () => { it('should set new remotes correctly', async () => {
await setUpRemotes({ await setupRemotes({
dir, dir,
remotes: [{ remotes: [{
name: 'origin', name: 'origin',

Просмотреть файл

@ -7,17 +7,15 @@ import * as simpleGit from 'simple-git/promise';
import { Label, PullRequest, TropConfig } from './Probot'; import { Label, PullRequest, TropConfig } from './Probot';
import queue from './Queue'; import queue from './Queue';
import { runCommand } from './runner'; import { runCommand } from '../operations/task-runner';
import { CHECK_PREFIX } from '../constants'; import { CHECK_PREFIX } from '../constants';
import { PRChange, TropAction, PRStatus } from '../enums'; import { PRChange, TropAction, PRStatus } from '../enums';
import * as labelUtils from '../utils/label-utils';
const makeQueue: IQueue = require('queue'); const makeQueue: IQueue = require('queue');
const { parse: parseDiff } = require('what-the-diff'); const { parse: parseDiff } = require('what-the-diff');
export const labelToTargetBranch = (label: Label, prefix: string) => {
return label.name.replace(prefix, '');
};
const getGitHub = () => { const getGitHub = () => {
const g = new GitHub(); const g = new GitHub();
g.authenticate({ g.authenticate({
@ -36,8 +34,8 @@ export const labelMergedPR = async (context: Context, pr: PullRequest, targetBra
const labelToAdd = `${labelPrefixes.merged}${targetBranch}`; const labelToAdd = `${labelPrefixes.merged}${targetBranch}`;
const labelToRemove = labelPrefixes.inFlight + targetBranch; const labelToRemove = labelPrefixes.inFlight + targetBranch;
await removeLabel(context, prNumber, labelToRemove); await labelUtils.removeLabel(context, prNumber, labelToRemove);
await addLabel(context, prNumber, [labelToAdd]); await labelUtils.addLabel(context, prNumber, [labelToAdd]);
} }
}; };
@ -154,6 +152,7 @@ export const backportImpl = async (robot: Application,
targetRepoRemote = targetRepoRemote =
`https://${process.env.GITHUB_FORK_USER_CLONE_LOGIN}:${process.env.GITHUB_FORK_USER_TOKEN}@github.com/${slug}.git`; `https://${process.env.GITHUB_FORK_USER_CLONE_LOGIN}:${process.env.GITHUB_FORK_USER_TOKEN}@github.com/${slug}.git`;
} }
await runCommand({ await runCommand({
what: TropAction.SET_UP_REMOTES, what: TropAction.SET_UP_REMOTES,
payload: { payload: {
@ -269,15 +268,15 @@ export const backportImpl = async (robot: Application,
if (labelToRemove) { if (labelToRemove) {
log(`Removing label '${labelToRemove}'`); log(`Removing label '${labelToRemove}'`);
await removeLabel(context, pr.number, labelToRemove); await labelUtils.removeLabel(context, pr.number, labelToRemove);
} }
if (labelToAdd) { if (labelToAdd) {
log(`Adding label '${labelToAdd}'`); log(`Adding label '${labelToAdd}'`);
await addLabel(context, pr.number, [labelToAdd]); await labelUtils.addLabel(context, pr.number, [labelToAdd]);
} }
await addLabel(context, newPr.number!, ['backport', `${targetBranch}`]); await labelUtils.addLabel(context, newPr.number!, ['backport', `${targetBranch}`]);
log('Backport complete'); log('Backport complete');
} }
@ -343,10 +342,10 @@ export const backportImpl = async (robot: Application,
const labelPrefixes = await getLabelPrefixes(context); const labelPrefixes = await getLabelPrefixes(context);
const labelToRemove = labelPrefixes.target + targetBranch; const labelToRemove = labelPrefixes.target + targetBranch;
await removeLabel(context, pr.number, labelToRemove); await labelUtils.removeLabel(context, pr.number, labelToRemove);
const labelToAdd = labelPrefixes.needsManual + targetBranch; const labelToAdd = labelPrefixes.needsManual + targetBranch;
await addLabel(context, pr.number, [labelToAdd]); await labelUtils.addLabel(context, pr.number, [labelToAdd]);
} }
if (purpose === BackportPurpose.Check) { if (purpose === BackportPurpose.Check) {
@ -378,16 +377,6 @@ export const backportImpl = async (robot: Application,
); );
}; };
const labelExistsOnPR = async (context: Context, labelName: string) => {
const labels = await context.github.issues.listLabelsOnIssue(context.repo({
number: context.payload.pull_request.number,
per_page: 100,
page: 1,
}));
return labels.data.some(label => label.name === labelName);
};
export const getLabelPrefixes = async (context: Pick<Context, 'config'>) => { export const getLabelPrefixes = async (context: Pick<Context, 'config'>) => {
const config = await context.config<TropConfig>('config.yml') || {}; const config = await context.config<TropConfig>('config.yml') || {};
const target = config.targetLabelPrefix || PRStatus.TARGET; const target = config.targetLabelPrefix || PRStatus.TARGET;
@ -411,7 +400,7 @@ export const updateManualBackport = async (
if (type === PRChange.OPEN) { if (type === PRChange.OPEN) {
labelToRemove = labelPrefixes.needsManual + pr.base.ref; labelToRemove = labelPrefixes.needsManual + pr.base.ref;
if (!await labelExistsOnPR(context, labelToRemove)) { if (!await labelUtils.labelExistsOnPR(context, labelToRemove)) {
labelToRemove = labelPrefixes.target + pr.base.ref; labelToRemove = labelPrefixes.target + pr.base.ref;
} }
labelToAdd = labelPrefixes.inFlight + pr.base.ref; labelToAdd = labelPrefixes.inFlight + pr.base.ref;
@ -441,8 +430,8 @@ please check out #${pr.number}`;
labelToAdd = labelPrefixes.merged + pr.base.ref; labelToAdd = labelPrefixes.merged + pr.base.ref;
} }
await removeLabel(context, oldPRNumber, labelToRemove); await labelUtils.removeLabel(context, oldPRNumber, labelToRemove);
await addLabel(context, oldPRNumber, [labelToAdd]); await labelUtils.addLabel(context, oldPRNumber, [labelToAdd]);
}; };
export const backportToLabel = async ( export const backportToLabel = async (
@ -456,7 +445,7 @@ export const backportToLabel = async (
return; return;
} }
const targetBranch = labelToTargetBranch(label, labelPrefixes.target); const targetBranch = labelUtils.labelToTargetBranch(label, labelPrefixes.target);
if (!targetBranch) { if (!targetBranch) {
robot.log('Nothing to do'); robot.log('Nothing to do');
return; return;
@ -482,22 +471,3 @@ export const backportToBranch = async (
robot, context, targetBranch, BackportPurpose.ExecuteBackport, labelToRemove, labelToAdd, robot, context, targetBranch, BackportPurpose.ExecuteBackport, labelToRemove, labelToAdd,
); );
}; };
// HELPERS
const addLabel = async (context: Context, prNumber: number, labelsToAdd: string[]) => {
return context.github.issues.addLabels(context.repo({
number: prNumber,
labels: labelsToAdd,
}));
};
const removeLabel = async (context: Context, prNumber: number, labelToRemove: string) => {
// If the issue does not have the label, don't try remove it
if (!await labelExistsOnPR(context, labelToRemove)) return;
return context.github.issues.removeLabel(context.repo({
number: prNumber,
name: labelToRemove,
}));
};

Просмотреть файл

@ -4,13 +4,13 @@ import {
backportToBranch, backportToBranch,
backportToLabel, backportToLabel,
getLabelPrefixes, getLabelPrefixes,
labelToTargetBranch,
backportImpl, backportImpl,
BackportPurpose, BackportPurpose,
labelMergedPR, labelMergedPR,
updateManualBackport, updateManualBackport,
} from './backport/utils'; } from './backport/utils';
import { labelToTargetBranch } from './utils/label-utils';
import { PullRequest, TropConfig } from './backport/Probot'; import { PullRequest, TropConfig } from './backport/Probot';
import { CHECK_PREFIX } from './constants'; import { CHECK_PREFIX } from './constants';
import { PRChange } from './enums'; import { PRChange } from './enums';

Просмотреть файл

@ -24,6 +24,12 @@ export type RunnerOptions = {
const baseDir = path.resolve(os.tmpdir(), 'trop-working'); const baseDir = path.resolve(os.tmpdir(), 'trop-working');
/*
* Initializes the cloned repo trop will use to run backports
*
* @param {InitRepoOptions} repo and payload for repo initialization
* @returns {Object} - an object containing the repo initialization directory
*/
export const initRepo = async (options: InitRepoOptions) => { export const initRepo = async (options: InitRepoOptions) => {
const slug = `${options.owner}/${options.repo}`; const slug = `${options.owner}/${options.repo}`;
await fs.mkdirp(path.resolve(baseDir, slug)); await fs.mkdirp(path.resolve(baseDir, slug));
@ -33,10 +39,15 @@ export const initRepo = async (options: InitRepoOptions) => {
await fs.remove(dir); await fs.remove(dir);
await fs.mkdirp(dir); await fs.mkdirp(dir);
const git = simpleGit(dir); const git = simpleGit(dir);
// This adds support for the target_repo being private as long as the fork user has read access
if (process.env.GITHUB_FORK_USER_CLONE_LOGIN) { const forkLogin = process.env.GITHUB_FORK_USER_CLONE_LOGIN;
const forkToken = process.env.GITHUB_FORK_USER_TOKEN;
// Adds support for the target_repo being private as
// long as the fork user has read access
if (forkLogin) {
await git.clone( await git.clone(
`https://${process.env.GITHUB_FORK_USER_CLONE_LOGIN}:${process.env.GITHUB_FORK_USER_TOKEN}@github.com/${slug}.git`, `https://${forkLogin}:${forkToken}@github.com/${slug}.git`,
'.', '.',
); );
} else { } else {
@ -62,7 +73,15 @@ export const initRepo = async (options: InitRepoOptions) => {
return { dir }; return { dir };
}; };
export const setUpRemotes = async (options: RemotesOptions) => { /*
* Sets up remotes that trop will run backports with.
*
* @param {RemotesOptions} - an object containing:
* 1) dir - the repo directory
* 2) remotes - the list of remotes to set on the initialized git repository
* @returns {Object} - an object containing the repo initialization directory
*/
export const setupRemotes = async (options: RemotesOptions) => {
const git = simpleGit(options.dir); const git = simpleGit(options.dir);
// Add remotes // Add remotes
@ -77,6 +96,17 @@ export const setUpRemotes = async (options: RemotesOptions) => {
return { dir: options.dir }; return { dir: options.dir };
}; };
/*
* Runs the git commands to apply backports in a series of cherry-picked commits.
*
* @param {BackportOptions} - an object containing:
* 1) dir - the repo directory,
* 2) targetBranch - the target branch
* 3) patches - a list of patches to apply to the target branch
* 3) tempBranch - the temporary branch to PR against the target branch
* 4) tempRemote - the temporary remote for use in backporting
* @returns {Object} - an object containing the repo initialization directory
*/
export const backportCommitsToBranch = async (options: BackportOptions) => { export const backportCommitsToBranch = async (options: BackportOptions) => {
const git = simpleGit(options.dir); const git = simpleGit(options.dir);
// Create branch // Create branch
@ -99,12 +129,13 @@ export const backportCommitsToBranch = async (options: BackportOptions) => {
return { dir: options.dir }; return { dir: options.dir };
}; };
// Helper method for running one of three primary git action sets
export const runCommand = async (options: RunnerOptions): Promise<{ dir: string }> => { export const runCommand = async (options: RunnerOptions): Promise<{ dir: string }> => {
switch (options.what) { switch (options.what) {
case TropAction.INIT_REPO: case TropAction.INIT_REPO:
return await initRepo(options.payload); return await initRepo(options.payload);
case TropAction.SET_UP_REMOTES: case TropAction.SET_UP_REMOTES:
return await setUpRemotes(options.payload); return await setupRemotes(options.payload);
case TropAction.BACKPORT: case TropAction.BACKPORT:
return await backportCommitsToBranch(options.payload); return await backportCommitsToBranch(options.payload);
default: default:

33
src/utils/label-utils.ts Normal file
Просмотреть файл

@ -0,0 +1,33 @@
import { Context } from 'probot';
import { Label } from '../backport/Probot';
export const addLabel = async (context: Context, prNumber: number, labelsToAdd: string[]) => {
return context.github.issues.addLabels(context.repo({
number: prNumber,
labels: labelsToAdd,
}));
};
export const removeLabel = async (context: Context, prNumber: number, labelToRemove: string) => {
// If the issue does not have the label, don't try remove it
if (!await labelExistsOnPR(context, labelToRemove)) return;
return context.github.issues.removeLabel(context.repo({
number: prNumber,
name: labelToRemove,
}));
};
export const labelToTargetBranch = (label: Label, prefix: string) => {
return label.name.replace(prefix, '');
};
export const labelExistsOnPR = async (context: Context, labelName: string) => {
const labels = await context.github.issues.listLabelsOnIssue(context.repo({
number: context.payload.pull_request.number,
per_page: 100,
page: 1,
}));
return labels.data.some(label => label.name === labelName);
};