mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
Added tests for migrations
refs https://github.com/TryGhost/DevOps/issues/39 - up until now, we've had a CI job which does a really basic test for migrations, but it barely functions and misses bugs all the time - this commit removes that and switches to an actual test suite for our migrations, so we can ensure they function as expected - also removes the env var hack I came up with for those migrations tests - this should lead to safer migrations and faster tests
This commit is contained in:
parent
ebad10e242
commit
289e459283
72
.github/workflows/ci.yml
vendored
72
.github/workflows/ci.yml
vendored
@ -78,9 +78,6 @@ jobs:
|
||||
sodo-search:
|
||||
- *shared
|
||||
- 'apps/sodo-search/**'
|
||||
migrations:
|
||||
- *shared
|
||||
- 'ghost/core/core/server/data/migrations/**'
|
||||
any-code:
|
||||
- '!**/*.md'
|
||||
outputs:
|
||||
@ -92,7 +89,6 @@ jobs:
|
||||
changed_portal: ${{ steps.changed.outputs.portal }}
|
||||
changed_signup_form: ${{ steps.changed.outputs.signup-form }}
|
||||
changed_sodo_search: ${{ steps.changed.outputs.sodo-search }}
|
||||
changed_migrations: ${{ steps.changed.outputs.migrations }}
|
||||
changed_any_code: ${{ steps.changed.outputs.any-code }}
|
||||
commit_label: '${{ env.COMMIT_SHA }}: ${{ env.COMMIT_MESSAGE }}'
|
||||
is_git_sync: ${{ github.head_ref == 'main' || github.ref == 'refs/heads/main' }}
|
||||
@ -209,72 +205,6 @@ jobs:
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
job_migrations:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
if: needs.job_get_metadata.outputs.changed_migrations == 'true' && (github.event_name == 'push' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/')))
|
||||
strategy:
|
||||
matrix:
|
||||
env:
|
||||
- DB: sqlite3
|
||||
DB_CLIENT: sqlite3
|
||||
- DB: mysql8
|
||||
DB_CLIENT: mysql
|
||||
env:
|
||||
database__client: ${{ matrix.env.DB_CLIENT }}
|
||||
name: Migrations checks (${{ matrix.env.DB }})
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v3
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
node-version: '18.12.1'
|
||||
|
||||
- name: Shutdown MySQL
|
||||
run: sudo service mysql stop
|
||||
if: matrix.env.DB == 'mysql8'
|
||||
|
||||
- uses: daniellockyer/mysql-action@main
|
||||
if: matrix.env.DB == 'mysql8'
|
||||
with:
|
||||
authentication plugin: 'caching_sha2_password'
|
||||
mysql version: '8.0'
|
||||
mysql database: 'ghost_testing'
|
||||
mysql root password: 'root'
|
||||
|
||||
- name: Set env vars (SQLite)
|
||||
if: contains(matrix.env.DB, 'sqlite')
|
||||
run: echo "database__connection__filename=/dev/shm/ghost-test.db" >> $GITHUB_ENV
|
||||
|
||||
- name: Set env vars (MySQL)
|
||||
if: contains(matrix.env.DB, 'mysql')
|
||||
run: |
|
||||
echo "database__connection__host=127.0.0.1" >> $GITHUB_ENV
|
||||
echo "database__connection__user=root" >> $GITHUB_ENV
|
||||
echo "database__connection__password=root" >> $GITHUB_ENV
|
||||
echo "database__connection__database=ghost_testing" >> $GITHUB_ENV
|
||||
|
||||
- name: Restore caches
|
||||
uses: ./.github/actions/restore-cache
|
||||
env:
|
||||
DEPENDENCY_CACHE_KEY: ${{ needs.job_install_deps.outputs.dependency_cache_key }}
|
||||
|
||||
- name: Run Ghost and then kill it
|
||||
run: yarn workspace ghost run start
|
||||
env:
|
||||
GHOST_TESTS_KILL_SERVER_AFTER_BOOT: true
|
||||
|
||||
- run: sqlite3 ${{ env.database__connection__filename }} "DELETE FROM migrations WHERE version LIKE '5.%';"
|
||||
if: matrix.env.DB == 'sqlite3'
|
||||
- run: mysql -h127.0.0.1 -uroot -proot ghost_testing -e "DELETE FROM migrations WHERE version LIKE '5.%';"
|
||||
if: matrix.env.DB == 'mysql8'
|
||||
|
||||
- run: yarn knex-migrator migrate --force
|
||||
|
||||
job_unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
@ -768,7 +698,6 @@ jobs:
|
||||
job_lint,
|
||||
job_ghost-cli,
|
||||
job_admin-tests,
|
||||
job_migrations,
|
||||
job_unit-tests,
|
||||
job_database-tests,
|
||||
job_regression-tests,
|
||||
@ -790,7 +719,6 @@ jobs:
|
||||
job_lint,
|
||||
job_ghost-cli,
|
||||
job_admin-tests,
|
||||
job_migrations,
|
||||
job_unit-tests,
|
||||
job_database-tests,
|
||||
job_regression-tests
|
||||
|
@ -536,14 +536,6 @@ async function bootGhost({backend = true, frontend = true, server = true} = {})
|
||||
// Step 7 - Init our background services, we don't wait for this to finish
|
||||
initBackgroundServices({config});
|
||||
|
||||
// Step 8 - Kill the process - what??
|
||||
// During the migration tests, we want to boot ghost, run migrations, then shut down
|
||||
// This is the easiest way to get Ghost to boot and then kill itself
|
||||
if (process.env.GHOST_TESTS_KILL_SERVER_AFTER_BOOT === 'true') {
|
||||
debug('Killing Ghost Server after boot');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// We return the server purely for testing purposes
|
||||
if (server) {
|
||||
debug('End Boot: Returning Ghost Server');
|
||||
|
@ -4,13 +4,67 @@ const testUtils = require('../../utils');
|
||||
const _ = require('lodash');
|
||||
const Models = require('../../../core/server/models');
|
||||
|
||||
describe('Database Migration (special functions)', function () {
|
||||
before(testUtils.teardownDb);
|
||||
afterEach(testUtils.teardownDb);
|
||||
const KnexMigrator = require('knex-migrator');
|
||||
const path = require('path');
|
||||
const semver = require('semver');
|
||||
|
||||
const knexMigrator = new KnexMigrator({
|
||||
knexMigratorFilePath: path.join(__dirname, '../../../')
|
||||
});
|
||||
|
||||
const db = require('../../../core/server/data/db');
|
||||
const dbUtils = require('../../utils/db-utils');
|
||||
|
||||
const currentVersion = require('@tryghost/version');
|
||||
const currentMajor = semver.major(currentVersion.original);
|
||||
const previousMinor = semver.minor(currentVersion.original) - 1;
|
||||
const previousVersion = `${currentMajor}.${previousMinor}`;
|
||||
|
||||
describe('Migrations', function () {
|
||||
beforeEach(async function () {
|
||||
await dbUtils.teardown();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe('Database initialization + rollback', function () {
|
||||
beforeEach(async function () {
|
||||
await knexMigrator.init();
|
||||
});
|
||||
|
||||
it('can rollback to the previous minor version', async function () {
|
||||
await knexMigrator.rollback({
|
||||
version: previousVersion,
|
||||
force: true
|
||||
});
|
||||
});
|
||||
|
||||
it('can rollback to the previous minor version and then forwards again', async function () {
|
||||
await knexMigrator.rollback({
|
||||
version: previousVersion,
|
||||
force: true
|
||||
});
|
||||
await knexMigrator.migrate({
|
||||
force: true
|
||||
});
|
||||
});
|
||||
|
||||
it('should have idempotent migrations', async function () {
|
||||
// Delete all knowledge that we've run migrations so we can run them again
|
||||
if (dbUtils.isMySQL()) {
|
||||
await db.knex('migrations').whereILike('version', `${currentMajor}.%`).del();
|
||||
} else {
|
||||
await db.knex('migrations').whereLike('version', `${currentMajor}.%`).del();
|
||||
}
|
||||
|
||||
await knexMigrator.migrate({
|
||||
force: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Fixtures', function () {
|
||||
// Custom assertion for detection that a permissions is assigned to the correct roles
|
||||
should.Assertion.add('AssignedToRoles', function (roles) {
|
||||
|
Loading…
Reference in New Issue
Block a user