Skip to content

Commit

Permalink
Add support for workflow_run pull_request events
Browse files Browse the repository at this point in the history
Also adds typings for incoming event data and auto mocks in tests based
off the event typing.
  • Loading branch information
chinthakagodawita committed Apr 17, 2021
1 parent dbae7e1 commit fb31698
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 86 deletions.
19 changes: 17 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
"@actions/core": "^1.2.6",
"@actions/github": "^4.0.0",
"@octokit/types": "^6.13.0",
"@octokit/webhooks": "^9.0.0",
"@types/node": "^14.14.37",
"@vercel/ncc": "^0.27.0",
"ttypescript": "^1.5.12",
"typescript": "^4.2.4"
},
"devDependencies": {
Expand All @@ -33,16 +35,29 @@
"eslint-plugin-jest": "^24.3.5",
"eslint-plugin-prettier": "^3.3.1",
"jest": "^26.6.3",
"jest-ts-auto-mock": "^2.0.0",
"nock": "^13.0.11",
"prettier": "^2.2.1",
"ts-auto-mock": "^3.1.2",
"ts-jest": "^26.5.4"
},
"jest": {
"preset": "ts-jest",
"clearMocks": true,
"collectCoverage": true,
"coverageDirectory": "coverage",
"coverageProvider": "v8",
"testEnvironment": "node"
"globals": {
"ts-jest": {
"compiler": "ttypescript"
}
},
"preset": "ts-jest",
"setupFiles": [
"<rootDir>/test/config.ts"
],
"testEnvironment": "node",
"transform": {
".(ts|tsx)": "ts-jest"
}
}
}
56 changes: 32 additions & 24 deletions src/autoupdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,48 @@ import * as github from '@actions/github';
import { GitHub } from '@actions/github/lib/utils';
import * as ghCore from '@actions/core';
import * as octokit from '@octokit/types';
import {
PullRequestEvent,
PushEvent,
Repository,
WebhookEvent,
WorkflowRunEvent,
} from '@octokit/webhooks-definitions/schema';
import { ConfigLoader } from './config-loader';
import { PayloadRepository } from '@actions/github/lib/interfaces';
import { Endpoints } from '@octokit/types';

type PullRequest =
| PullRequestResponse['data']
| PullRequestEvent['pull_request'];
type PullRequestResponse = Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}']['response'];
type MergeParameters = Endpoints['POST /repos/{owner}/{repo}/merges']['parameters'];

export class AutoUpdater {
eventData: any;
// See https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads
eventData: WebhookEvent;
config: ConfigLoader;
octokit: InstanceType<typeof GitHub>;

constructor(
config: ConfigLoader,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
eventData: any,
) {
constructor(config: ConfigLoader, eventData: WebhookEvent) {
this.eventData = eventData;
this.config = config;
this.octokit = github.getOctokit(this.config.githubToken());
}

async handlePush(): Promise<number> {
const { ref, repository } = this.eventData;
const { ref, repository } = this.eventData as PushEvent;

ghCore.info(`Handling push event on ref '${ref}'`);

return await this.pulls(ref, repository);
}

async handlePullRequest(): Promise<boolean> {
const { action } = this.eventData;
const { action, pull_request } = this.eventData as PullRequestEvent;

ghCore.info(`Handling pull_request event triggered by action '${action}'`);

const isUpdated = await this.update(this.eventData.pull_request);
const isUpdated = await this.update(pull_request);
if (isUpdated) {
ghCore.info(
'Auto update complete, pull request branch was updated with changes from the base branch.',
Expand All @@ -50,31 +56,33 @@ export class AutoUpdater {
}

async handleWorkflowRun(): Promise<number> {
const { workflow_run, repository } = this.eventData;
const branch = workflow_run.head_branch;
const event = workflow_run.event;
const { workflow_run: workflowRun, repository } = this
.eventData as WorkflowRunEvent;
const { head_branch: branch, event } = workflowRun;

if (workflow_run.event !== 'push') {
ghCore.warning(
`Workflow_run event triggered via ${event} workflow not yet supported.`,
if (!['push', 'pull_request'].includes(event)) {
ghCore.error(
`workflow_run events triggered via ${event} workflows are not supported.`,
);
return 0;
}

// this may not be possible given the check above, but leaving in for now
if (branch.length === 0) {
// This may not be possible given the check above, but here for safety.
if (!branch) {
ghCore.warning('Event was not on a branch, skipping.');
return 0;
}

ghCore.info(
`Handling workflow-run event triggered by '${event}' on '${branch}'`,
`Handling workflow_run event triggered by '${event}' on '${branch}'`,
);

// The `pull_request` event is handled the same way as `push` as we may
// get multiple PRs.
return await this.pulls(`refs/heads/${branch}`, repository);
}

async pulls(ref: string, repository: PayloadRepository): Promise<number> {
async pulls(ref: string, repository: Repository): Promise<number> {
if (!ref.startsWith('refs/heads/')) {
ghCore.warning('Push event was not on a branch, skipping.');
return 0;
Expand Down Expand Up @@ -113,7 +121,7 @@ export class AutoUpdater {
return updated;
}

async update(pull: octokit.PullsUpdateResponseData): Promise<boolean> {
async update(pull: PullRequest): Promise<boolean> {
const { ref } = pull.head;
ghCore.info(`Evaluating pull request #${pull.number}...`);

Expand Down Expand Up @@ -161,7 +169,7 @@ export class AutoUpdater {
return true;
}

async prNeedsUpdate(pull: PullRequestResponse['data']): Promise<boolean> {
async prNeedsUpdate(pull: PullRequest): Promise<boolean> {
if (pull.merged === true) {
ghCore.warning('Skipping pull request, already merged.');
return false;
Expand Down Expand Up @@ -200,7 +208,7 @@ export class AutoUpdater {
if (excludedLabels.length > 0) {
for (const label of pull.labels) {
if (label.name === undefined) {
ghCore.warning(`Label name is undefined, continuing.`);
ghCore.debug(`Label name is undefined, continuing.`);
continue;
}
if (excludedLabels.includes(label.name)) {
Expand Down Expand Up @@ -239,7 +247,7 @@ export class AutoUpdater {

for (const label of pull.labels) {
if (label.name === undefined) {
ghCore.warning(`Label name is undefined, continuing.`);
ghCore.debug(`Label name is undefined, continuing.`);
continue;
}

Expand Down
7 changes: 2 additions & 5 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { WebhookEvent } from '@octokit/webhooks-definitions/schema';
import { AutoUpdater } from '../src/autoupdater';
import { ConfigLoader } from '../src/config-loader';

export class Router {
updater: AutoUpdater;

constructor(
config: ConfigLoader,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
eventData: any,
) {
constructor(config: ConfigLoader, eventData: WebhookEvent) {
this.updater = new AutoUpdater(config, eventData);
}

Expand Down
Loading

0 comments on commit fb31698

Please sign in to comment.