Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Locking dependencies doesn't actually work #28874

Open
distinctdan opened this issue Apr 18, 2024 · 3 comments
Open

Locking dependencies doesn't actually work #28874

distinctdan opened this issue Apr 18, 2024 · 3 comments
Labels
a:documentation Documentation content in:dependency-locking re:comprehensibility reasonable errors and warnings, clear dsl, mental overload

Comments

@distinctdan
Copy link

Current Behavior

Changing the version of a dependency doesn't cause the build to fail, even though strict locking is enabled.

Expected Behavior

Gradle sync should fail if the specified version doesn't match the lock file.

Context (optional)

I'm trying to lock down my versions, which has proved to be a lot more difficult than it should be. Multimodule projects are even worse, requiring custom scripts to go generate all the lock files, which is just ridiculous. In Node, dependency locking is on by default and just works. I would like to see gradle make this easier since locking is a best practice for reproducible builds.

Steps to Reproduce

  1. Create a lock file by running ./gradlew dependencies --write-locks from within the folder of my app module. This successfully generates a gradle.lockfile in the same directory.
  2. Change the version of a dependency. In this test, I changed implementation "androidx.hilt:hilt-navigation-compose:1.2.0" to use version 1.0.0.
  3. Run gradle sync, which succeeds.
  4. Build the app, which succeeds.
  5. Also tried Build -> Rebuild Project, which also succeeded.

Interestingly, if I do this in the opposite direction, locking at version 1.0.0 and then upgrading to 1.2.0, I do get a build error. Here are the relevant parts of my build.gradle files:

build.gradle

buildscript {
    configurations.classpath {
        resolutionStrategy.activateDependencyLocking()
    }
}

app/build.gradle

dependencyLocking {
    lockAllConfigurations()
    lockMode = LockMode.STRICT
}

dependencies {
    implementation "androidx.hilt:hilt-navigation-compose:1.2.0"
}

gradle.lockfile (just the relevant line)

androidx.hilt:hilt-navigation-compose:1.2.0=Mirror-Cloud-HardcodedAuth-DebugAndroidTestCompileClasspath,Mirror-Cloud-HardcodedAuth-DebugCompileClasspath,Mirror-Cloud-HardcodedAuth-DebugRuntimeClasspath,Mirror-Cloud-HardcodedAuth-DebugUnitTestCompileClasspath,Mirror-Cloud-HardcodedAuth-DebugUnitTestRuntimeClasspath,Mirror-Cloud-HardcodedAuth-ReleaseCompileClasspath,Mirror-Cloud-HardcodedAuth-ReleaseRuntimeClasspath,Mirror-Cloud-HardcodedAuth-ReleaseUnitTestCompileClasspath,Mirror-Cloud-HardcodedAuth-ReleaseUnitTestRuntimeClasspath,Mirror-Cloud-MdmAuth-DebugAndroidTestCompileClasspath,Mirror-Cloud-MdmAuth-DebugCompileClasspath,Mirror-Cloud-MdmAuth-DebugRuntimeClasspath,Mirror-Cloud-MdmAuth-DebugUnitTestCompileClasspath,Mirror-Cloud-MdmAuth-DebugUnitTestRuntimeClasspath,Mirror-Cloud-MdmAuth-ReleaseCompileClasspath,Mirror-Cloud-MdmAuth-ReleaseRuntimeClasspath,Mirror-Cloud-MdmAuth-ReleaseUnitTestCompileClasspath,Mirror-Cloud-MdmAuth-ReleaseUnitTestRuntimeClasspath,Mirror-Edge-HardcodedAuth-DebugAndroidTestCompileClasspath,Mirror-Edge-HardcodedAuth-DebugCompileClasspath,Mirror-Edge-HardcodedAuth-DebugRuntimeClasspath,Mirror-Edge-HardcodedAuth-DebugUnitTestCompileClasspath,Mirror-Edge-HardcodedAuth-DebugUnitTestRuntimeClasspath,Mirror-Edge-HardcodedAuth-ReleaseCompileClasspath,Mirror-Edge-HardcodedAuth-ReleaseRuntimeClasspath,Mirror-Edge-HardcodedAuth-ReleaseUnitTestCompileClasspath,Mirror-Edge-HardcodedAuth-ReleaseUnitTestRuntimeClasspath,Mirror-Edge-MdmAuth-DebugAndroidTestCompileClasspath,Mirror-Edge-MdmAuth-DebugCompileClasspath,Mirror-Edge-MdmAuth-DebugRuntimeClasspath,Mirror-Edge-MdmAuth-DebugUnitTestCompileClasspath,Mirror-Edge-MdmAuth-DebugUnitTestRuntimeClasspath,Mirror-Edge-MdmAuth-ReleaseCompileClasspath,Mirror-Edge-MdmAuth-ReleaseRuntimeClasspath,Mirror-Edge-MdmAuth-ReleaseUnitTestCompileClasspath,Mirror-Edge-MdmAuth-ReleaseUnitTestRuntimeClasspath,Prod-Cloud-HardcodedAuth-DebugAndroidTestCompileClasspath,Prod-Cloud-HardcodedAuth-DebugCompileClasspath,Prod-Cloud-HardcodedAuth-DebugRuntimeClasspath,Prod-Cloud-HardcodedAuth-DebugUnitTestCompileClasspath,Prod-Cloud-HardcodedAuth-DebugUnitTestRuntimeClasspath,Prod-Cloud-HardcodedAuth-ReleaseCompileClasspath,Prod-Cloud-HardcodedAuth-ReleaseRuntimeClasspath,Prod-Cloud-HardcodedAuth-ReleaseUnitTestCompileClasspath,Prod-Cloud-HardcodedAuth-ReleaseUnitTestRuntimeClasspath,Prod-Cloud-MdmAuth-DebugAndroidTestCompileClasspath,Prod-Cloud-MdmAuth-DebugCompileClasspath,Prod-Cloud-MdmAuth-DebugRuntimeClasspath,Prod-Cloud-MdmAuth-DebugUnitTestCompileClasspath,Prod-Cloud-MdmAuth-DebugUnitTestRuntimeClasspath,Prod-Cloud-MdmAuth-ReleaseCompileClasspath,Prod-Cloud-MdmAuth-ReleaseRuntimeClasspath,Prod-Cloud-MdmAuth-ReleaseUnitTestCompileClasspath,Prod-Cloud-MdmAuth-ReleaseUnitTestRuntimeClasspath,Prod-Edge-HardcodedAuth-DebugAndroidTestCompileClasspath,Prod-Edge-HardcodedAuth-DebugCompileClasspath,Prod-Edge-HardcodedAuth-DebugRuntimeClasspath,Prod-Edge-HardcodedAuth-DebugUnitTestCompileClasspath,Prod-Edge-HardcodedAuth-DebugUnitTestRuntimeClasspath,Prod-Edge-HardcodedAuth-ReleaseCompileClasspath,Prod-Edge-HardcodedAuth-ReleaseRuntimeClasspath,Prod-Edge-HardcodedAuth-ReleaseUnitTestCompileClasspath,Prod-Edge-HardcodedAuth-ReleaseUnitTestRuntimeClasspath,Prod-Edge-MdmAuth-DebugAndroidTestCompileClasspath,Prod-Edge-MdmAuth-DebugCompileClasspath,Prod-Edge-MdmAuth-DebugRuntimeClasspath,Prod-Edge-MdmAuth-DebugUnitTestCompileClasspath,Prod-Edge-MdmAuth-DebugUnitTestRuntimeClasspath,Prod-Edge-MdmAuth-ReleaseCompileClasspath,Prod-Edge-MdmAuth-ReleaseRuntimeClasspath,Prod-Edge-MdmAuth-ReleaseUnitTestCompileClasspath,Prod-Edge-MdmAuth-ReleaseUnitTestRuntimeClasspath,implementationDependenciesMetadata

Gradle version

8.7

Build scan URL (optional)

No response

Your Environment (optional)

No response

@ov7a
Copy link
Member

ov7a commented Apr 22, 2024

This is actually a documentation issue.

When you have 1.2.0 version in the lockfile and declare 1.0.0 in build script, the version is upgraded automatically to 1.2.0 by the dependency resolution mechanism. However, when you have 1.0.0 in the lockfile and try to declare 1.2.0, we can't upgrade to a newer version since the lock uses "strictly" as a modifier.

@ov7a ov7a added the re:comprehensibility reasonable errors and warnings, clear dsl, mental overload label Apr 22, 2024
@distinctdan
Copy link
Author

Thanks for the explanation, I think I understand what's going on now. However, from a user experience point of view, my expectation was that any change in a build script version should cause a build failure if I don't update the lockfile. Even though what it's doing now should technically work assuming packages follow semantic versioning, it differs from other package managers I've used, so it just feels like another "gotcha" that you have to know about. So in my case, I'm guessing if I added "strictly" to my 1.0.0, then that would cause it to report an error?

I'm toying with the idea of how to make locking completely automatic. I'm not 100% sure this would work, but perhaps something where gradle saves the input dependencies in addition to the resolved dependencies, and if the inputs change, then automatically update the lock file for the changed dependencies, like npm does when you run an npm install. Gradle already supports updating the lock for a changed dependency, but you currently have to run a command and manually specify it as an argument, so I'm picturing an automatic version instead. Again, this is more of a separate idea, I may consider submitting a separate feature request for it.

For this issue, it sounds like it actually is working as intended, so we can probably close this. Would there be any docs updates that should be made? It is slightly unintuitive that the build fails for upgrades but not downgrades, even though it does still work, but maybe not many other users have run into this.

@ov7a
Copy link
Member

ov7a commented Apr 23, 2024

For this issue, it sounds like it actually is working as intended, so we can probably close this. Would there be any docs updates that should be made?

Let's keep it open. The docs should be improved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:documentation Documentation content in:dependency-locking re:comprehensibility reasonable errors and warnings, clear dsl, mental overload
Projects
None yet
Development

No branches or pull requests

2 participants