Skip to content

Commit

Permalink
DT companion Plugin v1.0.0 (#1)
Browse files Browse the repository at this point in the history
* Refactor: Move Property Resolution from Configuration to Execution Time

This commit addresses an issue where properties were being resolved during configuration time
By transitioning the property resolution process to execution time, we leverage the full potential of Gradle properties.
This change enhances build performance and optimizes resource usage by preventing premature property resolution.

* wip: add default task tests

* wip: add GenerateVex integrationTest

* wip: add meta task and task group/desc to all tasks

* fix runDepTrackWorkflow Task execution order

* wip: add integrationTest with docker compose

* Refactor build.gradle.kts to use Gradle version catalogs for dependencies and plugins

* Refactor build.gradle.kts to enhance test setup and improve code organization

* wip: replace file input/output string with RegularFileProperty

* wip: rename package name and add readme

* wip: configurate gradle plugin publish

* wip: rename class name, remove unnecessary return types

* feat: add plugin properties handler

added a task for generating plugin.properties file
inspired by the cyclondx sbom gradle plugin

* remove unused import

* Refactor toNonNullPairList methods in UploadSBOM and UploadVex classes

The toNonNullPairList methods in the UploadSBOM and UploadVex classes have been refactored for simplicity and readability.
The changes include replacing the previous approach of using a mutable list and conditionally adding items with a simpler,
more direct approach of creating a list and filtering out any null values.

* Refactor form data handling in UploadSBOM and UploadVex tasks

* chore:(docker-compose) remove default config comments

* feat: add workflow for tests/publish

---------

Co-authored-by: nvima <mirwald@liftric.com>
  • Loading branch information
nvima and nvima authored Jul 3, 2023
1 parent fa4ce90 commit 575b247
Show file tree
Hide file tree
Showing 37 changed files with 15,789 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/pre-merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Pre Merge Checks

on:
push:
branches:
- main
pull_request:
branches:
- '*'

jobs:
gradle:
runs-on: ubuntu-latest
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache
uses: gradle/gradle-build-action@v2
- name: Validate
run: ./gradlew check validatePlugins --continue
- name: Integration Test
run: ./gradlew integrationTest --info
24 changes: 24 additions & 0 deletions .github/workflows/publish-plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Publish to Gradle Plugin Portal

on:
push:
tags:
- '*'

jobs:
gradle:
runs-on: ubuntu-latest
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache
uses: gradle/gradle-build-action@v2
- name: Validate
run: ./gradlew check validatePlugins --continue
- name: Integration Test
run: ./gradlew integrationTest
- name: Publish
run: ./gradlew publishPlugins
44 changes: 44 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

.idea/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Gradle Dependency Track Companion w Plugin

This Gradle plugin is designed to ease the process of working with [Dependency Track](https://dependencytrack.org/), a Continuous SBOM Analysis Platform. With this plugin, you can automate the upload process of SBOM files, generate Vex files for component or vulnerability suppression, and more.

## Features

The plugin offers several tasks:

- `generateVex`: Generates VEX file.
- `getOutdatedDependencies`: Gets outdated dependencies.
- `getSuppressedVuln`: Gets suppressed vulnerabilities.
- `runDepTrackWorkflow`: Runs `uploadSbom`, `generateVex` and `uploadVex` tasks for CI/CD.
- `uploadSbom`: Uploads SBOM file.
- `uploadVex`: Uploads VEX file.

### Task Configuration

Each task requires certain inputs which are to be specified in your `build.gradle.kts`. The configuration for each task is as follows:

#### uploadSbom

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `inputFile`: *Optional* - Default: build/reports/bom.json
- `uploadSbom`: [Dependency Track BOM Upload Api Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/bom/operation/UploadBom)

#### generateVex

- `vexComponent`: *Optional* - For suppressing vulnerabilities in one component
- `vexVulnerability`: *Optional* - For suppressing vulnerabilities in all components
- `inputFile`: *Optional* - Default: build/reports/bom.json
- `outputFile`: *Optional* - Default: build/reports/vex.json

#### uploadVex

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `outputFile`: *Optional* (Default "build/reports/vex.json")
- `uploadVex`: [Dependency Track VEX Upload API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/vex/operation/uploadVex)

#### runDepTrackWorkflow

- This task requires configuration for `uploadSbom`, `generateVex`, and `uploadVex`.
- Runs `uploadSbom`, `generateVex` and `uploadVex` tasks for CI/CD.

#### getOutdatedDependencies

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `getOutdatedDependencies`: [Dependency Track Project Lookup API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/project/operation/getProjectByNameAndVersion)

#### getSuppressedVuln

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `getSuppressedVuln`: [Dependency Track Project Lookup API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/project/operation/getProjectByNameAndVersion)

## Example Configuration

Here's how you can configure all tasks:

```kotlin
import com.liftric.dtcp.extensions.*
import org.cyclonedx.model.vulnerability.Vulnerability

val version: String by project
val name: String by project
dependencyTrackCompanion {
url.set("https://api.dtrack.example.com")
apiKey.set(System.getenv("DT_API_KEY"))
uploadSBOM {
autoCreate.set(true)
projectName.set(name)
projectVersion.set(version)
parentName.set(name)
}
uploadVex {
projectName.set(name)
projectVersion.set(version)
}
getOutdatedDependencies {
projectName.set(name)
projectVersion.set(version)
}
getSuppressedVuln {
projectName.set(name)
projectVersion.set(version)
}
vexComponent {
purl.set("pkg:maven/org.eclipse.jetty/jetty-http@9.4.49.v20220914?type=jar")
vulnerability {
id.set("CVE-2023-26048")
source.set("NVD")
analysis.set(Vulnerability.Analysis.State.FALSE_POSITIVE)
}
}
vexVulnerability {
id.set("CVE-2020-8908")
source.set("NVD")
analysis.set(Vulnerability.Analysis.State.RESOLVED)
detail.set("This is resolved")
}
}
```

## License

This Gradle Dependency Track Plugin is released under MIT License.

This project is not a derivative of [Dependency Track](https://dependencytrack.org/), but a tool that interacts with it. Please note that Dependency Track is released under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Refer to their respective licenses for more information.
99 changes: 99 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
@Suppress("DSL_SCOPE_VIOLATION") // IntelliJ incorrectly marks libs as not callable
plugins {
`maven-publish`
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.dockerCompose)
alias(libs.plugins.gradlePluginPublish)
}

repositories {
mavenCentral()
gradlePluginPortal()
}

dockerCompose {
// Docker Compose v1 is needed for this Plugin to work
useComposeFiles.set(listOf("docker-compose.yml"))
waitForTcpPorts.set(true)
captureContainersOutput.set(true)
stopContainers.set(true)
removeContainers.set(true)
buildBeforeUp.set(true)
}

val integrationTest = sourceSets.create("integrationTest")
tasks {
val test by existing
withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
systemProperty("org.gradle.testkit.dir", gradle.gradleUserHomeDir)
}

val integrationTestTask = register<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = integrationTest.output.classesDirs
classpath = integrationTest.runtimeClasspath
mustRunAfter(test)
useJUnitPlatform()
}
dockerCompose.isRequiredBy(integrationTestTask)

val propertiesTask = register<WriteProperties>("writePluginProperties") {
outputFile = file("src/main/resources/plugin.properties")
property("vendor", project.property("pluginVendor").toString())
property("name", project.property("pluginName").toString())
property("version", project.property("pluginVersion").toString())
}
}

tasks.named("build") {
dependsOn("writePluginProperties")
}


gradlePlugin {
testSourceSets(integrationTest)
plugins {
create("dependency-track-companion-plugin") {
id = "${project.property("pluginGroup")}.${project.property("pluginName")}"
implementationClass = "${project.property("pluginGroup")}.dtcp.DepTrackCompanionPlugin"
displayName = project.property("pluginName").toString()
version = project.property("pluginVersion").toString()
group = project.property("pluginGroup").toString()
}
}
}
pluginBundle {
website = "https://github.com/Liftric/dependency-track-companion-plugin"
vcsUrl = "https://github.com/Liftric/dependency-track-companion-plugin"
description = "Common tasks for Dependency Track interaction, like SBOM upload or VEX Generation"
tags = listOf("dependency", "track", "sbom", "vex", "upload", "generate")
}


dependencies {
implementation(platform(libs.kotlinBom))
implementation(libs.kotlinStdlibJdk8)
implementation(libs.cyclonedxCoreJava)
implementation(libs.ktorClientCio)
implementation(libs.ktorClientCore)
implementation(libs.ktorClientJson)
implementation(libs.ktorClientSerialization)
implementation(libs.ktorClientContentNegotiation)
implementation(libs.ktorSerializationKotlinxJson)
implementation(libs.kotlinReflect)

testImplementation(libs.junitJupiter)

"integrationTestImplementation"(gradleTestKit())
"integrationTestImplementation"(libs.cyclonedxCoreJava)
"integrationTestImplementation"(libs.junitJupiter)
"integrationTestImplementation"(libs.ktorClientCio)
"integrationTestImplementation"(libs.ktorClientContentNegotiation)
"integrationTestImplementation"(libs.ktorSerializationKotlinxJson)
}
41 changes: 41 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: '3.7'

#####################################################
# This Docker Compose file contains two services
# Dependency-Track API Server
# Dependency-Track FrontEnd
#####################################################

volumes:
dependency-track:

services:
dtrack-apiserver:
image: dependencytrack/apiserver

environment:
- ALPINE_ENFORCE_AUTHENTICATION=false
- ALPINE_ENFORCE_AUTHORIZATION=true
deploy:
resources:
limits:
memory: 12288m
reservations:
memory: 8192m
restart_policy:
condition: on-failure
ports:
- '8081:8080'
volumes:
- 'dependency-track:/data'
restart: unless-stopped

dtrack-frontend:
image: dependencytrack/frontend
depends_on:
- dtrack-apiserver
environment:
- API_BASE_URL=http://localhost:8081
ports:
- "8080:8080"
restart: unless-stopped
5 changes: 5 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kotlin.code.style=official
pluginGroup=com.liftric
pluginVersion=1.0.0
pluginName=dependency-track-companion-plugin
pluginVendor=Liftric
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 575b247

Please sign in to comment.