diff --git a/.gitlab/merge_request_templates/new_feature.md b/.gitlab/merge_request_templates/new_feature.md index 74abae94c94dc0768bb5c51fe51ad253fce113fe..491b7f98ded7e0da03d18c95978eafcb7d86619f 100644 --- a/.gitlab/merge_request_templates/new_feature.md +++ b/.gitlab/merge_request_templates/new_feature.md @@ -8,8 +8,8 @@ Closes #999 ## Checklist * General: - * [ ] use [rules](https://docs.gitlab.com/ee/ci/yaml/#rules) instead of [only/except](https://docs.gitlab.com/ee/ci/yaml/#onlyexcept-advanced) - * [ ] optimized [cache](https://docs.gitlab.com/ee/ci/caching/) configuration (wherever applicable) + * [ ] use [rules](https://docs.gitlab.com/ci/yaml/#rules) instead of [only/except](https://docs.gitlab.com/ci/yaml/#onlyexcept-advanced) + * [ ] optimized [cache](https://docs.gitlab.com/ci/caching/) configuration (wherever applicable) * Publicly usable: * [ ] untagged runners * [ ] no proxy configuration but support `http_proxy`/`https_proxy`/`no_proxy` diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d184ff9cc6512a5c0541d81ac05d3787d051dde..47daa308ef5a022df712217fdabf2ff6f8481ee0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,33 @@ -# [4.12.0](https://git.code.tecnalia.dev/smartdatalab/public/ci-cd-components/golang/compare/4.11.1...4.12.0) (2025-01-29) +# [4.13.0](https://gitlab.com/to-be-continuous/golang/compare/4.12.3...4.13.0) (2025-04-30) + + +### Features + +* use go image for sbom job ([9b7e4ee](https://gitlab.com/to-be-continuous/golang/commit/9b7e4ee0ebbefc34c3cf374d72cbed10ed8ba7c6)) + +## [4.12.3](https://gitlab.com/to-be-continuous/golang/compare/4.12.2...4.12.3) (2025-03-28) + + +### Bug Fixes + +* typo in glc_major_ver ([e2cb9cf](https://gitlab.com/to-be-continuous/golang/commit/e2cb9cfc856ca19e8518b1a748386c4b2511e588)) + +## [4.12.2](https://gitlab.com/to-be-continuous/golang/compare/4.12.1...4.12.2) (2025-03-27) + + +### Bug Fixes + +* **ci-lint:** golangci-lint V2 no longer support --out-format arg ([d645607](https://gitlab.com/to-be-continuous/golang/commit/d645607caa016391f948362624be0311a29145fd)) +* **ci-lint:** golangci-lint V2 no longer support 'goimports' as a linter, but as formatter ([2f6c020](https://gitlab.com/to-be-continuous/golang/commit/2f6c0203e9ee0bf87078522c1e4cbae77322de21)) + +## [4.12.1](https://gitlab.com/to-be-continuous/golang/compare/4.12.0...4.12.1) (2025-01-31) + + +### Bug Fixes + +* **sbom:** only generate SBOMs on prod branches, integ branches and release tags ([261e8ce](https://gitlab.com/to-be-continuous/golang/commit/261e8ceb2d360768de0cc8fe3326cc9dfea4c121)) + +# [4.12.0](https://gitlab.com/to-be-continuous/golang/compare/4.11.1...4.12.0) (2025-01-27) ### Features diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a89e09b0f71cacb9d7273daf2e9d81410444f7bc..ec6ddc4b7ba7ce7e05557e7be697f95758cfce65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,7 +61,7 @@ To contribute: 1. Create an issue describing the bug or enhancement you want to propose (select the right issue template). 2. Make sure the issue has been reviewed and agreed. -3. Create a Merge Request, from your **own** fork (see [forking workflow](https://docs.gitlab.com/ee/user/project/repository/forking_workflow.html) documentation). +3. Create a Merge Request, from your **own** fork (see [forking workflow](https://docs.gitlab.com/user/project/repository/forking_workflow/) documentation). Don't hesitate to mark your MR as `Draft` as long as you think it's not ready to be reviewed. ### Git Commit Conventions diff --git a/README.md b/README.md index 75cd40d10c9c2e7e54fa72202976ed5622e207ab..8ae91f87edf62b3e68a14013b750cf40b0c4312c 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ This project implements a GitLab CI/CD template to build, test and analyse your ## Usage -This template can be used both as a [CI/CD component](https://docs.gitlab.com/ee/ci/components/#use-a-component) -or using the legacy [`include:project`](https://docs.gitlab.com/ee/ci/yaml/index.html#includeproject) syntax. +This template can be used both as a [CI/CD component](https://docs.gitlab.com/ci/components/#use-a-component) +or using the legacy [`include:project`](https://docs.gitlab.com/ci/yaml/#includeproject) syntax. ### Use as a CI/CD component @@ -14,7 +14,7 @@ Add the following to your `.gitlab-ci.yml`: ```yaml include: # 1: include the component - - component: $CI_SERVER_FQDN/to-be-continuous/golang/gitlab-ci-golang@4.12.0 + - component: $CI_SERVER_FQDN/to-be-continuous/golang/gitlab-ci-golang@4.13.0 # 2: set/override component inputs inputs: image: "registry.hub.docker.com/library/golang:buster" # ⚠ this is only an example @@ -28,7 +28,7 @@ Add the following to your `.gitlab-ci.yml`: include: # 1: include the template - project: 'to-be-continuous/golang' - ref: '4.12.0' + ref: '4.13.0' file: '/templates/gitlab-ci-golang.yml' variables: @@ -42,8 +42,8 @@ The Go template uses some global configuration used throughout all jobs. | Input / Variable | Description | Default value | |------------------|------------------------------------------------------------------------------------------------------------|-----------------| -| `image` / `GO_IMAGE` | The Docker image used to run Go for `go-build` <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/golang:bookworm` | -| `test-image` / `GO_TEST_IMAGE` | The Docker image used to run Go for `go-test` <br/>:warning: **set the version required by your project** | _none_ | +| `image` / `GO_IMAGE` | The Docker image used to run Go for `go-build` <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/golang:bookworm` <br/>[](https://to-be-continuous.gitlab.io/doc/secu/trivy-GO_IMAGE) | +| `test-image` / `GO_TEST_IMAGE` | The Docker image used to run Go for `go-test` <br/>:warning: **set the version required by your project** | _none_ | | `project-dir` / `GO_PROJECT_DIR` | Go project root directory | `.` | | `goproxy` / `GOPROXY` | URL of Go module proxy | _none_ | @@ -113,7 +113,7 @@ If `GO_TEST_IMAGE` is set, separate `go-build` and `go-test` jobs will be run in Separating `build` and `test` jobs can be useful to use different images (and hence different tools) or if you want to build muli-platform binaries. -Here is a `.gitlab-ci.yml` example that triggers a build on 3 target platforms using the [parallel matrix jobs](https://docs.gitlab.com/ee/ci/yaml/#parallel-matrix-jobs) pattern: +Here is a `.gitlab-ci.yml` example that triggers a build on 3 target platforms using the [parallel matrix jobs](https://docs.gitlab.com/ci/yaml/#parallel-matrix-jobs) pattern: ```yaml variables: @@ -155,9 +155,9 @@ In addition to a textual report in the console, the test jobs produce the follow |-----------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------| | `$GO_PROJECT_DIR/reports/go-test.native.txt` | native Go test report (text) | N/A | | `$GO_PROJECT_DIR/reports/go-test.native.json` | native Go test report (json) | [SonarQube integration](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/test-coverage/test-execution-parameters/#go) | -| `$GO_PROJECT_DIR/reports/go-test.xunit.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsjunit) | +| `$GO_PROJECT_DIR/reports/go-test.xunit.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportsjunit) | | `$GO_PROJECT_DIR/reports/go-coverage.native.out` | native Go coverage | N/A | -| `$GO_PROJECT_DIR/reports/go-coverage.cobertura.xml` | [Cobertura XML](https://gcovr.com/en/stable/output/cobertura.html) coverage report | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscoverage_report) | +| `$GO_PROJECT_DIR/reports/go-coverage.cobertura.xml` | [Cobertura XML](https://gcovr.com/en/stable/output/cobertura.html) coverage report | [GitLab integration](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportscoverage_report) | ### `go-ci-lint` job @@ -167,8 +167,8 @@ It is bound to the `build` stage, and uses the following variables: | Input / Variable | Description | Default value | |-----------------------|----------------------------------------------------------------------------------------------------------|----------------------------------------| -| `ci-lint-image` / `GO_CI_LINT_IMAGE` | The Docker image used to run `golangci-lint` | `registry.hub.docker.com/golangci/golangci-lint:latest-alpine` | -| `ci-lint-args` / `GO_CI_LINT_ARGS` | `golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options) | `-E gosec,goimports ./...` | +| `ci-lint-image` / `GO_CI_LINT_IMAGE` | The Docker image used to run `golangci-lint` | `registry.hub.docker.com/golangci/golangci-lint:latest-alpine` <br/>[](https://to-be-continuous.gitlab.io/doc/secu/trivy-GO_CI_LINT_IMAGE) | +| `ci-lint-args` / `GO_CI_LINT_ARGS` | `golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options) | `-E gosec ./...` | | `ci-lint-disabled` / `GO_CI_LINT_DISABLED` | Set to `true` to disable this job | _none_ (enabled) | | `go-ci-lint-job-tags` / `GO_CI_LINT_JOB_TAGS` | Tags to be used for selecting runners for the job | `[]` | @@ -176,7 +176,7 @@ In addition to a textual report in the console, this job produces the following | Report | Format | Usage | |-------------------------------------------------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------| -| `$GO_PROJECT_DIR/reports/go-ci-lint.codeclimate.json` | [Code Climate](https://docs.codeclimate.com/docs/pylint) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscodequality) | +| `$GO_PROJECT_DIR/reports/go-ci-lint.codeclimate.json` | [Code Climate](https://docs.codeclimate.com/docs/pylint) | [GitLab integration](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportscodequality) | | `$GO_PROJECT_DIR/reports/go-ci-lint.checkstyle.xml` | Checkstyle | [SonarQube integration](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/importing-external-issues/external-analyzer-reports/) | ### `go-semgrep` job @@ -188,7 +188,7 @@ It is bound to the `test` stage, and uses the following variables: | Input / Variable | Description | Default Value | | ---------------- | ----------- | ------------- | | `semgrep-disabled` / `GO_SEMGREP_DISABLED` | Set to `true` to disable this job | _none_ | -| `semgrep-image` / `GO_SEMGREP_IMAGE` | The Docker image used to run [Semgrep](https://semgrep.dev/docs/) | `registry.hub.docker.com/semgrep/semgrep:latest` | +| `semgrep-image` / `GO_SEMGREP_IMAGE` | The Docker image used to run [Semgrep](https://semgrep.dev/docs/) | `registry.hub.docker.com/semgrep/semgrep:latest` <br/>[](https://to-be-continuous.gitlab.io/doc/secu/trivy-GO_SEMGREP_IMAGE) | | `semgrep-args` / `GO_SEMGREP_ARGS` | Semgrep [scan options](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | `--metrics off --disable-version-check` | | `semgrep-rules` / `GO_SEMGREP_RULES` | Space-separated list of [Semgrep rules](https://semgrep.dev/docs/running-rules).<br/>Can be both local YAML files or remote rules from the [Segmrep Registry](https://semgrep.dev/explore) (denoted by the `p/` prefix). | `p/golang p/gosec` | | `semgrep-download-rules-enabled` / `GO_SEMGREP_DOWNLOAD_RULES_ENABLED` | Download Semgrep remote rules | `true` | @@ -204,7 +204,7 @@ In addition to a textual report in the console, this job produces the following | Report | Format | Usage | | ------ | ------ | ----- | -| `$GO_PROJECT_DIR/reports/golang-semgrep.gitlab.json` | [GitLab's SAST format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportssast) | +| `$GO_PROJECT_DIR/reports/golang-semgrep.gitlab.json` | [GitLab's SAST format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [GitLab integration](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportssast) | | `$GO_PROJECT_DIR/reports/golang-semgrep.native.json` | [Semgrep's JSON format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [DefectDojo integration](https://docs.defectdojo.com/en/connecting_your_tools/parsers/file/semgrep/)<br/>_This report is generated only if DefectDojo template is detected_ | ### `go-mod-outdated` job @@ -262,7 +262,8 @@ It is bound to the `test` stage, and uses the following variables: | Input / Variable | Description | Default value | | --------------------- | -------------------------------------- | ----------------- | | `sbom-disabled` / `GO_SBOM_DISABLED` | Set to `true` to disable this job | _none_ | -| `sbom-image` / `GO_SBOM_IMAGE` | Image of cyclonedx-gomod used for SBOM analysis | `registry.hub.docker.com/cyclonedx/cyclonedx-gomod:latest` | +| `TBC_SBOM_MODE` | Controls when SBOM reports are generated (`onrelease`: only on `$INTEG_REF`, `$PROD_REF` and `$RELEASE_REF` pipelines; `always`: any pipeline).<br/>:warning: `sbom-disabled` / `GO_SBOM_DISABLED` takes precedence | `onrelease` | +| `sbom-image` / `GO_SBOM_IMAGE` | Specific Docker image used to run cyclonedx-gomod | `$GO_IMAGE` | | `sbom-opts` / `GO_SBOM_OPTS` | [@cyclonedx/cyclonedx-gomod options](https://github.com/CycloneDX/cyclonedx-gomod#usage) used for SBOM analysis | `-main .` | | `go-sbom-job-tags` / `GO_SBOM_JOB_TAGS` | Tags to be used for selecting runners for the job | `[]` | diff --git a/kicker.json b/kicker.json index 26d334434c04959291acda8e70a41016bca9b5b8..deeba539f66dfb4945cda01b94eaf68e00b43f82 100644 --- a/kicker.json +++ b/kicker.json @@ -144,7 +144,7 @@ { "name": "GO_CI_LINT_ARGS", "description": "`golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options)", - "default": "-E gosec,goimports ./...", + "default": "-E gosec ./...", "advanced": true }, { @@ -182,9 +182,19 @@ "description": "This job generates a file listing all dependencies using [cyclonedx-gomod](https://github.com/CycloneDX/cyclonedx-gomod)", "disable_with": "GO_SBOM_DISABLED", "variables": [ + { + "name": "TBC_SBOM_MODE", + "type": "enum", + "values": ["onrelease", "always"], + "description": "Controls when SBOM reports are generated (`onrelease`: only on `$INTEG_REF`, `$PROD_REF` and `$RELEASE_REF` pipelines; `always`: any pipeline)", + "advanced": true, + "default": "onrelease" + }, { "name": "GO_SBOM_IMAGE", - "default": "registry.hub.docker.com/cyclonedx/cyclonedx-gomod:latest" + "description": "Specific Docker image used to run cyclonedx-gomod", + "advanced": true, + "default": "$GO_IMAGE" }, { "name": "GO_SBOM_OPTS", diff --git a/templates/gitlab-ci-golang.yml b/templates/gitlab-ci-golang.yml index 7eb6d93ec17fdb3b9a19d0d4cea228ba105f39b8..42ce47dba32530de6c2c1853f83241bbcf370ff0 100644 --- a/templates/gitlab-ci-golang.yml +++ b/templates/gitlab-ci-golang.yml @@ -80,7 +80,7 @@ spec: default: registry.hub.docker.com/golangci/golangci-lint:latest-alpine ci-lint-args: description: '`golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options)' - default: -E gosec,goimports ./... + default: -E gosec ./... semgrep-image: description: The Docker image used to run [Semgrep](https://semgrep.dev/docs/) default: registry.hub.docker.com/semgrep/semgrep:latest @@ -109,7 +109,8 @@ spec: type: boolean default: false sbom-image: - default: registry.hub.docker.com/cyclonedx/cyclonedx-gomod:latest + description: Specific Docker image used to run cyclonedx-gomod + default: '$GO_IMAGE' sbom-opts: description: '[@cyclonedx/cyclonedx-gomod options](https://github.com/CycloneDX/cyclonedx-gomod#usage) used for SBOM analysis' default: -main . @@ -197,7 +198,18 @@ workflow: # else (Ready MR): auto & failing - when: on_success +# software delivery job prototype: run on production and integration branches + release pipelines +.delivery-policy: + rules: + # on tag with release pattern + - if: '$CI_COMMIT_TAG =~ $RELEASE_REF' + # on production or integration branch(es) + - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF' + variables: + # Global TBC SBOM Mode (onrelease -> only generate SBOMs for releases, always -> generate SBOMs for all refs) + TBC_SBOM_MODE: "onrelease" + # Default Go project root directory GO_PROJECT_DIR: $[[ inputs.project-dir ]] @@ -261,6 +273,8 @@ variables: PROD_REF: /^(master|main)$/ # default integration ref name (pattern) INTEG_REF: /^develop$/ + # default release tag name (pattern) + RELEASE_REF: '/^v?[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-\.]+)?(\+[a-zA-Z0-9-\.]+)?$/' stages: - build @@ -625,7 +639,7 @@ stages: image: $GO_IMAGE services: - name: "$TBC_TRACKING_IMAGE" - command: ["--service", "golang", "4.12.0"] + command: ["--service", "golang", "4.13.0"] variables: # The directory where 'go install' will install a command. GOBIN: "$CI_PROJECT_DIR/$GO_PROJECT_DIR/bin" @@ -743,7 +757,14 @@ go-ci-lint: script: - mkdir -p -m 777 reports # produce all reports at once - - golangci-lint run --out-format "colored-line-number:stdout,code-climate:reports/go-ci-lint.codeclimate.json,checkstyle:reports/go-ci-lint.checkstyle.xml" $GO_CI_LINT_ARGS + - | + glc_major_ver=$(golangci-lint version | cut -d' ' -f4 | cut -d'.' -f1) + if [[ "$glc_major_ver" == "1" ]] + then + golangci-lint run --out-format "colored-line-number:stdout,code-climate:reports/go-ci-lint.codeclimate.json,checkstyle:reports/go-ci-lint.checkstyle.xml" $GO_CI_LINT_ARGS + else + golangci-lint run --output.text.path stdout --output.code-climate.path reports/go-ci-lint.codeclimate.json --output.checkstyle.path reports/go-ci-lint.checkstyle.xml $GO_CI_LINT_ARGS + fi artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day @@ -826,7 +847,7 @@ go-sbom: image: name: $GO_SBOM_IMAGE entrypoint: [""] - # manage separate GitLab cache to prevent permission denied error (this image being rootless, it can't rewrite Go cache - owned by root) + # manage separate GitLab cache to prevent permission denied error (cyclonedx-gomod image being rootless, it can't rewrite Go cache - owned by root) # see: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/29663 cache: key: "$CI_COMMIT_REF_SLUG-golang-sbom" @@ -836,10 +857,10 @@ go-sbom: dependencies: [] needs: [] script: + - command -v cyclonedx-gomod > /dev/null || go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest - mkdir -p -m 777 reports - go_mode=$(go_build_mode) - - | - cyclonedx-gomod "${go_mode:0:3}" -json -output reports/go-sbom.cyclonedx.json $GO_SBOM_OPTS + - cyclonedx-gomod "${go_mode:0:3}" -json -output reports/go-sbom.cyclonedx.json $GO_SBOM_OPTS - chmod a+r reports/go-sbom.cyclonedx.json artifacts: name: "SBOM for golang from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" @@ -854,7 +875,13 @@ go-sbom: # exclude if disabled - if: '$GO_SBOM_DISABLED == "true"' when: never - - !reference [.test-policy, rules] + # 'always' mode: run + - if: '$TBC_SBOM_MODE == "always"' + # exclude unsupported modes + - if: '$TBC_SBOM_MODE != "onrelease"' + when: never + # 'onrelease' mode: use common software delivery rules + - !reference [.delivery-policy, rules] tags: $[[ inputs.go-sbom-job-tags ]] go-govulncheck: