0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Added migration to insert builtin Zapier integration (#10500)

no issue

A new Zapier app will be released that uses the v2 Admin API which means it will require an ApiKey that is linked to an Integration.

- adds a `type` column to the `integrations` table with the following types allowed:
  - `custom` (default) used by custom integrations added by users
  - `builtin` used by built-in integrations that have their own UI and won't show up in the "Custom Integrations" list
  - `internal` used by "internal" integrations such as the scheduler
- adds a `zapier` "builtin" integration to the fixtures
This commit is contained in:
Kevin Ansfield 2019-02-15 14:48:21 +00:00 committed by GitHub
parent aab3a5b89d
commit 8e9ade6357
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 5 deletions

View file

@ -0,0 +1,40 @@
const common = require('../../../../lib/common');
const commands = require('../../../schema').commands;
const table = 'integrations';
const newColumnNames = [
'type'
];
function printResult(operation, columnName) {
return `${operation} column ${columnName} in ${table} table`;
}
module.exports.up = (options) => {
const connection = options.connection;
return Promise.map(newColumnNames, (newColumnName) => {
return connection.schema.hasColumn(table, newColumnName)
.then((exists) => {
if (exists) {
common.logging.warn(printResult('Adding', newColumnName));
return;
}
common.logging.info(printResult('Adding', newColumnName));
return commands.addColumn(table, newColumnName, connection);
});
});
};
module.exports.down = (options) => {
const connection = options.connection;
return Promise.map(newColumnNames, (newColumnName) => {
return connection.schema.hasColumn(table, newColumnName)
.then((exists) => {
if (!exists) {
common.logging.warn(printResult('Dropping', newColumnName));
return;
}
common.logging.info(printResult('Dropping', newColumnName));
return commands.dropColumn(table, newColumnName, connection);
});
});
};

View file

@ -0,0 +1,69 @@
const logging = require('../../../../lib/common/logging');
const merge = require('lodash/merge');
const models = require('../../../../models');
const utils = require('../../../schema/fixtures/utils');
const _private = {};
_private.printResult = function printResult(result, message) {
if (result.done === result.expected) {
logging.info(message);
} else {
logging.warn(`(${result.done}/${result.expected}) ${message}`);
}
};
_private.addZapierIntegration = (options) => {
const message = 'Adding "Zapier" integration';
const fixtureIntegration = utils.findModelFixtureEntry('Integration', {slug: 'zapier'});
return models.Integration.findOne({slug: fixtureIntegration.slug}, options)
.then((integration) => {
if (!integration) {
return utils.addFixturesForModel({
name: 'Integration',
entries: [fixtureIntegration]
}, options).then(result => _private.printResult(result, message));
}
logging.warn(message);
});
};
_private.removeZapierIntegration = (options) => {
const message = 'Rollback: Removing "Zapier" integration';
return models.Integration.findOne({slug: 'zapier'}, options)
.then((integration) => {
if (!integration) {
logging.warn(message);
return;
}
return integration.destroy().then(() => {
logging.info(message);
});
});
};
module.exports.config = {
transaction: true
};
module.exports.up = (options) => {
const localOptions = merge({
context: {internal: true},
migrating: true
}, options);
return _private.addZapierIntegration(localOptions);
};
module.exports.down = (options) => {
const localOptions = merge({
context: {internal: true},
migrating: true
}, options);
return _private.removeZapierIntegration(localOptions);
};

View file

@ -533,6 +533,18 @@
"feature_image": "https://static.ghost.org/v2.0.0/images/welcome-to-ghost.jpg"
}
]
},
{
"name": "Integration",
"entries": [
{
"slug": "zapier",
"name": "Zapier",
"description": "Built-in Zapier integration",
"type": "builtin",
"api_keys": [{"type": "admin"}]
}
]
}
],
"relations": [

View file

@ -333,6 +333,13 @@ module.exports = {
},
integrations: {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
type: {
type: 'string',
maxlength: 50,
nullable: false,
defaultTo: 'custom',
validations: {isIn: [['internal', 'builtin', 'custom']]}
},
name: {type: 'string', maxlength: 191, nullable: false},
slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
icon_image: {type: 'string', maxlength: 2000, nullable: true},

View file

@ -40,9 +40,6 @@ const ApiKey = ghostBookshelf.Model.extend({
return this.belongsTo('Role');
},
// if an ApiKey does not have a related Integration then it's considered
// "internal" and shouldn't show up in the UI. Example internal API Keys
// would be the ones used for the scheduler and backup clients
integration() {
return this.belongsTo('Integration');
},

View file

@ -10,6 +10,12 @@ const Integration = ghostBookshelf.Model.extend({
webhooks: 'webhooks'
},
defaults() {
return {
type: 'custom'
};
},
add(data, options) {
const addIntegration = () => {
return ghostBookshelf.Model.add.call(this, data, options)

View file

@ -19,8 +19,8 @@ var should = require('should'),
*/
describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = 'ddca519660d4c9489259557438a41c78';
const currentFixturesHash = '6b154399f5582f7744fbfd9c30ec709b';
const currentSchemaHash = '7c5d34376392d01c274700350de228c1';
const currentFixturesHash = 'db8cd644bc496d0ba34c7f54d7183ee4';
// If this test is failing, then it is likely a change has been made that requires a DB version bump,
// and the values above will need updating as confirmation