From 5c32520f6eecc18b58b2b2cf0f4326e04e023cec Mon Sep 17 00:00:00 2001 From: Pierre Smeyers <pierre.smeyers@gmail.com> Date: Sun, 12 Nov 2023 16:58:41 +0100 Subject: [PATCH] feat: GitLab CI/CD component migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠ requires GitLab 16.6 or later --- .gitlab-ci.yml | 2 +- README.md | 131 +++++++++++--------- bumpversion.sh | 4 +- kicker.json | 194 ++++++++++++++++-------------- logo.png | Bin 18448 -> 13030 bytes templates/gitlab-ci-maven-jib.yml | 76 ++++++++++-- templates/gitlab-ci-maven.yml | 185 +++++++++++++++++++++------- 7 files changed, 388 insertions(+), 204 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d163e33..6e5dffb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ include: file: '/templates/validation.yml' - project: 'to-be-continuous/bash' ref: '3.3' - file: 'templates/gitlab-ci-bash.yml' + file: '/templates/gitlab-ci-bash.yml' - project: 'to-be-continuous/semantic-release' ref: '3.7' file: '/templates/gitlab-ci-semrel.yml' diff --git a/README.md b/README.md index 0a4e11b..9876c55 100644 --- a/README.md +++ b/README.md @@ -4,27 +4,54 @@ This project implements a GitLab CI/CD template to build, test and analyse your ## Usage -In order to include this template in your project, add the following to your `gitlab-ci.yml`: +This template can be used both as a [CI/CD component](https://docs.gitlab.com/ee/ci/components/#use-a-component-in-a-cicd-configuration) +or using the legacy [`include:project`](https://docs.gitlab.com/ee/ci/yaml/index.html#includeproject) syntax. + +### Use as a CI/CD component + +Add the following to your `gitlab-ci.yml`: ```yaml include: + # 1: include the component + - component: gitlab.com/to-be-continuous/maven/gitlab-ci-maven@3.8.0 + # 2: set/override component inputs + inputs: + # ⚠ this is only an example + image: registry.hub.docker.com/library/maven:3.8-openjdk-18 + deploy-enabled: true +``` + +### Use as a CI/CD template (legacy) + +Add the following to your `gitlab-ci.yml`: + +```yaml +include: + # 1: include the template - project: 'to-be-continuous/maven' ref: '3.8.0' file: '/templates/gitlab-ci-maven.yml' + +variables: + # 2: set/override template variables + # ⚠ this is only an example + MAVEN_IMAGE: registry.hub.docker.com/library/maven:3.8-openjdk-18 + MAVEN_DEPLOY_ENABLED: "true" ``` ## Global configuration The Maven template uses some global configuration throughout all jobs. -| Name | description | default value | +| Input / Variable | Description | Default value | | --------------------- |--------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------| -| `MAVEN_IMAGE` | The Docker image used to run Maven <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/maven:latest` | -| `MAVEN_PROJECT_DIR` | Maven projet root directory | `.` | -| `MAVEN_CFG_DIR` | The Maven configuration directory | `.m2` | -| `MAVEN_SETTINGS_FILE` | The Maven `settings.xml` file path | `${MAVEN_CFG_DIR}/settings.xml` | -| `MAVEN_OPTS` | [Global Maven options](http://maven.apache.org/configure.html#maven_opts-environment-variable) | `-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=${MAVEN_CFG_DIR}/repository -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true` | -| `MAVEN_CLI_OPTS` | Additional [Maven options](https://maven.apache.org/ref/3-LATEST/maven-embedder/cli.html) used on the command line | `--no-transfer-progress --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true` | +| `image` / `MAVEN_IMAGE` | The Docker image used to run Maven <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/maven:latest` | +| `project-dir` / `MAVEN_PROJECT_DIR` | Maven projet root directory | `.` | +| `cfg-dir` / `MAVEN_CFG_DIR` | The Maven configuration directory | `.m2` | +| `settings-file` / `MAVEN_SETTINGS_FILE` | The Maven `settings.xml` file path | `${MAVEN_CFG_DIR}/settings.xml` | +| `opts` / `MAVEN_OPTS` | [Global Maven options](http://maven.apache.org/configure.html#maven_opts-environment-variable) | `-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=${MAVEN_CFG_DIR}/repository -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true` | +| `cli-opts` / `MAVEN_CLI_OPTS` | Additional [Maven options](https://maven.apache.org/ref/3-LATEST/maven-embedder/cli.html) used on the command line | `--no-transfer-progress --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true` | ### About `$MAVEN_CFG_DIR` @@ -51,9 +78,9 @@ for test jobs dependency reasons (some test jobs such as SONAR analysis have a d It uses the following variable: -| Name | description | default value | +| Input / Variable | Description | Default value | | --------------------- | ---------------------------------------- | ----------------- | -| `MAVEN_BUILD_ARGS` | Maven arguments for the build & test job | `org.jacoco:jacoco-maven-plugin:prepare-agent verify org.jacoco:jacoco-maven-plugin:report` | +| `build-args` / `MAVEN_BUILD_ARGS` | Maven arguments for the build & test job | `org.jacoco:jacoco-maven-plugin:prepare-agent verify org.jacoco:jacoco-maven-plugin:report` | #### About Code Coverage @@ -81,14 +108,14 @@ More info: This job, **disabled by default**, is bound to the `test` stage and performs a SonarQube analysis of your code. This job uses the following variables: -| Name | description | default value | +| Input / Variable | Description | Default value | | ------------------------ | -------------------------------------- | ----------------- | -| `SONAR_HOST_URL` | SonarQube server url | _none_ (disabled) | +| `sonar-host-url` / `SONAR_HOST_URL` | SonarQube server url | _none_ (disabled) | | :lock: `SONAR_TOKEN` | SonarQube authentication [token](https://docs.sonarsource.com/sonarqube/latest/user-guide/user-account/generating-and-using-tokens/#using-a-token) (depends on your authentication method) | _none_ | | :lock: `SONAR_LOGIN` | SonarQube [login](https://docs.sonarsource.com/sonarqube/latest/extension-guide/web-api/#http-basic-access) (depends on your authentication method) | _none_ | | :lock: `SONAR_PASSWORD` | SonarQube password (depends on your authentication method) | _none_ | -| `SONAR_BASE_ARGS` | SonarQube [analysis arguments](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/analysis-parameters/) | `sonar:sonar -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues` | -| `SONAR_QUALITY_GATE_ENABLED` | Set to `true` to enable SonarQube [Quality Gate](https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/) verification.<br/>_Uses `sonar.qualitygate.wait` parameter ([see doc](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/ci-integration/overview/#quality-gate-fails))._ | _none_ (disabled) | +| `sonar-base-args` / `SONAR_BASE_ARGS` | SonarQube [analysis arguments](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/analysis-parameters/) | `sonar:sonar -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues` | +| `sonar-quality-gate-enabled` / `SONAR_QUALITY_GATE_ENABLED` | Set to `true` to enable SonarQube [Quality Gate](https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/) verification.<br/>_Uses `sonar.qualitygate.wait` parameter ([see doc](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/ci-integration/overview/#quality-gate-fails))._ | _none_ (disabled) | #### Recommended minimal configuration @@ -141,10 +168,10 @@ analysis. It is bound to the `test` stage, and uses the following variables: -| Name | description | default value | +| Input / Variable | Description | Default value | | --------------------- | -------------------------------------- | ----------------- | -| `MAVEN_DEPENDENCY_CHECK_DISABLED` | Set to `true` to disable this job | _none_ | -| `MAVEN_DEPENDENCY_CHECK_ARGS` | Maven arguments for Dependency Check job | `org.owasp:dependency-check-maven:check -DretireJsAnalyzerEnabled=false -DassemblyAnalyzerEnabled=false` | +| `dependency-check-disabled` / `MAVEN_DEPENDENCY_CHECK_DISABLED` | Set to `true` to disable this job | _none_ | +| `dependency-check-args` / `MAVEN_DEPENDENCY_CHECK_ARGS` | Maven arguments for Dependency Check job | `org.owasp:dependency-check-maven:check -DretireJsAnalyzerEnabled=false -DassemblyAnalyzerEnabled=false` | A Dependency Check is a quite long operation and therefore the job is configured to be ran __manually__ by default. @@ -187,9 +214,9 @@ Failure is allowed in feature branches. It is bound to the `test` stage, and uses the following variables: -| Name | description | default value | +| Input / Variable | Description | Default value | | --------------------- | -------------------------------------- | ----------------- | -| `MVN_FORBID_SNAPSHOT_DEPENDENCIES_DISABLED` | Set to `true` to disable this job | _none_ | +| `mvn-forbid-snapshot-dependencies-disabled` / `MVN_FORBID_SNAPSHOT_DEPENDENCIES_DISABLED` | Set to `true` to disable this job | _none_ | ### `mvn-sbom` job @@ -197,10 +224,10 @@ This job generates a [SBOM](https://cyclonedx.org/) file listing all dependencie It is bound to the `test` stage, and uses the following variables: -| Name | description | default value | +| Input / Variable | Description | Default value | | --------------------- | -------------------------------------- | ----------------- | -| `MAVEN_SBOM_DISABLED` | Set to `true` to disable this job | _none_ | -| `MAVEN_SBOM_GEN_ARGS` | Maven command used for SBOM analysis | `org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom` | +| `sbom-disabled` / `MAVEN_SBOM_DISABLED` | Set to `true` to disable this job | _none_ | +| `sbom-gen-args` / `MAVEN_SBOM_GEN_ARGS` | Maven command used for SBOM analysis | `org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom` | ### `mvn-release` & `mvn-deploy-*` jobs @@ -216,18 +243,18 @@ These jobs are **disabled by default** and - when enabled - respectively perform They are bound to the `publish` stage, and use the following variables: -| Name | description | default value | +| Input / Variable | Description | Default value | | ----------------------------------- | ------------------------------------------------------------ | ----------------- | -| `MAVEN_DEPLOY_ENABLED` | Set to `true` to enable release and publish jobs | _none_ (disabled) | -| `MAVEN_DEPLOY_FROM_UNPROTECTED_DISABLED`| Set to `true` to limit snapshot publication to protected branches | _none_ (disabled) | -| `MAVEN_DEPLOY_SNAPSHOT_WITH_SLUG_ENABLED`| Set to `true` to inject the Git branch slug in SNAPSHOT versions | _none_ (disabled) | -| `MAVEN_DEPLOY_ARGS` | Maven arguments for the `mvn-deploy` job | `deploy -Dmaven.test.skip=true` | -| `MAVEN_RELEASE_ARGS` | Maven arguments for the `mvn-release` job | `release:prepare -DtagNameFormat=@{project.version} -Darguments=-Dmaven.test.skip=true` | -| `MAVEN_RELEASE_VERSION` | Explicit version to use when triggering a release | _none_ (uses the current snapshot version from `pom.xml`) | -| `MAVEN_RELEASE_SCM_COMMENT_PREFIX` | Maven release plugin [scmCommentPrefix](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmCommentPrefix) parameter | `chore(maven-release): ` | -| `MAVEN_RELEASE_SCM_RELEASE_COMMENT` | Maven release plugin [scmReleaseCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmReleaseCommitComment) parameter (since Maven `3.0.0-M1`) | _none_ (Maven default) | -| `MAVEN_RELEASE_SCM_DEV_COMMENT` | Maven release plugin [scmDevelopmentCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmDevelopmentCommitComment) parameter (since Maven `3.0.0-M1`) | _none_ (Maven default) | -| `MVN_SEMREL_RELEASE_DISABLED` | Set to `true` to disable [semantic-release integration](#semantic-release-integration) | _none_ (disabled) | +| `deploy-enabled` / `MAVEN_DEPLOY_ENABLED` | Set to `true` to enable release and publish jobs | _none_ (disabled) | +| `deploy-from-unprotected-disabled` / `MAVEN_DEPLOY_FROM_UNPROTECTED_DISABLED` | Set to `true` to limit snapshot publication to protected branches | _none_ (disabled) | +| `deploy-snapshot-with-slug-enabled` / `MAVEN_DEPLOY_SNAPSHOT_WITH_SLUG_ENABLED` | Set to `true` to inject the Git branch slug in SNAPSHOT versions | _none_ (disabled) | +| `deploy-args` / `MAVEN_DEPLOY_ARGS` | Maven arguments for the `mvn-deploy` job | `deploy -Dmaven.test.skip=true` | +| `release-args` / `MAVEN_RELEASE_ARGS` | Maven arguments for the `mvn-release` job | `release:prepare -DtagNameFormat=@{project.version} -Darguments=-Dmaven.test.skip=true` | +| `release-version` / `MAVEN_RELEASE_VERSION` | Explicit version to use when triggering a release | _none_ (uses the current snapshot version from `pom.xml`) | +| `release-scm-comment-prefix` / `MAVEN_RELEASE_SCM_COMMENT_PREFIX` | Maven release plugin [scmCommentPrefix](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmCommentPrefix) parameter | `chore(maven-release): ` | +| `release-scm-release-comment` / `MAVEN_RELEASE_SCM_RELEASE_COMMENT` | Maven release plugin [scmReleaseCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmReleaseCommitComment) parameter (since Maven `3.0.0-M1`) | _none_ (Maven default) | +| `release-scm-dev-comment` / `MAVEN_RELEASE_SCM_DEV_COMMENT` | Maven release plugin [scmDevelopmentCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmDevelopmentCommitComment) parameter (since Maven `3.0.0-M1`) | _none_ (Maven default) | +| `mvn-semrel-release-disabled` / `MVN_SEMREL_RELEASE_DISABLED` | Set to `true` to disable [semantic-release integration](#semantic-release-integration) | _none_ (disabled) | More info: @@ -436,10 +463,10 @@ This variant uses the [Jib Maven Plugin](https://github.com/GoogleContainerTools ##### Images and registries config -| Name | Description | Default value | +| Input / Variable | Description | Default value | | -------------------------------------------- | ------------------------ | ------------------------------------------------- | -| `MAVEN_JIB_SNAPSHOT_IMAGE` | Container snapshot image | `$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG` | -| `MAVEN_JIB_RELEASE_IMAGE` | Container release image | `$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME` | +| `jib-snapshot-image` / `MAVEN_JIB_SNAPSHOT_IMAGE` | Container snapshot image | `$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG` | +| `jib-release-image` / `MAVEN_JIB_RELEASE_IMAGE` | Container release image | `$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME` | | :lock: `MAVEN_JIB_REGISTRY_USER` | Default registry username for image registry | `$CI_REGISTRY_USER` _(default GitLab registry user)_ | | :lock: `MAVEN_JIB_REGISTRY_PASSWORD` | Default registry password for image registry | `$CI_REGISTRY_PASSWORD` _(default GitLab registry password)_ | | :lock: `MAVEN_JIB_REGISTRY_SNAPSHOT_USER` | Registry username for snapshot image registry.<br/> Only set if different from default. | _none_ | @@ -451,13 +478,13 @@ The template uses GitLab registries and authentication defaults. See the Docker ##### Security scanning and reporting -| Name | Description | Default value | +| Input / Variable | Description | Default value | | -------------------------------------- | ------------------------ | ------------------------------------------------- | -| `MAVEN_SBOM_IMAGE` | The image used to perform and complete the Security Bill of Materials | `registry.hub.docker.com/anchore/syft:debug` | -| `MAVEN_SBOM_OPTS` | SBOM options to complete the Security Bill of Materials | `--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-catalogerE` | -| `MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD` | Security level which fails the `mvn-trivy` job | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | -| `MAVEN_TRIVY_IMAGE` | The image to perform container security scanning | `registry.hub.docker.com/aquasec/trivy:latest` | -| `MAVEN_TRIVY_ARGS` | Arguments for the execution of Trivy | `--ignore-unfixed --vuln-type os` | +| `sbom-image` / `MAVEN_SBOM_IMAGE` | The image used to perform and complete the Security Bill of Materials | `registry.hub.docker.com/anchore/syft:debug` | +| `sbom-opts` / `MAVEN_SBOM_OPTS` | SBOM options to complete the Security Bill of Materials | `--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-catalogerE` | +| `trivy-security-level-threshold` / `MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD` | Security level which fails the `mvn-trivy` job | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | +| `trivy-image` / `MAVEN_TRIVY_IMAGE` | The image to perform container security scanning | `registry.hub.docker.com/aquasec/trivy:latest` | +| `trivy-args` / `MAVEN_TRIVY_ARGS` | Arguments for the execution of Trivy | `--ignore-unfixed --vuln-type os` | ##### Jib build and publish configuration @@ -467,12 +494,12 @@ Tho `mvn-build` job produces and uploads the container snapshot to the registry Publishing the release image follows the two-phase Maven release and deploy model. The `mvn-release` job is responsible for versioning and tagging the `pom.xml` using the Maven Release Plugin, e.g., `release:prepare`. The `mvn-deploy-release` job deploys, or "releases," the container via [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/main/docs/skopeo-copy.1.md) to the provided registry in `$MAVEN_JIB_RELEASE_IMAGE`. -| Name | Description | Default value | +| Input / Variable | Description | Default value | | --------------------------------- | ---------------------------------------------------------- | ----------------- | -| `MAVEN_SKOPEO_IMAGE` | The image used to publish docker image with Skopeo | `quay.io/skopeo/stable:latest` | -| `MAVEN_JIB_BUILD_ARGS` | [Jib Maven Plugin arguments](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage). | `-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE` | -| `MAVEN_JIB_PUBLISH_ARGS` | Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/main/docs/skopeo-copy.1.md), e.g., `--additional-tag=strings` | _none_ | -| `MAVEN_JIB_PROD_PUBLISH_STRATEGY` | Defines the publish to production strategy for `mvn-release` and `mvn-deploy-release` jobs. One of `none`, `auto`, `manual`. | `manual` | +| `skopeo-image` / `MAVEN_SKOPEO_IMAGE` | The image used to publish docker image with Skopeo | `quay.io/skopeo/stable:latest` | +| `jib-build-args` / `MAVEN_JIB_BUILD_ARGS` | [Jib Maven Plugin arguments](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage). | `-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE` | +| `jib-publish-args` / `MAVEN_JIB_PUBLISH_ARGS` | Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/main/docs/skopeo-copy.1.md), e.g., `--additional-tag=strings` | _none_ | +| `jib-prod-publish-strategy` / `MAVEN_JIB_PROD_PUBLISH_STRATEGY` | Defines the publish to production strategy for `mvn-release` and `mvn-deploy-release` jobs. One of `none`, `auto`, `manual`. | `manual` | #### Usage @@ -499,13 +526,7 @@ All authentication methods should use masked GitLab environment variables. ```yaml include: # main template - - project: 'to-be-continuous/maven' - ref: '3.8.0' - file: '/templates/gitlab-ci-maven.yml' + - component: gitlab.com/to-be-continuous/maven/gitlab-ci-maven@3.8.0 # Jib is implemented as an extension to Maven, and uses supporting features of the TBC Maven template - - project: 'to-be-continuous/maven' - ref: '3.8.0' - file: '/templates/gitlab-ci-maven-jib.yml' - -variables: + - component: gitlab.com/to-be-continuous/maven/gitlab-ci-maven-jib@3.8.0 ``` diff --git a/bumpversion.sh b/bumpversion.sh index f06829a..ed44d7b 100755 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -27,13 +27,13 @@ if [[ "$curVer" ]]; then log_info "Bump version from \\e[33;1m${curVer}\\e[0m to \\e[33;1m${nextVer}\\e[0m (release type: $relType)..." # replace in README - sed -e "s/ref: '$curVer'/ref: '$nextVer'/" README.md > README.md.next + sed -e "s/ref: *'$curVer'/ref: '$nextVer'/" -e "s/ref: *\"$curVer\”/ref: \”$nextVer\”/" -e "s/component: *\(.*\)@$curVer/component: \1@$nextVer/" README.md > README.md.next mv -f README.md.next README.md # replace in template and variants for tmpl in templates/*.yml do - sed -e "s/\"$curVer\"/\"$nextVer\"/" "$tmpl" > "$tmpl.next" + sed -e "s/command: *\[\"--service\", \"\(.*\)\", \"$curVer\"\]/command: [\"--service\", \"\1\", \"$nextVer\"]/" "$tmpl" > "$tmpl.next" mv -f "$tmpl.next" "$tmpl" done else diff --git a/kicker.json b/kicker.json index 3ecf397..23270ab 100644 --- a/kicker.json +++ b/kicker.json @@ -3,6 +3,8 @@ "description": "Build, test and analyse your [Maven](https://maven.apache.org/)-based projects", "template_path": "templates/gitlab-ci-maven.yml", "kind": "build", + "prefix": "maven", + "is_component": true, "variables": [ { "name": "MAVEN_IMAGE", @@ -205,98 +207,104 @@ } ], "variants": [ - { - "id": "jib", - "name": "Jib", - "description": "Build Docker and OCI images for your Java applications with [Jib](https://github.com/GoogleContainerTools/jib)", - "template_path": "templates/gitlab-ci-maven-jib.yml", - "features": [ - { - "id": "mvn-trivy", - "name": "Maven Trivy", - "description": "[Trivy](https://github.com/aquasecurity/trivy) vulnerability analysis", - "disable_with": "MAVEN_TRIVY_DISABLED", - "variables": [ - { - "name": "MAVEN_TRIVY_IMAGE", - "description": "The docker image used to scan images with Trivy", - "default": "registry.hub.docker.com/aquasec/trivy:latest", - "advanced": true - }, - { - "name": "MAVEN_TRIVY_ADDR", - "type": "url", - "description": "The Trivy server address" - }, - { - "name": "MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD", - "type": "enum", - "values": ["UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL", "LOW,MEDIUM,HIGH,CRITICAL", "MEDIUM,HIGH,CRITICAL", "HIGH,CRITICAL", "CRITICAL"], - "description": "Severities of vulnerabilities to be displayed (comma separated values: `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`)", - "default": "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" - }, - { - "name": "MAVEN_TRIVY_ARGS", - "description": "Additional `trivy client` arguments", - "default": "--ignore-unfixed --vuln-type os", - "advanced": true - } - ] - }, - { - "id": "mvn-sbom", - "name": "Maven Software Bill of Materials", - "description": "This job generates a file listing all dependencies using [syft](https://github.com/anchore/syft)", - "disable_with": "MAVEN_SBOM_DISABLED", - "variables": [ - { - "name": "MAVEN_SBOM_IMAGE", - "default": "registry.hub.docker.com/anchore/syft:debug", - "advanced": true - }, - { - "name": "MAVEN_SBOM_OPTS", - "description": "Options for syft used for SBOM analysis", - "default": "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger", - "advanced": true - } - ] - } - ], - "variables": [ - { - "name": "MAVEN_JIB_SNAPSHOT_IMAGE", - "description": "Maven Jib Snapshot image", - "default": "$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG" - }, - { - "name": "MAVEN_JIB_RELEASE_IMAGE", - "description": "Maven Jib Release image", - "default": "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME" - }, - { - "name": "MAVEN_SKOPEO_IMAGE", - "description": "The image used to publish images with Skopeo", - "default": "quay.io/skopeo/stable:latest", - "advanced": true - }, - { - "name": "MAVEN_JIB_BUILD_ARGS", - "description": "[Jib Maven Plugin arguments](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage)", - "default": "-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE" - }, - { - "name": "MAVEN_JIB_PROD_PUBLISH_STRATEGY", - "description": "Defines the publish to production strategy.", - "type": "enum", - "values": ["none", "manual", "auto"], - "default": "manual" - }, - { - "name": "MAVEN_JIB_PUBLISH_ARGS", - "description": "Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/master/docs/skopeo-copy.1.md#options)" - } - ] - } + { + "id": "jib", + "name": "Jib", + "description": "Build Docker and OCI images for your Java applications with [Jib](https://github.com/GoogleContainerTools/jib)", + "template_path": "templates/gitlab-ci-maven-jib.yml", + "features": [ + { + "id": "mvn-trivy", + "name": "Maven Trivy", + "description": "[Trivy](https://github.com/aquasecurity/trivy) vulnerability analysis", + "disable_with": "MAVEN_TRIVY_DISABLED", + "variables": [ + { + "name": "MAVEN_TRIVY_IMAGE", + "description": "The docker image used to scan images with Trivy", + "default": "registry.hub.docker.com/aquasec/trivy:latest", + "advanced": true + }, + { + "name": "MAVEN_TRIVY_ADDR", + "type": "url", + "description": "The Trivy server address" + }, + { + "name": "MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD", + "type": "enum", + "values": [ + "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL", + "LOW,MEDIUM,HIGH,CRITICAL", + "MEDIUM,HIGH,CRITICAL", + "HIGH,CRITICAL", + "CRITICAL" + ], + "description": "Severities of vulnerabilities to be displayed (comma separated values: `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`)", + "default": "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" + }, + { + "name": "MAVEN_TRIVY_ARGS", + "description": "Additional `trivy client` arguments", + "default": "--ignore-unfixed --vuln-type os", + "advanced": true + } + ] + }, + { + "id": "mvn-sbom", + "name": "Maven Software Bill of Materials", + "description": "This job generates a file listing all dependencies using [syft](https://github.com/anchore/syft)", + "disable_with": "MAVEN_SBOM_DISABLED", + "variables": [ + { + "name": "MAVEN_SBOM_IMAGE", + "default": "registry.hub.docker.com/anchore/syft:debug", + "advanced": true + }, + { + "name": "MAVEN_SBOM_OPTS", + "description": "Options for syft used for SBOM analysis", + "default": "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger", + "advanced": true + } + ] + } + ], + "variables": [ + { + "name": "MAVEN_JIB_SNAPSHOT_IMAGE", + "description": "Maven Jib Snapshot image", + "default": "$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG" + }, + { + "name": "MAVEN_JIB_RELEASE_IMAGE", + "description": "Maven Jib Release image", + "default": "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME" + }, + { + "name": "MAVEN_SKOPEO_IMAGE", + "description": "The image used to publish images with Skopeo", + "default": "quay.io/skopeo/stable:latest", + "advanced": true + }, + { + "name": "MAVEN_JIB_BUILD_ARGS", + "description": "[Jib Maven Plugin arguments](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage)", + "default": "-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE" + }, + { + "name": "MAVEN_JIB_PROD_PUBLISH_STRATEGY", + "description": "Defines the publish to production strategy.", + "type": "enum", + "values": ["none", "manual", "auto"], + "default": "manual" + }, + { + "name": "MAVEN_JIB_PUBLISH_ARGS", + "description": "Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/master/docs/skopeo-copy.1.md#options)" + } + ] + } ] } diff --git a/logo.png b/logo.png index 2dd51fb18916b429323eb0296756f1f8aa740a46..0776126ab1c1593539e5261ffd3733b75d7c85c3 100644 GIT binary patch literal 13030 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 literal 18448 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 VAFY-+kp;94&(qb<Wt~$(697o4W3vDN diff --git a/templates/gitlab-ci-maven-jib.yml b/templates/gitlab-ci-maven-jib.yml index 7e0875a..395c91e 100644 --- a/templates/gitlab-ci-maven-jib.yml +++ b/templates/gitlab-ci-maven-jib.yml @@ -1,17 +1,73 @@ # ===================================================================================================================== # === JIB template variant # ===================================================================================================================== +spec: + inputs: + jib-snapshot-image: + description: Maven Jib Snapshot image + default: $CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG + jib-release-image: + description: Maven Jib Release image + default: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME + skopeo-image: + description: The image used to publish images with Skopeo + default: quay.io/skopeo/stable:latest + jib-build-args: + description: '[Jib Maven Plugin arguments](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage)' + default: -Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE + jib-prod-publish-strategy: + description: Defines the publish to production strategy. + options: + - none + - manual + - auto + default: manual + jib-publish-args: + description: Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/master/docs/skopeo-copy.1.md#options) + default: '' + trivy-disabled: + description: Disable Maven Trivy + type: boolean + default: false + trivy-image: + description: The docker image used to scan images with Trivy + default: registry.hub.docker.com/aquasec/trivy:latest + trivy-addr: + description: The Trivy server address + default: '' + trivy-security-level-threshold: + description: 'Severities of vulnerabilities to be displayed (comma separated values: + `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`)' + options: + - UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL + - LOW,MEDIUM,HIGH,CRITICAL + - MEDIUM,HIGH,CRITICAL + - HIGH,CRITICAL + - CRITICAL + default: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL + trivy-args: + description: Additional `trivy client` arguments + default: --ignore-unfixed --vuln-type os + sbom-image: + default: registry.hub.docker.com/anchore/syft:debug + sbom-opts: + description: Options for syft used for SBOM analysis + default: --catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger +--- variables: - MAVEN_SBOM_IMAGE: "registry.hub.docker.com/anchore/syft:debug" - MAVEN_SBOM_OPTS: "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger" - MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" - MAVEN_TRIVY_IMAGE: "registry.hub.docker.com/aquasec/trivy:latest" - MAVEN_TRIVY_ARGS: "--ignore-unfixed --vuln-type os" - MAVEN_JIB_SNAPSHOT_IMAGE: "$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG" - MAVEN_JIB_RELEASE_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME" - MAVEN_JIB_BUILD_ARGS: "-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE" - MAVEN_JIB_PROD_PUBLISH_STRATEGY: "manual" - MAVEN_SKOPEO_IMAGE: "quay.io/skopeo/stable:latest" + MAVEN_SBOM_IMAGE: $[[ inputs.sbom-image ]] + MAVEN_SBOM_OPTS: $[[ inputs.sbom-opts ]] + MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD: $[[ inputs.trivy-security-level-threshold ]] + MAVEN_TRIVY_IMAGE: $[[ inputs.trivy-image ]] + MAVEN_TRIVY_ARGS: $[[ inputs.trivy-args ]] + MAVEN_JIB_SNAPSHOT_IMAGE: $[[ inputs.jib-snapshot-image ]] + MAVEN_JIB_RELEASE_IMAGE: $[[ inputs.jib-release-image ]] + MAVEN_JIB_BUILD_ARGS: $[[ inputs.jib-build-args ]] + MAVEN_JIB_PROD_PUBLISH_STRATEGY: $[[ inputs.jib-prod-publish-strategy ]] + MAVEN_SKOPEO_IMAGE: $[[ inputs.skopeo-image ]] + MAVEN_JIB_PUBLISH_ARGS: $[[ inputs.jib-publish-args ]] + MAVEN_TRIVY_DISABLED: $[[ inputs.trivy-disabled ]] + MAVEN_TRIVY_ADDR: $[[ inputs.trivy-addr ]] .mvn-jib-scripts: &mvn-jib-scripts | # BEGSCRIPT diff --git a/templates/gitlab-ci-maven.yml b/templates/gitlab-ci-maven.yml index 616fa22..c468b4d 100644 --- a/templates/gitlab-ci-maven.yml +++ b/templates/gitlab-ci-maven.yml @@ -13,6 +13,122 @@ # program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth # Floor, Boston, MA 02110-1301, USA. # ========================================================================================= +spec: + inputs: + image: + description: The Docker image used to run Maven - **set the version required by + your project** + default: registry.hub.docker.com/library/maven:latest + project-dir: + description: Maven project root directory + default: . + cfg-dir: + description: The Maven configuration directory + default: .m2 + settings-file: + description: The Maven `settings.xml` file path + default: ${MAVEN_CFG_DIR}/settings.xml + opts: + description: '[Global Maven options](http://maven.apache.org/configure.html#maven_opts-environment-variable)' + default: >- + -Dhttps.protocols=TLSv1.2 + -Dmaven.repo.local=${MAVEN_CFG_DIR}/repository + -Dorg.slf4j.simpleLogger.showDateTime=true + -Djava.awt.headless=true + cli-opts: + description: Additional [Maven options](https://maven.apache.org/ref/3-LATEST/maven-embedder/cli.html) + used on the command line + default: >- + --no-transfer-progress + --batch-mode + --errors + --fail-at-end + --show-version + -DinstallAtEnd=true + -DdeployAtEnd=true + build-args: + description: Maven arguments for the build & test job + default: org.jacoco:jacoco-maven-plugin:prepare-agent verify org.jacoco:jacoco-maven-plugin:report + sonar-host-url: + description: SonarQube server url + default: '' + sonar-base-args: + description: SonarQube [analysis arguments](https://docs.sonarqube.org/latest/analysis/analysis-parameters/) + default: >- + sonar:sonar + -Dsonar.links.homepage=${CI_PROJECT_URL} + -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines + -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues + sonar-quality-gate-enabled: + description: 'Enables SonarQube [Quality Gate](https://docs.sonarqube.org/latest/user-guide/quality-gates/) + verification. + + + _Uses `sonar.qualitygate.wait` parameter ([see doc](https://docs.sonarqube.org/latest/analysis/ci-integration-overview/#header-1))._' + type: boolean + default: false + dependency-check-disabled: + description: Disable Dependency-Check + type: boolean + default: false + dependency-check-args: + description: Maven arguments for Dependency Check job + default: >- + org.owasp:dependency-check-maven:aggregate + -DretireJsAnalyzerEnabled=false + -DassemblyAnalyzerEnabled=false + -Dformats=HTML,JSON,XML + mvn-forbid-snapshot-dependencies-disabled: + description: Disable Snapshot dependencies verification + type: boolean + default: false + sbom-disabled: + description: Disable Software Bill of Materials + type: boolean + default: false + sbom-gen-args: + description: Maven command used for SBOM analysis + default: org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom + deploy-enabled: + description: Enable Publish + type: boolean + default: false + deploy-args: + description: Maven arguments for the deploy job + default: deploy -Dmaven.test.skip=true + deploy-from-unprotected-disabled: + description: Set to limit snapshot publication to protected branches + type: boolean + default: false + deploy-snapshot-with-slug-enabled: + description: Enable to inject the Git branch slug in SNAPSHOT versions + type: boolean + default: false + release-args: + description: Maven arguments for the release job + default: release:prepare -DtagNameFormat=@{project.version} -Darguments=-Dmaven.test.skip=true + release-version: + description: 'Explicit version to use when triggering a release + _Otherwise uses the current snapshot version from `pom.xml`)_' + default: '' + release-scm-comment-prefix: + description: Maven release plugin [scmCommentPrefix](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmCommentPrefix) + parameter + default: 'chore(maven-release): ' + release-scm-release-comment: + description: 'Maven release plugin [scmReleaseCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmReleaseCommitComment) + parameter + (since Maven `3.0.0-M1`)' + default: '' + release-scm-dev-comment: + description: 'Maven release plugin [scmDevelopmentCommitComment](https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html#scmDevelopmentCommitComment) + parameter + (since Maven `3.0.0-M1`)' + default: '' + mvn-semrel-release-disabled: + description: Disable semantic-release integration + default: '' +--- # default workflow rules: Merge Request pipelines workflow: rules: @@ -59,70 +175,53 @@ variables: TBC_TRACKING_IMAGE: "registry.gitlab.com/to-be-continuous/tools/tracking:master" # Default Maven project root directory - MAVEN_PROJECT_DIR: . - + MAVEN_PROJECT_DIR: $[[ inputs.project-dir ]] # Maven image (can be overridden) - MAVEN_IMAGE: "registry.hub.docker.com/library/maven:latest" - + MAVEN_IMAGE: $[[ inputs.image ]] # default production ref name (pattern) 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]+$/' - # default configuration directory - MAVEN_CFG_DIR: ".m2" + MAVEN_CFG_DIR: $[[ inputs.cfg-dir ]] # default settings.xml file path - MAVEN_SETTINGS_FILE: "$MAVEN_CFG_DIR/settings.xml" - + MAVEN_SETTINGS_FILE: $[[ inputs.settings-file ]] # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. - MAVEN_OPTS: >- - -Dhttps.protocols=TLSv1.2 - -Dmaven.repo.local=${MAVEN_CFG_DIR}/repository - -Dorg.slf4j.simpleLogger.showDateTime=true - -Djava.awt.headless=true - + MAVEN_OPTS: $[[ inputs.opts ]] # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used # when running from the command line. # `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins. - MAVEN_CLI_OPTS: >- - --no-transfer-progress - --batch-mode - --errors - --fail-at-end - --show-version - -DinstallAtEnd=true - -DdeployAtEnd=true - + MAVEN_CLI_OPTS: $[[ inputs.cli-opts ]] # Maven build arguments - MAVEN_BUILD_ARGS: "org.jacoco:jacoco-maven-plugin:prepare-agent verify org.jacoco:jacoco-maven-plugin:report" - + MAVEN_BUILD_ARGS: $[[ inputs.build-args ]] # Sonar base analysis default args # see: https://docs.sonarqube.org/latest/analysis/analysis-parameters/ # default uses branch analysis: https://docs.sonarqube.org/latest/branches/overview/ - SONAR_BASE_ARGS: >- - sonar:sonar - -Dsonar.links.homepage=${CI_PROJECT_URL} - -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines - -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues - + SONAR_BASE_ARGS: $[[ inputs.sonar-base-args ]] # Dependency Check arguments - MAVEN_DEPENDENCY_CHECK_ARGS: >- - org.owasp:dependency-check-maven:aggregate - -DretireJsAnalyzerEnabled=false - -DassemblyAnalyzerEnabled=false - -Dformats=HTML,JSON,XML - + MAVEN_DEPENDENCY_CHECK_ARGS: $[[ inputs.dependency-check-args ]] # SBOM genenration arguments - MAVEN_SBOM_GEN_ARGS: org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom - + MAVEN_SBOM_GEN_ARGS: $[[ inputs.sbom-gen-args ]] # Maven deploy arguments - MAVEN_DEPLOY_ARGS: "deploy -Dmaven.test.skip=true" - + MAVEN_DEPLOY_ARGS: $[[ inputs.deploy-args ]] # Maven release arguments - MAVEN_RELEASE_ARGS: "release:prepare -DtagNameFormat=@{project.version} -Darguments=-Dmaven.test.skip=true" - MAVEN_RELEASE_SCM_COMMENT_PREFIX: "chore(maven-release): " + MAVEN_RELEASE_ARGS: $[[ inputs.release-args ]] + MAVEN_RELEASE_SCM_COMMENT_PREFIX: $[[ inputs.release-scm-comment-prefix ]] + + SONAR_HOST_URL: $[[ inputs.sonar-host-url ]] + SONAR_QUALITY_GATE_ENABLED: $[[ inputs.sonar-quality-gate-enabled ]] + MAVEN_DEPENDENCY_CHECK_DISABLED: $[[ inputs.dependency-check-disabled ]] + MVN_FORBID_SNAPSHOT_DEPENDENCIES_DISABLED: $[[ inputs.mvn-forbid-snapshot-dependencies-disabled ]] + MAVEN_SBOM_DISABLED: $[[ inputs.sbom-disabled ]] + MAVEN_DEPLOY_ENABLED: $[[ inputs.deploy-enabled ]] + MAVEN_DEPLOY_FROM_UNPROTECTED_DISABLED: $[[ inputs.deploy-from-unprotected-disabled ]] + MAVEN_DEPLOY_SNAPSHOT_WITH_SLUG_ENABLED: $[[ inputs.deploy-snapshot-with-slug-enabled ]] + MAVEN_RELEASE_VERSION: $[[ inputs.release-version ]] + MAVEN_RELEASE_SCM_RELEASE_COMMENT: $[[ inputs.release-scm-release-comment ]] + MAVEN_RELEASE_SCM_DEV_COMMENT: $[[ inputs.release-scm-dev-comment ]] + MVN_SEMREL_RELEASE_DISABLED: $[[ inputs.mvn-semrel-release-disabled ]] stages: - build -- GitLab