-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
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
PATCH
version or run a staging deploy when a checklist is locked. Instead, we bump thePATCH
version 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
PATCH
version bumped, and a staging deploy should occur./The new checklist should be created with the new
PATCH
version.Lock the checklist when there is no staging deploy running.
The
awaitStagingDeploys
action should complete quickly, andOSBotify
should 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
awaitStagingDeploys
action should poll the GH API every 90 seconds until the staging deploy completes.Once the staging deploy completes, the action should complete and
OSBotify
should comment on the deploy checklist with the name comment as above, using the new build version.