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

Add migration lifecycle hooks #5541

Merged

Conversation

timorthi
Copy link
Contributor

@timorthi timorthi commented Apr 12, 2023

This is an attempt at addressing the use cases described in #2983 .

This adds the ability for the user to define a beforeAll, afterAll, beforeEach, afterEach hook during migrations.

Comment on lines -589 to -592
if (commitFn) {
commitFn();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the explicit commit so that we can run the afterEach hook in the same transaction (line 527)

@coveralls
Copy link

coveralls commented Apr 12, 2023

Coverage Status

coverage: 92.888% (+0.1%) from 92.787%
when pulling f7a3147 on leaselock:timorthi/issue2983-migration-lifecycle-hooks
into 4ca3dd5 on knex:master.

@timorthi
Copy link
Contributor Author

@kibertoad gentle ping - would love to get your feedback on this 😄

Copy link
Member

@rluvaton rluvaton left a comment

Choose a reason for hiding this comment

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

Looking good! thanks for the great job!
could you please also update the types?

left few comments and I also think docs should be updated as well (Cc @kibertoad)

Also few questions:

  1. If you have 2 migrations, and the second one failed, should you run the afterAll should you rollback the beforeAll?
  2. In case transaction are disabled for migrations, should we allow hooks?

test/integration2/migrate/migration-integration.spec.js Outdated Show resolved Hide resolved
test/integration2/migrate/migration-integration.spec.js Outdated Show resolved Hide resolved
test/integration2/migrate/migration-integration.spec.js Outdated Show resolved Hide resolved
test/integration2/migrate/migration-integration.spec.js Outdated Show resolved Hide resolved
@timorthi
Copy link
Contributor Author

@rluvaton

  1. If you have 2 migrations, and the second one failed, should you run the afterAll should you rollback the beforeAll?

In this scenario, I feel like it may be appropriate to abandon the afterAll and roll back the beforeAll.

  1. In case transaction are disabled for migrations, should we allow hooks?

I can't personally think of a situation in which someone would want to run these hooks without also running their migrations in a transaction, though I wouldn't be surprised if that's a use case for someone out there. Maybe for the initial release, we can require transactions to run hooks, and see if anyone raises an issue with that.

@timorthi timorthi marked this pull request as ready for review December 20, 2023 00:52
Copy link
Member

@rluvaton rluvaton left a comment

Choose a reason for hiding this comment

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

Could you please add test when transaction are disabled for migration? And also update the types


// Force clean slate before each test
beforeEach(async () => {
rimraf.sync(path.join(__dirname, './migration'));
Copy link
Member

Choose a reason for hiding this comment

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

Why sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not 100% sure - this setup block was copied from migration-integration.spec.js and I chose not to change anything.

name
);
return await this.knex.transaction(async (trx) => {
await beforeEach(trx, [migration]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The migration that's passed into the hook is wrapped in an array here to maintain consistent types between the each and all hooks (instead of passing in an array in all but a migration object in each)


// Force clean slate before each test
beforeEach(async () => {
rimraf.sync(path.join(__dirname, './migration'));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not 100% sure - this setup block was copied from migration-integration.spec.js and I chose not to change anything.

@timorthi
Copy link
Contributor Author

@rluvaton

Could you please add test when transaction are disabled for migration?

I took a closer look at the code and it appears that the user is allowed to customize whether each migration is run in a transaction or not:

// If transaction config for a single migration is defined, use that.
// Otherwise, rely on the common config. This allows enabling/disabling
// transaction for a single migration at will, regardless of the common
// config.
_useTransaction(migrationContent, allTransactionsDisabled) {
const singleTransactionValue = get(migrationContent, 'config.transaction');
return isBoolean(singleTransactionValue)
? singleTransactionValue
: !allTransactionsDisabled;
}

Because of this, I think it may be simpler to just run the lifecycle hooks all the time, even if transactions are disabled. Otherwise, we will be dealing with a bunch of edge cases regarding when or when not to run lifecycle hooks. What do you think and would you still like me to test the non-transaction case if we choose to always run hooks?

@rluvaton
Copy link
Member

rluvaton commented Dec 20, 2023

Can you please update the types and fix the CI so we can merge this

@timorthi
Copy link
Contributor Author

@rluvaton I've updated index.d.ts, did I miss any other type definitions?

For CI, it looks like this particular step (Legacy Types Linting) has been failing for the last 3 weeks, unrelated to this PR https://github.com/knex/knex/actions/workflows/linting-legacy.yml

Copy link
Member

@rluvaton rluvaton left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution

@kibertoad LGTM

@michaelwiles
Copy link

Please can this be merged? I need this as well.

@kibertoad kibertoad merged commit 3764ded into knex:master Jan 13, 2024
35 of 36 checks passed
@m33ch
Copy link

m33ch commented May 31, 2024

Hello and thank you all for your contribution! I really needed this feature.

I noticed that the change has been merged into master but I see that a new version hasn't been pubilshed to npm.
Approximately, when is a new release on npm expected?

Thanks a lot!

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.

None yet

6 participants