Skip to content

Commit

Permalink
Feature: Add support for merge commits (#303)
Browse files Browse the repository at this point in the history
* Add support for merge commits
* Fix bug where backport would fail if no .backportrc.json file existed
* Fix problem with clone
* Improve tests
  • Loading branch information
sorenlouv authored Feb 20, 2022
1 parent da4b365 commit 75efeaf
Show file tree
Hide file tree
Showing 49 changed files with 1,481 additions and 1,052 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/backport
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
os:
- linux
- osx
language: node_js
node_js:
- '16'
Expand Down
11 changes: 1 addition & 10 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,7 @@
{
"type": "node",
"request": "launch",
"name": "Run file",
"program": "${file}",
"runtimeArgs": ["-r", "ts-node/register/transpile-only"],
"console": "integratedTerminal"
},

{
"type": "node",
"request": "launch",
"name": "Start backport (CLI)",
"name": "Run backport (ts-node)",
"program": "${workspaceRoot}/src/entrypoint.cli.ts",
"runtimeArgs": ["-r", "ts-node/register/transpile-only"],
"args": [
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"coverage": true
},
"search.exclude": {
"dist/*": true,
"**/node_modules": true,
"**/bower_components": true,
"**/*.code-search": true,
Expand All @@ -14,7 +15,7 @@
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}
22 changes: 6 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,19 @@
### Run

```
yarn start --branch 6.1 --repo-owner backport-org --repo-name backport-demo --all
yarn start --branch 6.1 --repo backport-org/backport-demo --all
```

or
**Run `backport` CLI globally**
This will build backport continously and link it, so it can accessed with `backport` command globally

```
# Compile
yarn tsc
# Run
node dist/entrypoint.cli.js --branch 6.1 --repo-owner backport-org --repo-name backport-demo --all
yarn tsc && sudo chmod +x bin/backport && yarn link && yarn tsc --watch
```

**Run `backport` CLI globally**

**Remove linked backport**
```
yarn global remove backport
npm -g uninstall backport
yarn unlink backport
yarn unlink
yarn link
sudo chmod +x dist/entrypoint.cli.js
yarn tsc --watch
yarn global remove backport; npm -g uninstall backport; yarn unlink backport; yarn unlink;
```

You can now use `backport` command anywhere, and it'll point to the development version.
Expand Down
2 changes: 2 additions & 0 deletions bin/backport
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
require('../dist/entrypoint.cli.js')
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"main": "./dist/entrypoint.module.js",
"types": "dist/entrypoint.module.d.ts",
"bin": {
"backport": "./dist/entrypoint.cli.js"
"backport": "./bin/backport"
},
"license": "MIT",
"scripts": {
Expand Down Expand Up @@ -78,7 +78,7 @@
"strip-json-comments": "^3.1.1",
"terminal-link": "^2.1.1",
"utility-types": "^3.10.0",
"winston": "^3.5.1",
"winston": "^3.6.0",
"yargs": "^17.3.1",
"yargs-parser": "^21.0.0"
},
Expand All @@ -88,22 +88,22 @@
"@types/inquirer": "^8.2.0",
"@types/jest": "^27.4.0",
"@types/lodash": "^4.14.178",
"@types/node": "^17.0.8",
"@types/node": "^17.0.18",
"@types/safe-json-stringify": "^1.1.2",
"@types/yargs": "^17.0.8",
"@types/yargs-parser": "^20.2.1",
"@typescript-eslint/eslint-plugin": "^5.11.0",
"@typescript-eslint/parser": "^5.11.0",
"eslint": "^8.8.0",
"eslint-config-prettier": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.4.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^26.1.0",
"eslint-plugin-jest": "^26.1.1",
"eslint-plugin-prettier": "^4.0.0",
"graphql-config": "^4.1.0",
"husky": "^7.0.4",
"jest": "^27.5.1",
"jest-snapshot-serializer-ansi": "^1.0.0",
"lint-staged": "^12.3.3",
"lint-staged": "^12.3.4",
"nock": "^13.2.4",
"prettier": "^2.5.1",
"strip-ansi": "^6.0.1",
Expand Down
21 changes: 11 additions & 10 deletions src/entrypoint.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import { fetchCommitBySha } from './services/github/v4/fetchCommits/fetchCommitB
import { fetchCommitsByAuthor } from './services/github/v4/fetchCommits/fetchCommitsByAuthor';
import { getOptionsFromGithub } from './services/github/v4/getOptionsFromGithub/getOptionsFromGithub';
import { initLogger } from './services/logger';
import { Commit } from './services/sourceCommit/parseSourceCommit';
import { excludeUndefined } from './utils/excludeUndefined';

// public API
export { BackportResponse } from './backportRun';
export { ConfigFileOptions } from './options/ConfigOptions';
export { Commit } from './services/sourceCommit/parseSourceCommit';
export { Commit };
export { fetchRemoteProjectConfig as getRemoteProjectConfig } from './services/github/v4/fetchRemoteProjectConfig';
export { getGlobalConfig as getLocalGlobalConfig } from './options/config/globalConfig';

Expand Down Expand Up @@ -41,12 +42,12 @@ export async function getCommits(options: {
branchLabelMapping?: ValidConfigOptions['branchLabelMapping'];
githubApiBaseUrlV4?: string;
pullNumber?: number;
sha?: string;
sha?: string | string[];
skipRemoteConfig?: boolean;
sourceBranch?: string;
dateUntil?: string;
dateSince?: string;
}) {
}): Promise<Commit[]> {
initLogger({ ci: true, accessToken: options.accessToken });

const optionsFromGithub = await getOptionsFromGithub(options);
Expand All @@ -62,13 +63,13 @@ export async function getCommits(options: {
}

if (options.sha) {
return [
await fetchCommitBySha({
...optionsFromGithub,
...options,
sha: options.sha,
}),
];
const shas = Array.isArray(options.sha) ? options.sha : [options.sha];

return Promise.all(
shas.map((sha) =>
fetchCommitBySha({ ...optionsFromGithub, ...options, sha })
)
);
}

return fetchCommitsByAuthor({
Expand Down
2 changes: 1 addition & 1 deletion src/options/ConfigOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Options = Partial<{
repoOwner: string;
resetAuthor: boolean;
reviewers: string[];
sha: string;
sha: string | string[];
skipRemoteConfig: boolean;
sourceBranch: string;
sourcePRLabels: string[];
Expand Down
5 changes: 5 additions & 0 deletions src/options/cliArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export function getOptionsFromCliArgs(
type: 'boolean',
})

.option('dryRun', {
description: 'Run backport locally without pushing to Github',
type: 'boolean',
})

.option('editor', {
description: 'Editor to be opened during conflict resolution',
type: 'string',
Expand Down
87 changes: 57 additions & 30 deletions src/runSequentially.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe('runSequentially', () => {

rpcExecMock = jest
.spyOn(childProcess, 'exec')
.mockResolvedValue({ stdout: 'success', stderr: '' });
.mockResolvedValue({ stdout: '', stderr: '' });
rpcExecOriginalMock = jest.spyOn(childProcess, 'execAsCallback');

const scope = nock('https://api.github.com')
Expand Down Expand Up @@ -162,36 +162,63 @@ describe('runSequentially', () => {
`);
});

it('should run all exec commands in the either source or backport directory', () => {
it('should run commands in correct folders', () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
expect(rpcExecMock.mock.calls.map(([cmd, opts]) => opts.cwd)).toEqual([
'/path/to/source/repo',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
'/myHomeDir/.backport/repositories/elastic/kibana',
]);
});

it('exec commands should be called with correct args', () => {
expect(rpcExecMock.mock.calls.map(([cmd]) => cmd)).toEqual([
'git remote --verbose',
'git remote rm origin',
'git remote rm sqren_authenticated',
'git remote add sqren_authenticated https://x-access-token:[email protected]/sqren_authenticated/kibana.git',
'git remote rm elastic',
'git remote add elastic https://x-access-token:[email protected]/elastic/kibana.git',
'git reset --hard && git clean -d --force && git fetch elastic 7.x && git checkout -B backport/7.x/pr-55 elastic/7.x --no-track',
'git fetch elastic master:master --force',
'git cherry-pick -x abcd',
'git push sqren_authenticated backport/7.x/pr-55:backport/7.x/pr-55 --force',
'git reset --hard && git checkout my-source-branch-from-options && git branch -D backport/7.x/pr-55',
expect(
rpcExecMock.mock.calls.map(([cmd, { cwd }]) => ({ cmd, cwd }))
).toEqual([
{
cmd: 'git rev-parse --show-toplevel',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git remote --verbose',
cwd: '/path/to/source/repo',
},
{
cmd: 'git remote rm origin',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git remote rm sqren_authenticated',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git remote add sqren_authenticated https://x-access-token:[email protected]/sqren_authenticated/kibana.git',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git remote rm elastic',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git remote add elastic https://x-access-token:[email protected]/elastic/kibana.git',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git reset --hard && git clean -d --force && git fetch elastic 7.x && git checkout -B backport/7.x/pr-55 elastic/7.x --no-track',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git fetch elastic master:master --force',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git rev-list -1 --merges abcd~1..abcd',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git cherry-pick -x abcd',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git push sqren_authenticated backport/7.x/pr-55:backport/7.x/pr-55 --force',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
{
cmd: 'git reset --hard && git checkout my-source-branch-from-options && git branch -D backport/7.x/pr-55',
cwd: '/myHomeDir/.backport/repositories/elastic/kibana',
},
]);
});

Expand Down
1 change: 1 addition & 0 deletions src/runSequentially.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export async function runSequentially({
pullRequestNumber: number,
});
} catch (e) {
process.exitCode = 1;
results.push({
targetBranch,
status: 'failure',
Expand Down
Loading

0 comments on commit 75efeaf

Please sign in to comment.