Build your first component

This topic tells you how to use Tanzu Supply Chain to build a component.

Caution

Tanzu Supply Chain is currently in beta and is not intended for production use. It is intended only for evaluation purposes of the next generation Supply Chain. For the current Supply Chain solution, see the Supply Chain Choreographer documentation.

Prepare

Build a SupplyChain resource if you do not already have one. For how to build one, see Build your first SupplyChain.

Get started

In Build your first Supply Chain, you built a SupplyChain resource that retrieves the source code from a Git repository, and builds and packages it as a Carvel package. The SupplyChain resource then initiates a pull request to transfer the Carvel package to a GitOps repository, which enables the installation of the built package on the Run clusters.

This topic tells you how to create a component that you can use in your SupplyChain resource for unit-testing your Maven apps. You will create a component called maven-unit-tester, which will run unit tests on the source pulled by the source-git-provider stage.

tanzu supplychain component get source-git-provider-1.0.0 --show-details

Example:

...
📤 Outputs
   git
    ├─ digest: $(resumptions.check-source.results.sha)
    ├─ type: git
    └─ url: $(resumptions.check-source.results.url)
   source
    ├─ digest: $(pipeline.results.digest)
    ├─ type: source
    └─ url: $(pipeline.results.url)
...

Create a Tekton Pipeline

The first step for creating a Component resource is to make a Tekton Pipeline resource that includes the logic the component uses. In this case, maven-unit-tester:

  • Obtains the source code extracted by the source-git-provider component.
  • Uses the source code as input.
  • Runs the unit test command on the source repository.

Tekton Pipeline:

  • Defines parameters that a developer can provide by using the workload.
  • Creates a shared workspace to store intermediate files, such as the source code from the source-git-provider stage.
  • Provides tasks that run the unit-testing logic.

To create a Tekton Pipeline:

  1. Define parameters as shown in the following YAML:

    ---
    apiVersion: tekton.dev/v1
    kind: Pipeline
    metadata:
        name: maven-unit-tester-1.0.0
    spec:
        description: Test maven application using mvn test command
        params:
          - description: url of source registry image
            name: source-url
            type: string
          - description: sub directory in source to become root dir for build
            name: sub-path
            default: "."
            type: string
          - description: The test command to run in my task
            name: testcmd
            type: string
          - description: The test command to run in my task
            name: workload-name
            type: string
    
  2. Define a Tekton workspace as shown in the following YAML:

        workspaces:
          - name: shared-data
    
  3. Add two tasks to the Pipeline resource. Task 1 pulls the output from source-git-provider and puts it in the workspace shared-data that was defined in the Pipeline resource earlier. Task 2 runs the unit tests and records the output as a Tekton Result.

    See the following example YAML:

        tasks:
          # task 1 pulls the output from source-git-provider and puts it in a workspace called shared-data
          - name: fetch-source
            params:
              - name: url
                value: $(params.source-url)
            taskRef:
              kind: Task
              name: fetch-tgz-content-oci
            workspaces:
              - name: store
                workspace: shared-data
    
          # task 2 runs the unit tests
          - name: test
            runAfter:
              - fetch-source
            params:
              - name: sub-path
                value: $(params.sub-path)
              - name: testcmd
                value: $(params.testcmd)
              - name: workload-name
                value: $(params.workload-name)
            taskSpec:
              params:
                - name: sub-path
                - name: testcmd
                - name: workload-name
              results:
                - description: Error message if things failed
                  name: message
                  type: string
              steps:
                - name: test
                  image: maven
                  env:
                    - name: HOME
                      value: /tekton/home/
                  script: |-
                    #!/usr/bin/env sh
                    set -eu
                    ls -al $(workspaces.store.path)
                    cd $(workspaces.store.path)/$(params.sub-path)
    
                    set +e
                    $(params.testcmd)
                    testval=$?
                    set -e
    
                    if [ $testval -ne 0 ]; then
                      echo "Unit tests stage failed. Please run 'tanzu workload logs $(params.workload-name)' to see the run logs for more details." | tee "$(results.message.path)"
                      exit $testval
                    fi
              stepTemplate:
                  computeResources: {}
                  securityContext:
                      allowPrivilegeEscalation: false
                      capabilities:
                          drop:
                              - ALL
                      runAsNonRoot: true
                      runAsUser: 1001
                      seccompProfile:
                          type: RuntimeDefault
            workspaces:
              - name: store
                workspace: shared-data
    
  4. Add the version of the pipeline in the name of the YAML file and the name of the pipeline. This enables you to create new versions of the pipelines without interfering with the old one.

  5. Store the Pipeline resource in the pipelines directory created by the CLI as maven-unit-tester-1.0.0.yaml, as shown in the following YAML:

    ---
    apiVersion: tekton.dev/v1
    kind: Pipeline
    metadata:
        name: maven-unit-tester-1.0.0
    spec:
        description: Test maven application using mvn test command
        params:
          - description: url of source registry image
            name: source-url
            type: string
          - description: sub directory in source to become root dir for build
            name: sub-path
            default: "."
            type: string
          - description: The test command to run in my task
            name: testcmd
            type: string
          - description: The test command to run in my task
            name: workload-name
            type: string
        workspaces:
          - name: shared-data
        # My tasks starts here
        tasks:
          # task 1 pulls the output from source-git-provider and puts it in a workspace called shared-data
          - name: fetch-source
            params:
              - name: url
                value: $(params.source-url)
            taskRef:
              kind: Task
              name: fetch-tgz-content-oci
            workspaces:
              - name: store
                workspace: shared-data
    
          # task 2 runs the unit tests
          - name: test
            runAfter:
              - fetch-source
            params:
              - name: sub-path
                value: $(params.sub-path)
              - name: testcmd
                value: $(params.testcmd)
              - name: workload-name
                value: $(params.workload-name)
            taskSpec:
              params:
                - name: sub-path
                - name: testcmd
                - name: workload-name
              results:
                - description: Error message if things failed
                  name: message
                  type: string
              steps:
                - name: test
                  image: maven
                  env:
                    - name: HOME
                      value: /tekton/home/
                  script: |-
                    #!/usr/bin/env sh
                    set -eu
                    ls -al $(workspaces.store.path)
                    cd $(workspaces.store.path)/$(params.sub-path)
    
                    set +e
                    $(params.testcmd)
                    testval=$?
                    set -e
    
                    if [ $testval -ne 0 ]; then
                      echo "Unit tests stage failed. Please run 'tanzu workload logs $(params.workload-name)' to see the run logs for more details." | tee "$(results.message.path)"
                      exit $testval
                    fi
              stepTemplate:
                  computeResources: {}
                  securityContext:
                      allowPrivilegeEscalation: false
                      capabilities:
                          drop:
                              - ALL
                      runAsNonRoot: true
                      runAsUser: 1001
                      seccompProfile:
                          type: RuntimeDefault
            workspaces:
              - name: store
                workspace: shared-data
    
    

Create a SupplyChain Component

The section describes how to write a Component manifest that defines the following:

  • Configuration for a Component that is exposed as part of the Developer API. This is the configuration that a platform engineer can override at a SupplyChain level or that a developer can provide by using the Workload if a platform engineer does not override it at the SupplyChain level.

  • Inputs, which is a list of named Outputs from a previous stage in a SupplyChain resource that the current Component resource depends on.

  • Outputs, which are named outputs from this component another Component resource can use as Inputs.

  • The Pipeline Run Definition section, which defines the work performed by this component. spec.pipelineRun is used to create a Tekton PipelineRun and has many similarities.

  • Define the Component resource configuration as shown in the following YAML:

    ---
    apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
    kind: Component
    metadata:
        name: maven-unit-tester-1.0.0
    spec:
        description: Execute a maven unit test command using the mvn CLI
        config:
            - path: spec.test.cmd
              schema:
                description: |
                    Unit testing mvn command to run
                required:
                    - cmd
                type: string
                default: "mvn test"
                example: "mvn test"
    
  • Define Component inputs and outputs. In this case, the output of the source-git-provider component is used as an input for the maven-unit-tester component.

        inputs:
          - name: source
            type: source
    
  • Define Component PipelineRun details. The Pipeline resource created earlier is referenced here. The values are passed from the Workload and Inputs to satisfy the parameters for the Pipeline resource. See the following example YAML:

        pipelineRun:
            params:
                - name: source-url
                  value: $(inputs.source.url)
                - name: sub-path
                  value: $(workload.spec.source.subPath)
                - name: testcmd
                  value: $(workload.spec.test.cmd)
                - name: workload-name
                  value: $(workload.metadata.name)
            pipelineRef:
                name: maven-unit-tester-1.0.0
            taskRunTemplate:
                podTemplate:
                    securityContext:
                        fsGroup: 1000
                        runAsGroup: 1000
                        runAsUser: 1001
            workspaces:
                - name: shared-data
                  volumeClaimTemplate:
                    spec:
                        accessModes:
                            - ReadWriteOnce
                        resources:
                            requests:
                                storage: 1Gi
    
  • Store the Component resource in the components directory created by the CLI as maven-unit-tester-1.0.0.yaml. See the following example YAML:

    ---
    apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
    kind: Component
    metadata:
        name: maven-unit-tester-1.0.0
    spec:
        description: Execute a maven unit test command using the mvn CLI
        inputs:
          - name: source
            type: source
        config:
            - path: spec.test.cmd
              schema:
                description: |
                    Unit testing mvn command to run
                required:
                    - cmd
                type: string
                default: "mvn test"
                example: "mvn test"
        pipelineRun:
            params:
                - name: source-url
                  value: $(inputs.source.url)
                - name: sub-path
                  value: $(workload.spec.source.subPath)
                - name: testcmd
                  value: $(workload.spec.test.cmd)
                - name: workload-name
                  value: $(workload.metadata.name)
            pipelineRef:
                name: maven-unit-tester-1.0.0
            taskRunTemplate:
                podTemplate:
                    securityContext:
                        fsGroup: 1000
                        runAsGroup: 1000
                        runAsUser: 1001
            workspaces:
                - name: shared-data
                  volumeClaimTemplate:
                    spec:
                        accessModes:
                            - ReadWriteOnce
                        resources:
                            requests:
                                storage: 1Gi
    

Install the component

You can now use the make install target created by the tanzu supplychain CLI to install the new Component and Pipeline resources to see if they reconcile.

Install the component by running:

NAMESPACE=mysupplychains make install

This command also displays any errors that Tekton throws.

Next Steps

Add your new Component to a SupplyChain. For instructions, see Add stages to your Supply Chain.

Useful links

check-circle-line exclamation-circle-line close-line
Scroll to top icon