Update semver logic: one patch version per checklist#7458
Conversation
|
Planned changes to this SO: New Expensify uses Github Actions for CI/CD. At a high level, the process works like this:
1) When a PR is merged to main, a new `BUILD` version is created (`1.0.2-72` becomes `1.0.2-73`) and it is typically deployed to staging immediately.
2) As PRs are deployed, they are accumulated in a special tracking issue in Expensify/App labeled `StagingDeployCash`. That issue contains:
1) The latest version on staging
2) A link to a comparison between the latest staging version and the previous production version.
3) A checklist of all PRs that were merged and deployed to staging since the last production deploy
4) A checklist of any deploy blockers found by Applause during QA.
+3) When Applause is ready to begin QA, they add the `🔐LockCashDeploys🔐` label to the `StagingDeployCash`. That will prevent any newly merged PRs from being deployed to staging.
-3) When Applause is ready to begin QA, they add the `🔐LockCashDeploys🔐` label to the `StagingDeployCash`. That will:
- 1) Create a new `PATCH` version (`1.0.2-73` becomes `1.0.3-0`)
- 2) Prevent any newly merged PRs from being deployed to staging.
4) If issues are found on staging that are not present on production, they become deploy blockers.
1) Any issue or PR labelled `DeployBlockerCash` will be auto-assigned to an Expensify engineer as an `Hourly`.
2) To fix a `DeployBlocker`, there are two options:
1) Create a PR to fix the deploy blocker, and give it the `CherryPickStaging` label. When merged, that PR will be CP'd to staging.
2) Remove the lock label from the `StagingDeployCash` checklist, and "open the floodgates" by deploying the main branch to staging. This is the nuclear option that deploys any and all new code to staging and invalidates the current QA cycle.
4) When Applause finishes QA, one of two things can happen:
1) If there are issues found during QA, they must wait for Expensify engineers to fix the deploy blockers and proceed with the production deploy.
2) If there are no issues found during QA, the assigned mobile-deployer for the week will close the `StagingDeployCash` issue with a comment that includes the `:shipit:` emoji. That will:
1) Deploy the latest staging version to production
- 2) Create a new `StagingDeployCash` checklist with all the PRs that were merged while the `StagingDeployCash` was locked, thus restarting the process.
+ 2) Create a new `StagingDeployCash` checklist with all the PRs that were merged while the `StagingDeployCash` was locked, thus restarting the process. At this time, we will bump the `PATCH` version (`1.0.2-73` becomes `1.0.3-0`), so each checklist is associated with a unique `PATCH` version.
Applause does daily QA Monday through Friday, so we'll do a production deploy Monday trough Thursday when no issues are found during QA. As per company policy, we typically don't do production deploys on Fridays, but the deployer can decide to do a deploy regardless [if nedeed](https://stackoverflow.com/c/expensify/questions/10635).
**Note:** There is currently no process to cherry-pick hotfixes to production.
|
|
|
||
| function run() { | ||
| let currentStagingDeploys = []; | ||
| return promiseDoWhile( |
There was a problem hiding this comment.
FWIW our async/await ban really kills me here, in my opinion this would be much cleaner written like so:
const _ = require('underscore');
const GitHubUtils = require('../../libs/GithubUtils');
async function run() {
let currentStagingDeploys = [];
do {
const response = await GitHubUtils.octokit.actions.listWorkflowRuns({
owner: GitHubUtils.GITHUB_OWNER,
repo: GitHubUtils.APP_REPO,
workflow_id: 'platformDeploy.yml',
event: 'push',
});
currentStagingDeploys = _.filter(response.data.workflow_runs, workflowRun => workflowRun.status !== 'completed');
console.log(
_.isEmpty(currentStagingDeploys)
? 'No current staging deploys found'
: `Found ${currentStagingDeploys.length} staging deploy${currentStagingDeploys.length > 1 ? 's' : ''} still running...`,
);
await new Promise(resolve => setTimeout(resolve, GitHubUtils.POLL_RATE * 9))
} while(!_.isEmpty(currentStagingDeploys));
}
if (require.main === module) {
run();
}
module.exports = run;|
This is a pretty large change so I'm going to pull in a second reviewer here. |
pecanoro
left a comment
There was a problem hiding this comment.
It looks good but I left a comment of something I don't fully understand
|
@pecanoro's question led me to realize there was another potential race condition hiding here that's now solved. Before my last two commits, this was possible:
To resolve this, |
|
Triggered auto assignment to @pecanoro ( |
|
@timszot looks like this was merged without passing tests. Please add a note explaining why this was done and remove the |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
Not sure why this got flagged as |
|
Okay, doing the internal QA steps slightly out of order here:
|
|
🚀 Deployed to production by @sketchydroide in version: 1.1.35-1 🚀
|
Details
This changes the deploy paradigm so that we no longer bump the
PATCHversion or run a staging deploy when a checklist is locked. Instead, we bump thePATCHversion when the checklist is first created.Fixed Issues
$ #7166
Tests
I tested commands locally and added automated unit tests where possible.
QA Steps
Close the deploy checklist.
The app should have it's
PATCHversion bumped, and a staging deploy should occur./The new checklist should be created with the new
PATCHversion.Lock the checklist when there is no staging deploy running.
The
awaitStagingDeploysaction should complete quickly, andOSBotifyshould comment on the deploy checklist:🚀 All staging deploys are complete, @Expensify/applauseleads please begin QA on version https://github.com/Expensify/App/releases/tag/new-build-version 🚀
Unlock the checklist and merge another PR.
While the staging deploy for the other PR is running, lock the checklist again.
The
awaitStagingDeploysaction should poll the GH API every 90 seconds until the staging deploy completes.Once the staging deploy completes, the action should complete and
OSBotifyshould comment on the deploy checklist with the name comment as above, using the new build version.