Skip to content

jenkins-infra/plugin-modernizer-tool

Repository files navigation

Plugin Modernizer Tool

Using OpenRewrite Recipes for Plugin Modernization or Automation Plugin Build Metadata Updates

Build Status Coverage LOC GitHub license

Note

This tool is currently in development and looking for contributors and early adopters. Please report any issues or feature requests on the GitHub repository.

It's configuration and APIs might change in future releases

About

Plugin Modernizer is a generic CLI tool designed to automate the modernization of Jenkins plugins. It utilizes OpenRewrite recipes to apply transformations to the plugin, validating the applied transformations and creating pull requests with the results.

The CLI is also used to collect metadata from Jenkins plugins, such as the plugin's dependencies (including transitive) or JDKs used for building the plugin. Such metadata is planned to be integrated with existing Jenkins tooling such as

Learn more at this project page.

Usage

Getting Started

Note

Releases are paused until the end of the GSoC period. To use the latest version of the tool, clone this project locally and build it using the following commands.

Requirements to build

  • Maven version 3.9.7 or later, or mvnd
  • Java 17 or Java 21

Build

mvn clean install

Using the tool

After building, the JAR file will be available at plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --help

Setup

This tool requires forking repositories from GitHub, so you need to set the GitHub token and GitHub owner as environment variables. Use either GH_TOKEN or GITHUB_TOKEN for the GitHub token, and either GH_OWNER or GITHUB_OWNER for the GitHub owner. Alternatively, you can pass the GitHub owner through the CLI option -g or --github-owner.

Your classic token should have the following scopes

  • repo (Full control of private repositories)
  • user:email (Read-only access to email addresses)
  • delete_repo (Delete repositories) (Only if using the --clean-forks option)

Note

The GitHub owner can be either a personal account or an organization.

The CLI also support GitHub app installation for CI scenario.

The app must be installed on the owner's and target account and a private key generated and downloaded in PEM format.

From there you need to save both ID of installation (found on URL)

https://github.com/organizations/<org>/settings/installations/<installation ID>

To activate app authentication, just set the following CLI argument

--github-app-id <app-id> or GH_APP_ID environment variable --github-app-source-installation-id <installation-id> or GH_APP_SOURCE_INSTALLATION_ID environment variable --github-app-target-installation-id <installation-id> or GH_APP_TARGET_INSTALLATION_ID environment variable --github-app-private-key <path-to-private-key> or GH_APP_PRIVATE_KEY environment variable

CLI Options

  • --plugins or -p: (optional) Name(s) of plugin directory cloned inside the test-plugins directory.

  • --recipes or -r: (required) Name(s) of recipes to apply to the plugins.

  • --plugin-file or -f: (optional) Path to the text file that contains a list of plugins. (see example plugin file)

  • --list-recipes or -l: (optional) Displays the list of available recipes.

  • --dry-run or -n: (optional) Enables dry run mode, generating patch files instead of applying changes. The patch files will be generated at target/rewrite/rewrite.patch inside the plugin directory if any change is made.

  • --skip-push (optional) Skips pushing changes to the remote repository. Always enabled in dry-run mode.

  • --skip-pull-request (optional) Skips creating pull requests in the remote repository. Always enabled in dry-run mode.

  • --clean-local-data (optional) Deletes the local plugin directory before and after the process is completed.

  • --clean-forks (optional) Remove forked repositories before and after the modernization process. Might cause data loss if you have other changes pushed on those forks. Forks with open pull request targeting original repo are not removed to prevent closing unmerged pull requests.

  • --export-datatables or -e: (optional) Creates a report or summary of the changes made through OpenRewrite in CSV format. The report will be generated at target/rewrite/datatables inside the plugin directory.

  • --debug or -d: (optional) Enables debug mode.

  • --jenkins-update-center: (optional) Sets main update center; will override JENKINS_UC environment variable. If not set via CLI option or environment variable, will default to url in properties file

  • --jenkins-plugins-stats-installations-url (optional) Set the URL for the Jenkins Plugins Stats installations API. If not set via CLI option or environment variable, will default to url in properties file

  • --cache-path or -c: (optional) Custom path to the cache directory. Defaults to ${user.home}/.cache/jenkins-plugin-modernizer-cli.

  • --github-owner or -g: (optional) GitHub owner for forked repositories. Can also be set via the environment variable GH_OWNER or GITHUB_OWNER.

  • --maven-home or -m: (optional) Path to the Maven home directory. Required if both MAVEN_HOME and M2_HOME environment variables are not set. The minimum required version is 3.9.7.

  • --version or -v: (optional) Displays the version of the Plugin Modernizer tool.

Plugin Input Format

Plugins can be passed to the CLI tool in two ways:

  • Plugin option
  • Plugin file option

Plugin option

Pass the plugin names directly using the -p or --plugins option. The expected input format for plugins is artifact ID.

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --plugins git,git-client,jobcacher --recipes AddPluginsBom,AddCodeOwner

Here, git, git-client, and jobcacher are plugin artifact IDs (also known as plugin names), while AddPluginsBom and AddCodeOwners are recipe names. For more details about available recipes, refer to the recipe_data.yaml file.

Plugin file option

Pass the path to a file that contains plugin names. The expected input format for plugins in the .txt file is artifact ID or artifact ID:version. See example plugin file

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --plugin-file path/to/plugin-file --recipes AddPluginsBom,AddCodeOwner

Configuring Environmental Variables

  • GITHUB_TOKEN or GH_TOKEN: (required) GitHub Token.

  • GITHUB_OWNER or GH_OWNER: (required) GitHub username or organization name. Can also be passed through the CLI option -g or --github-owner.

  • JENKINS_UC: (optional) Update Center URL. Can also be passed through the CLI option --jenkins-update-center.

  • MAVEN_HOME or M2_HOME: (required) Path to Maven home directory. Can also be passed through the CLI option -m or --maven-home.

  • CACHE_DIR: (optional) Path to cache directory. Can also be passed through the CLI option -c or --cache-path.

Examples

without dry-run

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --plugins git,git-client,jobcacher --recipes AddPluginsBom,AddCodeOwner

The above command creates pull requests in the respective remote repositories after applying the changes.

with dry-run

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --plugins git,git-client,jobcacher --recipes AddPluginsBom,AddCodeOwner --dry-run

The above command generates patch files instead of applying changes directly. These patch files are saved in /target/rewrite/rewrite.patch inside each plugin directory. No pull requests will be created.

Note

Enable dry-run to avoid opening pull requests in the remote repositories.

with export-datatables

java -jar plugin-modernizer-cli/target/jenkins-plugin-modernizer-999999-SNAPSHOT.jar --plugins git,git-client,jobcacher --recipes AddPluginsBom,AddCodeOwner --export-datatables

The above command creates a report of the changes made through OpenRewrite in csv format. The report will be generated in target/rewrite/datatables inside the plugin directory.

See example generated files:

More about Openrewrite Data Tables

Running with Docker

You can use the Docker image supplied by this project to run the Plugin Modernizer Tool without needing to install Java or Maven on your local machine.

Prerequisites

  • Docker installed on your machine.
  • A GitHub token with the necessary scopes.
  • A file named plugins.txt containing the list of plugins.

Of course, you don't need a plugins.txt file if you are using the --plugins option.

Example

Below is an example of how to use the Docker image with a local plugins.txt file.

docker run \
  -e GH_TOKEN=${GH_TOKEN} \
  -e GH_OWNER=${GH_OWNER} \
  -v $(pwd)/plugins.txt:/plugins.txt \
  ghcr.io/jenkins-infra/plugin-modernizer-tool:main \
  --plugin-file /plugins.txt --recipes AddPluginsBom,AddCodeOwner

Explanation

  • -e GH_TOKEN=${GH_TOKEN}: Passes the GitHub token as an environment variable.
  • -e GH_OWNER=${GH_OWNER}: Passes the GitHub owner as an environment variable.
  • -v $(pwd)/plugins.txt:/plugins.txt: Mounts the plugins.txt file from the current directory to the Docker container.
  • ghcr.io/jenkins-infra/plugin-modernizer-tool:main: Specifies the Docker image to use.
  • --plugin-file /plugins.txt: Specifies the path to the plugin file inside the Docker container.
  • --recipes AddPluginsBom,AddCodeOwner: Specifies the recipes to apply.

This command will run the Plugin Modernizer Tool inside the Docker container using the specified environment variables and plugin file.

Reproducibility

The maven build should be reproducible

See

Reproducible Builds for more information.

Ensure the repository is clean before running the following commands (otherwise you can pass the -Dignore.dirty flag to the maven command).

mvn -Dset.changelist clean install
mvn -Dset.changelist -Dreference.repo=central clean verify artifact:compare

The property project.build.outputTimestamp will be set with the timestamp of the latest commit.

If you are using a mirror for central you should adapt the reference.repo property accordingly to match the id of the mirror in your settings.xml.

Contributing

Thanks to all our contributors! Check out our CONTRIBUTING file to learn how to get started.

References