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

@aws-amplify/backend should inherit version bump of same kind from dependencies #2042

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

ShadowCat567
Copy link
Contributor

@ShadowCat567 ShadowCat567 commented Sep 23, 2024

Problem

@aws-amplify/backend sometimes does not properly inherit the right kind of version bump from its dependencies.

Issue number, if available: #1693

Changes

  • refactored check_changeset_completeness.ts to be split into functions
  • added a function to check_changeset_completeness.ts that checks whether backend should be inheriting a version bump and whether it is currently inheriting the right kind of version bump
    Corresponding docs PR, if applicable:

Validation

  • ran manual tests using different version bumps for backend and its dependencies
  • Test 1: backend: none, dependencies have version bump of minor
image
  • Test 2: backend: minor, dependencies are patch or none
image
  • Test 3: backend: patch, dependencies are minor or patch
image
  • Test 4: backend: patch, no dependency versions
image
  • Test 5: backend: minor, one dependency is major
image

Checklist

  • If this PR includes a functional change to the runtime behavior of the code, I have added or updated automated test coverage for this change.
  • If this PR requires a change to the Project Architecture README, I have included that update in this PR.
  • If this PR requires a docs update, I have linked to that docs PR above.
  • If this PR modifies E2E tests, makes changes to resource provisioning, or makes SDK calls, I have run the PR checks with the run-e2e label set.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link

changeset-bot bot commented Sep 23, 2024

⚠️ No Changeset found

Latest commit: c21e963

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines 5 to 6
// eslint-disable-next-line import/no-extraneous-dependencies
import { ReleasePlan } from '@changesets/types';
Copy link
Member

Choose a reason for hiding this comment

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

we should just add this package as dev dep.

Comment on lines 31 to 70
const backendName: string = '@aws-amplify/backend';
const versionBumpOfWrongKind: string[] = [];
let backendMaxVersionType: string = 'none';

for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (release.name === backendName) {
if (
release.type === 'major' ||
backendMaxVersionType === 'none' ||
(backendMaxVersionType === 'patch' && release.type === 'minor')
) {
backendMaxVersionType = release.type;
}
}
}
}

for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (backendDependencies.includes(release.name)) {
if (
backendMaxVersionType !== release.type &&
(release.type === 'major' ||
backendMaxVersionType === 'none' ||
(backendMaxVersionType === 'patch' && release.type === 'minor'))
) {
versionBumpOfWrongKind.push(release.name);
}
}
}
}

if (versionBumpOfWrongKind.length > 0) {
throw new Error(
`${backendName} has a version bump of a different kind of the following packages but is expected to have a version bump of the same kind:${EOL}${versionBumpOfWrongKind.join(
EOL
)}`
);
}
Copy link
Member

Choose a reason for hiding this comment

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

This code is a bit hard to read.

Consider adding const maxVersion = (...versionType: Array<string>): string => { // some logic to pick max }

Suggested change
const backendName: string = '@aws-amplify/backend';
const versionBumpOfWrongKind: string[] = [];
let backendMaxVersionType: string = 'none';
for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (release.name === backendName) {
if (
release.type === 'major' ||
backendMaxVersionType === 'none' ||
(backendMaxVersionType === 'patch' && release.type === 'minor')
) {
backendMaxVersionType = release.type;
}
}
}
}
for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (backendDependencies.includes(release.name)) {
if (
backendMaxVersionType !== release.type &&
(release.type === 'major' ||
backendMaxVersionType === 'none' ||
(backendMaxVersionType === 'patch' && release.type === 'minor'))
) {
versionBumpOfWrongKind.push(release.name);
}
}
}
}
if (versionBumpOfWrongKind.length > 0) {
throw new Error(
`${backendName} has a version bump of a different kind of the following packages but is expected to have a version bump of the same kind:${EOL}${versionBumpOfWrongKind.join(
EOL
)}`
);
}
const backendName: string = '@aws-amplify/backend';
let effectiveBackendVersionType: string = 'none';
let effectiveBackendDependenciesVersionType: string = 'none';
for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (release.name === backendName) {
effectiveBackendVersionType = maxVersion(effectiveBackendVersionType, release.type);
}
}
}
for (const changeset of releasePlan.changesets) {
for (const release of changeset.releases) {
if (backendDependencies.includes(release.name)) {
effectiveBackendDependenciesVersionType = maxVersion(effectiveBackendDependenciesVersionType, release.type);
}
}
}
if (effectiveBackendVersionType !== effectiveBackendDependenciesVersionType) {
throw new Error(
`${backendName} has a version bump of a different kind of the following packages but is expected to have a version bump of the same kind:${EOL}${versionBumpOfWrongKind.join(
EOL
)}`
);
}

Copy link
Member

Choose a reason for hiding this comment

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

You could also consider something like this.

Assuming maxVersion(...versions) and findEffectiveVersion(releasePlan, packageName

have something like that:

const backendVersion = findEffectiveVersion(releasePlan, '@aws-amplify/backend`);
const backendAuthVersion = findEffectiveVersion(releasePlan, '@aws-amplify/backend-auth`);
const backendDataVersion = findEffectiveVersion(releasePlan, '@aws-amplify/backend-data`);
...

if (backendVersion !== maxVersion(backendAuthVersion, backendDataVersion, ...)) { throw}

Copy link
Member

Choose a reason for hiding this comment

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

And. don't worry about optimizing loops. These arrays have ~10-20 items. Ability to understand what code is doing is more important here.

Copy link
Contributor Author

@ShadowCat567 ShadowCat567 Sep 23, 2024

Choose a reason for hiding this comment

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

Would you prefer I remove the versionBumpOfWrongKind array as well? Since with this rework, it won't have anything in it

Copy link
Member

Choose a reason for hiding this comment

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

yes.

Copy link
Member

Choose a reason for hiding this comment

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

And.. there's one interesting edge case here.

It might happen that @aws-amplify/backend will get version bump but all of backend-X will not. That should be a legit case.

I.e. the condition should be if(effectiveBackendVersionType < effectiveBackendDependenciesVersionType) { throw } (this is pesudocode).

For that you might either consider either creating some kind of comparator function for minor|major|patch|none

or create enum with numerical values like enum { MAJOR: 3, MINOR: 2... }..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

enum sounds like the cleaner option. My original code was able to handle cases where backend got changes but backend-X didn't through this: backendMaxVersionType !== release.type && (release.type === 'major' || backendMaxVersionType === 'none' || (backendMaxVersionType === 'patch' && release.type === 'minor'))
but it is a fairly ugly looking set of code that is not intuitive to understand.

Copy link
Member

@sobolk sobolk left a comment

Choose a reason for hiding this comment

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

Looks good.

}
}
}
const versionTypeConverter = (version: VersionType): VersionTypeEnum => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const versionTypeConverter = (version: VersionType): VersionTypeEnum => {
const convertVersionType = (version: VersionType): VersionTypeEnum => {

function name should be verb-ish.

Comment on lines 95 to 100
maxVersion(
backendAuthVersion,
backendDataVersion,
backendFunctionVersion,
backendStorageVersion
)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
maxVersion(
backendAuthVersion,
backendDataVersion,
backendFunctionVersion,
backendStorageVersion
)
Math.max(
backendAuthVersion,
backendDataVersion,
backendFunctionVersion,
backendStorageVersion
)

would this just work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, the function is unnecessary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants