All Products
Search
Document Center

Container Compute Service:Build CI pipelines with Argo Workflows

Last Updated:Mar 26, 2026

The ci-go-v1 ClusterWorkflowTemplate gives you a ready-to-run CI pipeline for Go projects on Argo Workflows. It clones a Git repository, runs Go tests, and builds and pushes a container image — all as parallel-capable DAG tasks.

The template uses two mechanisms to speed up the pipeline:

  • BuildKit Cache (registry type) — caches intermediate image layers in your container registry to accelerate subsequent builds

  • File Storage NAS (NAS) Go module cache — persists the Go module cache on a NAS volume so go test and go build skip repeated downloads

image

Key concepts

Two terms in Argo Workflows look similar but mean different things:

  • `ClusterWorkflowTemplate` — a cluster-scoped Kubernetes custom resource (CRD) that defines a reusable workflow. It acts as a workflow blueprint available to all namespaces.

  • `template` (lowercase) — a single task unit *inside* a ClusterWorkflowTemplate. Types include container, script, dag, steps, suspend, and resource.

In ci-go-v1, the top-level templates field contains one dag template (named main) that orchestrates three inline container templates as tasks.

Prerequisites

Before you begin, make sure you have:

  • An ACK cluster with Argo Workflows installed

  • A Container Registry Enterprise Edition (ACR EE) instance with an image repository

  • A NAS volume mounted to the cluster (see Use volumes)

  • kubectl configured to access the cluster

  • The Argo CLI installed (required if submitting pipelines from the command line)

Important

The Secret that stores ACR EE credentials and the NAS PersistentVolumeClaim (PVC) must belong to the same namespace where you submit the pipeline.

How the ci-go-v1 template works

The template runs three tasks in sequence using a DAG:

  1. Git clone and checkout — Clones the Git repository to the NAS volume and checks out the target branch. The commit ID is written to a file on the NAS volume so the build step can append it to the image tag.

  2. Go test — Copies the repository to an ephemeral volume and runs go test -v ./... against all packages. The GOMODCACHE environment variable points to /workdir/pkg/mod on the NAS volume, so Go module downloads are cached across pipeline runs. This step is skipped when enable_test is set to false.

  3. Build and push image — Runs buildctl-daemonless.sh to build the Dockerfile and push two tags to ACR EE: a versioned tag ({container_tag}-{commit_id}) and latest. BuildKit Cache is imported from and exported back to the buildcache tag in your registry, so unchanged layers are reused on the next run.

All three tasks share the NAS volume (workdir) to pass data between steps. The Go test task additionally mounts an emptyDir volume (run-test) to isolate test execution from the source directory.

The ci-go-v1 ClusterWorkflowTemplate

View the template YAML

apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
  name: ci-go-v1
spec:
  entrypoint: main         # Entry point: the "main" DAG template defined below
  volumes:
  - name: run-test
    emptyDir: {}           # Ephemeral volume for isolated test execution
  - name: workdir
    persistentVolumeClaim:
      claimName: pvc-nas   # NAS PVC — shared across all three tasks
  - name: docker-config
    secret:
      secretName: docker-config  # Secret holding ACR EE credentials
  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   # NAS volume: persists repo and commit ID for downstream tasks
                resources:
                  requests:
                    memory: 1Gi
                    cpu: 1
                activeDeadlineSeconds: 1200
          - name: run-test
            when: "{{workflow.parameters.enable_test}} == true"   # Skip this task when enable_test=false
            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   # Point Go module cache to NAS for persistence

                    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   # NAS volume: read repo, write Go module cache
                - name: run-test
                  mountPath: /test      # emptyDir: isolated test workspace
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: git-checkout-pr    # Runs after git-checkout-pr completes
          - 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   # e.g. v1.0.0-abc1234
                    fi

                    echo "Image Tag is: "$tag
                    echo "Start to Build And Push Container Image"

                    cd /workdir/{{workflow.parameters.repo_name}}

                    # Build and push: exports versioned tag + latest; imports/exports BuildKit Cache from registry
                    buildctl-daemonless.sh build \
                    --frontend \
                    dockerfile.v0 \
                    --local \
                    context=. \
                    --local \
                    dockerfile=. \
                    --opt filename={{workflow.parameters.dockerfile}} \
                    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       # NAS volume: read repo and commit ID
                  - name: docker-config
                    mountPath: /.docker       # Secret: ACR EE credentials for push
                securityContext:
                  seccompProfile:
                    type: Unconfined
                  runAsUser: 1000
                  runAsGroup: 1000
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: run-test               # Runs after run-test completes (or after git-checkout-pr if enable_test=false)

Deploy the template to your cluster:

kubectl apply -f cluster-workflow-template.yaml

Template parameters

ParameterDescriptionDefault
repo_urlURL of the Git repository(blank)
repo_nameName of the repository(blank)
target_branchBranch to check outmain
container_imageImage to build. Format: <ACR EE Domain>/<ACR EE Namespace>/<Repository Name>(blank)
container_tagBase image tagv1.0.0
dockerfileRelative path to the Dockerfile from the repository root./Dockerfile
enable_suffix_commitidAppend the commit ID to the image tag. When true, produces tags like v1.0.0-abc1234.true
enable_testRun the Go test step. Set to false to skip testing.true

Set up and run a CI pipeline

This example uses a public Git repository. For private repositories, see Clone a private Git repository in a CI pipeline first.

Step 1: Create ACR EE credentials

The docker-config Secret stores the credentials BuildKit uses to push images to ACR EE.

  1. Configure access credentials for your ACR EE instance. See Configure access credentials for a Container Registry Enterprise Edition instance.

  2. Create the Secret in your pipeline namespace:

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

    Replace the following placeholders:

    PlaceholderDescription
    $repositoryDomainDomain name of your ACR EE image repository
    $usernameUsername for your ACR EE image repository
    $passwordPassword for your ACR EE image repository

Step 2: Mount a NAS volume

The NAS volume is shared across all three pipeline tasks. It stores the cloned repository, the commit ID file written by the git clone step, and the Go module cache that persists between pipeline runs.

Mount the NAS volume to your cluster — see Use volumes.

Step 3: Submit the pipeline

Option 1: Argo console

  1. Open the Argo console and click Cluster Workflow Templates in the left navigation pane. Click the ci-go-v1 template.

    image

  2. Click + SUBMIT in the upper-right corner. Set the parameters for your environment (see Template parameters), then click + SUBMIT.

    image

  3. View the pipeline status on the Workflows page.

    image

Option 2: Argo CLI

  1. Create a file named workflow.yaml with the following content, updating the parameters for your environment:

    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. Submit the pipeline:

    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).