diff --git a/.github/workflows/check-sidecar-tasks.sh b/.github/workflows/check-sidecar-tasks.sh new file mode 100755 index 00000000..040b4785 --- /dev/null +++ b/.github/workflows/check-sidecar-tasks.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -eu + +make sidecar-tasks +if ! git diff --quiet deploy/central/tasks-chart/templates; then + echo "Sidecar Tasks are not up-to-date! Run 'make sidecar-tasks' to update." + exit 1 +else + echo "Sidecar Tasks are up-to-date." +fi diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 82bd873f..ea131328 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -157,6 +157,9 @@ jobs: uses: actions/setup-go@v2 with: go-version: 1.16 + - + name: Check if sidecar tasks are up-to-date + run: ./.github/workflows/check-sidecar-tasks.sh - name: Check if docs are up-to-date run: ./.github/workflows/check-docs.sh diff --git a/Makefile b/Makefile index 7ea94f8e..948bf8ff 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,11 @@ start-local-env: cd scripts && ./start-local-env.sh .PHONY: start-local-env +## Render sidecar task variants. +sidecar-tasks: + go run cmd/sidecar-tasks/main.go +.PHONY: sidecar-tasks + ## Render documentation for tasks. docs: go run cmd/docs/main.go diff --git a/cmd/sidecar-tasks/main.go b/cmd/sidecar-tasks/main.go new file mode 100644 index 00000000..ee82f343 --- /dev/null +++ b/cmd/sidecar-tasks/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "strings" + + tekton "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func main() { + tasksWithSidecars := []string{ + "ods-build-go", + "ods-build-gradle", + "ods-build-python", + "ods-build-typescript", + } + t, err := parseTasks(tasksWithSidecars) + if err != nil { + log.Fatal(err) + } + adjustTasks(t) + err = writeTasks(t) + if err != nil { + log.Fatal(err) + } +} + +func parseTasks(taskNames []string) (map[string]*tekton.ClusterTask, error) { + tasks := map[string]*tekton.ClusterTask{} + for _, task := range taskNames { + fmt.Printf("Parsing task %s ...\n", task) + b, err := ioutil.ReadFile(fmt.Sprintf("deploy/central/tasks-chart/templates/task-%s.yaml", task)) + if err != nil { + return nil, err + } + var t tekton.ClusterTask + err = yaml.Unmarshal(b, &t) + if err != nil { + return nil, err + } + tasks[task] = &t + } + return tasks, nil +} + +func adjustTasks(tasks map[string]*tekton.ClusterTask) { + for name, t := range tasks { + fmt.Printf("Adding sidecar to task %s ...\n", name) + nameParts := strings.Split(t.Name, "{{") + t.Name = strings.Replace(t.Name, "{{.Values.taskSuffix}}", "-with-sidecar{{.Values.taskSuffix}}", 1) + t.Spec.Description = t.Spec.Description + ` +**Sidecar variant!** Use this task if you need to run a container next to the build task. +For example, this could be used to run a database to allow for integration tests. +The sidecar image to must be supplied via ` + "`sidecar-image`" + `. +Apart from the sidecar, the task is an exact copy of ` + "`" + nameParts[0] + "`" + `.` + t.Spec.Params = append(t.Spec.Params, tekton.ParamSpec{ + Name: "sidecar-image", + Description: "Image to use for sidecar", + Type: tekton.ParamTypeString, + }) + t.Spec.Sidecars = []tekton.Sidecar{ + { + Container: corev1.Container{ + Name: "sidecar", + Image: "$(params.sidecar-image)", + }, + }, + } + } +} + +func writeTasks(tasks map[string]*tekton.ClusterTask) error { + for name, t := range tasks { + fmt.Printf("Writing sidecar task %s ...\n", name) + out, err := yaml.Marshal(t) + if err != nil { + return err + } + out = append([]byte("# Generated by cmd/sidecar-tasks/main.go; DO NOT EDIT.\n"), out...) + err = ioutil.WriteFile( + fmt.Sprintf("deploy/central/tasks-chart/templates/task-%s-with-sidecar.yaml", name), + out, 0644, + ) + if err != nil { + return err + } + } + return nil +} diff --git a/deploy/central/tasks-chart/templates/task-ods-build-go-with-sidecar.yaml b/deploy/central/tasks-chart/templates/task-ods-build-go-with-sidecar.yaml new file mode 100644 index 00000000..c652070e --- /dev/null +++ b/deploy/central/tasks-chart/templates/task-ods-build-go-with-sidecar.yaml @@ -0,0 +1,133 @@ +# Generated by cmd/sidecar-tasks/main.go; DO NOT EDIT. +apiVersion: tekton.dev/v1beta1 +kind: ClusterTask +metadata: + creationTimestamp: null + name: ods-build-go-with-sidecar{{.Values.taskSuffix}} +spec: + description: |- + Builds Go (module) applications. + + The following steps are executed: + + - check proper formatting against gofmt + - linting using golangci-lint + - build (using `go-os` and `go-arch` parameters) + - test execution + + Tests exclude the vendor directory. Test results are converted into xUnit format. + + Both xUnit report and coverage report are placed into .ods/artifacts. + + After tests ran successfully, the application source code is scanned by SonarQube. + When `sonar-quality-gate` is set to `true`, the task will fail if the quality gate + is not passed. If SonarQube is not desired, it can be disabled via `sonar-skip`. + The SonarQube scan will include parameters to perform a pull request analysis if + there is an open pull request for the branch being built. Pull request decoration + in Bitbucket is done automatically by SonarQube provided the ALM integration is setup + properly in SonarQube. + + **Sidecar variant!** Use this task if you need to run a container next to the build task. + For example, this could be used to run a database to allow for integration tests. + The sidecar image to must be supplied via `sidecar-image`. + Apart from the sidecar, the task is an exact copy of `ods-build-go`. + params: + - default: . + description: | + Working directory. The path must be relative to the root of the repository, + without leading `./` and trailing `/`. + name: working-dir + type: string + - default: "false" + description: Whether to enable CGO. When not enabled the build will set `CGO_ENABLED=0`. + name: enable-cgo + type: string + - default: linux + description: '`GOOS` variable (the execution operating system such as `linux`, + `windows`).' + name: go-os + type: string + - default: amd64 + description: '`GOARCH` variable (the execution architecture such as `arm`, `amd64`).' + name: go-arch + type: string + - default: docker + description: Path to the directory into which the resulting Go binary should be + copied, relative to `working-dir`. This directory may then later be used as + Docker context for example. + name: output-dir + type: string + - default: "" + description: Script to execute before running tests, relative to the working directory. + name: pre-test-script + type: string + - default: "false" + description: Whether the SonarQube quality gate needs to pass for the task to + succeed. + name: sonar-quality-gate + type: string + - default: "false" + description: Whether to skip SonarQube analysis or not. + name: sonar-skip + type: string + - description: Image to use for sidecar + name: sidecar-image + type: string + sidecars: + - image: $(params.sidecar-image) + name: sidecar + resources: {} + steps: + - env: + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-go-toolset:{{.Values.imageTag}}' + name: build-go-binary + resources: {} + script: |2 + + # build-go is build/package/scripts/build-go.sh. + build-go \ + --working-dir=$(params.working-dir) \ + --enable-cgo=$(params.enable-cgo) \ + --go-os=$(params.go-os) \ + --go-arch=$(params.go-arch) \ + --pre-test-script=$(params.pre-test-script) \ + --output-dir=$(params.output-dir) \ + --debug=${DEBUG} + workingDir: $(workspaces.source.path) + - env: + - name: SONAR_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-sonar + - name: SONAR_AUTH_TOKEN + valueFrom: + secretKeyRef: + key: password + name: ods-sonar-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-sonar:{{.Values.imageTag}}' + name: scan-with-sonar + resources: {} + script: | + if [ "$(params.sonar-skip)" = "true" ]; then + echo "Skipping SonarQube analysis" + else + mkdir -p .ods/artifacts/sonarqube-analysis + # sonar is built from cmd/sonar/main.go. + sonar \ + -working-dir=$(params.working-dir) \ + -quality-gate=$(params.sonar-quality-gate) + fi + workingDir: $(workspaces.source.path) + workspaces: + - name: source diff --git a/deploy/central/tasks-chart/templates/task-ods-build-gradle-with-sidecar.yaml b/deploy/central/tasks-chart/templates/task-ods-build-gradle-with-sidecar.yaml new file mode 100644 index 00000000..7f3e28ac --- /dev/null +++ b/deploy/central/tasks-chart/templates/task-ods-build-gradle-with-sidecar.yaml @@ -0,0 +1,187 @@ +# Generated by cmd/sidecar-tasks/main.go; DO NOT EDIT. +apiVersion: tekton.dev/v1beta1 +kind: ClusterTask +metadata: + creationTimestamp: null + name: ods-build-gradle-with-sidecar{{.Values.taskSuffix}} +spec: + description: |2- + + Builds Gradle applications. + + The following steps are executed: + + - build gradle application, using `gradlew clean build`, which includes tests execution and coverage report generation + - SonarQube quality scan + + Notes: + + - tests exclude the vendor directory. + - test results are converted into xUnit format. + - both xUnit report and coverage report are placed into .ods/artifacts. + + Environment variables available: + + - `ODS_OUTPUT_DIR`: this environment variable points to the folder + that this build expects generated application artifacts to be copied to. + The gradle script should read it and copy there the generated artifacts. + - `NEXUS_* env vars`: `NEXUS_HOST`, `NEXUS_USER` and `NEXUS_PASSWORD` + are available and should be read by the gradle script. + + To enable the gradle script to copy the generated application artifacts script follow these steps: + + - read the environment variable `ODS_OUTPUT_DIR` in the buildscript section of the gradle script: + ``` + buildscript { + ext { + outputDir = System.getenv('ODS_OUTPUT_DIR') + } + } + ``` + - customize the jar tasks to set the destination directory + ``` + jar { + println("Set application jar name to 'app'") + archiveBaseName = 'app' + if (outputDir != null) { + println("Set destinationDirectory to '${projectDir}/${outputDir}'") + destinationDirectory = file("${projectDir}/${outputDir}") + } + } + ``` + + To create a coverage report be sure that you add to `gradle.properties` the required + configuration. For example to enable Jacoco coverage repot you will need to: + + - add `jacoco` plugin: + ``` + plugins { + id 'application' + id 'jacoco' + } + ``` + - add task `jacocoTestReport`: + ``` + jacocoTestReport { + reports { + xml.enabled true + } + } + ``` + - add `finalizedBy jacocoTestReport` to the task `test`: + ``` + tasks.named('test') { + useJUnitPlatform() + finalizedBy jacocoTestReport + } + ``` + + To configure SonarQube the project has to include at the root folder of the project the property file `sonar-project.properties`. + Otherwise the SonarQube scan will fail. + Following example properties show default working values for a standard gradle project: + ``` + sonar.sources=src + sonar.java.binaries=build/classes + sonar.junit.reportPaths=build/test-results/test + sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml + ``` + + When `sonar-quality-gate` is set to `true`, the task will fail if the quality gate + is not passed. If SonarQube is not desired, it can be disabled via `sonar-skip`. + The SonarQube scan will include parameters to perform a pull request analysis if + there is an open pull request for the branch being built. Pull request decoration + in Bitbucket is done automatically by SonarQube provided the ALM integration is setup + properly in SonarQube. + + **Sidecar variant!** Use this task if you need to run a container next to the build task. + For example, this could be used to run a database to allow for integration tests. + The sidecar image to must be supplied via `sidecar-image`. + Apart from the sidecar, the task is an exact copy of `ods-build-gradle`. + params: + - default: . + description: | + Working directory. The path must be relative to the root of the repository, + without leading `./` and trailing `/`. + name: working-dir + type: string + - default: "" + description: Additional gradle tasks to be passed to the gradle build. (default + tasks called are `clean` and `build`). + name: gradle-additional-tasks + type: string + - default: "" + description: 'Options to be passed to the gradle build. (See ref: https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_debugging)' + name: gradle-options + type: string + - default: docker + description: Path to the directory into which the resulting Java application jar + should be copied, relative to `working-dir`. This directory may then later be + used as Docker context for example. + name: output-dir + type: string + - default: "false" + description: Whether the SonarQube quality gate needs to pass for the task to + succeed. + name: sonar-quality-gate + type: string + - default: "false" + description: Whether to skip SonarQube analysis or not. + name: sonar-skip + type: string + - description: Image to use for sidecar + name: sidecar-image + type: string + sidecars: + - image: $(params.sidecar-image) + name: sidecar + resources: {} + steps: + - env: + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-gradle-toolset:{{.Values.imageTag}}' + name: build-gradle-binary + resources: {} + script: | + # build-gradle is build/package/scripts/build-gradle.sh. + build-gradle \ + --working-dir=$(params.working-dir) \ + --output-dir=$(params.output-dir) \ + --gradle-additional-tasks=$(params.gradle-additional-tasks) \ + --gradle-options=$(params.gradle-options) + workingDir: $(workspaces.source.path) + - env: + - name: SONAR_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-sonar + - name: SONAR_AUTH_TOKEN + valueFrom: + secretKeyRef: + key: password + name: ods-sonar-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-sonar:{{.Values.imageTag}}' + name: scan-with-sonar + resources: {} + script: | + if [ "$(params.sonar-skip)" = "true" ]; then + echo "Skipping SonarQube analysis" + else + mkdir -p .ods/artifacts/sonarqube-analysis + # sonar is built from cmd/sonar/main.go. + sonar \ + -working-dir=$(params.working-dir) \ + -quality-gate=$(params.sonar-quality-gate) + fi + workingDir: $(workspaces.source.path) + workspaces: + - name: source diff --git a/deploy/central/tasks-chart/templates/task-ods-build-python-with-sidecar.yaml b/deploy/central/tasks-chart/templates/task-ods-build-python-with-sidecar.yaml new file mode 100644 index 00000000..8d315afc --- /dev/null +++ b/deploy/central/tasks-chart/templates/task-ods-build-python-with-sidecar.yaml @@ -0,0 +1,116 @@ +# Generated by cmd/sidecar-tasks/main.go; DO NOT EDIT. +apiVersion: tekton.dev/v1beta1 +kind: ClusterTask +metadata: + creationTimestamp: null + name: ods-build-python-with-sidecar{{.Values.taskSuffix}} +spec: + description: |- + ODS Build Python applications + **Sidecar variant!** Use this task if you need to run a container next to the build task. + For example, this could be used to run a database to allow for integration tests. + The sidecar image to must be supplied via `sidecar-image`. + Apart from the sidecar, the task is an exact copy of `ods-build-python`. + params: + - default: . + description: | + Working directory. The path must be relative to the root of the repository, + without leading `./` and trailing `/`. + name: working-dir + type: string + - default: docker + description: Path to the directory into which outputs should be placed, relative + to `working-dir`. This directory may then later be used as Docker context for + example. + name: output-dir + type: string + - default: "120" + description: Maximum line length. + name: max-line-length + type: string + - default: "" + description: Script to execute before running tests, relative to the working directory. + name: pre-test-script + type: string + - default: "false" + description: Whether quality gate needs to pass. + name: sonar-quality-gate + type: string + - default: "false" + description: Whether to skip the SonarQube analysis or not. + name: sonar-skip + type: string + - description: Image to use for sidecar + name: sidecar-image + type: string + sidecars: + - image: $(params.sidecar-image) + name: sidecar + resources: {} + steps: + - env: + - name: NEXUS_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-nexus + - name: NEXUS_USERNAME + valueFrom: + secretKeyRef: + key: username + name: ods-nexus-auth + - name: NEXUS_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ods-nexus-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-python-toolset:{{.Values.imageTag}}' + name: build-python + resources: {} + script: |2 + + # build-python is build/package/scripts/build-python.sh. + build-python \ + --working-dir=$(params.working-dir) \ + --max-line-length=$(params.max-line-length) \ + --pre-test-script=$(params.pre-test-script) \ + --output-dir=$(params.output-dir) \ + --debug=${DEBUG} + workingDir: $(workspaces.source.path) + - env: + - name: SONAR_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-sonar + - name: SONAR_AUTH_TOKEN + valueFrom: + secretKeyRef: + key: password + name: ods-sonar-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-sonar:{{.Values.imageTag}}' + name: scan-with-sonar + resources: {} + script: | + if [ "$(params.sonar-skip)" = "true" ]; then + echo "Skipping SonarQube analysis" + else + mkdir -p .ods/artifacts/sonarqube-analysis + # sonar is built from cmd/sonar/main.go. + sonar \ + -working-dir=$(params.working-dir) \ + -quality-gate=$(params.sonar-quality-gate) + fi + workingDir: $(workspaces.source.path) + workspaces: + - name: source diff --git a/deploy/central/tasks-chart/templates/task-ods-build-typescript-with-sidecar.yaml b/deploy/central/tasks-chart/templates/task-ods-build-typescript-with-sidecar.yaml new file mode 100644 index 00000000..bff8ab38 --- /dev/null +++ b/deploy/central/tasks-chart/templates/task-ods-build-typescript-with-sidecar.yaml @@ -0,0 +1,106 @@ +# Generated by cmd/sidecar-tasks/main.go; DO NOT EDIT. +apiVersion: tekton.dev/v1beta1 +kind: ClusterTask +metadata: + creationTimestamp: null + name: ods-build-typescript-with-sidecar{{.Values.taskSuffix}} +spec: + description: |- + ODS Build Typescript applications + **Sidecar variant!** Use this task if you need to run a container next to the build task. + For example, this could be used to run a database to allow for integration tests. + The sidecar image to must be supplied via `sidecar-image`. + Apart from the sidecar, the task is an exact copy of `ods-build-typescript`. + params: + - default: . + description: | + Working directory. The path must be relative to the root of the repository, + without leading `./` and trailing `/`. + name: working-dir + type: string + - default: docker + description: Path to the directory into which outputs should be placed, relative + to `working-dir`. This directory may then later be used as Docker context for + example. + name: output-dir + type: string + - default: "false" + description: Whether quality gate needs to pass. + name: sonar-quality-gate + type: string + - default: "false" + description: Whether to skip the SonarQube analysis or not. + name: sonar-skip + type: string + - description: Image to use for sidecar + name: sidecar-image + type: string + sidecars: + - image: $(params.sidecar-image) + name: sidecar + resources: {} + steps: + - env: + - name: NEXUS_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-nexus + - name: NEXUS_USERNAME + valueFrom: + secretKeyRef: + key: username + name: ods-nexus-auth + - name: NEXUS_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ods-nexus-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-typescript-toolset:{{.Values.imageTag}}' + name: build-typescript + resources: {} + script: |2 + + # build-typescript is build/package/scripts/build-typescript.sh. + build-typescript \ + --working-dir=$(params.working-dir) \ + --output-dir=$(params.output-dir) \ + --debug=${DEBUG} + workingDir: $(workspaces.source.path) + - env: + - name: SONAR_URL + valueFrom: + configMapKeyRef: + key: url + name: ods-sonar + - name: SONAR_AUTH_TOKEN + valueFrom: + secretKeyRef: + key: password + name: ods-sonar-auth + - name: DEBUG + valueFrom: + configMapKeyRef: + key: debug + name: ods-pipeline + image: '{{.Values.registry}}/{{.Values.namespace}}/ods-sonar:{{.Values.imageTag}}' + name: scan-with-sonar + resources: {} + script: | + if [ "$(params.sonar-skip)" = "true" ]; then + echo "Skipping SonarQube analysis" + else + mkdir -p .ods/artifacts/sonarqube-analysis + # sonar is built from cmd/sonar/main.go. + sonar \ + -working-dir=$(params.working-dir) \ + -quality-gate=$(params.sonar-quality-gate) + fi + workingDir: $(workspaces.source.path) + workspaces: + - name: source diff --git a/docs/tasks/ods-build-go-with-sidecar.adoc b/docs/tasks/ods-build-go-with-sidecar.adoc new file mode 100644 index 00000000..94e78bd3 --- /dev/null +++ b/docs/tasks/ods-build-go-with-sidecar.adoc @@ -0,0 +1,87 @@ +// Document generated by internal/documentation/tasks.go from template.adoc.tmpl; DO NOT EDIT. + += ods-build-go-with-sidecar + +Builds Go (module) applications. + +The following steps are executed: + +- check proper formatting against gofmt +- linting using golangci-lint +- build (using `go-os` and `go-arch` parameters) +- test execution + +Tests exclude the vendor directory. Test results are converted into xUnit format. + +Both xUnit report and coverage report are placed into .ods/artifacts. + +After tests ran successfully, the application source code is scanned by SonarQube. +When `sonar-quality-gate` is set to `true`, the task will fail if the quality gate +is not passed. If SonarQube is not desired, it can be disabled via `sonar-skip`. +The SonarQube scan will include parameters to perform a pull request analysis if +there is an open pull request for the branch being built. Pull request decoration +in Bitbucket is done automatically by SonarQube provided the ALM integration is setup +properly in SonarQube. + +**Sidecar variant!** Use this task if you need to run a container next to the build task. +For example, this could be used to run a database to allow for integration tests. +The sidecar image to must be supplied via `sidecar-image`. +Apart from the sidecar, the task is an exact copy of `ods-build-go`. + +== Parameters + +[cols="1,1,2"] +|=== +| Parameter | Default | Description + +| working-dir +| . +| Working directory. The path must be relative to the root of the repository, +without leading `./` and trailing `/`. + + + +| enable-cgo +| false +| Whether to enable CGO. When not enabled the build will set `CGO_ENABLED=0`. + + +| go-os +| linux +| `GOOS` variable (the execution operating system such as `linux`, `windows`). + + +| go-arch +| amd64 +| `GOARCH` variable (the execution architecture such as `arm`, `amd64`). + + +| output-dir +| docker +| Path to the directory into which the resulting Go binary should be copied, relative to `working-dir`. This directory may then later be used as Docker context for example. + + +| pre-test-script +| +| Script to execute before running tests, relative to the working directory. + + +| sonar-quality-gate +| false +| Whether the SonarQube quality gate needs to pass for the task to succeed. + + +| sonar-skip +| false +| Whether to skip SonarQube analysis or not. + + +| sidecar-image +| +| Image to use for sidecar + +|=== + +== Results + +N/A diff --git a/docs/tasks/ods-build-gradle-with-sidecar.adoc b/docs/tasks/ods-build-gradle-with-sidecar.adoc new file mode 100644 index 00000000..571200fe --- /dev/null +++ b/docs/tasks/ods-build-gradle-with-sidecar.adoc @@ -0,0 +1,143 @@ +// Document generated by internal/documentation/tasks.go from template.adoc.tmpl; DO NOT EDIT. + += ods-build-gradle-with-sidecar + + +Builds Gradle applications. + +The following steps are executed: + +- build gradle application, using `gradlew clean build`, which includes tests execution and coverage report generation +- SonarQube quality scan + +Notes: + +- tests exclude the vendor directory. +- test results are converted into xUnit format. +- both xUnit report and coverage report are placed into .ods/artifacts. + +Environment variables available: + +- `ODS_OUTPUT_DIR`: this environment variable points to the folder +that this build expects generated application artifacts to be copied to. +The gradle script should read it and copy there the generated artifacts. +- `NEXUS_* env vars`: `NEXUS_HOST`, `NEXUS_USER` and `NEXUS_PASSWORD` +are available and should be read by the gradle script. + +To enable the gradle script to copy the generated application artifacts script follow these steps: + +- read the environment variable `ODS_OUTPUT_DIR` in the buildscript section of the gradle script: +``` +buildscript { + ext { + outputDir = System.getenv('ODS_OUTPUT_DIR') + } +} +``` +- customize the jar tasks to set the destination directory +``` +jar { + println("Set application jar name to 'app'") + archiveBaseName = 'app' + if (outputDir != null) { + println("Set destinationDirectory to '${projectDir}/${outputDir}'") + destinationDirectory = file("${projectDir}/${outputDir}") + } +} +``` + +To create a coverage report be sure that you add to `gradle.properties` the required +configuration. For example to enable Jacoco coverage repot you will need to: + +- add `jacoco` plugin: +``` +plugins { + id 'application' + id 'jacoco' +} +``` +- add task `jacocoTestReport`: +``` +jacocoTestReport { + reports { + xml.enabled true + } +} +``` +- add `finalizedBy jacocoTestReport` to the task `test`: +``` +tasks.named('test') { + useJUnitPlatform() + finalizedBy jacocoTestReport +} +``` + +To configure SonarQube the project has to include at the root folder of the project the property file `sonar-project.properties`. +Otherwise the SonarQube scan will fail. +Following example properties show default working values for a standard gradle project: +``` +sonar.sources=src +sonar.java.binaries=build/classes +sonar.junit.reportPaths=build/test-results/test +sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml +``` + +When `sonar-quality-gate` is set to `true`, the task will fail if the quality gate +is not passed. If SonarQube is not desired, it can be disabled via `sonar-skip`. +The SonarQube scan will include parameters to perform a pull request analysis if +there is an open pull request for the branch being built. Pull request decoration +in Bitbucket is done automatically by SonarQube provided the ALM integration is setup +properly in SonarQube. + +**Sidecar variant!** Use this task if you need to run a container next to the build task. +For example, this could be used to run a database to allow for integration tests. +The sidecar image to must be supplied via `sidecar-image`. +Apart from the sidecar, the task is an exact copy of `ods-build-gradle`. + +== Parameters + +[cols="1,1,2"] +|=== +| Parameter | Default | Description + +| working-dir +| . +| Working directory. The path must be relative to the root of the repository, +without leading `./` and trailing `/`. + + + +| gradle-additional-tasks +| +| Additional gradle tasks to be passed to the gradle build. (default tasks called are `clean` and `build`). + + +| gradle-options +| +| Options to be passed to the gradle build. (See ref: https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_debugging) + + +| output-dir +| docker +| Path to the directory into which the resulting Java application jar should be copied, relative to `working-dir`. This directory may then later be used as Docker context for example. + + +| sonar-quality-gate +| false +| Whether the SonarQube quality gate needs to pass for the task to succeed. + + +| sonar-skip +| false +| Whether to skip SonarQube analysis or not. + + +| sidecar-image +| +| Image to use for sidecar + +|=== + +== Results + +N/A diff --git a/docs/tasks/ods-build-python-with-sidecar.adoc b/docs/tasks/ods-build-python-with-sidecar.adoc new file mode 100644 index 00000000..23524a8c --- /dev/null +++ b/docs/tasks/ods-build-python-with-sidecar.adoc @@ -0,0 +1,57 @@ +// Document generated by internal/documentation/tasks.go from template.adoc.tmpl; DO NOT EDIT. + += ods-build-python-with-sidecar + +ODS Build Python applications +**Sidecar variant!** Use this task if you need to run a container next to the build task. +For example, this could be used to run a database to allow for integration tests. +The sidecar image to must be supplied via `sidecar-image`. +Apart from the sidecar, the task is an exact copy of `ods-build-python`. + +== Parameters + +[cols="1,1,2"] +|=== +| Parameter | Default | Description + +| working-dir +| . +| Working directory. The path must be relative to the root of the repository, +without leading `./` and trailing `/`. + + + +| output-dir +| docker +| Path to the directory into which outputs should be placed, relative to `working-dir`. This directory may then later be used as Docker context for example. + + +| max-line-length +| 120 +| Maximum line length. + + +| pre-test-script +| +| Script to execute before running tests, relative to the working directory. + + +| sonar-quality-gate +| false +| Whether quality gate needs to pass. + + +| sonar-skip +| false +| Whether to skip the SonarQube analysis or not. + + +| sidecar-image +| +| Image to use for sidecar + +|=== + +== Results + +N/A diff --git a/docs/tasks/ods-build-typescript-with-sidecar.adoc b/docs/tasks/ods-build-typescript-with-sidecar.adoc new file mode 100644 index 00000000..67ec0713 --- /dev/null +++ b/docs/tasks/ods-build-typescript-with-sidecar.adoc @@ -0,0 +1,47 @@ +// Document generated by internal/documentation/tasks.go from template.adoc.tmpl; DO NOT EDIT. + += ods-build-typescript-with-sidecar + +ODS Build Typescript applications +**Sidecar variant!** Use this task if you need to run a container next to the build task. +For example, this could be used to run a database to allow for integration tests. +The sidecar image to must be supplied via `sidecar-image`. +Apart from the sidecar, the task is an exact copy of `ods-build-typescript`. + +== Parameters + +[cols="1,1,2"] +|=== +| Parameter | Default | Description + +| working-dir +| . +| Working directory. The path must be relative to the root of the repository, +without leading `./` and trailing `/`. + + + +| output-dir +| docker +| Path to the directory into which outputs should be placed, relative to `working-dir`. This directory may then later be used as Docker context for example. + + +| sonar-quality-gate +| false +| Whether quality gate needs to pass. + + +| sonar-skip +| false +| Whether to skip the SonarQube analysis or not. + + +| sidecar-image +| +| Image to use for sidecar + +|=== + +== Results + +N/A diff --git a/pkg/tasktesting/run.go b/pkg/tasktesting/run.go index c9dd81e3..79abc122 100644 --- a/pkg/tasktesting/run.go +++ b/pkg/tasktesting/run.go @@ -25,6 +25,10 @@ type TestOpts struct { } type TestCase struct { + // TaskVariant allows to target a variant of the task. E.g. the `ods-build-go task` + // has a `ods-build-go-with-sidecar` variant. This variant can be targeted by + // setting TaskVariant to `with-sidecar`. + TaskVariant string // Map workspace name of task to local directory under test/testdata/workspaces. WorkspaceDirMapping map[string]string WantRunSuccess bool diff --git a/test/tasks/common_test.go b/test/tasks/common_test.go index efb3707c..dd7cbe59 100644 --- a/test/tasks/common_test.go +++ b/test/tasks/common_test.go @@ -2,6 +2,7 @@ package tasks import ( "flag" + "fmt" "io/ioutil" "path/filepath" "strings" @@ -104,9 +105,12 @@ func runTaskTestCases(t *testing.T, taskName string, testCases map[string]taskte for name, tc := range testCases { t.Run(name, func(t *testing.T) { + if tc.TaskVariant != "" { + taskName = fmt.Sprintf("%s-%s", taskName, tc.TaskVariant) + } tasktesting.Run(t, tc, tasktesting.TestOpts{ - TaskKindRef: taskKindRef, // could be read from task definition - TaskName: taskName, // could be read from task definition + TaskKindRef: taskKindRef, + TaskName: taskName, Clients: c, Namespace: ns, Timeout: 5 * time.Minute, // depending on the task we may need to increase or decrease it diff --git a/test/tasks/ods-build-go_test.go b/test/tasks/ods-build-go_test.go index aaad1ee0..a8c5512b 100644 --- a/test/tasks/ods-build-go_test.go +++ b/test/tasks/ods-build-go_test.go @@ -166,5 +166,18 @@ func TestTaskODSBuildGo(t *testing.T) { } }, }, + "build go app with redis sidecar": { + TaskVariant: "with-sidecar", + WorkspaceDirMapping: map[string]string{"source": "go-redis"}, + PreRunFunc: func(t *testing.T, ctxt *tasktesting.TaskRunContext) { + wsDir := ctxt.Workspaces["source"] + ctxt.ODS = tasktesting.SetupGitRepo(t, ctxt.Namespace, wsDir) + ctxt.Params = map[string]string{ + "sonar-skip": "true", + "sidecar-image": "redis:6.2.5-buster", + } + }, + WantRunSuccess: true, + }, }) } diff --git a/test/testdata/workspaces/go-redis/docker/Dockerfile b/test/testdata/workspaces/go-redis/docker/Dockerfile new file mode 100644 index 00000000..6dd74cc9 --- /dev/null +++ b/test/testdata/workspaces/go-redis/docker/Dockerfile @@ -0,0 +1,7 @@ +FROM alpine + +COPY app app + +EXPOSE 8080 + +CMD ["./app"] diff --git a/test/testdata/workspaces/go-redis/go.mod b/test/testdata/workspaces/go-redis/go.mod new file mode 100644 index 00000000..a6588e5c --- /dev/null +++ b/test/testdata/workspaces/go-redis/go.mod @@ -0,0 +1,5 @@ +module go-redis + +go 1.15 + +require github.com/go-redis/redis/v8 v8.11.3 diff --git a/test/testdata/workspaces/go-redis/go.sum b/test/testdata/workspaces/go-redis/go.sum new file mode 100644 index 00000000..868d1787 --- /dev/null +++ b/test/testdata/workspaces/go-redis/go.sum @@ -0,0 +1,88 @@ +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8= +github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/test/testdata/workspaces/go-redis/main.go b/test/testdata/workspaces/go-redis/main.go new file mode 100644 index 00000000..534e3a3b --- /dev/null +++ b/test/testdata/workspaces/go-redis/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "context" + "fmt" + "log" + + redis "github.com/go-redis/redis/v8" +) + +func main() { + err := example() + if err != nil { + log.Fatal(err) + } +} + +var ctx = context.Background() + +func example() error { + rdb := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password set + DB: 0, // use default DB + }) + + err := rdb.Set(ctx, "key", "value", 0).Err() + if err != nil { + return err + } + + val, err := rdb.Get(ctx, "key").Result() + if err != nil { + return err + } + fmt.Println("key", val) + + val2, err := rdb.Get(ctx, "key2").Result() + if err == redis.Nil { + fmt.Println("key2 does not exist") + } else if err != nil { + return err + } else { + fmt.Println("key2", val2) + } + // Output: key value + // key2 does not exist + return nil +} diff --git a/test/testdata/workspaces/go-redis/main_test.go b/test/testdata/workspaces/go-redis/main_test.go new file mode 100644 index 00000000..b808fea4 --- /dev/null +++ b/test/testdata/workspaces/go-redis/main_test.go @@ -0,0 +1,10 @@ +package main + +import "testing" + +func TestExample(t *testing.T) { + err := example() + if err != nil { + t.Fatal(err) + } +} diff --git a/test/testdata/workspaces/go-redis/sonar-project.properties b/test/testdata/workspaces/go-redis/sonar-project.properties new file mode 100644 index 00000000..1a955659 --- /dev/null +++ b/test/testdata/workspaces/go-redis/sonar-project.properties @@ -0,0 +1,11 @@ +# Comma-separated paths to directories with sources (required) +sonar.sources=. +sonar.exclusions=**/*_test.go,**/vendor/** + +sonar.tests=. +sonar.test.inclusions=**/*_test.go +sonar.test.exclusions=**/vendor/** + +# Encoding of the source files (optional but recommended as default is ASCII) +sonar.sourceEncoding=UTF-8 +sonar.go.coverage.reportPaths=coverage.out