To everyone struggling with this, I have a partial answer.
To people recommending other tools:
Semgrep’s vulnerability reachability, interface, and APIs are better than Snyk’s from what I’ve seen. Snyk is also a lot more expensive.
Going the open source route for SAST/SCA is time consuming, with a lot of work that falls on application security to dig through CVE noise and fine tune the tools, with less mature programs, this might not be an option.
You can’t change what SCA/SAST vendors require for their tools to work, and they’re all terrible in some way imo.
The following script, when added to a build.gradle file will generate new lockfiles during every build, and if there are changes, it’ll commit them as well. Since gitops in gitlab pipelines are problematic, I’ve put the onus on the dev machine to deliver new gradle lockfiles
For multiple project builds, put this in each build file, OR create a seperate file and reference it in the build file
// Automatically handle dependency locking, lockfile generation, lockfile cleanup, and git add
dependencyLocking {
lockAllConfigurations()
}
// Check for CI environment variables in the configuration phase
val ciEnvVars = listOf("CI", "GITLAB_CI", "CI_PIPELINE_ID")
val isCI = ciEnvVars.any { System.getenv(it) != null }
// Define the lockfiles task
tasks.register("lockfiles") {
if (isCI) {
logger.lifecycle("Skipping lockfiles task in CI environment.")
this.enabled = false // Disable the task in CI environment
} else {
doFirst {
// Remove the lockfile in the current directory
try {
delete(fileTree(".").matching { include("*.lockfile") })
logger.lifecycle("Deleted lockfile in the current directory.")
} catch (e: Exception) {
logger.warn("Warning: Failed to delete lockfile due to: ${e.message}")
}
// Try to generate or update lockfiles
try {
exec {
commandLine = listOf("gradle", "dependencies", "--write-locks")
}
logger.lifecycle("Lockfiles successfully updated or created.")
} catch (e: Exception) {
logger.warn("Warning: Lockfile was not created or updated due to: ${e.message}")
}
// Try to add the lockfiles to git
try {
exec {
commandLine = listOf("git", "add", "*.lockfile")
}
logger.lifecycle("Lockfiles successfully added to git.")
} catch (e: Exception) {
logger.warn("Warning: Lockfile was not added to git due to: ${e.message}")
}
}
}
}
// Make all tasks depend on 'lockfiles', except 'lockfiles' itself to prevent circular dependency
tasks.configureEach {
if (!listOf("lockfiles", "dependencies").contains(name)) {
dependsOn(tasks.named("lockfiles"))
}
}
I know OP’s specific ask was to “not honor” the lockfile, but I feel like this is where OP might have gotten if they continued to struggle with this issue.