Use java-image-build-scan-deploy Pipeline
This pipeline is designed to automate a full CI/CD workflow for Java applications.
It is reusable and flexible, supporting custom build arguments, multiple workspaces, and conditional execution of steps.
Key Features:
- ✅ Flexible code source
- ⚙️ Customizable Maven settings
- 🚀 Maven local repo caching support
- 🔌 Pluggable tasks via params
- 🛠️ Dynamic image build and push
- ☁️ Workload image update via kubectl
TOC
Specifying it using hub resolvers
The following example pipeline run references pipeline from the catalog:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: java-pipeline-run
spec:
pipelineRef:
resolver: hub
params:
- name: catalog
value: catalog
- name: kind
value: pipeline
- name: name
value: java-image-build-scan-deploy
- name: version
value: "0.1"
Parameters
Git Clone
-
git-url
- type: string
- default:
""
- description: Repository URL to clone from.
-
git-revision
- type: string
- default:
""
- description: Revision to checkout (branch, tag, sha, ref, etc...).
-
skip-git-clone
- type: string
- default:
"false"
- description: Skip to execute the git clone task. It can only be enabled if the corresponding code repository already exists in the workspace.
-
git-crt-file-name
- type: string
- default:
"ca-bundle.crt"
- description: File name of mounted crt using ssl-ca-directory workspace. default value is ca-bundle.crt.
Maven
-
maven-subdirectory
- type: string
- default:
.
- description: The context directory for Maven project.
-
maven-goals
- type: array
- default:
["package"]
- description: Maven goals to run.
-
maven-mirror-url
- type: string
- default:
""
- description: Maven repository mirror URL.
SonarQube Scanner
-
sonar-url
- type: string
- default:
""
- description: The URL to your SonarQube Server instance. If not specified, sonarqube scanner task will be skipped.
-
sonar-project-key
- type: string
- default:
""
- description: Unique key of the Sonarqube project.
-
sonar-properties
- type: array
- default:
["sonar.sources=.", "sonar.java.binaries=target/classes"]
- description: Additional properties to pass to SonarQube. You can refer to Configuration of SonarQube properties for more details.
Build Images
-
images
- type: array
- description: Reference of the images buildah will produce. Can contain multiple image addresses separated by commas. For example:
-
dockerfile-path
- type: string
- default: ./Dockerfile
- description: Path to the Dockerfile to build.
-
build-extra-args
- type: string
- default: ""
- description: Extra parameters passed for the build command when building images. WARNING - must be sanitized to avoid command injection (e.g. --build-arg key=value --label key=value).
-
build-args
- type: array
- default: [""]
- description: Specifies a build argument and its value, which will be interpolated in instructions read from the Dockerfile in the same way that environment variables are, but which will not be added to environment variable list in the resulting image's configuration. eg. HTTP_PROXY=http://10.10.10.10:8080
-
build-context
- type: string
- default: .
- description: Path to the directory to use as context.
-
push-extra-args
- type: string
- default: ""
- description: Extra parameters passed for the push command when pushing images. WARNING - must be sanitized to avoid command injection (e.g. --creds=username).
Trivy Scanner
-
skip-trivy-scan
- type: string
- default: "false"
- description: Set to skip trivy image scan after build.
-
trivy-extra-args
- type: string
- default: ""
- description: Extra parameters passed for the trivy command when scanning images. WARNING - must be sanitized to avoid command injection (e.g. --insecure). You can use
--skip-db-update
--skip-java-db-update
to skip updating vulnerability database.
Deploy or upgrade workload
-
workload-name
- type: string
- default: ""
- description: The name of the workload to deploy or upgrade. If it is not specified,
deploy-or-upgrade
task will be skipped.
-
workload-kind
- type: string
- default: Deployment
- description: The kind of workload to deploy or upgrade, such as Deployment, StatefulSet, etc.
-
workload-namespace
- type: string
- default: ""
- description: The namespace of the workload to deploy or upgrade. If not specified, will use the namespace of the current TaskRun.
-
workload-container
- type: string
- default: []
- description: This parameter is used to specify the containers within the workload whose image needs to be updated. By default, all of the container's image in the workload will be updated.
-
workload-rollout-timeout
- type: string
- default: "0"
- description: The length of time to wait before ending waiting workload ready,
0
means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).
-
workload-manifests-dir
- type: string
- default: ""
- description: The manifest of the workload to deploy. If it is not specified, will only update the image of the workload which is already in cluster. You can use the relative path to the manifest directory in the
source
workspace. For example: "manifests".
Workspaces
- source: Workspace to share information between tasks.
- git-basic-auth: An optional workspace containing a .gitconfig and .git-credentials file. These will be copied to the user's home before any git commands are run. Any other files in this Workspace are ignored. It is strongly recommended to use ssh-directory over basic-auth whenever possible and to bind a Secret to this Workspace over other volume types.
- git-ssh-directory: An optional workspace with private key, known_hosts, config, etc. Copied to the user's home before git commands are executed. Used to authenticate with the git remote when performing the clone. Binding a Secret to this Workspace is strongly recommended over other volume types.
- git-ssl-ca-directory: An optional workspace containing CA certificates, this will be used by Git to verify the peer with when fetching or pushing over HTTPS.
- maven-settings: An optional workspace containing custom maven settings.
- maven-local-repo: An optional workspace for Maven local repository.
- maven-server-secret: An optional workspace containing server credentials.
- sonar-settings: An optional workspace where SonarQube properties can be mounted.
- sonar-credentials: An optional workspace containing credentials for use within SonarQube.
- dockerconfig: An optional workspace for Docker configuration files, such as
config.json
or .dockerconfigjson
. This is optional and is used for authentication when pushing images to the registry.
- kubeconfig: An Optional workspace containing kubeconfig file. The name of kubeconfig should be
kubeconfig
. If there is no kubeconfig in this workspace, the workspace will be ignored.
Platforms
The Task can be run on linux/amd64
and linux/arm64
platforms.
Usage
Minimal Setup: Run End-to-End With Minimal Parameters
Optional tasks (sonarqube-scanner
, deploy-or-upgrade
, etc.) will be gracefully skipped when unset or omitted.
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: java-build-run-
spec:
pipelineRef:
name: java-image-build-scan-deploy
params:
- name: git-url
value: https://github.com/example/java-app
- name: git-revision
value: refs/heads/main
- name: images
value: ["registry.example.com/java-app:latest"]
workspaces:
- name: source
persistentVolumeClaim:
claimName: source
- name: git-basic-auth
secret:
secretName: gitconfig
- name: dockerconfig
secret:
secretName: dockerconfig
Use Maven Settings.xml
You can mount maven-settings
workspace to apply the settings.xml
for Maven builds.
workspaces:
- name: maven-settings
configMap:
name: maven-settings
apiVersion: v1
kind: ConfigMap
metadata:
name: maven-settings
data:
settings.xml: |
<!--# your maven settings.xml ...-->
You can also use maven-mirror-url
param to set a Maven repository mirror. It will be used as the <mirror>
in settings.xml
.
<mirror>
<id>mirror.default</id>
<url>$(params.maven-mirror-url)</url>
<mirrorOf>central</mirrorOf>
</mirror>
Use Build Cache to Accelerate CI
Attach a persistent maven-local-repo
workspace to cache .m2/repository
contents between pipeline runs.
Reuse dependencies can greatly reduce Maven dependency resolution time. Dramatically reduce build time across runs.
workspaces:
- name: maven-local-repo
persistentVolumeClaim:
claimName: maven-repo-cache
Configuration of SonarQube properties
You can mount sonar-settings
workspace or use sonar-properties
param to apply the properties for sonar-project.properties
file.
The default properties are: sonar.sources=.
, sonar.java.binaries=target/classes
.
You can find the usage of SonarQube properties from analysis parameters, and the properties for Java
Here is some of the properties you can set:
Properties | Description |
---|
sonar.java.binaries (required) | Comma-separated paths to directories containing the compiled bytecode files corresponding to your source files. |
sonar.java.libraries | Comma-separated paths to files with third-party libraries (JAR or Zip files) used by your project. Wildcards can be used: sonar.java.libraries=path/to/Library.jar,directory/**/*.jar |
sonar.java.test.binaries | Comma-separated paths to directories containing the compiled bytecode files corresponding to your test files |
sonar.java.test.libraries | Comma-separated paths to files with third-party libraries (JAR or Zip files) used by your tests. (For example, this should include the junit jar). Wildcards can be used: sonar.java.test.libraries=directory/**/*.jar |
sonar.qualitygate.wait | Forces the analysis step to poll the server instance and wait for the Quality Gate status. |
sonar.qualitygate.timeout | The number of seconds that the scanner should wait for a report to be processed. |
sonar.projectVersion | The project version. It should be set for branch analysis in case you use the new code definition based on the previous version. |
sonar.sources | Comma-separated paths to directories containing main source files |
sonar.organization | The organization in SonarQube where the project exists |
Deploy or upgrade a workload
You can deploy or upgrade a workload using the image built by the build-image
task in this pipeline.
By setting the workload-manifests-dir
param, you can apply Kubernetes manifests from the specified directory to create or update the workload.
Both JSON and YAML formats are supported. All manifests within the specified directory will be processed using kubectl apply
. Note that kubectl apply
does not traverse subdirectories.
If the directory contains a Kustomize configuration file (e.g. kustomization.yaml
, kustomization.yml
, or Kustomization
), it will be processed using kubectl kustomize
.
Here is an example structure of the workload-manifests-dir
:
manifests
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
You can configure the following parameters:
spec:
params:
# ...
- name: images
value:
- foo/bar:latest
- name: workload-name
value: bar
- name: workload-namespace
value: default
- name: workload-kind
value: Deployment
- name: workload-manifests-dir
value: manifests
# ...
If you prefer not to deploy the workload using manifests. Simply leave the workload-manifests-dir
param empty. In that case, the task will only update the image of an existing workload in the cluster.
You need to manage image pull secrets for the workload. If the new image is hosted in a different registry, make sure to create and configure the appropriate pull secret for your workload.
Skip tasks with Params
The pipeline supports skipping tasks using params:
Task | Param | Default | Description |
---|
git-clone | skip-git-clone | "false" | If code already exists in source workspace, you can set this to "true" to skip cloning. |
sonarqube-scanner | sonar-url | "" | Scan will be skipped if sonar-url is not set. |
trivy-scanner | skip-trivy-scan | "false" | Scan will be skipped if skip-trivy-scan is set to "true" . |
deploy-or-upgrade | workload-name | "" | If you don't want to deploy or upgrade the workload, you can left workload-name empty. |
Full Example with All Tasks
This example demonstrates how to use all tasks in the pipeline. It includes following tasks:
- Cloning the source code
- Building the code by Maven
- Building the image and pushing the image to the registry.
- Scanning the image with Trivy
- Scanning the code with SonarQube
- Deploying or Upgrading the workload
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: java-build-run-
spec:
pipelineRef:
name: java-image-build-scan-deploy
params:
- name: git-url
value: https://github.com/example/java-app
- name: git-revision
value: refs/heads/main
- name: sonar-url
value: https://sonar.example.com
- name: sonar-project-key
value: java-pipeline-example-key
- name: images
value: ["registry.example.com/java-app:latest"]
- name: workload-name
value: java-app
- name: workload-namespace
value: default
workspaces:
- name: source
persistentVolumeClaim:
claimName: source
- name: git-basic-auth
secret:
secretName: gitconfig
- name: sonar-credentials
secret:
secretName: sonar-credentials
- name: dockerconfig
secret:
secretName: docker-credentials
- name: kubeconfig
configMap:
name: kubeconfig