Skip to content

Commit

Permalink
feat(github-actions): introduce action to identify PRs affecting Google
Browse files Browse the repository at this point in the history
This is the external part to the internal service. The internal service
will complete the commit statuses for PRs needing internal presubmits.

This action exists as we do not auto-generate presubmits for PRs.
  • Loading branch information
devversion committed Oct 10, 2022
1 parent db59d49 commit 7dbcdef
Show file tree
Hide file tree
Showing 6 changed files with 16,768 additions and 0 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ng-dev/utils/protos/*.js

github-actions/create-pr-for-changes/main.js
github-actions/feature-request/main.js
github-actions/google-internal-tests/main.js
github-actions/lock-closed/main.js
github-actions/commit-message-based-labels/main.js
github-actions/slash-commands/main.js
Expand Down
12 changes: 12 additions & 0 deletions github-actions/google-internal-tests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("//tools:defaults.bzl", "esbuild_checked_in")

package(default_visibility = ["//github-actions/google-internal-tests:__subpackages__"])

esbuild_checked_in(
name = "main",
entry_point = "//github-actions/google-internal-tests/lib:main.ts",
target = "node16",
deps = [
"//github-actions/google-internal-tests/lib",
],
)
22 changes: 22 additions & 0 deletions github-actions/google-internal-tests/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Google Internal Tests
description: |
Action for identifying pull requests which require the execution of Google Internal
tests. For irrelevant PRs, a status check is added to indicate the irrelevance to G3.
author: 'Angular'
inputs:
github-token:
required: true
description: GitHub Token used for creating the commit statuses.
affected-file-patterns:
required: true
description: |
List of file patterns which match files synced into Google.
Multiple patterns should be separated by new lines.
run-tests-guide-url:
required: false
description: |
URL to post into the GitHub commit status when Google Internal
tests need to be run. This is useful for helping other Googlers.
runs:
using: 'node16'
main: 'main.js'
15 changes: 15 additions & 0 deletions github-actions/google-internal-tests/lib/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("//tools:defaults.bzl", "ts_library")

package(default_visibility = ["//github-actions/google-internal-tests:__subpackages__"])

ts_library(
name = "lib",
srcs = glob(["*.ts"]),
deps = [
"@npm//@actions/core",
"@npm//@actions/github",
"@npm//@octokit/rest",
"@npm//@types/minimatch",
"@npm//minimatch",
],
)
79 changes: 79 additions & 0 deletions github-actions/google-internal-tests/lib/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import core from '@actions/core';
import {context} from '@actions/github';
import {Octokit} from '@octokit/rest';
import minimatch from 'minimatch';

async function main() {
if (context.repo.owner !== 'angular') {
core.info('Skipping Google Internal Tests action for non-Angular repos.');
return;
}
if (context.eventName !== 'pull_request_target' || context.payload.action !== 'synchronize') {
throw new Error(
'Expected Google Internal Tests action to be triggered for ' +
'`pull_request_target.synchronize` events.',
);
}

const githubToken = core.getInput('github-token', {required: true});
const rawPatterns = core.getInput('affected-file-patterns', {required: true});
const runTestGuideURL = core.getInput('run-tests-guide-url', {required: false});
const patterns = constructPatterns(rawPatterns);

const github = new Octokit({auth: githubToken});
const prNum = context.payload.pull_request!.number;
const prHeadSHA = context.payload.pull_request!.head!.sha;

const files = await github.paginate(github.pulls.listFiles, {
...context.repo,
pull_number: prNum,
});

let affectsGoogle = false;
for (const f of files) {
if (patterns.some((p) => p.match(f.filename))) {
affectsGoogle = true;
break;
}
}

const status = affectsGoogle
? ({
state: 'pending',
// The initial waiting status is expected to be overridden by the
// internal presubmit status service then.
description: `Waiting for Google Internal Tests. ${
runTestGuideURL ? `@Googlers: See Details for instructions -->` : ''
}`.trim(),
url: runTestGuideURL,
} as const)
: ({
state: 'success',
description: 'Does not affect Google.',
} as const);

await github.repos.createCommitStatus({
...context.repo,
sha: prHeadSHA,
state: status.state,
description: status.description,
context: 'google-internal-tests',
target_url: status.url,
});
}

function constructPatterns(rawPatterns: string): minimatch.IMinimatch[] {
const patterns: minimatch.IMinimatch[] = [];
for (let p of rawPatterns.split(/\r?\n/g)) {
p = p.trim();
if (p !== '') {
patterns.push(new minimatch.Minimatch(p));
}
}
return patterns;
}

main().catch((e: Error) => {
core.error(e);
core.setFailed(e.message);
});
Loading

0 comments on commit 7dbcdef

Please sign in to comment.