Publish to the Bazel Central Registry - #1
Conversation
This repository is no longer just a checkout of griffinbank/rules_clojure
with a patch on top — it is published independently to the Bazel Central
Registry — so it has to say so, and it has to satisfy the licence it
inherits.
Upstream is Apache-2.0 (LICENSE, unchanged and byte-identical here).
Section 4(b) requires modified files to carry prominent notices stating
that they were changed, which is what the new NOTICE does. NOTICE also
inventories the third-party code already vendored under
src/rules_clojure/{namespace,tools/reader,java/classpath}: tools.namespace,
tools.reader and java.classpath are EPL-1.0, and their per-file copyright
headers must never be stripped.
The README gains a fork banner, and its Setup section moves from the
`http_archive` + WORKSPACE snippet — which referenced repositories.bzl and
setup.bzl, files that no longer exist — to `bazel_dep`. It also documents
the JDK 21 requirement explicitly: the clojure_library worker runs on the
TOOL JVM, and rules_clojure.fs uses java.util.HexFormat, so a build whose
tool runtime is older fails with ClassNotFoundException. That is the most
common way a first rules_clojure build fails and it was undocumented.
One inherited inconsistency is documented rather than silently resolved:
the README footer claims EPL-1.0 and points at an epl-v10.html that is not
in the tree, while LICENSE is Apache-2.0. Upstream's notice is reproduced
verbatim, with a statement that LICENSE governs. Resolving it is upstream's
call, not this fork's.
AGENTS.md records the fork's branch discipline — in particular that
bazel-9-compat is the branch PR griffinbank#108 is opened from and must stay
mergeable by upstream, so fork-only work does not land there.
Two changes to how a build here is configured, in every module.
.bazeliskrc becomes .bazelversion. Both are read by bazelisk and
USE_BAZEL_VERSION overrides either, so CI can still drive the version
matrix; .bazelversion is the conventional file and is what the tooling
around Bazel (IDE plugins, setup-bazel) looks for. The pin moves to 9.2.0,
the version this fork exists to support. The examples move with it rather
than trailing behind at their own version, which is how their Bazel 9
breakage went unnoticed in the first place.
local_jdk becomes remotejdk_21, with the language version stated too, and
the TOOL runtime set alongside the target one. Three reasons, in order of
how much they bite:
- The release workflow runs `bazel test //...` on a runner whose default
JDK this project does not control. With local_jdk that is a coin flip
on the runner image, decided at release time.
- The worker runs on the tool JVM and needs Java 21 for
java.util.HexFormat, so tool_java_runtime_version is the setting that
actually matters and it was being left to chance.
- CI no longer needs a setup-java step, and a fresh clone builds without
the developer first installing a matching JDK.
rules_clojure has never been in the BCR, so every consumer needs an
archive_override or git_override — and git_override is honoured only in
the root module, which means a module that depends on rules_clojure cannot
be published either. This makes the fork installable with a plain
bazel_dep.
Version 0.6.0. Upstream's latest is 0.5, so this leaves 0.5.x free and a
future upstream patch release cannot collide with this line.
The Clojure 1.8 maven install moves to a dev_dependency extension proxy.
It exists only for persistent-classloader-test, which proves the
classloader cache copes with a foreign Clojure version; dev dependencies
are ignored when this module is not the root, so a consumer no longer
downloads it. Verified with `bazel mod graph` from examples/bzlmod: the
module now brings rules_java and rules_jvm_external and nothing else.
Release automation follows bazel-contrib's, and several details in it are
load-bearing rather than stylistic — the comments in release.yml say which
and why, because each was a failure paid for once already elsewhere:
- publish-to-bcr is called directly, not through a local wrapper. A
wrapper relying on `secrets: inherit` for its REQUIRED publish_token
fails workflow startup validation for every job in the file.
- publish_token is mapped explicitly for the same reason, and because it
is an environment secret, which `inherit` does not pass.
- The release is cut as a draft and published only after BCR succeeds:
attestations must be attached while the release is still mutable.
- The archive is built by .github/workflows/release_prep.sh at exactly
that path, because release_ruleset takes no command input — an archive
attested any other way is rejected by BCR.
- A prerelease tag (v0.6.0-rc1) runs everything except opening the
upstream pull request, so the pipeline can be rehearsed without
spending BCR reviewers' attention on an add-only registry.
examples/bzlmod is new and is what the registry presubmit runs: a module
that depends on rules_clojure over bzlmod, brings its own Clojure from
Maven, and AOT-compiles and tests Clojure code. It deliberately does not
use rules_clojure's own `deps` extension — that downloads the Clojure CLI
from download.clojure.org and symlinks $HOME/.m2/repository, which is too
non-hermetic to hang a registry presubmit on. examples/simple keeps
covering that path from CI instead.
presubmit.yml also builds //src/rules_clojure:worker from an anonymous
module. That runs the bootstrap genrules, which proves the module's own
maven_deps install resolves when rules_clojure is NOT the root module —
the most likely way publication breaks.
The two pipelines here had drifted into covering neither claim properly.
The GitHub Actions workflow built only the root `//...` and only on
`master`, a branch this repository does not have; CircleCI covered the
examples but on one platform, one Bazel version, and a JDK installed by
apt.
One workflow now covers what .bcr/presubmit.yml promises, because a
registry entry claiming Bazel 8 and 9 on Linux and macOS should not be the
only place either is tested:
- the ruleset and examples/bzlmod on both majors and both platforms
- examples/simple and examples/stress on Linux only for now. The macOS
branch of rules/tools_deps.bzl needs HOMEBREW_RUBY_PATH and is the
least exercised code in the repo; promote it once it is seen to pass
rather than blocking every pull request on it today.
Caches are restored by pull requests but written only from main. That is
the standard Actions cache-poisoning shape — otherwise an untrusted pull
request writes entries a later trusted build restores — and it also stops
pull-request caches evicting main's from the shared repository quota. It
is gated on the ref rather than the event because workflow_dispatch can
target any branch.
No setup-java step: every module now selects remotejdk_21 itself.
The only action in either workflow that was behind. Everything else is already current: bazel-contrib/setup-bazel 0.19.0, bazel-contrib/.github v7.7.0 and bazel-contrib/publish-to-bcr v1.5.0 are each the latest release. Both call sites use checkout with no inputs, so there is nothing for the v5 -> v7 major bumps to break; the change is the newer Node runtime.
… of it Being a hard fork is a statement about maintenance, not about ownership, and the README did not make that distinction — it carried only upstream's copyright, which understated this fork's changes, while leaving room to read "hard fork" as licence independence, which it is not. Apache-2.0 section 4(c) requires a derivative work to retain all copyright and attribution notices from the original. Nearly every line here is still Griffin Bank's, so their notice stays exactly as it is. Section 4 also permits a copyright statement over one's own modifications, which is what the second line now is: added alongside theirs, never in place of it. Both README and NOTICE now say this explicitly, so that a future reader — or a future fork of this fork — does not have to infer it.
|
Closing unmerged: this fork is deprecated in favour of bpalermo/rules_clj, so there is no registry entry for this machinery to publish. Nothing here was wrong — CI was green and it was ready to release. What changed is that maintaining two rulesets covering the same ground means splitting attention between them and asking users to choose. What stays: the Bazel 9 fix on The BCR machinery in this branch is not lost either — the same arrangement, with the reasoning that was learned the hard way, is in |
Makes this fork an independently published Bazel module: installable from the Bazel Central Registry with a plain
bazel_dep, on Bazel 8 and 9.Upstream (
griffinbank/rules_clojure) has never been in the BCR, so every consumer needs anarchive_overrideorgit_override— andgit_overrideis honoured only in the root module, which means a module that depends on rules_clojure cannot itself be published. That is the gap this closes.The Bazel 9 fix itself is already on
main(offered upstream as griffinbank/rules_clojure#108, open since 9 Aug, no review). Nothing here touches that PR's branch.Commits
docs(fork)NOTICE(Apache-2.0 §4(b) modification notice + vendored EPL-1.0 inventory), README fork banner /bazel_depsetup / JDK-21 section,AGENTS.mdbranch disciplinebuild.bazeliskrc→.bazelversion(9.2.0) in every module;local_jdk→remotejdk_21, target and tool runtimefeat(bcr)clojure_old,.bcr/templates, release automation,examples/bzlmodciLicence
LICENSEis untouched and byte-identical — upstream is Apache-2.0, and §4(b) requires modified files to carry notices, which is whatNOTICEdoes. The EPL-1.0 headers on the vendored tools.namespace / tools.reader / java.classpath sources are unchanged.One inherited inconsistency is documented rather than resolved: the README footer claims EPL-1.0 and points at an
epl-v10.htmlthat is not in the tree, whileLICENSEis Apache-2.0. Upstream's notice is reproduced verbatim with a statement thatLICENSEgoverns. Resolving it is upstream's call.Verification
bazel test //...in every module, on both majors, on macOS arm64:examples/bzlmodexamples/simpleexamples/stressexamples/gen_srcs_benchbazel mod graphfromexamples/bzlmodconfirms a consumer now pulls onlyrules_javaandrules_jvm_external— no Clojure 1.8, no buildifier.Not done here, needed before a release can run
BCR_AUTHOR_EMAIL, set to the address the Google CLA is signed under. The BCR entry commit's author is checked bycla/google, and a wrong address fails after the release is published and the tag can no longer move.bcr-publishdeployment environment holding secretPUBLISH_TOKEN(a PAT that can push branches tobpalermo/bazel-central-registry), with a deployment policy allowing onlyv*tags.v0.6.0-rc1tag: everything runs except the pull request againstbazelbuild/bazel-central-registry.Known risk
The module keeps the name
rules_clojure. That name is unclaimed in the BCR, but the registry is add-only, so publishing claims it permanently while upstream is still active — expect the reviewer to ask. The fallback is renaming tobpalermo_rules_clojure, which costs the internal@rules_clojure//self-references plus arepo_name = "rules_clojure"line for consumers.