Website: Create Platform model and use platform record to track mergefreeze status. (#13681)

Closes: #11755

Changes:
- Created a new model: `Platform` that has a single attribute:
`currentUnfrozenGitHubPrNumbers`
- Updated bootstrap.js to throw an error if more than one platform
record exists, and to create a platform record when the server is lifted
with the `--drop` flag.
- Updated the receive-from-github webhook to use a Platform record to
track the PRs that are currently unfrozen in the fleetdm/fleet repo.

Before this Pr is merged, we will need to:
- [x] Migrate the Fleet website's database to add the new database
table.
- [x] Create a single platform record.
This commit is contained in:
Eric 2023-09-05 16:31:40 -05:00 committed by GitHub
parent 51485beb40
commit ac8150a319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 16 deletions

2
website/.eslintrc vendored
View File

@ -48,7 +48,7 @@
"NewsletterSubscription": true,
"VantaConnection": true,
"CertificateSigningRequest": true,
"Platform": true,
// …and any others.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
},

View File

@ -26,14 +26,17 @@ module.exports = {
fn: async function ({botSignature, action, sender, repository, changes, issue, comment, pull_request: pr, label, release}) {
// Since we're only using a single instance, and because the worst case scenario is that we refreeze some
// all-markdown PRs that had already been frozen, instead of using the database, we'll just use a little
// in-memory pocket here of PRs seen by this instance of the Sails app. To get around any issues with this,
// users can edit and resave the PR description to trigger their PR to be unfrozen.
// FUTURE: Go through the trouble to migrate the database and make a little Platform model to hold this state in.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Grab the set of GitHub pull request numbers the bot considers "unfrozen".
sails.pocketOfPrNumbersUnfrozen = sails.pocketOfPrNumbersUnfrozen || [];
// Grab the set of GitHub pull request numbers the bot considers "unfrozen" from the platform record.
// If there is more than one platform record, or it is missing, we'll throw an error.
let platformRecords = await Platform.find();
let platformRecord = platformRecords[0];
if(!platformRecord) {
throw new Error(`Consistency violation: when the GitHub webhook received an event, no platform record was found.`);
} else if(platformRecords.length > 1) {
throw new Error(`Consistency violation: when the GitHub webhook received an event, more than one platform record was found.`);
}
let pocketOfPrNumbersUnfrozen = platformRecord.currentUnfrozenGitHubPrNumbers;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -453,8 +456,8 @@ module.exports = {
// Note: We'll only do this if the PR is from the fleetdm/fleet repo.
if (isMainBranchFrozen && repo === 'fleet') {
sails.pocketOfPrNumbersUnfrozen = _.union(sails.pocketOfPrNumbersUnfrozen, [ prNumber ]);
sails.log.verbose('#'+prNumber+' autoapproved, main branch is frozen... prNumbers unfrozen:',sails.pocketOfPrNumbersUnfrozen);
pocketOfPrNumbersUnfrozen = _.union(pocketOfPrNumbersUnfrozen, [ prNumber ]);
sails.log.verbose('#'+prNumber+' autoapproved, main branch is frozen... prNumbers unfrozen:',pocketOfPrNumbersUnfrozen);
// [?] See May 6th, 2022 changelog, which includes this code sample:
// (https://www.mergefreeze.com/news)
@ -467,9 +470,10 @@ module.exports = {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
await sails.helpers.http.post(`https://www.mergefreeze.com/api/branches/fleetdm/fleet/main?access_token=${encodeURIComponent(sails.config.custom.mergeFreezeAccessToken)}`, {
user_name: 'fleet-release',//eslint-disable-line camelcase
unblocked_prs: sails.pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
unblocked_prs: pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
});
// Update the Platform record to have the current unfrozen PR numbers
await Platform.updateOne({id: platformRecord.id}).set({currentUnfrozenGitHubPrNumbers: pocketOfPrNumbersUnfrozen});
}//fi
} else {
@ -478,14 +482,16 @@ module.exports = {
// Note: We'll only do this if the PR is from the fleetdm/fleet repo.
if (isMainBranchFrozen && repo === 'fleet') {
sails.pocketOfPrNumbersUnfrozen = _.difference(sails.pocketOfPrNumbersUnfrozen, [ prNumber ]);
sails.log.verbose('#'+prNumber+' not autoapproved, main branch is frozen... prNumbers unfrozen:',sails.pocketOfPrNumbersUnfrozen);
pocketOfPrNumbersUnfrozen = _.difference(pocketOfPrNumbersUnfrozen, [ prNumber ]);
sails.log.verbose('#'+prNumber+' not autoapproved, main branch is frozen... prNumbers unfrozen:',pocketOfPrNumbersUnfrozen);
// [?] See explanation above.
await sails.helpers.http.post(`https://www.mergefreeze.com/api/branches/fleetdm/fleet/main?access_token=${encodeURIComponent(sails.config.custom.mergeFreezeAccessToken)}`, {
user_name: 'fleet-release',//eslint-disable-line camelcase
unblocked_prs: sails.pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
unblocked_prs: pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
});
// Update the Platform record to have the current unfrozen PR numbers
await Platform.updateOne({id: platformRecord.id}).set({currentUnfrozenGitHubPrNumbers: pocketOfPrNumbersUnfrozen});
}//fi
// Is this in use?

34
website/api/models/Platform.js vendored Normal file
View File

@ -0,0 +1,34 @@
/**
* Platform.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
currentUnfrozenGitHubPrNumbers: {
type: 'json',
description: 'An array containing the numbers of PRs to the fleetdm/fleet repo that can currently bypass MergeFreeze.',
example: [13638, 13447, 13673],
required: true,
}
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
},
};

View File

@ -62,6 +62,7 @@
"NewsletterSubscription": false,
"VantaConnection": false,
"CertificateSigningRequest": false,
"Platform": false,
// ...and any other backend globals (e.g. `"Organization": false`)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}

View File

@ -40,6 +40,11 @@ module.exports.bootstrap = async function() {
var lastRunBootstrapInfo = await sails.helpers.fs.readJson(bootstrapLastRunInfoPath)
.tolerate('doesNotExist');// (it's ok if the file doesn't exist yet-- just keep going.)
let numberOfPlatformRecords = await Platform.count();
if(numberOfPlatformRecords > 1) {
throw new Error('Consistency error: More than one platform record exists. To accurately freeze and unfreeze GitHub pull requests when the main branch is frozen, only one of these records should exist. Number of platform records found'+numberOfPlatformRecords);
}
if (lastRunBootstrapInfo && lastRunBootstrapInfo.lastRunVersion === HARD_CODED_DATA_VERSION) {
sails.log('Skipping v'+HARD_CODED_DATA_VERSION+' bootstrap script... (because it\'s already been run)');
sails.log('(last run on this computer: @ '+(new Date(lastRunBootstrapInfo.lastRunAt))+')');
@ -71,6 +76,8 @@ module.exports.bootstrap = async function() {
password: await sails.helpers.passwords.hashPassword('abc123')
}).fetch();
// Note: We do not create a platform record to avoid potential consistency violations.
if (sails.config.custom.enableBillingFeatures) {
let stripeCustomerId = await sails.helpers.stripe.saveBillingInfo.with({
emailAddress: adminUser.emailAddress