mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Tool: Bring back mergefreeze API integration (#6905)
* Tool: Bring back mergefreeze API integration Context: https://github.com/fleetdm/fleet/pull/5628#issuecomment-1196175485 Unfortunately, the API doesn't work. * Lay out how this would work in the database - but instead, do it ephemerally for now * Remove model * Maintain state (the easy way for now)
This commit is contained in:
parent
8369f6b1b5
commit
39fea292b9
@ -27,7 +27,13 @@ module.exports = {
|
||||
|
||||
let GitHub = require('machinepack-github');
|
||||
|
||||
let IS_FROZEN = false;// « Set this to `true` whenever a freeze is in effect, then set it back to `false` when the freeze ends.
|
||||
// Is this in use?
|
||||
// > For context on the history of this bit of code, which has gone been
|
||||
// > implemented a couple of different ways, and gone back and forth, check out:
|
||||
// > https://github.com/fleetdm/fleet/pull/5628#issuecomment-1196175485
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// let IS_FROZEN = false;// « Set this to `true` whenever a freeze is in effect, then set it back to `false` when the freeze ends.
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
let GITHUB_USERNAMES_OF_BOTS_AND_MAINTAINERS = [// « Used in multiple places below.
|
||||
'sailsbot',
|
||||
@ -71,6 +77,10 @@ module.exports = {
|
||||
|
||||
let GITHUB_USERNAME_OF_DRI_FOR_LABELS = 'noahtalerman';// « Used below (FUTURE: Remove this capability as Fleet has outgrown it. 2022-05-05)
|
||||
|
||||
if (!sails.config.custom.mergeFreezeAccessToken) {
|
||||
throw new Error('An access token for the MergeFreeze API (sails.config.custom.mergeFreezeAccessToken) is required to enable automated unfreezing/freezing of changes based on the files they change. Please ask for help in #g-digital-experience, whether you are testing locally or using this as a live webhook.');
|
||||
}
|
||||
|
||||
if (!sails.config.custom.slackWebhookUrlForGithubBot) {
|
||||
throw new Error('No Slack webhook URL configured for the GitHub bot to notify with alerts! (Please set `sails.config.custom.slackWebhookUrlForGithubBot`.)');
|
||||
}//•
|
||||
@ -218,18 +228,78 @@ module.exports = {
|
||||
isGithubUserMaintainerOrDoesntMatter: GITHUB_USERNAMES_OF_BOTS_AND_MAINTAINERS.includes(sender.login.toLowerCase())
|
||||
});
|
||||
|
||||
// Check whether the "main" branch is currently frozen (i.e. a feature freeze)
|
||||
// [?] https://docs.mergefreeze.com/web-api#get-freeze-status
|
||||
let isMainBranchFrozen = (await sails.helpers.http.get('https://www.mergefreeze.com/api/branches/fleetdm/fleet/main', { access_token: sails.config.custom.mergeFreezeAccessToken })).frozen;//eslint-disable-line camelcase
|
||||
|
||||
// Now, if appropriate, auto-approve the change.
|
||||
if (isAutoApproved) {
|
||||
// [?] https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request
|
||||
await sails.helpers.http.post(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`, {
|
||||
event: 'APPROVE'
|
||||
}, baseHeaders);
|
||||
} else if (IS_FROZEN) {
|
||||
// [?] https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request
|
||||
await sails.helpers.http.post(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`, {
|
||||
event: 'REQUEST_CHANGES',
|
||||
body: 'The repository is currently frozen for an upcoming release. \n> After the freeze has ended, please dismiss this review. \n\nIn case of emergency, you can dismiss this review and merge now.'
|
||||
}, baseHeaders);
|
||||
|
||||
// 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 || [];
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// If "main" is explicitly frozen, then unfreeze this PR because it no longer contains
|
||||
// (or maybe never did contain) changes to freezeworthy files.
|
||||
if (isMainBranchFrozen) {
|
||||
|
||||
sails.pocketOfPrNumbersUnfrozen = _.union(sails.pocketOfPrNumbersUnfrozen, [ prNumber ]);
|
||||
|
||||
// [?] See May 6th, 2022 changelog, which includes this code sample:
|
||||
// (https://www.mergefreeze.com/news)
|
||||
// (but as of July 26, 2022, I didn't see it documented here: https://docs.mergefreeze.com/web-api#post-freeze-status)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// > You may now freeze or unfreeze a single PR (while maintaining the overall freeze) via the Web API.
|
||||
// ```
|
||||
// curl -d "frozen=true&user_name=Scooby Doo&unblocked_prs=[3]" -X POST https://www.mergefreeze.com/api/branches/mergefreeze/core/master/?access_token=[Your access token]
|
||||
// ```
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
await sails.helpers.http.post(`https://www.mergefreeze.com/api/branches/fleetdm/fleet/main?access_token=${encodeURIComponent(sails.config.custom.mergeFreezeAccessToken)}`, {
|
||||
frozen: true,
|
||||
user_name: 'fleet-release',//eslint-disable-line camelcase
|
||||
unblocked_prs: sails.pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
|
||||
});
|
||||
|
||||
}//fi
|
||||
|
||||
} else {
|
||||
// If "main" is explicitly frozen, then freeze this PR because it now contains
|
||||
// (or maybe always did contain) changes to freezeworthy files.
|
||||
if (isMainBranchFrozen) {
|
||||
|
||||
sails.pocketOfPrNumbersUnfrozen = _.difference(sails.pocketOfPrNumbersUnfrozen, [ prNumber ]);
|
||||
|
||||
// [?] See explanation above.
|
||||
await sails.helpers.http.post(`https://www.mergefreeze.com/api/branches/fleetdm/fleet/main?access_token=${encodeURIComponent(sails.config.custom.mergeFreezeAccessToken)}`, {
|
||||
frozen: true,
|
||||
user_name: 'fleet-release',//eslint-disable-line camelcase
|
||||
unblocked_prs: sails.pocketOfPrNumbersUnfrozen,//eslint-disable-line camelcase
|
||||
});
|
||||
}//fi
|
||||
|
||||
// Is this in use?
|
||||
// > For context on the history of this bit of code, which has gone been
|
||||
// > implemented a couple of different ways, and gone back and forth, check out:
|
||||
// > https://github.com/fleetdm/fleet/pull/5628#issuecomment-1196175485
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// if (IS_FROZEN) {
|
||||
// // [?] https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request
|
||||
// await sails.helpers.http.post(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`, {
|
||||
// event: 'REQUEST_CHANGES',
|
||||
// body: 'The repository is currently frozen for an upcoming release. \n> After the freeze has ended, please dismiss this review. \n\nIn case of emergency, you can dismiss this review and merge now.'
|
||||
// }, baseHeaders);
|
||||
// }//fi
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
}
|
||||
|
||||
}
|
||||
|
5
website/assets/.eslintrc
vendored
5
website/assets/.eslintrc
vendored
@ -55,7 +55,10 @@
|
||||
// Make sure backend globals aren't indadvertently tolerated in our client-side JS:
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
"sails": false,
|
||||
"User": false
|
||||
"User": false,
|
||||
"HistoricalUsageSnapshot": false,
|
||||
"Quote": false,
|
||||
"Subscription": false,
|
||||
// ...and any other backend globals (e.g. `"Organization": false`)
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
}
|
||||
|
116
website/scripts/freeze-open-pull-requests.js
vendored
116
website/scripts/freeze-open-pull-requests.js
vendored
@ -1,6 +1,5 @@
|
||||
module.exports = {
|
||||
|
||||
|
||||
friendlyName: 'Freeze open pull requests',
|
||||
|
||||
|
||||
@ -22,62 +21,69 @@ module.exports = {
|
||||
},
|
||||
|
||||
|
||||
fn: async function ({dry: isDryRun, limit: maxNumPullRequestsToCheck }) {
|
||||
|
||||
sails.log('Running custom shell script... (`sails run freeze-open-pull-requests`)');
|
||||
|
||||
let owner = 'fleetdm';
|
||||
let repo = 'fleet';
|
||||
let baseHeaders = {
|
||||
'User-Agent': 'sails run freeze-open-pull-requests',
|
||||
'Authorization': `token ${sails.config.custom.githubAccessToken}`
|
||||
};
|
||||
|
||||
// Fetch open pull requests
|
||||
// [?] https://docs.github.com/en/rest/pulls/pulls#list-pull-requests
|
||||
let openPullRequests = await sails.helpers.http.get(`https://api.github.com/repos/${owner}/${repo}/pulls`, {
|
||||
state: 'open',
|
||||
per_page: maxNumPullRequestsToCheck,//eslint-disable-line camelcase
|
||||
}, baseHeaders);
|
||||
|
||||
if (openPullRequests.length > maxNumPullRequestsToCheck) {
|
||||
openPullRequests = openPullRequests.slice(0,maxNumPullRequestsToCheck);
|
||||
}
|
||||
|
||||
let SECONDS_TO_WAIT = 5;
|
||||
sails.log(`Examining and potentially freezing ${openPullRequests.length} PRs very soon… (To cancel, press CTRL+C quickly within ${SECONDS_TO_WAIT}s!)`);
|
||||
await sails.helpers.flow.pause(SECONDS_TO_WAIT*1000);
|
||||
|
||||
// For all open pull requests…
|
||||
await sails.helpers.flow.simultaneouslyForEach(openPullRequests, async(pullRequest)=>{
|
||||
|
||||
let prNumber = pullRequest.number;
|
||||
let prAuthor = pullRequest.user.login;
|
||||
require('assert')(prAuthor !== undefined);
|
||||
|
||||
// Freeze, if appropriate.
|
||||
// (Check versus the intersection of DRIs for all changed files to make sure SOMEONE is preapproved for all of them.)
|
||||
let isAuthorPreapproved = await sails.helpers.githubAutomations.getIsPrPreapproved.with({
|
||||
prNumber: prNumber,
|
||||
isGithubUserMaintainerOrDoesntMatter: true// « doesn't matter here because no auto-approval is happening. Worst case, a community PR to an area with a "*" in the DRI mapping remains unfrozen.
|
||||
});
|
||||
|
||||
if (isDryRun) {
|
||||
sails.log(`#${prNumber} by @${prAuthor}:`, isAuthorPreapproved ? 'Would have skipped freeze…' : 'Would have frozen…');
|
||||
} else {
|
||||
sails.log(`#${prNumber} by @${prAuthor}:`, isAuthorPreapproved ? 'Skipping freeze…' : 'Freezing…');
|
||||
if (!isAuthorPreapproved) {
|
||||
// [?] https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request
|
||||
await sails.helpers.http.post(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`, {
|
||||
event: 'REQUEST_CHANGES',
|
||||
body: 'The repository has been frozen for an upcoming release. In case of emergency, you can dismiss this review and merge.'
|
||||
}, baseHeaders);
|
||||
}//fi
|
||||
}
|
||||
});
|
||||
|
||||
fn: async function () {
|
||||
// Is this in use?
|
||||
// > For context on the history of this bit of code, which has gone been
|
||||
// > implemented a couple of different ways, and gone back and forth, check out:
|
||||
// > https://github.com/fleetdm/fleet/pull/5628#issuecomment-1196175485
|
||||
throw new Error('Not currently in use. See comments in this script for more information.');
|
||||
}
|
||||
|
||||
// fn: async function ({dry: isDryRun, limit: maxNumPullRequestsToCheck }) {
|
||||
|
||||
// sails.log('Running custom shell script... (`sails run freeze-open-pull-requests`)');
|
||||
|
||||
// let owner = 'fleetdm';
|
||||
// let repo = 'fleet';
|
||||
// let baseHeaders = {
|
||||
// 'User-Agent': 'sails run freeze-open-pull-requests',
|
||||
// 'Authorization': `token ${sails.config.custom.githubAccessToken}`
|
||||
// };
|
||||
|
||||
// // Fetch open pull requests
|
||||
// // [?] https://docs.github.com/en/rest/pulls/pulls#list-pull-requests
|
||||
// let openPullRequests = await sails.helpers.http.get(`https://api.github.com/repos/${owner}/${repo}/pulls`, {
|
||||
// state: 'open',
|
||||
// per_page: maxNumPullRequestsToCheck,//eslint-disable-line camelcase
|
||||
// }, baseHeaders);
|
||||
|
||||
// if (openPullRequests.length > maxNumPullRequestsToCheck) {
|
||||
// openPullRequests = openPullRequests.slice(0,maxNumPullRequestsToCheck);
|
||||
// }
|
||||
|
||||
// let SECONDS_TO_WAIT = 5;
|
||||
// sails.log(`Examining and potentially freezing ${openPullRequests.length} PRs very soon… (To cancel, press CTRL+C quickly within ${SECONDS_TO_WAIT}s!)`);
|
||||
// await sails.helpers.flow.pause(SECONDS_TO_WAIT*1000);
|
||||
|
||||
// // For all open pull requests…
|
||||
// await sails.helpers.flow.simultaneouslyForEach(openPullRequests, async(pullRequest)=>{
|
||||
|
||||
// let prNumber = pullRequest.number;
|
||||
// let prAuthor = pullRequest.user.login;
|
||||
// require('assert')(prAuthor !== undefined);
|
||||
|
||||
// // Freeze, if appropriate.
|
||||
// // (Check versus the intersection of DRIs for all changed files to make sure SOMEONE is preapproved for all of them.)
|
||||
// let isAuthorPreapproved = await sails.helpers.githubAutomations.getIsPrPreapproved.with({
|
||||
// prNumber: prNumber,
|
||||
// isGithubUserMaintainerOrDoesntMatter: true// « doesn't matter here because no auto-approval is happening. Worst case, a community PR to an area with a "*" in the DRI mapping remains unfrozen.
|
||||
// });
|
||||
|
||||
// if (isDryRun) {
|
||||
// sails.log(`#${prNumber} by @${prAuthor}:`, isAuthorPreapproved ? 'Would have skipped freeze…' : 'Would have frozen…');
|
||||
// } else {
|
||||
// sails.log(`#${prNumber} by @${prAuthor}:`, isAuthorPreapproved ? 'Skipping freeze…' : 'Freezing…');
|
||||
// if (!isAuthorPreapproved) {
|
||||
// // [?] https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request
|
||||
// await sails.helpers.http.post(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`, {
|
||||
// event: 'REQUEST_CHANGES',
|
||||
// body: 'The repository has been frozen for an upcoming release. In case of emergency, you can dismiss this review and merge.'
|
||||
// }, baseHeaders);
|
||||
// }//fi
|
||||
// }
|
||||
// });
|
||||
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user