Skip to content
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

Add git node staging command #875

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ruyadorno
Copy link
Member

@ruyadorno ruyadorno commented Nov 27, 2024

Add a new git node staging command that automates cherry-picking commits into staging branches.

It works by cherry-picking all commits that have no conflicts and skipping any commits that have conflicts while automating the sending of GitHub PR interactions to request backport for these commits, sending a message to the original PR and properly labelling it.

Usage:

Fetches a commit list using branch-diff and automatically cherry-picks / skips commits based on whether or not they land cleanly:

  git node staging

Sets a custom reporter to be used at the end of the automated operation:

  git node staging --reporter=markdown

Limits to 10 the number of commits to be cherry-picked:

  git node staging --pagination=10

Defines the release line (usually this can be inferred from the ncu.branch value as it should not be required most of the time):

  git node staging --releaseLine=22

Automates the backport request message, this won't run any of the branch-diff or cherry-pick routines. Useful for when you removed a faulty commit from the branch and want to signal to PR author and collaborators that commit now needs backporting, just use its PR#:

  git node staging --backport=12345

The skipGH option avoids gh hitting API requests. As such it enables for running a local-only / dry-run if the releaser wants to validate the final result of the staging branch without having to incur on all the automated messages spamming the Pull Requests:

git node staging --skipGH

Report

A report is generated at the end of operations listing information on the commits that were successfully cherry picked and commits that failed to be cherry-picked due to conflicts.

Important

Below is a short example of how these reports look like. The following report was generated for an operation that was limited using --pagination=10

Cherry-pick Report

6 successfully cherry-picked commits:

4 commits that failed to cherry-pick:


More

The automate cherry-pick logic also includes local persistency of the ongoing commit list, in case a fatal error happens during the command execution, it's possible to resume after cleaning up the git repo state by running git node staging again.

If no text is provided to `cli.stopSpinner` then it should allow for
non-persistent usage of the spinner.
Added a `captureStderr` option to `lib/run.js` `runAsyncBase` method
that allows for adding stderr information to thrown errors.
Add a new `git node staging` command that automates cherry-picking
commits into staging branches.

It works by cherry-picking all commits that have no conflicts and
skipping any commits that have conflicts while automating the sending
of GitHub PR interactions to request backport for these commits,
sending a message to the original PR and properly labelling it.

Usage:

Fetches a commit list using `branch-diff` and automatically
cherry-picks / skips commits based on whether or not they land
cleanly:

  git node staging

Sets a custom reporter at the end of the automated operation:

  git node staging --reporter=markdown

Limits to 10 the number of commits to be cherry-picked:

  git node staging --pagination=10

Defines the release line (usually this can be inferred from the
ncu.branch value os it should not be required most of the time):

  git node staging --releaseLine=22

Automates the backport request message, this won't run any of the
`branch-diff` or cherry-pick routines. Useful for when you removed
a faulty commit from the branch and want to signal to PR author and
collaborators that commit now needs backporting, just use its PR#:

  git node staging --backport=12345

More:

The automate cherry-pick logic also includes local persistency of
the ongoing commit list, in case a fatal error happens during the
command execution, it's possible to resume after cleaning up the
git repo state by running `git node staging` again.
@ruyadorno
Copy link
Member Author

ruyadorno commented Nov 27, 2024

When working on the v22 release, I did a progressive run of the automation using the --pagination option to ensure that the tooling was working as intended, as a result I ended up with multiple reports that I'm linking below for future reference:

  1. https://gist.github.com/ruyadorno/29d880a0029c50e6642f2dd1c4d09d1b
  2. https://gist.github.com/ruyadorno/d1813b10d473f1540e008c3ad5cf8769
  3. https://gist.github.com/ruyadorno/2f7d5ecb459f50c71f2e6ed027e942a3
  4. https://gist.github.com/ruyadorno/292b6bdf531e63078b7a5ce9b1d01253

These markdown format reports are way more useful when properly rendered on the GitHub UI or something similar. Right now the command is just printing this result to stdout but as you can imagine this opens the door to having a future GitHub action that either comments or stores this report somewhere, I'm very open to ideas on how to improve that next step of the automation.

Comment on lines +96 to +106
if (this.isLTS) {
excludeLabels.push('baking-for-lts');
const res = await fetch('https://nodejs.org/dist/index.json');
if (!res.ok) throw new Error('Failed to fetch', { cause: res });
const [latest] = await res.json();
// Assume Current branch matches tag with highest semver value.
const latestReleaseLine = semver.coerce(latest.version).major;
if (!validNumber(latestReleaseLine)) {
throw new Error('Could not determine latest release line');
}
comparisonBranch = `v${latestReleaseLine}.x`;
Copy link
Member

@richardlau richardlau Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest current may not be the best thing to compare to. For example, if you were to take the latest v23.x today, that would be v23.3.0 which was only released one week ago and presumably commits would be identified that do not meet the usual "two weeks in a current release" (depending, of course, on when the planned date for the release being prepared is).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we need a better way to handle that 2-weeks delay for sure! That said, for now I think it might still be usable as long as we put enough guardrails in the release docs.

btw I'm def falling for that rn with my current release but given that I postponed it to next week I don't think it's worth going back to remove all the v23.3.0 commits but it goes to say that you're definitely right that this is a concern in the current implementation.

@targos
Copy link
Member

targos commented Nov 28, 2024

I understand why you are doing it but I'm afraid of the notification spamming that this generates when there are many conflicts. It's also actually not a good idea to ask for backports on most PRs because landing backports in the wrong order increases the risk of conflicts.

@RafaelGSS
Copy link
Member

I understand why you are doing it but I'm afraid of the notification spamming that this generates when there are many conflicts. It's also actually not a good idea to ask for backports on most PRs because landing backports in the wrong order increases the risk of conflicts.

I was afraid of it too. Maybe collapse all the messages into a single issue and add the backport-requested label to each one that might reduce the spamming?

@targos
Copy link
Member

targos commented Nov 28, 2024

I really like that! It would solve many problems:

  • No more spam
  • Single place to collaborate on backports
  • Encourage doing the backports in the correct order
  • More visibility, by having an open issue instead of comments on merged PRs

@ruyadorno
Copy link
Member Author

Right, I agree that having a single place to manage all the backports has many benefits, I think a simple way to tweak the implementation is to use thegh cli to open a new issue with that markdown report in which the commits that failed to cherry-pick section is the list of commits that need backporting in their expected order. Then the releasers and any other collaborator could work on that.

That said, I still believe that automatically placing the label is a fundamental step that needs to be part of the logic here but we can remove the automatic-commenting to avoid spamming.

@ruyadorno
Copy link
Member Author

@targos to reinforce on the idea here, my hope is that this is going to be a much more sane workflow for the releasers.

As anedoctal evidence, for the current release I'm working on I signed off for the day after running the script (which spammed a bunch of comments and added all the labels) and the next day when I woke up in the morning I noticed that @aduh95 jumped in and landed a dozen of the straightforward backports. This happened without any coordination but it does reinforces my believe that if we put a little bit more structure around the process we can have a workflow that is going to be way less demanding on a single releaser.

And of course this new workflow won't prevent the releaser themselves to go through the list of backport-requested commits on their own time and land the straighforward conflict resolutions.

@targos
Copy link
Member

targos commented Nov 28, 2024

I agree with everything you said.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants