Skip to content

Utility that turns Bazel-built jars into Maven compatible artifacts

License

Notifications You must be signed in to change notification settings

salesforce/pomgen

pomgen

ci

:octocat: Please do us a huge favor. If you think this project could be useful for you, now or in the future, please hit the Star button at the top. That helps us advocate for more resources on this project. Thanks!

Overview

The set of scripts in this repository provides a solution for:

  • Generating pom.xml files for jars built by Bazel (typically java_library or java_binary rules)
  • Uploading the pom.xmls and jars to a Maven Artifact Repository such as Nexus (or installing them into the local Maven Repository at ~/.m2/repository)

pomgen does not run as part of the Bazel build - therefore Bazel BUILD files can remain free of pom.xml related metadata.

Usage Requirements

  • External Maven Central/Nexus dependencies must be managed using rules_jvm_external's maven_install rule
  • Artifacts must be pinned, because pomgen parses the pinned artifacts' json file(s)
    • The location of all pinned artifact json files must be declared in the pomgen config file by setting maven_install_paths

Compatibility

Pomgen uses the lockfiles generated by rules_jvm_external. Version 5.0 of rules_jvm_external included a new lockfile format. In October 2023, we released pomgen 2.0.0 which uses the new lockfile format.

  • pomgen < 2.0.0 is compatible with rules_jvm_external < 5.0
  • pomgen >= 2.0.0 is compatible with rules_jvm_external >= 5.0

Setup

  • Add a java_library rule to your Bazel Package as the default target (the target has same name as its Bazel Package, ie the directory the BUILD file lives in)
  • For each Maven Artifact producing Bazel Package, a BUILD.pom file defines Maven specific metadata
  • A special marker file groups one or more Maven Artifacts into a Library

See this doc for more information on pomgen files.

Bazel Package References

The BUILD file of a Maven Artifact producing Bazel Package may obviously reference other Bazel Packages in the repository. pomgen will follow these references and generate pom.xmls for all referenced Bazel Packages.

Change Detection

pomgen tracks whether the content of a Bazel Package has changed since it was last released. Generated poms reference the previously released Maven Artifact if no change is detected.

See this doc for more information on change detection.

Example

Please see the hello-world example to see how pomgen works.

External Dependencies

  • Bazel, ideally through bazelisk
    • This branch has been tested with Bazel 6.4.x
  • Python 3 is required and must be configured as a toolchain or available in your $PATH
  • You need to install lxml: pip install --user lxml

Running pomgen in your own repository

Reference this repository in your WORKSPACE file using Bazel's git_repository rule:

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
    name = "pomgen",
    remote = "https://github.com/salesforce/pomgen.git",
    commit = "<git-commit-sha>"
)

You can then run pomgen commands as documented, for example:

bazel run @pomgen//maven -- -a pomgen,install

Configuration

Some pomgen behavior is driven by an optional configuration file .pomgenrc. pomgen looks for this file at the root of the repository it is running in.

Running pomgen with --verbose causes the current config to be echoed.

The file format is:

[general]
# Path to the pom template, used when generating pom.xml files for jar artifacts
# Default value: config/pom_template.xml
pom_template_path=

# The base filename (without extension) of the generated pom files.
# Default value: pom
pom_base_filename=

# The list of all maven install json files with pinned dependencies, comma-separated. 
# All dependencies that pomgen encounters in BUILD files must exist in one of the files
# listed here.
# Default value: maven_install.json
# Example value: tools/maven_install/*.json,another/path/to/mvn_install.json,
maven_install_paths=

# The list of all overridden deps bzl files, comma-separated.
# Default value: empty (not set)
override_file_paths=

[crawler]
# A list of path prefixes that are not crawled by pomgen.  Any source dependency
# that starts with one of the specified paths is skipped and not processed
# (and not included in the generated pom.xml).
# These dependencies are similar to Maven's "provided" scope: if they are
# needed at runtime, it is expected that the final runtime assembly
# contains them.
# Default value: []
# Example value: projects/protos/,
excluded_dependency_paths=

# A list of labels that are skipped over by pomgen.  Any dependency
# that matches one of the specified strings is skipped and not processed
# (and not included in the generated pom.xml).
# These dependencies are similar to Maven's "provided" scope: if they are
# needed at runtime, it is expected that the final runtime assembly
# contains them.
# Default value: []
# Example value: @maven//:com_google_guava_guava,
excluded_dependency_labels=


[artifact]
# Global toggle for change detection (docs/change_detection.md)
# Default value: True
change_detection_enabled=

# Paths not considered when determining whether an artifact has changed
# Default value: src/test,
excluded_relative_paths=

# File names not considered when determining whether an artifact has changed
# Default value: .gitignore,
excluded_filenames=

# Ignored file extensions when determining whether an artifact has changed
# Default value: .md,
excluded_extensions=

# Specifies how to increment the versions of libraries released transitively
# Default value: semver
# Possible values: semver|counter
transitives_versioning_mode=

# The classifier used for all jars artifacts assembled by pomgen
# The same value can also be specified by setting the environment variable
# POMGEN_JAR_CLASSIFIER - the environment variable takes precedence over the
# value set in this cfg file
# Default value: empty (not set)
jar_classifier=

transitives_versioning_mode

Please see more information about transitives versioning.

override_file_paths

rules_jvm_external allows to override dependencies at runtime. pomgen provides an equivalent override mechanism: use override_file_paths in the [general] section of .pomgenrc file. The value of override_file_paths is one or more paths (comma-separated) to .bzl files, containing a dependency -> overriden dependency mapping.

See this example.

CI setup

This document goes over the CI setup.