Skip to content

Commit

Permalink
feat: mergify
Browse files Browse the repository at this point in the history
mergify rule that will merge automatically for a single approver and "build" job passes.
  • Loading branch information
Elad Ben-Israel committed May 18, 2020
1 parent 2207ef3 commit 5974506
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 4 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ tsconfig.json
!# synthesized by projen, but committed to git
!/.github/workflows/release.yml
!# synthesized by projen, but committed to git
!/.github/workflows/build.yml
!/.github/workflows/build.yml
!# synthesized by projen, but committed to git
!/.mergify.yml
14 changes: 14 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by projen. To modify, edit .projenrc.js and run "npx projen".

pull_request_rules:
- name: Automatic merge on approval and successful build
conditions:
- "#approved-reviews-by>=1"
- status-success=build
actions:
merge:
method: squash
commit_message: title+body
strict: smart
strict_method: merge
delete_head_branch: {}
42 changes: 40 additions & 2 deletions lib/jsii-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GithubWorkflow } from './github-workflow';
import { Project } from './project';
import { PROJEN_VERSION } from './common';
import { Jest } from './jest';
import { Mergify } from './mergify';

export interface JsiiProjectOptions extends CommonOptions {
/**
Expand Down Expand Up @@ -43,6 +44,12 @@ export interface JsiiProjectOptions extends CommonOptions {
* @default true
*/
readonly jest?: boolean;

/**
* Add mergify configuration
* @default true
*/
readonly mergify?: boolean;
}

export enum Stability {
Expand Down Expand Up @@ -163,12 +170,38 @@ export class JsiiProject extends NodeProject {
this.npmignore.comment('include .jsii manifest');
this.npmignore.include('.jsii');

new JsiiBuildWorkflow(this, options.workflowOptions);
const buildWorkflow = new JsiiBuildWorkflow(this, options.workflowOptions);

const jest = options.jest ?? true;
if (jest) {
new Jest(this);
}

const mergify = options.mergify ?? true;
if (mergify) {
const m = new Mergify(this);
m.addRule({
name: 'Automatic merge on approval and successful build',
conditions: [
'#approved-reviews-by>=1',
`status-success=${buildWorkflow.jobName}`,
],
actions: {
merge: {
// squash all commits into a single commit when merging
method: 'squash',

// use PR title+body as the commit message
commit_message: 'title+body',

// update PR branch so it's up-to-date before merging
strict: 'smart',
strict_method: 'merge',
},
delete_head_branch: { },
},
});
}
}
}

Expand Down Expand Up @@ -340,13 +373,18 @@ class JsiiReleaseWorkflow extends GithubWorkflow {
}

export class JsiiBuildWorkflow extends GithubWorkflow {

public readonly jobName: string;

constructor(project: Project, options: WorkflowOptions = { }) {
super(project, 'build', { name: 'Build' });

this.jobName = 'build';

this.on({ pull_request: { } });

this.addJobs({
build: {
[this.jobName]: {
'runs-on': 'ubuntu-latest',
container: {
image: 'jsii/superchain',
Expand Down
2 changes: 1 addition & 1 deletion lib/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface JsonFileOptions extends FileBaseOptions {
}

export class JsonFile extends FileBase {
private readonly obj: object;
protected readonly obj: object;

constructor(project: Project, filePath: string, options: JsonFileOptions) {
super(project, filePath, options);
Expand Down
32 changes: 32 additions & 0 deletions lib/mergify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Construct } from 'constructs';
import { Project } from './project';
import { YamlFile } from './yaml';

export interface MergifyRule {
readonly name: string;
readonly conditions: string[];
readonly actions: { [action: string]: any };
}

export interface MergifyOptions {
readonly rules?: MergifyRule[];
}

export class Mergify extends Construct {
private readonly rules = new Array<MergifyRule>();

constructor(project: Project) {
super(project, 'mergify');

new YamlFile(project, '.mergify.yml', {
committed: true, // must be committed for mergify to be able to find it dah!
obj: {
pull_request_rules: this.rules,
},
});
}

public addRule(rule: MergifyRule) {
this.rules.push(rule);
}
}
24 changes: 24 additions & 0 deletions lib/yaml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { JsonFile, JsonFileOptions } from './json';
import * as YAML from 'yaml';
import { Project } from './project';
import { GENERATION_DISCLAIMER } from './common';

export interface YamlFileOptions extends JsonFileOptions {

}

export class YamlFile extends JsonFile {
constructor(project: Project, filePath: string, options: YamlFileOptions) {
super(project, filePath, options);
}

protected get data() {
// sanitize object references by serializaing and deserializing to JSON
const sanitized = JSON.parse(JSON.stringify(this.obj));
return [
`# ${GENERATION_DISCLAIMER}`,
'',
YAML.stringify(sanitized, { indent: 2 }),
].join('\n')
}
}

0 comments on commit 5974506

Please sign in to comment.