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

feat(git): Support baseBranches in fork mode #34532

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

Conversation

janhoy
Copy link
Contributor

@janhoy janhoy commented Feb 27, 2025

Changes

Building upon #34467, this PR adds code that makes baseBranches feature work also in forking mode:

  • Extend scm interface with syncForkBranch()
  • Added new util/git methods:
    • checkoutBranchFromRemote()
    • resetHardFromRemote()
    • forcePushToRemote()
    • localBranchExists()
    • syncForkBranch() which syncs <baseBranch> from upstream to local and force-push to origin
  • Refactor syncGit() upstream handling to use the new syncForkBranch() instead of using individual git commands
  • Call syncForkBranch() in extractDependencies() inside the loop for each baseBranch
  • Removed disclaimer from documentation that forkMode does not support baseBranchews

PS: This PR includes the commit from #34467 for completeness, i.e. that PR can be merged first if you so choose.

Context

See #7850 for discussion and context.

Documentation (please check one with an [x])

  • I have updated the documentation, or
  • No documentation update is required

How I've tested my work (please select one)

I have verified these changes via:

  • Code inspection only, or
  • Newly added/modified unit tests, or
  • No unit tests but ran on a real repository, or
  • Both unit tests + ran on a real repository

TODO: Add unit tests

Public repos:

I used dummy repo: https://github.com/cominvent/dummy for testing. It contains two branches main and dev, both having a Dockerfile with out-of-date FROM tag. Ran renovate locally in my IDE with a token that forks to https://github.com/janhoy/cominvent-_-dummy . You can see how the forked repo has both branches, and that the upstream repo has two PR's created, one for each branch.

Revival of renovatebot#13808

Signed-off-by: Jan Høydahl <janhoy@users.noreply.github.com>
Signed-off-by: Jan Høydahl <jan.git@cominvent.com>
@janhoy janhoy marked this pull request as draft February 27, 2025 14:32
Signed-off-by: Jan Høydahl <jan.git@cominvent.com>
janhoy added 2 commits March 2, 2025 23:57
Signed-off-by: Jan Høydahl <jan.git@cominvent.com>
Signed-off-by: Jan Høydahl <jan.git@cominvent.com>
Comment on lines 1463 to 1469
* This function ensures that the specified branch in the forked repository is up-to-date
* with the corresponding branch in the upstream repository. It performs the following steps:
* 1. Checks if the branch exists locally.
* 2. If the branch exists locally, it checks out the branch.
* 3. If the branch does not exist locally, it checks out the branch from the upstream repository.
* 4. Resets the local branch to match the upstream branch.
* 5. Force pushes the updated branch to the origin repository.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
* This function ensures that the specified branch in the forked repository is up-to-date
* with the corresponding branch in the upstream repository. It performs the following steps:
* 1. Checks if the branch exists locally.
* 2. If the branch exists locally, it checks out the branch.
* 3. If the branch does not exist locally, it checks out the branch from the upstream repository.
* 4. Resets the local branch to match the upstream branch.
* 5. Force pushes the updated branch to the origin repository.
* The syncForkWithUpstream function ensures the fork's branch is up-to-date with the corresponding branch in the upstream repository.
* The steps are:
* 1. Check if the branch exists locally.
* 2. If the branch exists locally: check out the branch.
* 3. If the branch does _not_ exist locally: checkout the upstream branch.
* 4. Reset the local branch to match the upstream branch.
* 5. Force push the updated branch to the origin repository.

About my rewrite

Here's a small rewrite to the comment to:

  • Use simple words and phrases
  • Use one sentence per line (this makes it easier to move/change bits around later, and helps with the git diff)
  • Write short sentences
  • Put the name of the function in the comment
  • Use if: then formatting for steps that rely on a condition to be true
  • Emphasize the not part in a sentence

Questions

After reading just the comment, I don't understand:

  • Does step 4 "Reset the local branch to match the upstream branch" always happen, or does step 4 depend on the outcome of step 2/3?
  • What is the "updated branch" that's pushed to the origin repository in step 5. Is it the local branch, or the upstream branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does step 4 "Reset the local branch to match the upstream branch" always happen, or does step 4 depend on the outcome of step 2/3?

Currently we always do a git reset to upstream branch. If we for some reason had an existing local repo with a stale local branch, just checking it out won't bring it up to date. If we fetch from upstream for the first time, it is not necessary to "git reset", but again, it is mostly a NOOP so does not hurt.

What is the "updated branch" that's pushed to the origin repository in step 5. Is it the local branch, or the upstream branch?

It will be the local branch, which is just reset to match "upstream". So we fetch/pull from "upstream" to local, then push (force) to origin which is our fork. It has same effect as calling the GitHub API we did before which brought the fork up to date on github, before pulling.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you for explaining how the code works, and which branches each steps targets. My new suggestion puts this extra info in the code comment. 😄

After reviewing and applying my new suggestion, a maintainer can mark this discussion as resolved. 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the attention to details and understandable docs.

janhoy and others added 5 commits March 5, 2025 22:35
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
@janhoy janhoy marked this pull request as ready for review March 5, 2025 21:48
janhoy and others added 7 commits March 10, 2025 23:24
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Signed-off-by: Jan Høydahl <jan.git@cominvent.com>
@janhoy
Copy link
Contributor Author

janhoy commented Mar 10, 2025

Thanks for the reviews. I merged it all and ran prettier etc.
How do we approach testing?

@@ -19,6 +19,7 @@ export interface StorageConfig {
currentBranch?: string;
defaultBranch?: string;
url: string;
upstreamUrl?: string;
Copy link
Contributor Author

@janhoy janhoy Mar 11, 2025

Choose a reason for hiding this comment

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

The "build-docker" test fails with a message

"message": "remote: Not Found\nfatal: repository 'https://github.com/undefined.git/' not found\n"

I believe that is because the upstreamUrl variable is always passed in to git.initRepo(), even if undefined, but the upstreamUrl?: string declaration here only catches cases where the property is not passed in at all.

I believe the fix is to modify the type here.

Suggested change
upstreamUrl?: string;
upstreamUrl?: string | undefined;

Not tested, thoughts? There are subtle differences between not-provided, null and undefined in TS....

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tested, but same error. Will need to Reproduce locally and find a working fix.

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.

3 participants