mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-03 08:25:06 +03: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,5 +1,6 @@
|
||||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment-timezone');
|
||||
const models = require('../../../../models');
|
||||
const fixtures = require('../../../../data/schema/fixtures');
|
||||
const common = require('../../../../lib/common');
|
||||
@ -7,17 +8,49 @@ const message1 = 'Replacing fixture posts.';
|
||||
const message2 = 'Replaced 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');
|
||||
|
||||
module.exports.config = {
|
||||
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) => {
|
||||
let localOptions = _.merge({
|
||||
context: {internal: true},
|
||||
columns: ['id'],
|
||||
columns: ['id', 'updated_at', 'created_at', 'published_at', 'title', 'slug'],
|
||||
withRelated: ['authors', 'tags'],
|
||||
migrating: true
|
||||
}, options);
|
||||
@ -25,10 +58,17 @@ module.exports.up = (options) => {
|
||||
common.logging.info(message1);
|
||||
let oldFixturePostsCount = 0;
|
||||
|
||||
return Promise.each(oldFixtureSlugs, (slug) => {
|
||||
return models.Post.findOne({slug: slug, status: 'all'}, localOptions)
|
||||
// Remember a reference date of the old fixture posts
|
||||
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) => {
|
||||
// CASE: fixture post doesn't exist
|
||||
// CASE 1: old fixture post doesn't exist
|
||||
// CASE 2: old fixture post not published, ignore
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
@ -40,23 +80,53 @@ module.exports.up = (options) => {
|
||||
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'})) {
|
||||
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;
|
||||
|
||||
// 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));
|
||||
});
|
||||
}).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) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newPostFixtures = fixtures.utils.findModelFixtures('Post');
|
||||
const newPostFixtures = _.cloneDeep(fixtures.utils.findModelFixtures('Post'));
|
||||
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']))
|
||||
.then(() => {
|
||||
return fixtures.utils.addFixturesForRelation(newPostRelationFixtures, _.omit(localOptions, ['withRelated', 'columns']));
|
||||
@ -69,7 +139,7 @@ module.exports.up = (options) => {
|
||||
module.exports.down = (options) => {
|
||||
let localOptions = _.merge({
|
||||
context: {internal: true},
|
||||
columns: ['id'],
|
||||
columns: ['id', 'title', 'slug'],
|
||||
withRelated: ['authors', 'tags'],
|
||||
migrating: true
|
||||
}, options);
|
||||
@ -79,7 +149,7 @@ module.exports.down = (options) => {
|
||||
return Promise.each(newFixtureSlugs, (slug) => {
|
||||
return models.Post.findOne({slug: slug, status: 'all'}, localOptions)
|
||||
.then((model) => {
|
||||
// CASE: fixture post doesn't exist
|
||||
// CASE: new fixture post doesn't exist
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
@ -91,11 +161,26 @@ module.exports.down = (options) => {
|
||||
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
|
||||
if (!_.find(model.tags, {slug: 'getting-started'})) {
|
||||
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));
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user