-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Release management in CI #18398
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
Release management in CI #18398
Conversation
|
App Name | ![]() |
|
Flavor | Jalapeno | |
Build Type | Debug | |
Version | pr18398-0af7b97 | |
Commit | 0af7b97 | |
Direct Download | jetpack-prototype-build-pr18398-0af7b97.apk |
|
App Name | ![]() |
|
Flavor | Jalapeno | |
Build Type | Debug | |
Version | pr18398-0af7b97 | |
Commit | 0af7b97 | |
Direct Download | wordpress-prototype-build-pr18398-0af7b97.apk |
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.
We intend to bring this configuration to our agents, so that we don't have to do it in every pipeline.
1e8c36e
to
686f0f6
Compare
Gemfile
Outdated
# gem 'fastlane-plugin-wpmreleasetoolkit', path: '../../release-toolkit' | ||
# gem 'fastlane-plugin-wpmreleasetoolkit', git: 'https://github.com/wordpress-mobile/release-toolkit', branch: 'trunk' | ||
gem 'fastlane-plugin-wpmreleasetoolkit', git: 'https://github.com/wordpress-mobile/release-toolkit', branch: 'remove/git-push-actions' |
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.
I'll do a proper release before we merge this PR in.
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.
I am not sure where the best place for this helper is. I've asked @jkmassel's opinion and he agreed that this approach made sense. However, if you have a suggestion, I'd be happy to apply it.
Note that I initially had this in the lanes/release_management_in_ci.rb
file but I couldn't get it to work. I am now realizing that if I import that before the other lanes, that approach also would have worked. However, I like the separate file a bit better.
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.
This seems like a good start – long-term, might be good to see if we can turn it into a release toolkit action – I find that helpers generally end up there!
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.
I agree. To provide some context;
I initially intended to do this and created an internal discussion where Olivier pointed out that there is already a fastlane
action for creating pull requests. That's when I moved on to adding it to the project instead. I went back and forth on where it belongs but decided to go with this initial implementation because this helper doesn't have much added value. However, at some point, I think it'll make sense to have separate helpers for code freeze, new beta, finalize release etc and then it'll make sense to move it to release-toolkit
so we can use it in other projects as well.
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.
+1. It makes sense to start local and extract/abstract later.
@@ -0,0 +1,10 @@ | |||
def create_release_management_pull_request(base_branch, title) | |||
create_pull_request( | |||
api_token: ENV['GITHUB_TOKEN'], |
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.
Fastlane uses ENV["GITHUB_API_TOKEN"]
as the default whereas we are using ENV["GITHUB_TOKEN"]
. Instead of adding another environment variable, I thought it'd be better to default to the existing one.
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.
Sound 👍
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.
This is a good way to go. The reason we use that environment variable is that it's what OctoKit expects FWIW.
title: title, | ||
head: Fastlane::Helper::GitHelper.current_git_branch, | ||
base: base_branch, | ||
labels: 'Releases' |
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.
We can add reviewers
field, but I wanted to skip that for now to not create extra noise. I have tested creating PRs a few times and will likely do a few more. Once everything settles down, it's easy enough to add this field.
api_token: ENV['GITHUB_TOKEN'], | ||
repo: GHHELPER_REPO, | ||
title: title, | ||
head: Fastlane::Helper::GitHelper.current_git_branch, |
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.
Fastlane defaults to the current branch. However, it does so by using the git_branch
helper which uses environment variables to override the value. We do not want this behavior which is why we added our own helper in wordpress-mobile/release-toolkit#463.
|
||
apps.each do |app| | ||
app_values = APP_SPECIFIC_VALUES[app] | ||
|
||
metadata_folder = File.join(PROJECT_ROOT_FOLDER, 'WordPress', app_values[:metadata_dir]) | ||
version = options.fetch(:version, android_get_app_version) |
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.
The version value is not application specific, in fact it's fetched from version.properties
file which has a shared value. So, there is no harm in moving this outside of the loop and reuse the value in release_branch
variable.
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.
Our goal is to remove these triggers from fastlane
. We'll likely use curl
for this, so that release managers don't need to have anything setup in their local environment. However, since we already have buildkite_trigger_build
helper, it made sense to use it during the initial implementation phase.
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.
I like that this is nicely separated out for easy removal later!
Created and added the "Do Not Merge" label, and Peril picked it up. |
|
||
# EDITORIAL_BRANCH is passed as an environment variable from fastlane to Buildkite | ||
# | ||
if [[ -z "${EDITORIAL_BRANCH}" ]]; then |
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.
TIL about this approach to avoid the set -u
from the shebang to fail the script at this point because of an unbound access. Neat 👏
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.
I started looking at this but I don't have the energy to give it the attention it deserves right now.
Just a not. Looking at the various new pipelines and how similar they are, it occurred to me that we might make the setup easier to maintain – as a possible followup! – by generating the pipeline. See the dynamic pipelines docs.
It's definitely worth exploring. I think the main benefit we should look to gain from that should be to get rid of the boilerplate part but still keep the command steps. As long as we keep each file separate - or somehow put it all in a small and easy to read file, then it's a net positive for us. However, if it makes it harder to navigate the code, then I don't think we should do it. |
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.
Looks solid to me!
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.
This seems like a good start – long-term, might be good to see if we can turn it into a release toolkit action – I find that helpers generally end up there!
@@ -0,0 +1,10 @@ | |||
def create_release_management_pull_request(base_branch, title) | |||
create_pull_request( | |||
api_token: ENV['GITHUB_TOKEN'], |
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.
This is a good way to go. The reason we use that environment variable is that it's what OctoKit expects FWIW.
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.
I like that this is nicely separated out for easy removal later!
fi | ||
|
||
# Buildkite, by default, checks out a specific commit. When we update the app store strings, we open | ||
# a PR from the current branch. So, we need to checkout the `EDITORIAL_BRANCH`. |
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.
Is the difference that we wouldn't be able to open the PR if we were on a commit (detached HEAD?)?
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.
We can't add a new commit in a detached HEAD. When we update the app store strings, we need to create new commits and push it to remote.
|
||
new_version = android_get_app_version() | ||
trigger_beta_build(branch_to_build: "release/#{new_version}") | ||
|
||
create_release_management_pull_request('trunk', "Merge #{new_version} code freeze to trunk") |
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.
Nitpick. Since we dropped the develop
-trunk
setup, I stopped adding "to trunk" in my PRs because that's the branch where usually release PRs land.
create_release_management_pull_request('trunk', "Merge #{new_version} code freeze to trunk") | |
create_release_management_pull_request('trunk', "Merge #{new_version} code freeze") |
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.
With release management in CI, not all PRs target the trunk
branch. Some of them target the release branch, so I think it's useful to have this information.
setfrozentag(repository: GHHELPER_REPO, milestone: version['name'], freeze: false) | ||
create_new_milestone(repository: GHHELPER_REPO) | ||
close_milestone(repository: GHHELPER_REPO, milestone: version['name']) | ||
|
||
# Trigger release build | ||
trigger_release_build(branch_to_build: "release/#{version['name']}") | ||
|
||
create_release_management_pull_request('trunk', "Merge #{app_version} final to trunk") |
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.
Same rationale as above.
create_release_management_pull_request('trunk', "Merge #{app_version} final to trunk") | |
create_release_management_pull_request('trunk', "Merge #{app_version} final") |
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.
Same rationale as above. 😅
buildkite_pipeline: BUILDKITE_PIPELINE, | ||
branch: "release/#{release_version}", | ||
pipeline_file: 'complete-code-freeze.yml', | ||
message: 'Complete Code Freeze in CI', |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
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.
Only left nitpicks that have little to do with the actual implementation. Things are looking pretty good 😄
Co-authored-by: Gio Lodi <gio.lodi@automattic.com>
Generated by 🚫 dangerJS |
Co-authored-by: Gio Lodi <gio.lodi@automattic.com>
Thank you for the review @mokagio! I've applied all your suggestions except for dropping |
git config --global user.name "Automattic Release Bot" | ||
|
||
# Buildkite is currently using the https url to checkout. We need to override it to be able to use the deploy key. | ||
git remote set-url origin git@github.com:wordpress-mobile/WordPress-Android.git |
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.
💡 I wonder if it would be better to make this a bit more generic, like:
REPO_NO_TRAILING=${BUILDKITE_REPO%/}
git remote set-url origin ${REPO_NO_TRAILING/#https:\/\/github.com\//git@github:}
Or alternatively (inspired by this):
REPO_SLUG=$(basename $(dirname "$BUILDKITE_REPO"))/$(basename "$BUILDKITE_REPO%.git")
git remote set-url origin git@github.com:${REPO_SLUG}.git
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.
If this was in a toolkit repo, it'd make sense to go with a generic version. However, since this is part of WordPress-Android, I think this just makes it harder to understand the code.
Furthermore, it looks like I forgot to mention that this is a temporary issue specific to WordPress-Android. We should not be using the https
url to clone in the first place. I just didn't have a chance to figure out why this is the case for WordPress-Android. I think we used to have a specific configuration for WPAndroid, but I couldn't find it yet.
For example, we don't need this bit in release-toolkit-demo
. I also checked FluxC & WCAndroid and they both use the ssh
url.
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.
Aaah.. and I think I might have found the culprit. All this time I've been checking the Buildkite settings' Checkout using:
section which says that we are using ssh
to checkout. However, I just checked the terraform and the repository
field for WPAndroid is https://github.com/wordpress-mobile/WordPress-Android/
. I compared this against WPiOS, WCAndroid & FluxC and they all use the ssh
url. So, I think we'll be able to get rid of this configuration all together.
Having said that, I hope my previous logic also made sense in terms of keeping the specific url.
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.
If this was in a toolkit repo, it'd make sense to go with a generic version. However, since this is part of WordPress-Android, I think this just makes it harder to understand the code.
🤦♂️ I've reviewed so many PRs in the past few days that I think I lost track of which repo each PR was about, and since I reviewed a PR about buildkite-ci
repo just before this one, I think I didn't realize I was now reviewing a WPAndroid repo when I switched to this review 🤦♂️🤦 Sorry 😅
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.
No worries at all 🤗
I've reviewed so many PRs in the past few days
I noticed ❤️ - thank you for doing that! 🙇♂️
This PR adds the necessary configurations to handle the project's release management in CI. It closely follows the approach we've explored in release-toolkit-demo project and discussed internally in our RFCs.
There are a few moving parts to be aware of:
fastlane/lanes/release_management_in_ci.rb
. We intend to remove these triggers and usecurl
instead..buildkite/code-freeze.yml
,.buildkite/complete-code-freeze.yml
etc. These are pretty straightforward as they just call the relevant lane after some basic configuration..buildkite/commands/configure-git-for-release-management.sh
configures the git client, which we intend to move to our agents..buildkite/commands/checkout-release-branch.sh
checks out the release branch which is necessary because Buildkite starts the job in a detached state and we need to be on a branch to be able to commit and push the changes. Similarly.buildkite/commands/checkout-editorial-branch.sh
checks out the editorial branch which is a parameter in the job's trigger.remove/git-push-actions
release-toolkit
branch which is already approved. I intend to create the new release tomorrow. As a result of this, you'll notice a few additions ofpush_to_git_remote
.429: Too Many Requests
errors as we try to download several translations and we need to manually confirm to retry. I'm working on a possible fix for this, but it won't be part of this PR.To test:
Unfortunately there is no way to test the full release flow directly in WPAndroid. However, we used release-toolkit-demo project to test this implementation before bringing it to WPAndroid. So, hopefully any issues we might experience will be minimal.
I was able the test updating release notes flow and it verified that the general setup is working correctly. It's a bit cumbersome to test this and since it's in CI, there isn't anything new to expect, so I suggest skipping this testing step.
We expect some minor issues with the initial implementation, but I am in a position to quickly address them as this project's release manager.
Regression Notes
Potential unintended areas of impact
Parts of release management might break as we move it to CI.
What I did to test those areas of impact (or what existing automated tests I relied on)
N/A
What automated tests I added (or what prevented me from doing so)
N/A
PR submission checklist:
RELEASE-NOTES.txt
if necessary.UI Changes testing checklist:
N/A