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

fix(auto-approve): allow Python major dependency updates #4998

Merged
merged 12 commits into from
Apr 10, 2023
6 changes: 3 additions & 3 deletions packages/auto-approve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ Below is what each process checks for:
* PythonDependency:
- 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*)$/
- Max 3 files changed in the PR
- Each file path must match one of these regexps:
- /requirements.txt$/
- /^samples/**/requirements*.txt$/
- All files must:
- Match this regexp: /^samples\/snippets\/requirements.txt$/
- Increase the non-major package version of a dependency
- Match this regexp: /requirements.txt$/
- Increase the package version of a dependency (major or nonmajor)
- Only change one dependency
- Change the dependency that was there previously, and that is on the title of the PR
* PythonSampleDependency:
Expand Down
3 changes: 2 additions & 1 deletion packages/auto-approve/package-lock.json

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

3 changes: 2 additions & 1 deletion packages/auto-approve/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"ajv": "^8.11.0",
"dayjs": "^1.11.5",
"gcf-utils": "^14.2.0",
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0",
"semver": "^7.3.8"
},
"devDependencies": {
"@octokit/rest": "^19.0.4",
Expand Down
34 changes: 10 additions & 24 deletions packages/auto-approve/src/process-checks/python/dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,18 @@ import {LanguageRule, File, FileRule, Process} from '../../interfaces';
import {
checkAuthor,
checkTitleOrBody,
checkFileCount,
checkFilePathsMatch,
doesDependencyChangeMatchPRTitleV2,
getVersionsV2,
runVersioningValidation,
isOneDependencyChanged,
reportIndividualChecks,
isVersionBumped,
} from '../../utils-for-pr-checking';
import {Octokit} from '@octokit/rest';

export class PythonDependency extends Process implements LanguageRule {
classRule: {
author: string;
titleRegex?: RegExp;
maxFiles: number;
fileNameRegex?: RegExp[];
fileRules?: {
oldVersion?: RegExp;
Expand Down Expand Up @@ -66,11 +63,13 @@ export class PythonDependency extends Process implements LanguageRule {
author: 'renovate-bot',
titleRegex:
/^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/,
maxFiles: 3,
fileNameRegex: [/requirements.txt$/],
fileNameRegex: [
/^samples\/.*?\/.*?requirements.*?\.txt$/,
/requirements\.txt$/,
],
fileRules: [
{
targetFileToCheck: /^samples\/snippets\/requirements.txt$/,
targetFileToCheck: /requirements.txt$/,
// This would match: fix(deps): update dependency @octokit to v1
dependencyTitle: new RegExp(
/^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/
Expand Down Expand Up @@ -99,11 +98,6 @@ export class PythonDependency extends Process implements LanguageRule {
this.classRule.titleRegex
);

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

const filePatternsMatch = checkFilePathsMatch(
this.incomingPR.changedFiles.map(x => x.filename),
this.classRule.fileNameRegex
Expand Down Expand Up @@ -135,8 +129,7 @@ export class PythonDependency extends Process implements LanguageRule {
this.incomingPR.title
);

const isVersionValid = runVersioningValidation(versions);

const isVersionValid = isVersionBumped(versions);
const oneDependencyChanged = isOneDependencyChanged(file);

if (!(doesDependencyMatch && isVersionValid && oneDependencyChanged)) {
Expand All @@ -153,19 +146,12 @@ export class PythonDependency extends Process implements LanguageRule {
}

reportIndividualChecks(
[
'authorshipMatches',
'titleMatches',
'fileCountMatches',
'filePatternsMatch',
],
[authorshipMatches, titleMatches, fileCountMatch, filePatternsMatch],
['authorshipMatches', 'titleMatches', 'filePatternsMatch'],
[authorshipMatches, titleMatches, filePatternsMatch],
this.incomingPR.repoOwner,
this.incomingPR.repoName,
this.incomingPR.prNumber
);
return (
authorshipMatches && titleMatches && fileCountMatch && filePatternsMatch
);
return authorshipMatches && titleMatches && filePatternsMatch;
}
}
15 changes: 15 additions & 0 deletions packages/auto-approve/src/utils-for-pr-checking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import {logger} from 'gcf-utils';
import {Octokit} from '@octokit/rest';
import * as semver from 'semver';

dayjs.extend(utc);
dayjs.extend(timezone);

Expand Down Expand Up @@ -309,6 +311,19 @@ export function isMinorVersionUpgraded(versions: Versions): boolean {
return Number(versions.newMinorVersion) > Number(versions.oldMinorVersion);
}

/**
* This function determines whether a package was upgraded, regardless of whether or not it was a major bump.
*
* @param versions an object containing the previous and newer versions of the package being updated
* @returns whether the minor version was upgraded.
*/
export function isVersionBumped(versions: Versions): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't care what kind a version bump, should we just check if oldVersion != newVersion? Why do we need to a semver comparison between constructed values?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or why have this check at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We'd want to confirm that it was increasing. You wouldn't want to autoapprove a rollback, for example.

Copy link
Contributor

Choose a reason for hiding this comment

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

For readability, please use semver.gt or semver.lt instead (https://github.com/npm/node-semver#comparison). The semver.compare return value (1, 0, -1) is used for sorting.

return semver.lt(
versions.oldMajorVersion + '.' + versions.oldMinorVersion,
versions.newMajorVersion + '.' + versions.newMinorVersion
);
}

/**
* This function determines whether there was at most one change in the given file.
*
Expand Down
10 changes: 6 additions & 4 deletions packages/auto-approve/test/python-dependency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ describe('behavior of Python Dependency process', () => {
author: 'renovate-bot',
titleRegex:
/^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/,
maxFiles: 3,
fileNameRegex: [/requirements.txt$/],
fileNameRegex: [
/^samples\/.*?\/.*?requirements.*?\.txt$/,
/requirements\.txt$/,
],
fileRules: [
{
targetFileToCheck: /^samples\/snippets\/requirements.txt$/,
targetFileToCheck: /requirements.txt$/,
// This would match: fix(deps): update dependency @octokit to v1
dependencyTitle: new RegExp(
/^(fix|chore)\(deps\): update dependency (@?\S*) to v(\S*)$/
Expand Down Expand Up @@ -154,7 +156,7 @@ describe('behavior of Python Dependency process', () => {
'@@ -1,2 +1,2 @@\n' +
' google-cloud-videointelligence==2.5.1\n' +
'-google-cloud-storage==1.42.3\n' +
'+google-cloud-storage==1.43.0',
'+google-cloud-storage==2.0.0',
},
],
'testRepoName',
Expand Down