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(auto-approve): add sample app repo processes #5053

Merged
merged 16 commits into from
May 16, 2023
1 change: 1 addition & 0 deletions packages/auto-approve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Below is what each process checks for:
- Change the dependency that was there previously, and that is on the title of the PR
- Not match any regexes in the 'excluded' list
* NodeDependency:
- Max 3 files changed in the PR
- Checks that the author is 'renovate-bot'
- Checks that the title of the PR matches the regexp: /^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/
- Each file path must match one of these regexps:
Expand Down
212 changes: 106 additions & 106 deletions packages/auto-approve/__snapshots__/auto-approve.test.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we revert these changes or fix the formatting?

Original file line number Diff line number Diff line change
@@ -1,185 +1,185 @@
exports['auto-approve main auto-approve function config exists on main branch approves and tags a PR if a config exists & is valid & PR is valid 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch approves and tags a PR if a config exists & is valid & PR is valid 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config exists on main branch does nothing if there is already an approval 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch approves and tags a PR if everything is valid, and it is coming from a fork 1'] = {
"head_sha": "65f14b92a8135948008c6e26344167a2dac9f066",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': '65f14b92a8135948008c6e26344167a2dac9f066',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch approves and tags a PR if everything is valid, and it is coming from a fork 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config exists on main branch submits a failing check if config exists but is not valid 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "failure",
"output": {
"title": "Auto-approve.yml check",
"summary": "auto-approve.yml config check failed",
"text": "See the following errors in your auto-approve.yml config:\n[{\"wrongProperty\":\"wrongProperty\",\"message\":\"message\"}]\n"
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'failure',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'auto-approve.yml config check failed',
'text': 'See the following errors in your auto-approve.yml config:\n[{"wrongProperty":"wrongProperty","message":"message"}]\n'
}
}

exports['auto-approve main auto-approve function config exists on main branch logs to the console if config is valid but PR is not 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch will not check config on master if the config is modified on PR 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "failure",
"output": {
"title": "Auto-approve.yml check",
"summary": "auto-approve.yml config check failed",
"text": "See the following errors in your auto-approve.yml config:\n\n"
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'failure',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'auto-approve.yml config check failed',
'text': 'See the following errors in your auto-approve.yml config:\n\n'
}
}

exports['auto-approve main auto-approve function config exists on main branch uses the correct function to check the PR if the config is V2 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch uses the correct function to check the PR if the config is V2 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config exists on main branch uses the correct function to check the PR if the config is V1 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch uses the correct function to check the PR if the config is V1 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config does not exist on main branch attempts to create a passing status check if PR contains correct config 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config does not exist on main branch attempts to create a failing status check if PR contains wrong config, and error messages check out 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "failure",
"output": {
"title": "Auto-approve.yml check",
"summary": "auto-approve.yml config check failed",
"text": "See the following errors in your auto-approve.yml config:\n[{\"wrongProperty\":\"wrongProperty\",\"message\":\"message\"}]\n"
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'failure',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'auto-approve.yml config check failed',
'text': 'See the following errors in your auto-approve.yml config:\n[{"wrongProperty":"wrongProperty","message":"message"}]\n'
}
}

exports['auto-approve main auto-approve function config does not exist on main branch passes PR if auto-approve is on main, not PR 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config does not exist on main branch passes PR if auto-approve is on main, not PR 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve gets secrets and authenticates separately for approval creates a separate octokit instance and authenticates with secret in secret manager 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve gets secrets and authenticates separately for approval creates a separate octokit instance and authenticates with secret in secret manager 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config exists on main branch retries if etag is not current 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch retries if etag is not current 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}

exports['auto-approve main auto-approve function config exists on main branch stops retrying to add the label after 3 attempts, even if it is never successful 1'] = {
"head_sha": "c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a",
"name": "Auto-approve.yml check",
"conclusion": "success",
"output": {
"title": "Auto-approve.yml check",
"summary": "Successful auto-approve.yml config check",
"text": ""
'head_sha': 'c5b0c82f5d58dd4a87e4e3e5f73cd752e552931a',
'name': 'Auto-approve.yml check',
'conclusion': 'success',
'output': {
'title': 'Auto-approve.yml check',
'summary': 'Successful auto-approve.yml config check',
'text': ''
}
}

exports['auto-approve main auto-approve function config exists on main branch stops retrying to add the label after 3 attempts, even if it is never successful 2'] = {
"event": "APPROVE"
'event': 'APPROVE'
}
15 changes: 15 additions & 0 deletions packages/auto-approve/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ export interface Versions {
oldMinorVersion: string;
newMajorVersion: string;
newMinorVersion: string;
}

/**
* Interface for the versions found in the selected files. These versions are
* picked out based on the regex listed in `./language-versioning-rules.json` for
* that particular file. From there, you will get the previous dependency, new
* dependency, and previous version number and changed version number.
*/
export interface VersionsWithShaDiff {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider extends Versions instead of duplicating the fields

oldDependencyName: string;
newDependencyName: string;
oldMajorVersion: string;
oldMinorVersion: string;
newMajorVersion: string;
newMinorVersion: string;
oldShaOrRevTag?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a need to overload this class? Can we have a separate class for a SHA diff. The function that parses the diff could return a Versions | ShaDiff type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

newShaOrRevTag?: string;
}
Expand Down
20 changes: 17 additions & 3 deletions packages/auto-approve/src/process-checks/node/dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {BaseLanguageRule} from '../base';
* true if the PR:
- has an author that is 'renovate-bot'
- has a title that matches the regexp: /^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/
- has max 3 files changed in the PR
- Each file path must match one of these regexps:
- /package\.json$/
- All files must:
Expand All @@ -46,6 +47,7 @@ export class NodeDependency extends BaseLanguageRule {
classRule = {
author: 'renovate-bot',
titleRegex: /^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/,
maxFiles: 3,
fileNameRegex: [/package\.json$/],
};
fileRules = [
Expand Down Expand Up @@ -83,6 +85,11 @@ export class NodeDependency extends BaseLanguageRule {
this.classRule.titleRegex
);

const fileCountMatch = checkFileCount(
incomingPR.fileCount,
this.classRule.maxFiles
);

const filePatternsMatch = checkFilePathsMatch(
incomingPR.changedFiles.map((x: {filename: string}) => x.filename),
this.classRule.fileNameRegex
Expand Down Expand Up @@ -135,12 +142,19 @@ export class NodeDependency extends BaseLanguageRule {
}

reportIndividualChecks(
['authorshipMatches', 'titleMatches', 'filePatternsMatch'],
[authorshipMatches, titleMatches, filePatternsMatch],
[
'authorshipMatches',
'titleMatches',
'fileCountMatches',
'filePatternsMatch',
],
[authorshipMatches, titleMatches, fileCountMatch, filePatternsMatch],
incomingPR.repoOwner,
incomingPR.repoName,
incomingPR.prNumber
);
return authorshipMatches && titleMatches && filePatternsMatch;
return (
authorshipMatches && titleMatches && fileCountMatch && filePatternsMatch
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
getVersionsV2,
isOneDependencyChanged,
reportIndividualChecks,
runVersioningValidationWithShaOrRev,
isVersionValidWithShaOrRev,
} from '../../utils-for-pr-checking';
import {Octokit} from '@octokit/rest';
import {BaseLanguageRule} from '../base';
Expand Down Expand Up @@ -111,7 +111,7 @@ export class DockerDependency extends BaseLanguageRule {
incomingPR.title
);

const isVersionValid = runVersioningValidationWithShaOrRev(versions);
const isVersionValid = isVersionValidWithShaOrRev(versions);

const oneDependencyChanged = isOneDependencyChanged(file);

Expand Down
Loading