mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
🏗 Added "labs" setting enabling feature flags
refs https://github.com/TryGhost/Team/issues/757
refs https://github.com/TryGhost/Team/issues/332
refs ea6d656457
- We have a need a quick way to add features behind flags. The old way of "labs" is the quickest way to achieve this. It has ready tooling around it and well understood pitfalls. This change reintroduces "labs" group & key in settings table in the same shape it used to be (see reffed commit)
- Next step will be introducing very basic guard rails to protect from pitfalls previous implementation of "labs" had. This will include an allowlist based input validation for lab's object's data
- The labs being an "object" type is an EXCEPTION. Even though it's an antipattern we aim to move away from, for now it's the lowest impact solution that will unblock the use of flags in the system. A proper solution will come at some point.
This commit is contained in:
parent
573b0db76a
commit
49ba26373d
5 changed files with 59 additions and 2 deletions
|
@ -4,9 +4,11 @@ const ObjectId = require('bson-objectid').default;
|
|||
const _ = require('lodash');
|
||||
const BaseImporter = require('./base');
|
||||
const models = require('../../../../models');
|
||||
const defaultSettings = require('../../../schema').defaultSettings;
|
||||
const keyGroupMapper = require('../../../../api/shared/serializers/input/utils/settings-key-group-mapper');
|
||||
const keyTypeMapper = require('../../../../api/shared/serializers/input/utils/settings-key-type-mapper');
|
||||
|
||||
const labsDefaults = JSON.parse(defaultSettings.labs.labs.defaultValue);
|
||||
const ignoredSettings = ['slack_url', 'members_from_address', 'members_support_address'];
|
||||
|
||||
// NOTE: drop support in Ghost 5.0
|
||||
|
@ -204,6 +206,12 @@ class SettingsImporter extends BaseImporter {
|
|||
}
|
||||
|
||||
_.each(this.dataToImport, (obj) => {
|
||||
if (obj.key === 'labs' && obj.value) {
|
||||
// Overwrite the labs setting with our current defaults
|
||||
// Ensures things that are enabled in new versions, are turned on
|
||||
obj.value = JSON.stringify(_.assign({}, JSON.parse(obj.value), labsDefaults));
|
||||
}
|
||||
|
||||
// CASE: we do not import "from address" for members settings as that needs to go via validation with magic link
|
||||
if ((obj.key === 'members_from_address') || (obj.key === 'members_support_address')) {
|
||||
obj.value = null;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
const ObjectID = require('bson-objectid');
|
||||
const logging = require('../../../../../shared/logging');
|
||||
const {createTransactionalMigration} = require('../../utils.js');
|
||||
|
||||
const MIGRATION_USER = 1;
|
||||
|
||||
module.exports = createTransactionalMigration(
|
||||
async function up(knex) {
|
||||
const labsExists = await knex('settings')
|
||||
.where('key', '=', 'labs')
|
||||
.first();
|
||||
|
||||
if (!labsExists) {
|
||||
logging.info('Adding "labs" record to "settings" table');
|
||||
|
||||
const now = knex.raw('CURRENT_TIMESTAMP');
|
||||
|
||||
await knex('settings')
|
||||
.insert({
|
||||
id: ObjectID().toHexString(),
|
||||
key: 'labs',
|
||||
value: JSON.stringify({}),
|
||||
group: 'labs',
|
||||
type: 'object',
|
||||
created_at: now,
|
||||
created_by: MIGRATION_USER,
|
||||
updated_at: now,
|
||||
updated_by: MIGRATION_USER
|
||||
});
|
||||
} else {
|
||||
logging.warn('Skipped adding "labs" record to "settings" table. Record already exists!');
|
||||
}
|
||||
},
|
||||
|
||||
async function down(knex) {
|
||||
logging.info('Removing "labs" record from "settings" table');
|
||||
|
||||
await knex('settings')
|
||||
.where('key', '=', 'labs')
|
||||
.del();
|
||||
}
|
||||
);
|
|
@ -413,6 +413,12 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"labs": {
|
||||
"labs": {
|
||||
"defaultValue": "{}",
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"slack": {
|
||||
"slack_url": {
|
||||
"defaultValue": "",
|
||||
|
|
|
@ -190,7 +190,8 @@ describe('Exporter', function () {
|
|||
}, 0);
|
||||
|
||||
// NOTE: if default settings changed either modify the settings keys blocklist or increase allowedKeysLength
|
||||
const allowedKeysLength = 76;
|
||||
// This is a reminder to think about the importer/exporter scenarios ;)
|
||||
const allowedKeysLength = 77;
|
||||
totalKeysLength.should.eql(SETTING_KEYS_BLOCKLIST.length + allowedKeysLength);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('DB version integrity', function () {
|
|||
// Only these variables should need updating
|
||||
const currentSchemaHash = '2099a4ba6b9462c5a0aa36a434139e8b';
|
||||
const currentFixturesHash = '8671672598d2a62e53418c4b91aa79a3';
|
||||
const currentSettingsHash = '8a3f69dfa11d56a6c630456a67f3a59a';
|
||||
const currentSettingsHash = '4f7fa90d4d545b9ec7eb0b86aa8f15ab';
|
||||
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';
|
||||
|
||||
// If this test is failing, then it is likely a change has been made that requires a DB version bump,
|
||||
|
|
Loading…
Add table
Reference in a new issue