mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Optimised fixture replacement migration script (#9812)
no issue - do only look for published old fixture posts - otherwise we detect draft old fixture post - and then we would replace them with published new fixture posts, which is not a very nice experience for the user - ensure, if we have found all old fixture posts, replace all of them with the correct date - otherwise they are getting replaced and the date is "now" - in general, this migration script is tricky and it tries to be smart, but there are so many cases we can run into - to remember: the goal was to replace all old with new fixture posts (e.g. you just installed 1.25 and straight migrate to 2.0 - the old fixture posts should get replaced) - added more protections to ensure we never delete custom posts using the same fixture post slugs
This commit is contained in:
parent
57a8bf229e
commit
91950cfea0
1 changed files with 95 additions and 10 deletions
|
@ -1,5 +1,6 @@
|
||||||
const Promise = require('bluebird');
|
const Promise = require('bluebird');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const moment = require('moment-timezone');
|
||||||
const models = require('../../../../models');
|
const models = require('../../../../models');
|
||||||
const fixtures = require('../../../../data/schema/fixtures');
|
const fixtures = require('../../../../data/schema/fixtures');
|
||||||
const common = require('../../../../lib/common');
|
const common = require('../../../../lib/common');
|
||||||
|
@ -7,17 +8,49 @@ const message1 = 'Replacing fixture posts.';
|
||||||
const message2 = 'Replaced fixture posts.';
|
const message2 = 'Replaced fixture posts.';
|
||||||
const message3 = 'Rollback: Fixture posts.';
|
const message3 = 'Rollback: Fixture posts.';
|
||||||
|
|
||||||
const oldFixtureSlugs = ['welcome', 'the-editor', 'using-tags', 'managing-users', 'private-sites', 'advanced-markdown', 'themes'];
|
const oldFixtures = [
|
||||||
|
{
|
||||||
|
slug: 'welcome',
|
||||||
|
title: 'Welcome to Ghost'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'the-editor',
|
||||||
|
title: 'Using the Ghost editor'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'using-tags',
|
||||||
|
title: 'Organising your content with tags'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'managing-users',
|
||||||
|
title: 'Managing Ghost users'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'private-sites',
|
||||||
|
title: 'Making your site private'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'advanced-markdown',
|
||||||
|
title: 'Advanced Markdown tips'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: 'themes',
|
||||||
|
title: 'Setting up your own Ghost theme'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const newFixtureSlugs = _.map(_.find(fixtures.models, {name: 'Post'}).entries, 'slug');
|
const newFixtureSlugs = _.map(_.find(fixtures.models, {name: 'Post'}).entries, 'slug');
|
||||||
|
|
||||||
module.exports.config = {
|
module.exports.config = {
|
||||||
transaction: true
|
transaction: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This migration scripts tries to cover one case: you have a fresh installed v1 blog and you migrate to v2.
|
||||||
|
// We try to replace the old fixture posts with the new fixture posts.
|
||||||
module.exports.up = (options) => {
|
module.exports.up = (options) => {
|
||||||
let localOptions = _.merge({
|
let localOptions = _.merge({
|
||||||
context: {internal: true},
|
context: {internal: true},
|
||||||
columns: ['id'],
|
columns: ['id', 'updated_at', 'created_at', 'published_at', 'title', 'slug'],
|
||||||
withRelated: ['authors', 'tags'],
|
withRelated: ['authors', 'tags'],
|
||||||
migrating: true
|
migrating: true
|
||||||
}, options);
|
}, options);
|
||||||
|
@ -25,10 +58,17 @@ module.exports.up = (options) => {
|
||||||
common.logging.info(message1);
|
common.logging.info(message1);
|
||||||
let oldFixturePostsCount = 0;
|
let oldFixturePostsCount = 0;
|
||||||
|
|
||||||
return Promise.each(oldFixtureSlugs, (slug) => {
|
// Remember a reference date of the old fixture posts
|
||||||
return models.Post.findOne({slug: slug, status: 'all'}, localOptions)
|
let createdAt;
|
||||||
|
let updatedAt;
|
||||||
|
let publishedAt;
|
||||||
|
|
||||||
|
return Promise.each(_.map(oldFixtures, 'slug'), (slug) => {
|
||||||
|
// Look for published old fixture posts
|
||||||
|
return models.Post.findOne({slug: slug}, localOptions)
|
||||||
.then((model) => {
|
.then((model) => {
|
||||||
// CASE: fixture post doesn't exist
|
// CASE 1: old fixture post doesn't exist
|
||||||
|
// CASE 2: old fixture post not published, ignore
|
||||||
if (!model) {
|
if (!model) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -40,23 +80,53 @@ module.exports.up = (options) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CASE: the old fixture post is NOT tagged with getting started
|
// CASE: could be your own post, the fixture posts only have 1 primary author by default
|
||||||
|
if (model.authors.length === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE: the old fixture post is NOT tagged with getting started, could be your own post
|
||||||
if (!_.find(model.tags, {slug: 'getting-started'})) {
|
if (!_.find(model.tags, {slug: 'getting-started'})) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CASE: could be your own post, the fixture posts only have 1 primary tag by default
|
||||||
|
if (model.tags.length === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE: title equals old fixture post, ensure it's not your own post
|
||||||
|
if (model.title !== _.find(oldFixtures, {slug: model.slug}).title) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
oldFixturePostsCount = oldFixturePostsCount + 1;
|
oldFixturePostsCount = oldFixturePostsCount + 1;
|
||||||
|
|
||||||
|
// remember date ref
|
||||||
|
createdAt = model.created_at;
|
||||||
|
updatedAt = model.updated_at;
|
||||||
|
publishedAt = model.published_at;
|
||||||
|
|
||||||
|
// destroy the old published fixture post
|
||||||
return models.Post.destroy(Object.assign({id: model.id}, localOptions));
|
return models.Post.destroy(Object.assign({id: model.id}, localOptions));
|
||||||
});
|
});
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// We only insert the new post fixtures if you had ALL old fixure posts in the database
|
// CASE: We only insert the new post fixtures if you had all old fixture posts in the database and they were published
|
||||||
|
// Otherwise we have no clue in which state your blog is in.
|
||||||
if (oldFixturePostsCount !== 7) {
|
if (oldFixturePostsCount !== 7) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newPostFixtures = fixtures.utils.findModelFixtures('Post');
|
const newPostFixtures = _.cloneDeep(fixtures.utils.findModelFixtures('Post'));
|
||||||
const newPostRelationFixtures = fixtures.utils.findRelationFixture('Post', 'Tag');
|
const newPostRelationFixtures = fixtures.utils.findRelationFixture('Post', 'Tag');
|
||||||
|
|
||||||
|
// Add all the new post fixtures with the old and correct reference date
|
||||||
|
_.forEach(newPostFixtures.entries, function (post, index) {
|
||||||
|
post.created_at = createdAt;
|
||||||
|
post.updated_at = updatedAt;
|
||||||
|
post.published_at = moment(publishedAt).add(index, 'seconds').toDate();
|
||||||
|
});
|
||||||
|
|
||||||
return fixtures.utils.addFixturesForModel(newPostFixtures, _.omit(localOptions, ['withRelated', 'columns']))
|
return fixtures.utils.addFixturesForModel(newPostFixtures, _.omit(localOptions, ['withRelated', 'columns']))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return fixtures.utils.addFixturesForRelation(newPostRelationFixtures, _.omit(localOptions, ['withRelated', 'columns']));
|
return fixtures.utils.addFixturesForRelation(newPostRelationFixtures, _.omit(localOptions, ['withRelated', 'columns']));
|
||||||
|
@ -69,7 +139,7 @@ module.exports.up = (options) => {
|
||||||
module.exports.down = (options) => {
|
module.exports.down = (options) => {
|
||||||
let localOptions = _.merge({
|
let localOptions = _.merge({
|
||||||
context: {internal: true},
|
context: {internal: true},
|
||||||
columns: ['id'],
|
columns: ['id', 'title', 'slug'],
|
||||||
withRelated: ['authors', 'tags'],
|
withRelated: ['authors', 'tags'],
|
||||||
migrating: true
|
migrating: true
|
||||||
}, options);
|
}, options);
|
||||||
|
@ -79,7 +149,7 @@ module.exports.down = (options) => {
|
||||||
return Promise.each(newFixtureSlugs, (slug) => {
|
return Promise.each(newFixtureSlugs, (slug) => {
|
||||||
return models.Post.findOne({slug: slug, status: 'all'}, localOptions)
|
return models.Post.findOne({slug: slug, status: 'all'}, localOptions)
|
||||||
.then((model) => {
|
.then((model) => {
|
||||||
// CASE: fixture post doesn't exist
|
// CASE: new fixture post doesn't exist
|
||||||
if (!model) {
|
if (!model) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -91,11 +161,26 @@ module.exports.down = (options) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CASE: could be your own post, the fixture posts only have 1 primary author by default
|
||||||
|
if (model.authors.length === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// CASE: the old fixture post is NOT tagged with getting started
|
// CASE: the old fixture post is NOT tagged with getting started
|
||||||
if (!_.find(model.tags, {slug: 'getting-started'})) {
|
if (!_.find(model.tags, {slug: 'getting-started'})) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CASE: could be your own post, the fixture posts only have 1 primary tag by default
|
||||||
|
if (model.tags.length === 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE: ensure it's not your own post
|
||||||
|
if (model.title !== _.find(_.find(fixtures.models, {name: 'Post'}).entries, {slug: model.slug}).title) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return models.Post.destroy(Object.assign({id: model.id}, localOptions));
|
return models.Post.destroy(Object.assign({id: model.id}, localOptions));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue