Giter VIP home page Giter VIP logo

rewrite-jenkins's Introduction

Logo

Modernize Jenkins plugins. Automatically.

ci Apache 2.0 Maven Central Revved up by Develocity Contributing Guide

What is this?

This project contains a series of Rewrite recipes and visitors to automatically upgrade and migrate Jenkins plugins.

Jenkins is a fast-moving project that recommends plugins update quarterly. As Jenkins evolves, functionality is regularly factored out from core into plugins. Implicit dependencies are added to plugins based on the version of Jenkins they depend on to retain backwards compatibility. By regularly marching plugins forward, we can drop these dependencies when unnecessary, making our deployments smaller and simpler.

Additionally, depending on newer versions of Jenkins allows our builds to pick up deprecations. These deprecations can often be migrated with new OpenRewrite recipes. Proactively handling deprecations in the plugins we depend on allows us to avoid runtime issues if and when the deprecated code is removed.

Quick start

Running Rewrite on a Maven project without modifying the build is very helpful for getting started. To run the org.openrewrite.jenkins.github.AddTeamToCodeowners recipe:

$ mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
      -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-jenkins:RELEASE \
      -Drewrite.activeRecipes=org.openrewrite.jenkins.github.AddTeamToCodeowners

How to use?

See the full documentation at docs.openrewrite.org.

Contributing

We appreciate all types of contributions. See the contributing guide for detailed instructions on how to get started.

rewrite-jenkins's People

Contributors

basil avatar gounthar avatar jkschneider avatar knutwannheden avatar markewaite avatar mike-solomon avatar sambsnyd avatar sghill avatar sghill-rewrite avatar shanman190 avatar sullis avatar timtebeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rewrite-jenkins's Issues

Enable Release Drafter if needed

If a plugin is using automated release, then any Release Drafter configuration should be deleted as explained here. But if the plugin is not using automated release and missing a Release Drafter configuration, it should be added to .github/release-drafter.yml and .github/workflows/release-drafter.yml as per the archetype:

The above configuration is for plugins with two digits in their version number. For plugins with three digits (SemVer-style), the following configuration should be used instead:

_extends: .github
name-template: $NEXT_PATCH_VERSION
tag-template: ${artifactId}-$NEXT_PATCH_VERSION
version-template: $MAJOR.$MINOR.$PATCH

Adapt repeatable delete buttons to new markup

As of 2.335 plugins with <input type="button" class="repeatable-delete"> log the following warning:

Adapted element to new markup, it should be changed to use f:repeatableDeleteButton instead in the plugin

As the warning says, the plugin should be changed to use f:repeatableDeleteButton.

Document maven command line to invoke recipes

What problem are you trying to solve?

The OpenRewrite documentation for the Jenkins recipes includes examples that allow me to run a recipe from the Maven command line, without modifying my pom.xml file. I'd like to apply the hudson.Util.getPastTimeString migration to the Jenkins basic branch build strategies plugin but I was unable to determine the command line options that are needed to apply that recipe.

Describe the solution you'd like

A sample Maven command line that will invoke that recipe or one of the other recipes in this repository would be enough to let me explore further.

Have you considered any alternatives or workarounds?

I could do the text replacement myself, but I wanted to try OpenRewrite with a recipe that I know is needed on a plugin that I maintain.

Additional context

Thanks so much for your work on OpenRewrite recipes for Jenkins.

Are you interested in contributing this feature to OpenRewrite?

I'm happy to help with documentation once I understand the basics.

Replace `joda-time` with JSR 310

Java 7 and prior had time libraries that were inadequate. The joda-time library was created to provide better ways of handling time. The joda-time library was used as the design basis for the JSR 310 time libraries. Use of joda-time should be replaced by calls to the JSR 310 time classes and methods. To identify sources with the issue, do a search in all project files for the pattern org.joda.time. See Stephen Colebourne’s 2014 blog post that describes the transition process from joda-time to JSR 310.

Simplify test idioms to build a project and assert the status

What problem are you trying to solve?

Some plugins have many functional test assertions using an overly verbose idiom for triggering a build of a test project, waiting for the build to complete, and then checking the result of the build. There are simpler idioms available in the JenkinsRule test utility, and we can also apply centralized improvements to make this workflow more reliable (removing nondeterministic aspects).

What precondition(s) should be checked before applying this recipe?

Any Jenkins plugins using JenkinsRule (a default test dependency), whether explicitly as a @Rule, or as a parameter passed into a method when the @Rule is actually something else (RestartableJenkinsRule, JenkinsSessionRule, RealJenkinsRule).

Describe the situation before applying the recipe

Some idiom variants:

rule.assertBuildStatusSuccess(project1.scheduleBuild2(0).get());
FreeStyleBuild build2 = project2.scheduleBuild2(0, new Cause.UserIdCause()).get();
rule.assertBuildStatus(Result.FAILURE, build2);

Describe the situation after applying the recipe

The corresponding simpler versions:

rule.buildAndAssertSuccess(project1);
FreeStyleBuild build2 = rule.buildAndAssertStatus(Result.FAILURE, project2);

Have you considered any alternatives or workarounds?

Regexp search and replace?!

Any additional context

N/A

Are you interested in contributing this recipe to OpenRewrite?

TBD

Update `git-changelist-maven-extension` if needed

In addition to updating the plugin parent POM to the latest version, the version of git-changelist-maven-extension in .mvn/extensions.xml should be updated to the latest version if necessary. Version 1.6 is the last version that works on Java 8; 1.7 and later require Java 11+.

Add `CODEOWNERS` if needed

Many plugins are missing a .github/CODEOWNERS. This results in maintainers not getting emails when contributors file pull requests. If this file is missing, it should be added per the archetype.

Remove `div`-based form layout conditionals

If the plugin was previously using HTML table tags to align the content of input forms, then it will likely contain conditional code that detects div-based layout and uses div tags instead of table tags on newer versions of Jenkins. When the base Jenkins version is 2.277.1 or later, the conditional for table based layout can be removed, since all layout is done with div tags beginning with 2.277.1. Search the Jelly files in the plugin for divBasedFormLayout to find conditionals that can be removed.

Replace `DomNode#asText` with `DomNode#asNormalizedTest`

HtmlUnit 2.55.0 removed the deprecated DomNode#asText in favor of DomNode#asNormalizedTest. Plugins with a very old plugin parent POM (one with HtmlUnit 2.54.0 or earlier) will likely still be using asText and will thus fail to compile until these usages are converted to asNormalizedText.

JellyEscapeByDefault Recipe

Jelly files will fail on newer tooling if they do not include

<?jelly escape-by-default='true'?>

Failure:

java.lang.AssertionError: <?jelly escape-by-default='true'?> is missing in file:/home/sghill/gh/sghill/show-build-parameters-plugin/target/classes/index.jelly

Increase scope of `ReplaceLibrariesWithApiPlugin`

ReplaceLibrariesWithApiPlugin is great, but its scope could be greatly increased. Right now it only seems to handle Commons Lang 3. Other examples:

  • Apache HttpComponents Client 4.x
  • Apache HttpComponents Client 5.x
  • BouncyCastle
  • Caffeine
  • Commons Text
  • Docker
  • Jackson
  • Jakarta Activation
  • Jakarta Mail
  • JavaBeans Activation
  • JavaMail
  • JAXB
  • Jersey
  • JSch
  • Kubernetes Client
  • SnakeYAML
  • Trilead

Incrementalify plugins

It is considered a best practice for Jenkins plugins to implement incrementals. Among other benefits, this allows for easy testing of PR builds and is a necessary prerequisite for setting up automated release. The steps are, roughly:

  • If missing, create .mvn/extensions.xml with the latest version of git-changelist-maven-extension.
  • If missing, add .mvn/maven.config with -Pconsume-incrementals and -Pmight-produce-incrementals.
    • Note that -Dchangelist.format is also needed for automated release, but not necessary for the traditional release process.
  • If a version like <version>1.20-SNAPSHOT</version> is present, change this to <version>${revision}${changelist}</version> and add <revision>1.20</revision> and <changelist>-SNAPSHOT</changelist> to the <properties> section.
    • Note that this could be set to just <version>${changelist}</version> or even <version>${revision}.${changelist}</version> for automated release as described here.
  • If missing, add <gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo> to the <properties> section.
    • Note that some plugins (not many, though) have an artifact ID that does not match their GitHub repository, so in that case one cannot use ${project.artifactId}.
  • Ensure the <scm> section reads like this:
<scm>
  <connection>scm:git:https://github.com/${gitHubRepo}.git</connection>
  <developerConnection>scm:git:[email protected]:${gitHubRepo}.git</developerConnection>
  <tag>${scmTag}</tag>
  <url>https://github.com/${gitHubRepo}</url>
</scm>

Incrementalifying a Java 9+ plugin for the first time will likely also expose #14.

Migrate JUnit 3 tests to JUnit 4

Some plugin tests still extend the JUnit 3 TestCase object. JUnit 4 tests are much more common in Jenkins core and in Jenkins plugins. Migrate the JUnit 3 tests to JUnit 4. See this StackOverflow article that describes the steps to migrate from JUnit 3 to JUnit 4. To identify the sources impacted, search in all project files for patterns like import junit.framework.TestCase or extends TestCase.

`org.openrewrite.jenkins.BomLookup` is too simplistic

org.openrewrite.jenkins.BomLookup reads jenkins-plugins-bom-lookup.txt and checks to see if the plugin is present in this file. In reality, this list is constantly changing as plugins are added/removed to the plugin BOM. For example, newer releases of the plugin BOM have more plugins in the managed set than older releases. For a foolproof strategy, fetch the plugin BOM in use in the <dependencyManagement> section and determine if it is managing the given plugin.

Update Javadoc for Java 9+ if needed

A common problem when modernizing plugins is that generating Javadoc (which only happens when running with mvn clean verify -Pjenkins-release or mvn clean verify -Dset.changelist) fails on Java9+ with error: tag not supported in the generated HTML version: tt if there are any <tt> tags in the Java code (for example, in cvs-plugin as of jenkinsci/cvs-plugin@26e82b2). The solution in these cases is to replace <tt>foo</tt> with {@code foo}, but this is quite tedious.

Incorrect CODEOWNERS file created for Priority Sorter plugin and TestNG plugin

What version of OpenRewrite are you using?

I am using

  • Maven plugin v5.4.2

I am not sure of the other versions, but the maven output indicates Maven plugin 5.4.2

How are you running OpenRewrite?

Running the Maven plugin on a single module project https://github.com/jenkinsci/priority-sorter-plugin I see an unexpected incorrect syntax in the generated CODEOWNERS file. The name of the developers team that was initially created by the OpenRewrite recipe was missing a "-" character.

The initial file was:

* @jenkinsci/prioritysorter-plugin-developers

The updated file was:

* @jenkinsci/priority-sorter-plugin-developers

I am using the Maven plugin with the command line as described in the pull request:

$ mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
      -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-jenkins:RELEASE \
      -Drewrite.activeRecipes=org.openrewrite.jenkins.github.AddTeamToCodeowners

Similar error with the TestNG plugin pull request, though in the case of the TestNG plugin, it may be due to the uncommon duplication of the word "plugin" in the repository name

What is the smallest, simplest way to reproduce the problem?

Run the provided command line after removing the corrected CODEOWNERS file from the repository.

What did you expect to see?

I expected the CODEOWNERS file to contain the correct team name * @jenkinsci/priority-sorter-plugin-developers as it did on the other pull requests that I created. Refer to the other pull requests:

The updated file was:

* @jenkinsci/priority-sorter-plugin-developers

What did you see instead?

The initial file was:

* @jenkinsci/prioritysorter-plugin-developers

What is the full stack trace of any errors you encountered?

No stack trace or other indication of error

Are you interested in contributing a fix to OpenRewrite?

I lack the skills to contribute a fix.

Complete adoption into OpenRewrite GitHub Org

What problem are you trying to solve?

Because this project started out independently, it diverges from other OpenRewrite modules, making it slightly harder to maintain automatically.

Describe the solution you'd like

Ensure we use the code style, CI and release pipeline from OpenRewrite.

  • Use the rewrite-build-gradle-plugin in build.gradle.kts
  • Use openrewrite/.github for CI
  • Use Java for tests
  • Add @DocumentExample to tests for documentation
  • Include module in recipe-markdown-generator
  • Include module in recipe-bom
  • Update README to include the usual blurps
  • Move rewrite.yml out of root
  • Drop duplicate LICENSE
  • Use 8 for src/main and 17 for src/test, likely drop java-version
  • Disassociate fork from rewrite-recipe-starter through GitHub support
  • Add a category.yml to show recipes in docs & platform under Jenkins with a logo

Have you considered any alternatives or workarounds?

No; it's preferred for projects to look alike, such that we can maintain, release and document them with ease.

Remove any usages of Animal Sniffer

Animal Sniffer was removed from the plugin parent POM in 4.52. Any imports of org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement and any @IgnoreJRERequirement annotations should be deleted.

CODEOWNERS Generated with excluded team name

The org.openrewrite.jenkins.github.AddTeamToCodeowners recipe has an issue where a * CODEOWNERS file is generated from a plugin that has been marked as excluded (introduced in #48) from having a team.

What is the smallest, simplest way to reproduce the problem?

Running the recipe on moderne.io for run-condition-extras-plugin.

What did you expect to see?

No file added.

What did you see instead?

* 

Visible in jenkinsci/run-condition-extras-plugin#4

Are you interested in contributing a fix to OpenRewrite?

Yes.

Migrate documentation from wiki if needed

If the plugin's <url> starts with http://wiki.jenkins-ci.org/display/JENKINS/ then its documentation needs to be migrated from the old wiki. This is a bit of a laborious process and I am not sure it can be fully automated. The steps are, roughly:

  • Change the URL to <url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>, unless of course the artifact ID is different from the GitHub repository.
  • Fetch the wiki page from https://github.com/jenkins-infra/plugins-wiki-docs/ and split it from a single page into a README.md page and a CHANGELOG.md page. These files notoriously contain non-ASCII characters, so best to also do some Unicode normalization here.
  • If the wiki export contains images, copy them from there to docs/images/.
  • If the plugin is now using Release Drafter, add a note to CHANGELOG.md saying that future change logs are available at the GitHub releases page rather than in CHANGELOG.md.

Migrate away from ancient Mockito

In Mockito 2 org.mockito.Matchers was deprecated in favor of org.mockito.ArgumentMatchers, and in Mockito 3 org.mockito.Matchers was deleted. Old plugins will still be relying on org.mockito.Matchers and thus will need to be updated to use org.mockito.ArgumentMatchers instead.

Minimum Non-BOM Plugin Versions Recipe

Non-BOM plugins, such as job-dsl, should have a way to specify a minimum version with a comment. This needs to work with property-driven versions as well.

Property-Driven Before:

<properties>
    <plugins.job-dsl.version>1.52</plugins.job-dsl.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.jenkins-ci.plugins</groupId>
        <artifactId>job-dsl</artifactId>
        <version>${plugins.job-dsl.version}</version>
        <optional>true</optional>
    </dependency>
</dependencies>

Property-Driven After:

<properties>
    <!-- <= 1.71 vulnerable: https://www.jenkins.io/security/advisory/2019-03-06/#SECURITY-1342 -->
    <plugins.job-dsl.version>1.72</plugins.job-dsl.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.jenkins-ci.plugins</groupId>
        <artifactId>job-dsl</artifactId>
        <version>${plugins.job-dsl.version}</version>
        <optional>true</optional>
    </dependency>
</dependencies>

Inline Before:

<dependencies>
    <dependency>
        <groupId>org.jenkins-ci.plugins</groupId>
        <artifactId>job-dsl</artifactId>
        <version>1.52</version>
        <optional>true</optional>
    </dependency>
</dependencies>

Inline After:

<dependencies>
    <dependency>
        <groupId>org.jenkins-ci.plugins</groupId>
        <artifactId>job-dsl</artifactId>
        <!-- <= 1.71 vulnerable: https://www.jenkins.io/security/advisory/2019-03-06/#SECURITY-1342 -->
        <version>1.72</version>
        <optional>true</optional>
    </dependency>
</dependencies>

For an example, see jenkinsci/applitools-eyes-plugin#9

Jenkinsfile is not overwritten

What version of OpenRewrite are you using?

I'm using it through Moderne.io, so I don't know, sorry.

How are you running OpenRewrite?

I'm using Moderne.io.
I don't think you will be able to see the results, but I used my latest recipe of recipes that gave: https://app.moderne.io/results/Dm3ZuYTUW

The plugin I tried this on is multibranch-scan-webhook-trigger-plugin.
You can see the first commit there: jenkinsci/multibranch-scan-webhook-trigger-plugin@fde4557

You can replay the recipe of recipes here: https://app.moderne.io/recipes/builder/j0daJWhoh?organizationId=SmVua2lucyBDSQ%3D%3D .

What is the smallest, simplest way to reproduce the problem?

Re-run the recipe.
A friend of mine tried only the modernize Jenkinsfile on his machine with the same project thanks to the maven command, and it failed to change the file too.

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
  -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-jenkins:RELEASE \
  -Drewrite.activeRecipes=org.openrewrite.jenkins.ModernizeJenkinsfile

Once the file was deleted, the recipe created the file correctly.

What did you expect to see?

Well, at least a rewritten Jenkinsfile, even if the complexity of the Jenkinsfile was lost (some of them are not just buildplugin(), but lots of instructions like in https://raw.githubusercontent.com/jenkinsci/kubernetes-plugin/master/Jenkinsfile.

What did you see instead?

Nothing, until we deleted the local Jenkinsfile.

What is the full stack trace of any errors you encountered?

No error.

Are you interested in [contributing a fix to OpenRewrite]

I'd love to contribute if possible. While I may not have all the required skills, I'm enthusiastic about the project and willing to learn.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.