Skip to content

Commit 7605593

Browse files
authored
SOLR-17602: Per-Module Dependency Locking (#2925)
* Introduce platform module The platform module includes all dependencies from the version catalog as constraints and is added to the root modules as API for transitive inheritance of the constraints. * Cleanup version catalog * Fix dependency conflicts when errorprone enabled * Add comment about platform module * Enable per-module dependency lockfiles Removes carrot-search dependencychecks plugin * Update renovate config to use new task * Update documentation * Replace references to versions.props, versions.lock and writeLocks * Add platform module as dependency to include constraints * Update lockfiles
1 parent 616a880 commit 7605593

File tree

72 files changed

+4924
-20352
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+4924
-20352
lines changed

.gitattributes

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Ignore all differences in line endings for the lock file.
1+
# Ignore all differences in line endings for lock files.
22
versions.lock text eol=lf
3+
**/*.lockfile text eol=lf
34

45
# Gradle files are always in LF.
56
*.gradle text eol=lf

.github/labeler.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
dependencies:
33
- changed-files:
44
- any-glob-to-any-file:
5-
- gradle/libs.versions.toml # Solr 10+
6-
- versions.props # Solr < v10
7-
- versions.lock
8-
- solr/licenses/**
5+
- "gradle/libs.versions.toml" # Solr 10+
6+
- "**/*.lockfile"
7+
- "versions.props" # Solr < v10
8+
- "versions.lock"
9+
- "solr/licenses/**"
910

1011
# Add 'documentation' label to any changes within ref-guide or dev-docs
1112
documentation:

.github/renovate.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"enabledManagers": ["gradle", "github-actions"],
77
"includePaths": ["gradle/libs.versions.toml", "versions.*", "build.gradle", ".github/workflows/*"],
88
"postUpgradeTasks": {
9-
"commands": ["./gradlew writeLocks", "./gradlew updateLicenses"],
9+
"commands": ["./gradlew resolveAndLockAll --write-locks", "./gradlew updateLicenses"],
1010
"fileFilters": ["solr/licenses/*.sha1"],
1111
"executionMode": "branch"
1212
},

.github/workflows/bin-solr-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
with:
3939
path: |
4040
~/.gradle/caches
41-
key: ${{ runner.os }}-gradle-binsolr-${{ hashFiles('versions.lock') }}
41+
key: ${{ runner.os }}-gradle-binsolr-${{ hashFiles('**/*.lockfile') }}
4242
restore-keys: |
4343
${{ runner.os }}-gradle-binsolr-
4444
${{ runner.os }}-gradle-

.github/workflows/docker-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
with:
4343
path: |
4444
~/.gradle/caches
45-
key: ${{ runner.os }}-gradle-docker-${{ hashFiles('versions.lock') }}
45+
key: ${{ runner.os }}-gradle-docker-${{ hashFiles('**/*.lockfile') }}
4646
restore-keys: |
4747
${{ runner.os }}-gradle-docker-
4848
${{ runner.os }}-gradle-

.github/workflows/gradle-precommit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
with:
3737
path: |
3838
~/.gradle/caches
39-
key: ${{ runner.os }}-gradle-precommit-${{ hashFiles('versions.lock') }}
39+
key: ${{ runner.os }}-gradle-precommit-${{ hashFiles('**/*.lockfile') }}
4040
restore-keys: |
4141
${{ runner.os }}-gradle-precommit-
4242
${{ runner.os }}-gradle-

.github/workflows/solrj-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
with:
3636
path: |
3737
~/.gradle/caches
38-
key: ${{ runner.os }}-gradle-solrj-${{ hashFiles('versions.lock') }}
38+
key: ${{ runner.os }}-gradle-solrj-${{ hashFiles('**/*.lockfile') }}
3939
restore-keys: |
4040
${{ runner.os }}-gradle-solrj-
4141
${{ runner.os }}-gradle-

build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ plugins {
2222
id 'base'
2323
id 'solr.build-infra'
2424

25-
alias(libs.plugins.carrotsearch.dependencychecks)
2625
alias(libs.plugins.owasp.dependencycheck)
2726
alias(libs.plugins.cutterslade.analyze)
2827
alias(libs.plugins.benmanes.versions)

dev-docs/dependency-upgrades.adoc

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,43 +30,40 @@ In order to upgrade a dependency, you need to run through a number of steps:
3030

3131
1. Identify the available versions from e.g. https://search.maven.org[Maven Central]
3232
2. Update the version in `gradle/libs.versions.toml` file
33-
3. Run `./gradlew writeLocks` to re-generate `versions.lock`. Note that this may cause a cascading effect where
33+
3. Run `./gradlew resolveAndLockAll` to re-generate lockfiles. Note that this may cause a cascading effect where
3434
the locked version of other dependencies also change.
3535
4. In case of a conflict, resolve the conflict according to `help/dependencies.txt`
36-
5. Check if there are any constraints that are obsolete after the dependency update
37-
6. Update the license and notice files of the changed dependencies. See `help/dependencies.txt` for
38-
details.
39-
7. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
40-
8. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
36+
5. Update the license and notice files of the changed dependencies. See `help/dependencies.txt` for details.
37+
6. Run `./gradlew updateLicenses` to re-generate SHA1 checksums of the new jar files.
38+
7. Once in a while, a new version of a dependency will transitively bring in brand-new dependencies.
4139
You'll need to decide whether to keep or exclude them. See `help/dependencies.txt` for details.
4240

43-
=== Reviewing Constraints
41+
=== Constraints and Version Alignment
4442

45-
The constraints are defined in gradle/validation/dependencies.gradle. There, if the updated dependency is listed,
46-
the constraint can be reviewed, updated or removed.
43+
To sync the version of direct and transitive dependencies across the project, we iterate in the `:platform` module
44+
over the libraries defined in `gradle/libs.version.toml` and add them as constraints. Then, we use the module in
45+
main modules like `:solr:api` and `:solr:core` and transitively pass down to all other modules the constraints.
4746

48-
The constraints fall into two "groups". In the first group there are dependency constraints from dependencies
49-
that our project directly includes and require version alignment to sync the versions across all transitive
50-
dependencies. In the second group are dependencies that are only present as transitive dependencies.
51-
There, we try to follow the convention to provide additional information with "which dependencies use what version",
52-
so that the next person reviewing the constraint does not have to look it up. However, this is quite time-consuming
53-
to analyze the dependencies and therefore subject to change.
47+
If a new module does not depend on another module that already includes `:platform` as a platform dependency, it should
48+
explicitly add it to sync the versions with the rest of the project. `:solr:server` is one case where this is necessary.
5449

55-
In order to review a constraint, you have to check if the updated dependency is mentioned in any of the constraints,
56-
either as a reason for another dependency constraint or as the constraint's dependency. Removing temporarily
57-
a constraint, the task writeLocks will fail if the constraint is still required.
50+
=== Addressing Security Vulnerabilities
5851

59-
This process and the constraints of dependencies.gradle are not optimal, as it is quite time-consuming and not obvious
60-
by just looking at it. We just haven't found yet a more efficient way to maintain these constraints.
52+
When it comes to security vulnerabilities that are found in direct or transitive dependencies, the recommended way to
53+
address them is to update the specific library if there is a new release that solves this issue. For both direct and
54+
transitive dependencies, we simply have to update the version as described above.
6155

62-
== Renovate bot Pull Requests
56+
In case it is a transitive dependency that is not directly used, you can simply add it to `libs.versions.toml` as you
57+
would with any other dependency. The dependency resolution approach defined in `:platform` will handle the rest.
58+
Don't forget to add a `# @keep` note with a reference to the vulnerable version and CVE that is fixed with the explicit
59+
definition of the library and new version. This way it is easier to keep track of unreferenced dependencies in our
60+
libraries toml file, and we can clean them up once the libraries using the modules are updated.
6361

64-
The renovate bot may be replaced in the future with dependabot and this section may only be relevant for older
65-
versions (<10.0). See https://lists.apache.org/thread/1sb9ttv3lp57z2yod1htx1fykp5sj73z for updates.
62+
== Renovate bot Pull Requests
6663

6764
A member of the Solr community operates a Github bot running https://github.com/renovatebot/renovate[Renovate], which
6865
files Pull Requests to Solr with dependency upgrade proposals. The PRs are labeled `dependencies` and do include
69-
changes resulting from `./gradlew writeLocks` and `updateLicenses`.
66+
changes resulting from the gradle tasks `resolveAndLockAll` and `updateLicenses`.
7067

7168
Community members and committers can then review, and if manual changes are needed, help bring the PR to completion.
7269
For many dependencies, a changelog is included in the PR text, which may help guide the upgrade decision.
@@ -78,9 +75,13 @@ that will get its own separate Pull Request, so you can choose.
7875
If an upgrade is decided, simply merge (and backport) the PR. To skip an upgrade, close the PR. If a PR is left open,
7976
it will be re-used and auto updated whenever a newer patch- or minor version gets available. Thus, one can reduce
8077
churn from frequently-updated dependencies by delaying merge until a few weeks before a new release. One can also
81-
choose to change to a less frequent schedule or disable the bot, by editing `renovate.json`
78+
choose to change to a less frequent schedule or disable the bot, by editing `renovate.json`.
79+
80+
Please note that Solr version prior to 10.X use a versions resolution plugin that uses `versions.lock` instead of
81+
`libs.version.toml`. Therefore, changes cannot be backported via cherry-pick.
8282

8383
=== Configuring renovate.json
84+
8485
While the bot runs on a https://github.com/solrbot/renovate-github-action[GitHub repo external to the project],
8586
the bot behavior can be tailored by editing `.github/renovate.json` in this project.
8687
See https://docs.renovatebot.com[Renovatebot docs] for available options.

dev-docs/lucene-upgrade.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ Create a new branch locally e.g. `git checkout -b lucene940 -t origin/main` for
3434
+ org.apache.lucene:*=9.4.0
3535
```
3636

37-
### `versions.lock` update
37+
### lockfiles update
3838

3939
```
40-
gradlew :writeLocks
40+
gradlew :resolveAndLockAll
4141
```
4242

4343
### `solr/licenses` update

0 commit comments

Comments
 (0)