Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(snippet-bot): require the config file to enable the bot #856

Merged
merged 1 commit into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/snippet-bot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

Instructions are provided in [googleapis/repo-automation-bots](https://github.com/googleapis/repo-automation-bots/blob/master/README.md) for deploying and testing your bots.

This bot needs read/write permissions on PRs and Checks.
This bot needs read/write permissions on PRs and Checks. Also make sure that the bot is listening to webhooks for PRs.

After installing the bot, you have to have `.github/snippet-bot.yml` for actually enabling it.

This bot uses nock for mocking requests to GitHub, and snap-shot-it for capturing responses; This allows updates to the API surface to be treated as a visual diff, rather than tediously asserting against each field.

Expand Down
14 changes: 0 additions & 14 deletions packages/snippet-bot/__snapshots__/snippet-bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,6 @@ exports['snippet-bot responds to PR sets a "failure" context on PR 1'] = {
},
};

exports[
'snippet-bot responds to PR sets a "failure" context on PR even when it failed to read the config 1'
] = {
name: 'Mismatched region tag',
conclusion: 'failure',
head_sha: 'ce03c1b7977aadefb5f6afc09901f106ee6ece6a',
output: {
title: 'Mismatched region tag detected.',
summary: 'Some new files have mismatched region tag',
text:
"test.py:5, tag `hello` has already started\ntest.py:10, tag `lol` doesn't have a matching start tag\ntest.py:8, tag `world` doesn't have a matching end tag",
},
};

exports[
'snippet-bot responds to PR sets a "success" context on PR by ignoreFile 1'
] = {
Expand Down
110 changes: 81 additions & 29 deletions packages/snippet-bot/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 15 additions & 8 deletions packages/snippet-bot/src/snippet-bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,28 @@ class Configuration {

export = (app: Application) => {
app.on('pull_request', async context => {
const repoUrl = context.payload.repository.full_name;
let configOptions!: ConfigurationOptions | null;
try {
configOptions = await context.config(
CONFIGURATION_FILE_PATH,
DEFAULT_CONFIGURATION
configOptions = await context.config<ConfigurationOptions>(
CONFIGURATION_FILE_PATH
);
} catch (err) {
err.message = `Error reading configuration: ${err.message}`;
logger.error(err);
// Falling back to default.
configOptions = DEFAULT_CONFIGURATION;
// Now this bot is only enabled if it finds the configuration file.
// Exiting.
return;
}
const configuration = new Configuration(
configOptions as ConfigurationOptions
);

if (configOptions === null) {
logger.info(`snippet-bot is not configured for ${repoUrl}.`);
return;
}
const configuration = new Configuration({
...DEFAULT_CONFIGURATION,
...configOptions,
});
logger.info({config: configuration});

// List pull request files for the given PR
Expand Down
39 changes: 24 additions & 15 deletions packages/snippet-bot/test/snippet-bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,15 @@ describe('snippet-bot', () => {
requests.done();
});

it('sets a "failure" context on PR even when it failed to read the config', async () => {
it('exits early when it failed to read the config', async () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const changedFiles = require(resolve(fixturesPath, './pr_files_added'));
const payload = require(resolve(fixturesPath, './pr_event'));
const blob = require(resolve(fixturesPath, './failure_blob'));

const requests = nock('https://api.github.com')
.get(
'/repos/tmatsuo/repo-automation-bots/contents/.github/snippet-bot.yml'
)
.reply(403, {content: 'Permission denied'})
.get('/repos/tmatsuo/repo-automation-bots/pulls/14/files?per_page=100')
.reply(200, changedFiles)
.get(
'/repos/tmatsuo/repo-automation-bots/git/blobs/223828dbd668486411b475665ab60855ba9898f3'
)
.reply(200, blob)
.post('/repos/tmatsuo/repo-automation-bots/check-runs', body => {
snapshot(body);
return true;
})
.reply(200);
.reply(403, {content: 'Permission denied'});

await probot.receive({
name: 'pull_request',
Expand Down Expand Up @@ -199,5 +186,27 @@ describe('snippet-bot', () => {

requests.done();
});

it('quits early if there is no config file', async () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const payload = require(resolve(fixturesPath, './pr_event'));

// probot tries to fetch the org's config too.
const requests = nock('https://api.github.com')
.get(
'/repos/tmatsuo/repo-automation-bots/contents/.github/snippet-bot.yml'
)
.reply(404, {content: 'Not Found'})
.get('/repos/tmatsuo/.github/contents/.github/snippet-bot.yml')
.reply(404, {content: 'Not Found'});

await probot.receive({
name: 'pull_request',
payload,
id: 'abc123',
});

requests.done();
});
});
});