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

refactor: Replace synchronous proxy with standard proxy #79

Merged
merged 1 commit into from
Jul 22, 2023

Conversation

rahulsom
Copy link

@rahulsom rahulsom commented Jul 4, 2023

The code in makeStaplerProxy2 used prototype.js to create a synchronous version of the standard proxy that comes with Jenkins Core.

This code switches back to the standard proxy.
That requires making the code execute in the correct order when there were dependencies. That is achieved by using async/await in the .es6 code and transpiling it down to use Promises so HtmlUnit tests continue to work.

Refs: JENKINS-71365

Testing done

The existing tests pass. The UI Acceptance test was relying on an unexpected side-effect of synchronous network calls.
To account for the network calls becoming asynchronous, the tests now wait for the condition to be successful instead of a straight assert.

Submitter checklist

@rahulsom rahulsom marked this pull request as draft July 4, 2023 20:02
@rahulsom rahulsom force-pushed the remove-prototype-dependency branch 16 times, most recently from f55a202 to 738a194 Compare July 5, 2023 19:54
@rahulsom rahulsom marked this pull request as ready for review July 5, 2023 20:02
Copy link
Member

@basil basil left a comment

Choose a reason for hiding this comment

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

Very nice! Highly appreciate this contribution.

The test fails on 2.413 when run with mvn clean verify -Dtest=org.biouno.unochoice.UiAcceptanceTest -Djenkins.version=2.413. The same test passes on 2.413 on the main branch. Console logs:

UnoChoice.js:1 Values returned from server: undefined
build:1 Uncaught (in promise) SyntaxError: "undefined" is not valid JSON
    at JSON.parse (<anonymous>)
    at UnoChoice.js:1:8886
    at bind.js:56:33

@rahulsom
Copy link
Author

rahulsom commented Jul 6, 2023

image

It looks like we don't receive a responseText anymore. We receive a responseJSON from the stapler proxy.
I can check which we have and either parse or use the parsed object. Does that seem reasonable?

@basil
Copy link
Member

basil commented Jul 6, 2023

If the server is returning JSON (which was the original use case supported by Stapler), then the client is expected to call r.responseObject() to get back a JSON object. The r.responseJSON field is only provided for backward compatibility for consumers that were incorrectly assuming the Prototype implementation. Similarly, the r.responseText field is only provided when non-JSON is being returned for backward compatibility for consumers that were incorrectly abusing the Prototype implementation to work with non-JSON values (not originally intended to be supported by Stapler, but supported in practice by the Prototype implementation). So I would recommend calling r.responseObject() and not attempting to parse the JSON.

@rahulsom rahulsom force-pushed the remove-prototype-dependency branch from 738a194 to 456a844 Compare July 6, 2023 23:38
@rahulsom
Copy link
Author

rahulsom commented Jul 6, 2023

Thanks! That is cleaner.

Copy link
Member

@basil basil left a comment

Choose a reason for hiding this comment

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

Looks good! I tested the result both with and without Prototype and it seems to be working without Prototype. Just two minor comments before approving this.

pom.xml Outdated Show resolved Hide resolved
@rahulsom rahulsom force-pushed the remove-prototype-dependency branch from 604ebc4 to 1e234e0 Compare July 7, 2023 01:28
Copy link
Member

@basil basil left a comment

Choose a reason for hiding this comment

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

Very nice!

pom.xml Outdated Show resolved Hide resolved
Copy link

@mawinter69 mawinter69 left a comment

Choose a reason for hiding this comment

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

The plugin is still using inline javascript. That should loading be changed to conform to CSP.
But this is probably something for a separate PR.

@rahulsom rahulsom force-pushed the remove-prototype-dependency branch from 1e234e0 to ed3398b Compare July 7, 2023 17:39
Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

Didn't have time to check out the code and play with it tonight, but it's looking good! Left a few questions, mostly me learning what's new in Jenkins API & dev :) Thanks!

}
function decrementLoadingCounter() {
loadingCounter--;
}
Copy link
Member

Choose a reason for hiding this comment

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

I thought it was going to be used to check for consistency, or maybe for the tests, but I couldn't locate where the loadingCounter value is being read. Is that somewhere in this file? Maybe GitHub UI is not showing it in the diff (didn't have time to check it out tonight, sorry).

Copy link
Author

Choose a reason for hiding this comment

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

I did try it. I got rid of it. I'll remove this code. Thanks for the extra pair of eyes on this.

@@ -2,6 +2,7 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
${it.parameters.clear()}
<st:include page="/org/biouno/unochoice/common/choiceParameterCommon.jelly"/>
<st:bind value="${it}" var="cascadeChoiceParameter"/>
Copy link
Member

Choose a reason for hiding this comment

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

👍 I think I used the other ugly syntax to fix warnings on my IDE (Eclipse + WebDev at that time, I think?). Do VSCode/WebStorm understand this? Maybe there's a stapler plug-in that I can install?

Copy link
Author

Choose a reason for hiding this comment

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

I'm on IntelliJ and it seems to understand it.
Also, now most of the JS is out of this file, so there isn't much context left.
I do have this plugin - https://github.com/jenkinsci/idea-stapler-plugin

Copy link
Author

Choose a reason for hiding this comment

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

#79 (comment)

That's the reason I changed this.

Copy link
Member

Choose a reason for hiding this comment

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

Right, inline syntax is not going to work with Content-Security-Policy prohibiting inline scripts. See JENKINS-60865 for context.

@rahulsom rahulsom force-pushed the remove-prototype-dependency branch 2 times, most recently from 964274e to 44d8b2e Compare July 8, 2023 01:42
Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

These changes look all good to me, @rahulsom !

I don't have an installation with jobs to test it, but I know @imoutsatsos maintains probably the largest and most complex series of jobs with active choices parameters 🙂

@imoutsatsos would you be able to test this change? If everything works for you we can merge it. No need to look at the code, just try the existing jobs you have, checking if you get any JavaScript errors, or parameters that were supposed to be rendered correctly not being displayed, displaying wrong values, etc.

Thanks!

@imoutsatsos
Copy link
Member

imoutsatsos commented Jul 10, 2023 via email

@rahulsom
Copy link
Author

For this version of the plugin to run, you need 2.375.3 or newer.

There isn't an LTS with the Prototype removal changes yet. You can use 2.413 to verify the change with prototype turned off (a user flag under the /user/{USERNAME}/configure URI).

@imoutsatsos
Copy link
Member

imoutsatsos commented Jul 17, 2023

CONFIRMED: Tests done with AC PR #80. I have completed some functional testing (using 6 different jobs that use Active Choice parameters in different ways) of the 2.6.6 SNAPSHOT with Jenkins 2.375.3 and Windows 2016 Server. Testing results look good. No issues @rahulsom and @kinow . Thank you!

@kinow
Copy link
Member

kinow commented Jul 17, 2023

Thank you @imoutsatsos ! Just to confirm, the snapshot version you mentioned was built from this branch/pull request? If so we might be ready for a release! Thanks!

@kinow
Copy link
Member

kinow commented Jul 17, 2023

@rahulsom could you base, please? Thanks 🙇

@rahulsom rahulsom force-pushed the remove-prototype-dependency branch from 44d8b2e to 5815d29 Compare July 18, 2023 02:16
@rahulsom
Copy link
Author

@kinow Rebased. We're ready for merging. Thanks!

@kinow
Copy link
Member

kinow commented Jul 18, 2023

Thanks @rahulsom . Just waiting for Ioannis confirmation that the tests used this branch and then we are ready to merge.

@imoutsatsos
Copy link
Member

Hi @kinow . Confirming that successful functional test of AC in various jobs were successfully performed with the PR #80 version

The code in `makeStaplerProxy2` used `prototype.js` to create a synchronous version of the standard proxy that comes with Jenkins Core.

This code switches back to the standard proxy.
That requires making the code execute in the correct order when there were dependencies.
That is achieved by using `async`/`await` in the `.es6` code and transpiling it down to use Promises so HtmlUnit tests continue to work.

Refs: JENKINS-71365
Co-authored-by: Basil Crow <[email protected]>
@rahulsom rahulsom force-pushed the remove-prototype-dependency branch from 5815d29 to 8fc61b5 Compare July 22, 2023 19:14
Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

Thank you for testing it, @imoutsatsos ! And thanks for the great work (again!) @rahulsom ! Merging.

@kinow kinow merged commit fdea6b4 into jenkinsci:master Jul 22, 2023
13 checks passed
@kinow
Copy link
Member

kinow commented Jul 22, 2023

@rahulsom , I think now we have everything merged, so I am planning to cut a release tomorrow with everything on master. I'll bump to 2.7 instead of 2.6.6 due to some bigger changes in the code (even though they should be internal and transparent to users). You should be able to try that version By Sun avro or Monday morning 👋 Thanks!

@kinow
Copy link
Member

kinow commented Jul 6, 2024

This is being reverted due to issues caused when parameters are handled out of order.

The user scripts may use document.getElementById, for instance, to access the elements of other parameters, which fails with this change as parameters may be rendered in any order with a proxy.

In order for this to work, there would have to be a JS layer option for users to attach their callbacks/code executed once all parameters have been loaded, or after a certain parameter has been loaded (which is possible in Vue, React, Svelte, etc., but not in pure Jenkins UI + JS).

kinow added a commit that referenced this pull request Jul 6, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Jul 27, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Aug 18, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Aug 30, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Sep 28, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Oct 6, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Oct 6, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Oct 6, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
kinow added a commit that referenced this pull request Oct 6, 2024
The merge request mentions JENKINS-71365 (prototype.JS is removed from Jenkins core)
but reverting this should not impact that.

What we are doing is removing the async calls and promises, and instead using the
synchronous code again. This is so that Active Choices parameters are rendering in
order as they were before.

Whilst rendering them asynchronously seemed like a good idea to provide a more
responsive UI, in reality we oversaw an important aspect: users write their scripts
relying on the order parameters are loaded.

Users wrote their code using document.getElementId, for instance, which worked previously
as users would put the parameter doing that after the parameter from which the ID was
being used.

There were several issues rendered, so this is not likely to be added back again
any time soon. In order to have a more smart reactivity, we would need places to hook
user callback code (like Vue or React do), but provided by Jenkins UI, or in a way
that could take some time to create in the plug-in without breaking things, and that
works well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants