All Products
Search
Document Center

Container Service for Kubernetes:Build a CI pipeline with Argo Workflows

Last Updated:Jun 21, 2026

Argo Workflows provides intuitive tools to define workflows in YAML, allowing you to quickly set up and configure a CI pipeline. You can run jobs in parallel within your cluster, dynamically scale computing resources as needed, and improve the overall efficiency of your CI pipeline.

How it works

When Argo Workflows builds a CI pipeline, it primarily uses BuildKit to build and push container images and BuildKit Cache to accelerate image building. Using NAS to store the Go mod cache accelerates the go test and go build processes, which in turn significantly speeds up the CI pipeline workflow.

image

Predefined workflow template

You can use the predefined template directly or customize it to create your own CI workflow template. This example shows how to create a CI workflow template (ClusterWorkflowTemplate) named ci-go-v1 that uses BuildKit Cache and NAS to store the Go mod cache, accelerating the CI pipeline.

CI workflow template process

  1. Git clone and checkout

    • Clones the Git repository and checks it out to the target branch.

    • Retrieves the commit ID and appends it as a suffix to the image tag during the build process.

  2. Run Go test

    • By default, this step runs all test cases in the Git repository (a Go project).

    • The enable_test workflow parameter controls whether this step runs.

    • The Go mod cache is stored in the /pkg/mod directory on the NAS to accelerate go test and subsequent go build.

  3. Build and push image

    • Uses BuildKit to build and push the container image. It also uses a registry-type cache from BuildKit Cache to accelerate the image build.

    • By default, the image tag uses the {container_tag}-{commit_id} format. When submitting the workflow, you can use a parameter to control whether to append the commit ID.

    • When the new image is pushed, the latest tag is also updated to point to it.

CI workflow template content

apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
  name: ci-go-v1
spec:
  entrypoint: main
  volumes:
  - name: run-test
    emptyDir: {}
  - name: workdir
    persistentVolumeClaim:
      claimName: pvc-nas
  - name: docker-config
    secret:
      secretName: docker-config
  arguments:
    parameters:
    - name: repo_url
      value: ""
    - name: repo_name
      value: ""
    - name: target_branch
      value: "main"
    - name: container_image
      value: ""
    - name: container_tag
      value: "v1.0.0"
    - name: dockerfile
      value: "./Dockerfile"
    - name: enable_suffix_commitid
      value: "true"
    - name: enable_test
      value: "true"
  templates:
    - name: main
      dag:
        tasks:
          - name: git-checkout-pr
            inline:
              container:
                image: mirrors-ssl.aliyuncs.com/alpine:latest
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    apk --update add git
                    cd /workdir
                    echo "Start to Clone "{{workflow.parameters.repo_url}}
                    git -C "{{workflow.parameters.repo_name}}" pull || git clone {{workflow.parameters.repo_url}} 
                    cd {{workflow.parameters.repo_name}}
                    echo "Start to Checkout target branch" {{workflow.parameters.target_branch}}
                    git checkout --track origin/{{workflow.parameters.target_branch}} || git checkout {{workflow.parameters.target_branch}}
                    git pull
                    echo "Get commit id" 
                    git rev-parse --short origin/{{workflow.parameters.target_branch}} > /workdir/{{workflow.parameters.repo_name}}-commitid.txt
                    commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                    echo "Commit id is got: "$commitId
                    echo "Git Clone and Checkout Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                resources:
                  requests:
                    memory: 1Gi
                    cpu: 1
                activeDeadlineSeconds: 1200
          - name: run-test
            when: "{{workflow.parameters.enable_test}} == true"
            inline: 
              container:
                image: mirrors-ssl.aliyuncs.com/golang:alpine3.21
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    if [ ! -d "/workdir/pkg/mod" ]; then
                      mkdir -p /workdir/pkg/mod
                      echo "GOMODCACHE Directory /pkg/mod is created"
                    fi
                    export GOMODCACHE=/workdir/pkg/mod
                    cp -R /workdir/{{workflow.parameters.repo_name}} /test/{{workflow.parameters.repo_name}} 
                    echo "Start Go Test..."
                    cd /test/{{workflow.parameters.repo_name}}
                    go test -v ./...
                    echo "Go Test Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                - name: run-test
                  mountPath: /test
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: git-checkout-pr    
          - name: build-push-image
            inline: 
              container:
                image: mirrors-ssl.aliyuncs.com/moby/buildkit:v0.13.0-rootless
                command:
                  - sh
                  - -c
                  - |         
                    set -eu
                    tag={{workflow.parameters.container_tag}}
                    if [ {{workflow.parameters.enable_suffix_commitid}} = "true" ]
                    then
                      commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                      tag={{workflow.parameters.container_tag}}-$commitId
                    fi
                    echo "Image Tag is: "$tag
                    echo "Start to Build And Push Container Image"
                    cd /workdir/{{workflow.parameters.repo_name}}
                    buildctl-daemonless.sh build \
                    --frontend \
                    dockerfile.v0 \
                    --local \
                    context=. \
                    --local \
                    dockerfile=. \
                    --opt filename={{workflow.parameters.dockerfile}} \
                    --opt build-arg:GOPROXY=http://goproxy.cn,direct \
                    --output \
                    type=image,\"name={{workflow.parameters.container_image}}:${tag},{{workflow.parameters.container_image}}:latest\",push=true,registry.insecure=true \
                    --export-cache mode=max,type=registry,ref={{workflow.parameters.container_image}}:buildcache \
                    --import-cache type=registry,ref={{workflow.parameters.container_image}}:buildcache
                    echo "Build And Push Container Image {{workflow.parameters.container_image}}:${tag} and {{workflow.parameters.container_image}}:latest Complete."
                env:
                  - name: BUILDKITD_FLAGS
                    value: --oci-worker-no-process-sandbox
                  - name: DOCKER_CONFIG
                    value: /.docker
                volumeMounts:
                  - name: workdir
                    mountPath: /workdir
                  - name: docker-config
                    mountPath: /.docker
                securityContext:
                  seccompProfile:
                    type: Unconfined
                  runAsUser: 1000
                  runAsGroup: 1000
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: run-test

You can run kubectl apply -f cluster-workflow-template.yaml to deploy the template to the cluster.

Template parameter descriptions

Parameter

Description

Example

entrypoint

Defines the entrypoint template.

main

repo_url

The URL of the Git repository.

https://github.com/ivan-cai/echo-server.git

repo_name

The name of the repository.

echo-server

target_branch

The target branch of the repository. The default value is main.

main

container_image

Specifies the container image to build. The format is <Container Registry Enterprise Edition Domain>/<Container Registry Enterprise Edition namespace>/<repository name>.

test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server

container_tag

Specifies the image tag to build. The default value is v1.0.0.

v1.0.0

dockerfile

The path and filename of the Dockerfile.

This is a relative path from the project's root directory. The default value is ./Dockerfile.

./Dockerfile

enable_suffix_commitid

Specifies whether to append the commit ID to the image tag.

  • true (default): Appends the ID.

  • false: Does not append the ID.

true

enable_test

Specifies whether to run the Go Test step.

  • true (default): Runs the step.

  • false: Does not run the step.

true

Procedure

This topic uses a public Git repository to demonstrate how to build a CI pipeline. If you use a private Git repository in your workflow's CI pipeline, you must first clone the private repository. For more information, see Clone a private Git repository in a CI pipeline.

Important

The Secret that stores the access credentials for the container image and the mounted NAS volume must be in the same namespace as the workflow you submit.

Step 1: Create ACR EE access credentials

BuildKit primarily uses access credentials for Container Registry Enterprise Edition to push images.

  1. Configure access credentials for Container Registry Enterprise Edition. For more information, see Configure access credentials.

  2. Run the following command to create a Secret in the cluster. This Secret stores the password for Container Registry Enterprise Edition and is used by BuildKit.

    Note

    Replace $repositoryDomain with the address of your Container Registry image repository.

    Replace $username with the username for your Container Registry image repository.

    Replace $password with the password for your Container Registry image repository.

    kubectl create secret -n argo generic docker-config --from-literal="config.json={\"auths\": {\"$repositoryDomain\": {\"auth\": \"$(echo -n $username:$password|base64)\"}}}"

Step 2: Mount a NAS volume

After mounting a NAS volume, you can share data, such as cloned repository information, between different jobs in the workflow. The volume is also used to store the Go mod cache, which accelerates the go test and go build processes in the CI pipeline.

For more information, see Use volumes.

Step 3: Start a workflow from the template

Console

  1. Log on to the Argo console. In the left-side navigation pane, click Cluster Workflow Templates, and then click the ci-go-v1 predefined template.

  2. On the template details page, click + SUBMIT in the upper-left corner. In the panel, enter the required parameters and then click + SUBMIT at the bottom.

    For more information about the parameters, see the Template parameter descriptions section earlier in this topic. Set the parameters to your actual values.

    After the workflow is submitted, you can view its status on the Workflows page:

    The workflow runs the git-checkout-pr, run-test, and build-push-image steps in sequence as a DAG. When all nodes turn green, the workflow has completed successfully.

Argo CLI

  1. Create a file named workflow.yaml with the following content. Modify the parameter values based on your requirements. For more information, see the Template parameter descriptions section.

    apiVersion: argoproj.io/v1alpha1
    kind: Workflow
    metadata:
      generateName: ci-go-v1-
      labels:
        workflows.argoproj.io/workflow-template: ackone-ci
      namespace: argo  
    spec:
      arguments:
        parameters:
        - name: repo_url
          value: https://github.com/ivan-cai/echo-server.git
        - name: repo_name
          value: echo-server
        - name: target_branch
          value: main
        - name: container_image
          value: "test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server"
        - name: container_tag
          value: "v1.0.0"
        - name: dockerfile
          value: ./Dockerfile
        - name: enable_suffix_commitid
          value: "true"
        - name: enable_test
          value: "true"
      workflowTemplateRef:
        name: ci-go-v1
        clusterScope: true
  2. Run the following command to submit the workflow.

    argo submit workflow.yaml

Contact us

If you have any product suggestions or questions, you can contact us by joining the DingTalk group (ID: 35688562).