Gradle - throw exception if project still has SNAPSHOT dependencies

Viewed 1075

I want to fail the gradle build if the current project still has snapshot dependencies.

My code so far only looks for java dependencies, missing the .NET ones so it only works for java projects. I want to make it work for all projects.

def addSnapshotCheckingTask(Project project) {
    project.tasks.withType(JavaCompile) { compileJava ->
        project.tasks.create(compileJava.name + 'SnapshotChecking', {
            onlyIf {
                project.ext.isRelease || project.ext.commitVersion != null
            }
            compileJava.dependsOn it
            doLast {
                def snapshots = compileJava.classpath
                        .filter { project.ext.isRelease || !(it.path ==~ /(?i)${project.rootProject.projectDir.toString().replace('\\', '\\\\')}.*build.libs.*/) }
                        .filter { it.path =~ /(?i)-SNAPSHOT/  }
                        .collect { it.name }
                        .unique()
                if (!snapshots.isEmpty()) {
                    throw new GradleException("Please get rid of snapshots for following dependencies before releasing $snapshots")
                }
            }
        })
    }
}

I need some help in generifying this snippet to be applicable to all types of dependencies(not just java)

Thanks!

L.E. Could something like this work? https://discuss.gradle.org/t/how-can-i-check-for-snapshot-dependencies-and-throw-an-exception-if-some-where-found/4064

3 Answers

So I got it working by tweaking a bit the response of @lance-java, it looks something like:

    Task snapshotCheckingTask = project.tasks.create('snapshotCheckingTask', {
        doLast {
            def snapshots = new ArrayList()
            def projectConfigurations = project.configurations.findAll { true }

            projectConfigurations.each {
                if (it.isCanBeResolved()) {
                    it.resolvedConfiguration.resolvedArtifacts.each {
                        if (it.moduleVersion.id.version.endsWith('-SNAPSHOT')) {
                            snapshots.add(it)
                        }
                    }
                }
            }
            if (!snapshots.isEmpty()) {
                throw new GradleException("Please get rid of snapshots for following dependencies before releasing $snapshots")
            } else {
                throw new GradleException("Hah, no snapshots!")
            }
        }
    })
    project.tasks.release.dependsOn snapshotCheckingTask

cc @Eugene

P.S. However, this does not take into account .net dependencies

Here's what I came up with using Gradle 7.2 and the modern Kotlin DSL:

tasks.register("releaseEnforcement") {
    group = "verification"
    description = "Check whether there are any SNAPSHOT dependencies."
    doLast {
        val violations = project.configurations
            .filter { it.name == "compileClasspath" || it.name == "runtimeClasspath" }
            .flatMap { configuration ->
                configuration.resolvedConfiguration.resolvedArtifacts
                    .map { it.moduleVersion.id }
                    .filter { it.version.endsWith("-SNAPSHOT") }
            }
            .toSet()
        if (violations.isNotEmpty()) {
            error("Snapshot dependencies found:\n\n${violations.joinToString(separator = "\n")}")
        }
    }
}
Related