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

Upgrade to htmlunit 3.x #589

Merged
merged 7 commits into from
Jun 4, 2023
Merged

Upgrade to htmlunit 3.x #589

merged 7 commits into from
Jun 4, 2023

Conversation

timja
Copy link
Member

@timja timja commented May 25, 2023

Part of #568

Testing done

Ran tests in the project

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

pom.xml Outdated
@@ -121,7 +121,7 @@ THE SOFTWARE.
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jenkins-test-harness-htmlunit</artifactId>
<version>141.v740721146265</version>
<version>142.ve874f871a_6e3</version>
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO update to release version

@@ -201,17 +201,6 @@ THE SOFTWARE.
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>embedded-rhino-debugger</artifactId>
Copy link
Member Author

Choose a reason for hiding this comment

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

some abandoned project of kohsuke's which could popup a swing dialog to do something with JavaScript errors I think we can drop this.
https://github.com/jenkinsci/lib-embedded-rhino-debugger/

Otherwise it needs to be refreshed, updated to new APIs and released

@timja timja added developer dependencies Pull requests that update a dependency file labels May 25, 2023
@timja timja changed the title Upgrade to 3.x Upgrade to htmlunit 3.x May 25, 2023
@timja timja force-pushed the 3.x branch 2 times, most recently from 6c184d7 to c943a26 Compare May 25, 2023 14:57
@timja timja added breaking and removed developer labels May 25, 2023
@timja timja marked this pull request as ready for review May 25, 2023 19:25
@timja timja requested review from NotMyFault and basil May 25, 2023 19:25
@timja timja marked this pull request as draft May 25, 2023 19:26
@timja
Copy link
Member Author

timja commented May 25, 2023

(requires jenkinsci/jenkins-test-harness-htmlunit#110 first)

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.

This is an incompatible change that will require at least 125 plugins to be adapted, including about 70 plugins with over 10,000 installations. While it may be fair to place the burden of adapting to a breaking change on plugin maintainers for breaking changes that are smaller in scope, I feel that this is too significant of a breaking change for the burden to be placed on plugin maintainers. By and large, we need to bring plugins along with this breaking change rather than leaving them to deal with the fallout by themselves.

@timja
Copy link
Member Author

timja commented May 25, 2023

Do you have any suggestions? So far I haven’t hit any functional issues it’s just a find and replace that can go in release notes although may complicate bom testing till those are released

@timja
Copy link
Member Author

timja commented May 25, 2023

I can do a bulk migration once it's released it's a very simple find and replace

@basil
Copy link
Member

basil commented May 25, 2023

although may complicate bom testing till those are released

I do not think it would because BOM/PCT does not update the plugin POM/JTH to the latest version but rather uses the plugin's version, and we should have any JTH method signatures in Jenkins core. Might be worth checking with a BOM PR that adds -Djenkins.version=<incremental> to the PCT invocation though.

I can do a bulk migration once it's released it's a very simple find and replace

OK, my goal is simply to ensure that this happens with us (it does not have to be just you!) taking on this burden rather than leaving the burden on plugin maintainers. The gap between the work done in this PR and the work promised above still seems a bit too large for me to feel comfortable approving this. I would like to understand in more detail how we plan to identify affected plugins, how we plan on migrating them (manually? an automated script?), who plans to be involved in the effort (I can help, but cannot take on the whole burden), how we plan to track progress, etc. In other words, seeing a more thorough migration plan (with some examples of it being followed successfully) would go a long way toward convincing me that this migration will be successful once it has begun and it is too late to turn back.

@timja
Copy link
Member Author

timja commented May 25, 2023

just planning on running multi-gitter over the jenkinsci org replacing the imports and methods and bumping the plugin pom to the version with the latest test harness

Shouldn't need any manual work once the script has been written.

@basil
Copy link
Member

basil commented May 25, 2023

OK, that sounds like a promising start. I would like to see the script written and applied to at least one repository successfully to have full confidence in the migration plan.

@timja
Copy link
Member Author

timja commented May 26, 2023

Migration script mostly finished and works on stapler:

#!/usr/bin/env bash

set -e

if [ "$(uname)" == "Darwin" ]; then
    sed=gsed
fi

find . -name 'pom.xml' -type f -exec $sed -i'' -e '
    /<artifactId>jenkins-test-harness-htmlunit<\/artifactId>/{
        N
        /<version>[^<]*<\/version>/{
            s/<version>[^<]*<\/version>/<version>143.v8979204b_fc0c<\/version>/
        }
    }
    /<artifactId>jenkins-test-harness<\/artifactId>/{
        N
        /<version>[^<]*<\/version>/{
            s/<version>[^<]*<\/version>/<version>1995.v96366f69785f<\/version>/
        }
    }
' {} +

# Iterate over all files in the current directory recursively
find . -type f -name '*.java' -exec $sed -i'' -e '
    /net\.sourceforge\.htmlunit/{
        s/net\.sourceforge\.htmlunit/org.htmlunit/g
    }
    /com\.gargoylesoftware\.htmlunit/{
        s/com\.gargoylesoftware\.htmlunit/org.htmlunit/g
    }
    /getValueAttribute/{
        s/getValueAttribute/getValue/g
    }
    /setAttribute("value", /{
        s/setAttribute("value", /setValue(/g
    }
    /setAttribute("value",/{
        s/setAttribute("value",/setValue(/g
    }
    /setValueAttribute/{
        s/setValueAttribute/setValue/g
    }
    /<artifactId>jenkins-test-harness<\/artifactId>.*<version>[^<]*<\/version>/{
        s/<version>[^<]*<\/version>/<version>1995.v96366f69785f<\/version>/
    }
' {} +

if git diff --exit-code > /dev/null
then
    echo "No replacements required"
    exit
fi

if grep -q '<artifactId>plugin</artifactId>' pom.xml
then
    mvn versions:update-parent -DparentVersion=4.64
fi

spotless_disabled=$(mvn help:evaluate -Dexpression=spotless.check.skip -q -DforceStdout)
if ! $spotless_disabled; then
    mvn spotless:apply
fi

git status
echo "Replacement completed."

@StefanSpieker
Copy link

For future migrations it might be nice to take a look at https://docs.openrewrite.org/
I have used this for a spring boot update and was quite impressed, but have not yet written my own recipe.

@timja
Copy link
Member Author

timja commented May 26, 2023

docs.openrewrite.org

Worth a look although chatgpt wrote this for me trivially with only minor changes needed 😄.

@basil
Copy link
Member

basil commented May 26, 2023

I think this script is fairly incomplete. For one thing, it didn't work in text-finder-plugin because it was missing the migration from setValueAttribute to setValue. To update the plugin parent POM you can do mvn versions:update-parent -DparentVersion=<new-version>. The Spotless check could be implemented with something like this:

spotless_disabled=$(mvn help:evaluate -Dexpression=spotless.check.skip -q -DforceStdout)
if ! $spotless_disabled; then
    mvn spotless:apply
fi

The other question I have is, what is going to be done if these bot-filed PRs fail to get a clean build?

pom.xml Outdated Show resolved Hide resolved
@timja timja marked this pull request as ready for review May 29, 2023 14:53
@timja
Copy link
Member Author

timja commented May 29, 2023

Script updated now, should be fairly good now can always re-run it if more is learnt after applying to a bunch of repositories.

The other question I have is, what is going to be done if these bot-filed PRs fail to get a clean build?

I think it would be good to try fix / apply enhance the script for more cases if the plugin is maintained.
If the plugin is not maintained I think we could just leave the pull request there.

I'm planning on running it from a bot account so I don't get notification spam from it.

What do you think about that?

@basil
Copy link
Member

basil commented May 29, 2023

If the plugin is not maintained I think we could just leave the pull request there.

The criteria for maintained/unmaintained are fairly subjective. If a plugin is in the top 250 and not obviously deprecated/useless (e.g., ace-editor) but has no maintainer, it is effectively/implicitly being maintained by a small group of people (including you and me), and I think we owe it to that group of people not to place additional unplanned work in their path. So in some cases I think we should get the build to pass even if there is no active maintainer.

For example, recent changes to the archetype's Jenkinsfile have not propagated to many key plugins, and I recently had to go around fixing them up. I would have much preferred it if those who made the changes to the archetype also updated key plugins to match.

While covering every plugin in the whole ecosystem is surely impractical, covering too few is an all too common scenario in the project and creates problems for other people when incomplete migrations delay unrelated efforts in the future.

Note that in many cases I already have build migration PRs open (e.g. jenkinsci/active-directory-plugin#168) that this migration will need to build on top of.

Why don't we start by identifying the plugins that need to be updated and create a spreadsheet sorted by # of installs to track the migration effort. This sheet is one example. I want to get a clear understanding of what is in scope and what isn't. If we disagree about what should be in scope I am willing to help out to some degree. My goal is not to create obstacles but rather to be part of the solution to ensure the overall health of the plugin ecosystem.

@timja
Copy link
Member Author

timja commented May 30, 2023

This search:
https://github.com/search?q=org%3Ajenkinsci+com.gargoylesoftware.htmlunit++NOT+is%3Aarchived+NOT+repo%3Ajenkinsci%2Fhtmlunit+NOT+repo%3Ajenkinsci%2Fjenkins-test-harness+NOT+repo%3Ajenkinsci%2Fjenkins&type=code&p=1

Identifies 540 results. The UI only shows about 100 though if I click through. It also reports multiple matches per repository.
How would you identify all of them? Clone all plugins?

I would really like to get started on this and clean up low hanging fruit and then look for stragglers.

@basil
Copy link
Member

basil commented May 30, 2023

I have a local clone of the top 250 which I supplement with results from the GitHub UI. By all means, get started, but I want to be clear that looking for stragglers is only one part of this. The other part is bringing those stragglers back into the fold by filing PRs and making sure those PRs build for the majority of the actively used parts of the ecosystem, regardless of whether or not there is somebody currently actively maintaining that plugin. People who adopt a plugin aren't likely to quickly come up to speed on arcane build trivia, so we owe it to them to make the onboarding process as straightforward as possible by providing ready-to-merge PRs.

@lemeurherve
Copy link
Member

lemeurherve commented Jun 1, 2023

This search: github.com/search?q=org%3Ajenkinsci+com.gargoylesoftware.htmlunit++NOT+is%3Aarchived+NOT+repo%3Ajenkinsci%2Fhtmlunit+NOT+repo%3Ajenkinsci%2Fjenkins-test-harness+NOT+repo%3Ajenkinsci%2Fjenkins&type=code&p=1

Identifies 540 results. The UI only shows about 100 though if I click through. It also reports multiple matches per repository. How would you identify all of them? Clone all plugins?

FWIW I ran a similar search on all @jenkinsci repos already cloned locally & up to date, found 310 of them containing com.gargoylesoftware.htmlunit:

List
Hudson-Gerrit-Plugin
active-choices-plugin
active-directory-plugin
additional-metrics-plugin
adobe-cloud-manager-plugin
agent-maintenance-plugin
alauda-devops-sync-plugin
alauda-kubernetes-support-plugin
alauda-pipeline-plugin
alibabacloud-pkg-deployment-plugin
allure-plugin
analysis-model
android-signing-plugin
ant-plugin
appcenter-plugin
archetypes
artifact-manager-s3-plugin
atlassian-bitbucket-server-integration-plugin
audit-log-plugin
audit-trail-plugin
audit2db-plugin
authorize-project-plugin
aws-codecommit-trigger-plugin
aws-codedeploy-plugin
aws-global-configuration-plugin
aws-secrets-manager-credentials-provider-plugin
aws-sqs-trigger-plugin
azure-container-agents-plugin
batch-task-plugin
beaker-builder-plugin
bitbucket-branch-source-plugin
bitbucket-plugin
bitbucket-push-and-pull-request-plugin
block-build-final-project-plugin
blueocean-plugin
boot-clj-plugin
branch-api-plugin
browserstack-integration-plugin
buckminster-plugin
build-environment-plugin
build-failure-analyzer-plugin
build-flow-plugin
build-history-metrics-plugin
build-publisher-plugin
build-timeout-plugin
build-token-root-plugin
build-user-vars-plugin
build-with-parameters-plugin
bulk-builder-plugin
ca-service-virtualization-plugin
calendar-view-plugin
carl-plugin
catlight-plugin
changelog-history-plugin
chaos-monkey-plugin
ci-game-plugin
claim-plugin
clamav-plugin
clang-scanbuild-plugin
cli-commander-plugin
cloud-stats-plugin
cloudbees-folder-plugin
cloudbees-jenkins-advisor-plugin
cloudfoundry-plugin
clover-plugin
cobertura-plugin
code-coverage-api-plugin
codeplex-plugin
collabnet-plugin
command-launcher-plugin
compact-columns-plugin
config-file-provider-plugin
configuration-as-code-plugin
configurationslicing-plugin
copyartifact-plugin
cors-filter-plugin
cpptest-plugin
credentials-binding-plugin
credentials-plugin
cucumber-testresult-plugin
customize-build-now-plugin
dashboard-view-plugin
defensics-plugin
deployer-framework-plugin
diagnostics-plugin
display-url-api-plugin
distinguishable-gray-balls-plugin
docker-commons-plugin
docker-traceability-plugin
docker-workflow-plugin
dockerhub-notification-plugin
doclinks-plugin
drools-plugin
dynamic-search-view-plugin
ec2-fleet-plugin
ec2-plugin
ecutest-plugin
editable-choice-plugin
eiffel-broadcaster-plugin
eks-token-plugin
elasticbox-plugin
email-ext-plugin
emma-plugin
envinject-plugin
exam-plugin
exclusion-plugin
experitest-cloud-plugin
extended-security-settings-plugin
extensible-choice-parameter-plugin
external-monitor-job-plugin
external-resource-dispatcher-plugin
file-leak-detector-plugin
file-parameters-plugin
flexible-publish-plugin
fluentd-plugin
flyway-runner-plugin
folder-auth-plugin
gerrit-trigger-plugin
git-client-plugin
git-plugin
gitflow-plugin
github-branch-source-plugin
github-oauth-plugin
github-plugin
gitlab-auth-plugin
gogs-webhook-plugin
google-cloud-backup-plugin
google-compute-engine-plugin
google-deployment-manager-plugin
googleanalytics-plugin
googlecode-plugin
gradle-plugin
graphql-server-plugin
gravatar-plugin
greenballs-plugin
groovy-label-assignment-plugin
groovy-plugin
hetzner-cloud-plugin
hgca-plugin
hockeyapp-plugin
hpe-application-automation-tools-plugin
html-audio-notifier-plugin
htmlpublisher-plugin
http-request-plugin
icq-notification-plugin
implied-labels-plugin
ironmq-notifier-plugin
jclouds-plugin
jdk-tool-plugin
jenkinslint-plugin
jira-plugin
jira-trigger-plugin
job-config-history-plugin
job-direct-mail-plugin
job-import-plugin
job-node-stalker-plugin
job-strongauth-simple-plugin
jobcopy-builder-plugin
jobtemplates-plugin
join-plugin
jslint-jenkins-plugin
jswidgets-plugin
junit-attachments-plugin
junit-plugin
jwt-support-plugin
karotz-plugin
kerberos-sso-plugin
kryptowire-plugin
kubernetes-plugin
labeled-test-groups-publisher-plugin
ldap-plugin
lenient-shutdown-plugin
lib-multiline-secrets-ui
liquibase-runner-plugin
loadrunner-cloud-plugin
localization-tr-plugin
localization-zh-cn-plugin
lockable-resources-plugin
logstash-plugin
machine-learning-plugin
mailer-plugin
mailmap-resolver-plugin
mantis-plugin
matlab-plugin
matrix-auth-plugin
matrix-combinations-plugin
matrix-project-plugin
maven-plugin
meliora-testlab-plugin
mentor-questa-vrm-plugin
mercurial-plugin
metadata-plugin
metrics-aggregation-plugin
minio-plugin
mock-slave-plugin
monitoring-plugin
multi-slave-config-plugin
multibranch-job-tear-down-plugin
naginator-plugin
negotiatesso-plugin
nested-view-plugin
next-build-number-plugin
nexus-platform-plugin
node-sharing-plugin
nodejs-plugin
nodelabelparameter-plugin
nodepool-agents-plugin
octoperf-plugin
oidc-provider-plugin
openid-plugin
openshift-login-plugin
openstack-cloud-plugin
openstack-heat-plugin
openstack-plugin
opentelemetry-plugin
ownership-plugin
p4-plugin
page-note-plugin
paginated-builds-plugin
people-redirector-plugin
perfecto-plugin
performance-signature-dynatrace-plugin
phing-plugin
pipeline-build-step-plugin
pipeline-config-history-plugin
pipeline-groovy-lib-plugin
pipeline-input-step-plugin
pipeline-model-definition-plugin
pipeline-snippetizer-plugin
pipeline-stage-view-plugin
plugin-usage-plugin
pom2config-plugin
powershell-plugin
proc-cleaner-plugin
promoted-builds-plugin
promoted-builds-simple-plugin
provar-automation-plugin
puppet-enterprise-pipeline-plugin
puppet-plugin
purge-job-history-plugin
radargun-plugin
rebuild-plugin
redis-fingerprint-storage-plugin
regression-report-plugin
release-plugin
remoting-kafka-plugin
resource-disposer-plugin
robot-plugin
rocketchatnotifier-plugin
role-strategy-plugin
rqm-plugin
run-selector-plugin
s3-plugin
saml-plugin
sauce-ondemand-plugin
scm2job-plugin
scoring-load-balancer-plugin
script-security-plugin
scriptler-plugin
sectioned-view-plugin
secure-requester-whitelist-plugin
seed-plugin
sidebar-link-plugin
simple-queue-plugin
simple-theme-plugin
sounds-plugin
spring-config-plugin
ssh-slaves-plugin
sshd-plugin
statuspage-gating-plugin
strict-crumb-issuer-plugin
subversion-plugin
sumologic-publisher-plugin
support-core-plugin
svnmerge-plugin
systemloadaverage-monitor-plugin
tap-plugin
teamconcert-plugin
terraform-plugin
test-results-analyzer-plugin
testcafe-plugin
testng-plugin-plugin
text-finder-plugin
tfs-plugin
throttle-concurrent-builds-plugin
timestamper-plugin
translation-plugin
uithemes-plugin
update-sites-manager-plugin
url-filter-plugin
usemango-runner-plugin
uuid-parameter-plugin
versioncolumn-plugin
view-job-filters-plugin
violations-plugin
vrealize-automation-8-plugin
warnings-ng-plugin
wavefront-plugin
webhook-step-plugin
workflow-basic-steps-plugin
workflow-cps-plugin
workflow-durable-task-step-plugin
workflow-job-plugin
workflow-support-plugin
x-developer-client-plugin
xframe-filter-plugin
xlrelease-plugin
youtrack-plugin
zanata-plugin
zulip-plugin

FTR, 5 archived repositories also match the search:

htmlunit
jenkins.rb
pipeline-leo-deploy-step-plugin
ruby-runtime-plugin
ssh-cli-auth-module

@basil
Copy link
Member

basil commented Jun 1, 2023

Thanks @lemeurherve! I started a spreadsheet for this migration here: https://docs.google.com/spreadsheets/d/1ih_gVd9uhxLw4BZ6IeJGrYsvu-DvIF0xovu4wZbaXy8/edit

As you can see, there is a huge amount of scope to this migration. Limiting the scope to the top 100, there are about 40 plugins that need migration. Limiting the scope to the top 250, there are about 80 plugins that need migration. Limiting the scope to anything > 10,000 installs there are about 90 plugins that need migration. Limiting the scope to anything > 1,000 installs there are about 150 plugins that need migration.

From my perspective filing PRs against the top 250 and making sure they have a clean build is critical, regardless of whether or not there is an active maintainer. Beyond that, I think it is important to file PRs for anything with > 10,000 installations (and desirable even for anything with > 1,000 installations), although I could be OK if the plugin is not maintained and therefore the PRs don't have a clean build. If something has less than 1,000 installations I don't think it is worth our time to focus on it.

This isn't a request for one person to do all of this work singlehandedly. We can surely discuss ways of sharing this burden. But I think it is important that we do take this burden on, as a group, rather than simply starting a migration and never finishing it.

@timja
Copy link
Member Author

timja commented Jun 2, 2023

Script created here: https://github.com/timja/htmlunit-2.x-to-3.x

Tested here: jenkinsci/junit-plugin#535

Out of time now so won't release and run.

pom.xml Outdated Show resolved Hide resolved
@timja timja enabled auto-merge (squash) June 4, 2023 20:14
@timja timja merged commit 1888f1a into jenkinsci:master Jun 4, 2023
13 checks passed
@timja timja deleted the 3.x branch June 4, 2023 20:38
@basil
Copy link
Member

basil commented Jun 5, 2023

The merge of this PR forestalled my intention to have the migration work completed before this PR was merged and released.

@sghill
Copy link

sghill commented Jun 11, 2023

+1 to @StefanSpieker's suggestion of using OpenRewrite. Here's what a recipe to change package names looks like:

type: specs.openrewrite.org/v1beta/recipe
name: net.sghill.rewrite.HtmlUnit3
displayName: Upgrade to HtmlUnit 3.x
description: Update packages to org.htmlunit
recipeList:
  - org.openrewrite.java.ChangePackage:
      oldPackageName: net.sourceforge.htmlunit
      newPackageName: org.htmlunit
      recursive: "False"
  - org.openrewrite.java.ChangePackage:
      oldPackageName: com.gargoylesoftware.htmlunit
      newPackageName: org.htmlunit
      recursive: "False"

For fun I ran this on https://public.moderne.io and it found a lot of changes that could be issued as PRs from the service. To completely automate this it'd be worth adding a few more recipes to ensure HtmlUnit 3 is being used, but as the yaml shows it's easy to compose recipes.

2023-06-10-htmlunit-moderne

@basil
Copy link
Member

basil commented Jun 23, 2023

HtmlUnit 2.x.x to 3.x.x migration guide

@basil
Copy link
Member

basil commented Jun 23, 2023

I worked on the spreadsheet today and made some progress, but there are still a lot of long-tail plugins without a passing build with the new version of HtmlUnit. I would like to see a bit more effort spent on the long tail before we declare this project a success.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants