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

Update PR title and body when relaunching a campaign #711

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

Conversation

biru-codeastromer
Copy link

@biru-codeastromer biru-codeastromer commented Jan 25, 2025

Fix #646

Description

-This pull request updates the functionality to ensure that the title and body of a pull request are updated when relaunching a campaign. This enhancement ensures that the pull request reflects the latest changes and feedback

Testing done

-Unit Tests done
-Will be adding the final test after original test issues get resolved

Summary of Changes

  • GHService.java
    • Added updatePullRequestTitleAndBody method to update the title and body of an existing pull request.
    • Updated openPullRequest method to check for existing pull requests and update their title and body if necessary.

Impact on Existing Functionality

  • No impact on existing functionality; the changes are additive and enhance the current implementation.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

Additional Notes

  • Ensure to review the changes and provide feedback if any adjustments are needed.

@biru-codeastromer
Copy link
Author

Hi @jonesbusy Sir,

I hope this message finds you well.

I’ve successfully raised the PR, and all CI checks have passed. However, I haven’t added unit tests for the new changes yet in the PR.

Should I proceed with adding the unit tests now?
Or would you prefer to review the changes first, and I can incorporate the tests based on your feedback?
Looking forward to your guidance.

Thank you!

@jonesbusy
Copy link
Collaborator

Yes tests ensure that it work as expected. Thanks

Copy link
Collaborator

@jonesbusy jonesbusy left a comment

Choose a reason for hiding this comment

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

Minor changes and tests missing

@@ -106,6 +106,19 @@ public void validate() {
}
}

public void updatePullRequestTitleAndBody(GHPullRequest pr, String newTitle, String newBody) throws IOException {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't it be private?

Copy link
Author

Choose a reason for hiding this comment

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

Surely Sir , I will updating it to private

LOG.info("Pull request already exists: {}", pr.getHtmlUrl());
updatePullRequestTitleAndBody(pr, prTitle, prBody);
} else {
LOG.warn("Existing pull request is null. Skipping update.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why a warning? Is just a normal behavior of no PR exist for a given recipe

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for the feedback. I used warn because I initially thought that having no existing pull request might be an unusual situation. However, I understand your point that it is a normal behavior when no PR exists for a given recipe.

I will update the code to use info instead of warn for this log message.

Optional<GHPullRequest> existingPR = checkIfPullRequestExists(plugin);
if (existingPR.isPresent()) {
GHPullRequest pr = existingPR.get();
if (pr != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why? It's an optional and we check it exists just before

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for pointing that out Sir. You're right, the null check is redundant since we are already checking if the Optional is present. I will remove the unnecessary null check and update the code accordingly.

I appreciate your feedback!

@biru-codeastromer
Copy link
Author

Yes tests ensure that it work as expected. Thanks

Okay Sir I will add and test it now !

@biru-codeastromer
Copy link
Author

Hi Sir ,

Thank you for the feedback. I have made the following changes as per your suggestions:

  1. Made the updatePullRequestTitleAndBody method private.
  2. Changed the warning log to an info log for the case when no existing pull request is found.
  3. Improved the use of Optional by removing the redundant null check.

I will now proceed to add the unit tests for the new changes and update you here.

Thank you for your guidance!

@biru-codeastromer
Copy link
Author

Thanks Sir for the feedbacks I am applying your suggestion and also will update the branch.
Please let me know if further enhancment needed in the main file before I can finally prepare the unit tests again .
Thanks !

@jonesbusy
Copy link
Collaborator

Yes but unit test must be implemented along of the changes. It's also a way to show that the feature is working.

By reading the code it looks ok. But without tests or evidence (for example a screenshot of and end to end test) I don't know if it works as expected.

So please implemented tests

@biru-codeastromer
Copy link
Author

Yes but unit test must be implemented along of the changes. It's also a way to show that the feature is working.

By reading the code it looks ok. But without tests or evidence (for example a screenshot of and end to end test) I don't know if it works as expected.

So please implemented tests

Thanks Sir for your help , I will now build the test and see if the changes works and also provide screenshots before finally updating you here .
Thanks for your guidance again!

@jonesbusy
Copy link
Collaborator

Open question. What happen if the result of a recipe change

For example I expect jenkinsci/date-parameter-plugin#21 to be updated with 2.463.3 (not only the PR title or body if not this will not match the diff of the PR)

@gounthar Did you saw a similar use case before?

I'm wonder if we need to "force" push the branch in order to update the changes

This definitely need to be tested before naïvely update the PR title and body but not update the PR content

@biru-codeastromer
Copy link
Author

biru-codeastromer commented Jan 26, 2025

Hi Sir,

Thank you for pointing this out. I understand the concern about ensuring the PR title, description, and content (code changes) remain consistent.

I will test thoroughly to verify that the title and body updates match the actual PR content and no discrepancies occur;
Check if a "force push" is needed to ensure the changes are properly updated;
Once I’ve implemented and verified everything, I’ll update you with the results. Please let me know if there’s anything else I should consider while testing.

Thank you for your guidance!

@biru-codeastromer
Copy link
Author

I have tested already but ran through some errors which I am trying to fix at the moment.

@jonesbusy
Copy link
Collaborator

Looking at

git.reset().setMode(ResetCommand.ResetType.HARD).setRef(defaultBranch).call();

and

List<PushResult> results = StreamSupport.stream(git.push().setForce(true)

It looks is already covered

@biru-codeastromer
Copy link
Author

Okay Sir.

@jonesbusy
Copy link
Collaborator

Improved one integration test to perform a second execution: #721

This should ensure that the new content is pushed

@biru-codeastromer
Copy link
Author

Improved one integration test to perform a second execution: #721

This should ensure that the new content is pushed

Thanks Sir , much appreciated!

@biru-codeastromer
Copy link
Author

Hello Sir , Sir I am repeatedly getting errors in my unit tests .

@biru-codeastromer
Copy link
Author

[ERROR] Tests run: 23, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.733 s <<< FAILURE! -- in io.jenkins.tools.pluginmodernizer.core.recipes.IsUsingArchetypeCommonFileTest
[ERROR] io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_NoChangesPushed -- Time elapsed: 0.094 s <<< ERROR!
io.jenkins.tools.pluginmodernizer.core.model.ModernizerException: Error reading PEM file
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:41)
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.getJWT(JWTUtils.java:55)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.refreshToken(GHService.java:216)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.openPullRequest(GHService.java:949)
        at io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_NoChangesPushed(GHServiceTest.java:938)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1499)
        at java.base/java.util.concurrent.ForkJoinPool.helpJoin(ForkJoinPool.java:2272)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:495)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:662)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1458)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2034)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)
Caused by: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toFile()" because "pemFile" is null
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:32)
        ... 14 more

[INFO] Running io.jenkins.tools.pluginmodernizer.core.recipes.UpgradeJenkinsVersionTest
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.044 s -- in io.jenkins.tools.pluginmodernizer.core.utils.PluginServiceTest
[INFO] Running io.jenkins.tools.pluginmodernizer.core.recipes.DeclarativeRecipesTest
[ERROR] Tests run: 5, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.601 s <<< FAILURE! -- in io.jenkins.tools.pluginmodernizer.core.visitors.UpdateJenkinsFileVisitorTest
[ERROR] io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_PluginArchived -- Time elapsed: 0.004 s <<< ERROR!
io.jenkins.tools.pluginmodernizer.core.model.ModernizerException: Error reading PEM file
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:41)
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.getJWT(JWTUtils.java:55)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.refreshToken(GHService.java:216)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.openPullRequest(GHService.java:949)
        at io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_PluginArchived(GHServiceTest.java:950)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1499)
        at java.base/java.util.concurrent.ForkJoinPool.helpJoin(ForkJoinPool.java:2272)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:495)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:662)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1458)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2034)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)
Caused by: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toFile()" because "pemFile" is null
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:32)
        ... 14 more

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.250 s -- in io.jenkins.tools.pluginmodernizer.core.recipes.code.ReplaceRemovedSSHLauncherConstructorTest
[INFO] Running io.jenkins.tools.pluginmodernizer.core.recipes.IsUsingBomTest
[ERROR] Tests run: 30, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 12.49 s <<< FAILURE! -- in io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest
[ERROR] io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_DryRunMode -- Time elapsed: 0.002 s <<< ERROR!
io.jenkins.tools.pluginmodernizer.core.model.ModernizerException: Error reading PEM file
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:41)
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.getJWT(JWTUtils.java:55)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.refreshToken(GHService.java:216)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.openPullRequest(GHService.java:949)
        at io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_DryRunMode(GHServiceTest.java:914)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1499)
        at java.base/java.util.concurrent.ForkJoinPool.helpJoin(ForkJoinPool.java:2272)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:495)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:662)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1458)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2034)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)
Caused by: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toFile()" because "pemFile" is null
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:32)
        ... 14 more

[ERROR] io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_FetchMetadataOnlyMode -- Time elapsed: 0.003 s <<< ERROR!
io.jenkins.tools.pluginmodernizer.core.model.ModernizerException: Error reading PEM file
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:41)
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.getJWT(JWTUtils.java:55)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.refreshToken(GHService.java:216)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.openPullRequest(GHService.java:949)
        at io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_FetchMetadataOnlyMode(GHServiceTest.java:926)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1499)
        at java.base/java.util.concurrent.ForkJoinPool.helpJoin(ForkJoinPool.java:2272)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:495)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:662)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1458)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2034)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)
Caused by: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toFile()" because "pemFile" is null
        at io.jenkins.tools.pluginmodernizer.core.utils.JWTUtils.buildPrivateKey(JWTUtils.java:32)
        ... 14 more

[ERROR] io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_ExistingPR -- Time elapsed: 0.004 s <<< ERROR!
java.lang.NullPointerException: Cannot invoke "org.kohsuke.github.GHCommitPointer.getRef()" because the return value of "org.kohsuke.github.GHPullRequest.getHead()" is null
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.lambda$checkIfPullRequestExists$4(GHService.java:1084)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:196)
        at java.base/java.util.AbstractList$RandomAccessSpliterator.tryAdvance(AbstractList.java:708)
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:147)
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:588)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:574)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
        at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
        at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:687)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.checkIfPullRequestExists(GHService.java:1085)
        at io.jenkins.tools.pluginmodernizer.core.github.GHService.openPullRequest(GHService.java:979)
        at io.jenkins.tools.pluginmodernizer.core.github.GHServiceTest.testOpenPullRequest_ExistingPR(GHServiceTest.java:902)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1499)
        at java.base/java.util.concurrent.ForkJoinPool.helpJoin(ForkJoinPool.java:2272)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:495)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:662)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1458)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2034)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)

@biru-codeastromer
Copy link
Author

I am not getting that these are errors from my end ,or it from original one .

@biru-codeastromer
Copy link
Author

[INFO] Results:
[INFO] 
[ERROR] Errors: 
[ERROR]   GHServiceTest.testOpenPullRequest_DryRunMode:914 » Modernizer Error reading PEM file
[ERROR]   GHServiceTest.testOpenPullRequest_ExistingPR:902 » NullPointer Cannot invoke "org.kohsuke.github.GHCommitPointer.getRef()" because the return value of "org.kohsuke.github.GHPullRequest.getHead()" is null
[ERROR]   GHServiceTest.testOpenPullRequest_FetchMetadataOnlyMode:926 » Modernizer Error reading PEM file
[ERROR]   GHServiceTest.testOpenPullRequest_NoChangesPushed:938 » Modernizer Error reading PEM file
[ERROR]   GHServiceTest.testOpenPullRequest_PluginArchived:950 » Modernizer Error reading PEM file
[INFO] 
[ERROR] Tests run: 269, Failures: 0, Errors: 5, Skipped: 3
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Plugin Modernizer Parent 999999-SNAPSHOT:
[INFO] 
[INFO] Plugin Modernizer Parent ........................... SUCCESS [  0.374 s]
[INFO] Plugin Modernizer Core ............................. FAILURE [03:39 min]
[INFO] Plugin Modernizer CLI Interface .................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:40 min
[INFO] Finished at: 2025-01-26T18:29:38+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.2:test (default-test) on project plugin-modernizer-core: 
[ERROR] 
[ERROR] See /Users/birajitsaikia/Documents/pr-issueplugin/plugin-modernizer-tool/plugin-modernizer-core/target/surefire-reports for the individual test results.
[ERROR] See dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <args> -rf :plugin-modernizer-core

@gounthar
Copy link
Collaborator

Open question. What happen if the result of a recipe change
For example I expect jenkinsci/date-parameter-plugin#21 to be updated with 2.463.3 (not only the PR title or body if not this will not match the diff of the PR)
As long as we are NOT changing the name of the recipe, the title, body, and content should be changed.

@gounthar Did you saw a similar use case before?
I have seen the very same use case in lots of plugins, but just because we upgraded from 2.252.x to 2.263.x.
That will also happen when we will move from JDK17 to 21, then 25.
If ever a PR stays open long enough for the rules to change, then it does not shock me we're reusing the same PR and modifying just about everything.

I'm wonder if we need to "force" push the branch in order to update the changes
🤔

This definitely need to be tested before naïvely update the PR title and body but not update the PR content
Definitely.
Thanks for this open question, I exposed my thoughts and feelings, but I don't feel like I own the truth. 😊

@jonesbusy
Copy link
Collaborator

I am not getting that these are errors from my end ,or it from original one .

So I must be the way test are implemented? Maybe miss some mocks.

You can check how others are implemented for GHService. I think one test that performed the update is enough.

It's possible that one test for opening PR already exists. Did you base your test on this one?

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.

Force the PR title/body if rerun
3 participants