-
Notifications
You must be signed in to change notification settings - Fork 9
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
Auto-detect the value of the no-squash option #118
Conversation
Coverage report
Show files with reduced coverage 🔻
Test suite run success177 tests passing in 16 suites. Report generated by 🧪jest coverage report action from f591021 |
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 absolutely agree on the overall approach, but I think that it relies on whether we can say if the merge_commit_sha
(retrieved by this.getSha(pr);
) is a merge commit or not (as it will always be filled in, either it is a merge commit, a squash commit or a rebase and merge commit).
Right now I am missing how this can be inferred from the pull request or github api but I might be missing somenthing too 😄
The original approach was not good because at the time the PR is examined the clone is not available and it is not possible to run Here is another approach:
After the clone is done, the following pseudo logic chooses the commits that should be cherry-picked: async getPrCommits(configs: Configs, originalPR: GitPullRequest, git: Git): Promise<string[]> {
let squash = configs.squash
if (originalPR.state == "open") {
squash = false
} else if (squash === undefined) {
squash = !git.isMerge(originalPR.sha)
}
if squash {
return [originalPR.sha]
} else {
return [originalPR.commits]
}
} Let me know if it is a sound approach and I'll keep going. P.S. I think it never makes sense to have |
Now that I think about it... another way would simply be to clone before inspecting the PR so the existing logic can |
Or not... clone would require the config to be available but that same config is the one parsing the PR so there is a chicken & egg problem. |
Both have the parents. $ curl -sS https://code.forgejo.org/api/v1/repos/forgejo/runner/git/commits/eb89a98c6a401bc0afc6f9a897a82de0dfcb9d8d | jq .parents
[
{
"url": "https://code.forgejo.org/api/v1/repos/forgejo/runner/git/commits/781606388cb46645bb84a31b48e081a4d350baea",
"sha": "781606388cb46645bb84a31b48e081a4d350baea",
"created": "0001-01-01T00:00:00Z"
},
{
"url": "https://code.forgejo.org/api/v1/repos/forgejo/runner/git/commits/4f4ec159f0256b1d393cca5fae6732754a0a181b",
"sha": "4f4ec159f0256b1d393cca5fae6732754a0a181b",
"created": "0001-01-01T00:00:00Z"
}
] Looks like the better option, at he expense of an additional request. But... since it will git clone an entire repository shortly after wards it seems futile to save this. Or am I being careless? |
Here is a draft using the API endpoints to determine if the commit is a merge or not. It feels right this time. |
585d522
to
b2554a6
Compare
It was semi-manually tested at https://code.forgejo.org/earl-warren/racepr with something like git fetch origin ; git reset --hard origin/main ; branch=b$(date +%s) ; date > adsf ; git add adsf ; git commit -m 'update one' ; sleep 1 ; date > adsf ; git add adsf ; git commit -m 'update two' ; git push origin HEAD:$branch ; pr=$(forgejo-curl.sh api_json --data '{"title":"t1","head":"'$branch'","base":"main"}' https://code.forgejo.org/api/v1/repos/earl-warren/racepr/pulls | jq -r .number) && forgejo-curl.sh api_json --data '{"Do": "merge"}' https://code.forgejo.org/api/v1/repos/earl-warren/racepr/pulls/$pr/merge and git fetch origin ; git reset --hard origin/main ; branch=b$(date +%s) ; date > adsf ; git add adsf ; git commit -m 'update one' ; sleep 1 ; date > adsf ; git add adsf ; git commit -m 'update two' ; git push origin HEAD:$branch ; pr=$(forgejo-curl.sh api_json --data '{"title":"t1","head":"'$branch'","base":"main"}' https://code.forgejo.org/api/v1/repos/earl-warren/racepr/pulls | jq -r .number) && forgejo-curl.sh api_json --data '{"Do": "squash"}' https://code.forgejo.org/api/v1/repos/earl-warren/racepr/pulls/$pr/merge and the workflow on:
pull_request_target:
types:
- closed
- labeled
jobs:
backporting:
runs-on: docker
container:
image: 'docker.io/node:20-bookworm'
steps:
- uses: https://github.com/earl-warren/git-backporting@b2554a678d5ea2814f0df3abad2ac4fcdee2d81f
with:
target-branch: other
cherry-pick-options: -x
git-client: codeberg
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }} that does not mean it is the right way to do it but it is not complete nonsense either 😄 |
Hey @earl-warren , that is a great investigation and I was not aware of that way to determine whether a commit is a merge-commit or not, thus it looks a valid option to evaluate.
No that's not a problem at all, I mean we don't have tight time restrictions here.
That's already a good early check, I will try to get some time today to review this approach as well! |
I'll complete this PR today and include GitLab as well. This is going to be good. |
Hi @earl-warren, I had chance to take a look at this PR (at least from the generic workflow point of view) and I think it could work. I did not try yet but based on the changes you did I think the idea could work as long as this https://github.com/kiegroup/git-backporting/pull/118/files#diff-6e3804f9a1581e5155295a17bbbc71343fa375a15bf5383dd4c4049a44be09cdR54-R60 is enough/true. There a couple of enhancement that could be done, e.g., now we could populate the |
I'll work on this PR today. Side note: this commit is in production at https://codeberg.org/forgejo/forgejo/pulls a behaves as it should. |
That's great!!! |
7510e7d
to
d74b7e3
Compare
I think this is a sane implementation. I thought it would be possible to just remove the no-squash option and rely on auto-detection for all cases. But there is one case that would create a non-backward compatible behavior (cherry-picking the merge commit). I also tried to change the no-squash option to have three state (undefined, true, false) instead of two. Adding another option is not elegant but it is easier to understand and makes for a clear implementation. The GitLab support is made easy by the fact that the merge request has information regarding the status of the merge. The PR is ready for review but I will leave it as a WIP: because it still lacks coverage for the logic. It would be great if you could review it before I polish it, in case there are changes needed that would require modifying the tests. I really enjoy working on this action with you. |
Thanks a lot @earl-warren ❤️
That's really good to hear 😄
Yeah I agree with you, I think I can find some time today to review this - it should not take much time as we were already on the same page.
+100, I am really glad there are people like you who are very proactive on contributing back, great example of community! Moreover I hope that this action will really save some of your day2day work time 🤞 |
It is already busy at work saving valuable time every day. ✨ |
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.
Ok so if I correctly understood the logic, that can be summarized as follow (correct me if I am wrong):
noSquash | autoNoSquash | SQUASH | Behavior |
---|---|---|---|
false | false | true | Try to cherry-pick single commit, merge_commit_sha |
true | false | false | Try to cherry-pick all commits in the original pull request |
false | true | undefined | * |
true | true | undefined | * |
- When
autoNoSquash
is undefined/false the behavior is the one already existing. - Whereas when the
autoNoSquash
is set to true (*) the value ofnoSquash
is ignored and the value ofsquash
is auto computed by the new logic https://github.com/kiegroup/git-backporting/pull/118/files#diff-6e3804f9a1581e5155295a17bbbc71343fa375a15bf5383dd4c4049a44be09cdR48-R66
Am I right?
If I am right I think the overall implementation looks really great! I am trying to see if we can simplify the logic but nothing came to my mind, so I think we can proceed with this approach 🚀
I left a couple of comments.
PS: worth to add some table like this in the doc to help users understand how to configure the tool to enable a specific behavior and to highlight the default.
Yes.
If it was not for the case where you want to cherry-pick a merge commit, I think both no-squash and auto-no-squash could be removed. And the default behavior would be to cherry-pick a single commit when there is a squash or all commits if not. If that behavior is really desirable, there could be a cherry-pick-merge-commit option. But removing no-squash and adding cherry-pick-merge-commit or something would be a breaking change and you probably do not want that.
👍 |
A table was added in the README |
@lampajr does this look like a good enough test to complete this PR? The logic is simple right now. But it is pivotal to how GitLab/Forgejo/GitHub decide to squash or not and it feels right to keep it DRY, just in case it becomes more complex in the future and really requires good unit testing. |
Manual tests. auto-no-squash: true - uses: https://github.com/earl-warren/git-backporting@21d3fe29b9cb1b1c1a0ab0625dcb1b13f407eddc
with:
target-branch-pattern: "^backport/(?<target>(o.*))$"
cherry-pick-options: -x
git-client: codeberg
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }}
auto-no-squash: true merged commithttps://code.forgejo.org/earl-warren/racepr/actions/runs/26#jobstep-1-4
squashed commithttps://code.forgejo.org/earl-warren/racepr/actions/runs/27#jobstep-1-4
auto-no-squash: unset & no-squash: unset - uses: https://github.com/earl-warren/git-backporting@21d3fe29b9cb1b1c1a0ab0625dcb1b13f407eddc
with:
target-branch-pattern: "^backport/(?<target>(o.*))$"
cherry-pick-options: -x
git-client: codeberg
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }} merge commithttps://code.forgejo.org/earl-warren/racepr/actions/runs/28#jobstep-1-10
squash commithttps://code.forgejo.org/earl-warren/racepr/actions/runs/29#jobstep-1-10
auto-no-squash: unset & no-squash: true - uses: https://github.com/earl-warren/git-backporting@21d3fe29b9cb1b1c1a0ab0625dcb1b13f407eddc
with:
target-branch-pattern: "^backport/(?<target>(o.*))$"
cherry-pick-options: -x
git-client: codeberg
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }}
no-squash: true https://code.forgejo.org/earl-warren/racepr/actions/runs/30#jobstep-1-8
|
bcefd52
to
44184ee
Compare
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.
Hi @earl-warren I think this is awesome!!!!
@lampajr does this look like a good enough test to complete this PR?
yeah they are, absolutely! I think the most important part was to guarantee the previous behavior is still woring without changes then we can always add more tests in the future if needed.
Furthermore it looks like you already did a lot of manual tests which are really great 🚀
I left just a couple of minor comments, they are not blockers so up to you. I'll wait your confirmation before merging this but FMPOV it is great!
The auto-no-squash option is added to: * backport all the commits when the pull/merge request has been merged * backport the squashed commit otherwise It is equivalent to dynamically adjust the value of the no-squash option, depending on the context. The no-squash option is kept for backward compatibility for a single use case: backporting the merged commit instead of backporting the commits of the pull/merge request request. Detecting if a pull/merge request was squashed or not depends on the underlying forge: * Forgejo / GitHub: use the API to count the number of parents * GitLab: if the squash_commit_sha is set, the merge request was squashed If the pull/merge request is open, always backport all the commits it contains. Fixes: kiegroup#113 Co-authored-by: Andrea Lamparelli <[email protected]>
Changes applied & README updated as suggested. |
Merged, thanks a lot for your contribution again @earl-warren ❤️ |
The auto-no-squash option is added to:
It is equivalent to dynamically adjust the value of the no-squash
option, depending on the context.
The no-squash option is kept for backward compatibility for a single
use case: backporting the merged commit instead of backporting the
commits of the pull/merge request request.
Detecting if a pull/merge request was squashed or not depends on the
underlying forge:
squashed
If the pull/merge request is open, always backport all the commits it
contains.
Fixes: #113