Go
You can build and test a Go application using a Linux platform on Harness Cloud or a self-managed Kubernetes cluster build infrastructure.
This guide assumes you've created a Harness CI pipeline.
Install dependencies
If necessary, add a Run step to install any dependencies.
- Harness Cloud
- Self-managed
- step:
    type: Run
    identifier: dependencies
    name: Dependencies
    spec:
      shell: Sh
      command: |-
        go get example.com/my-go-module
- step:
    type: Run
    identifier: dependencies
    name: Dependencies
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: golang:latest
      command: |-
        go get example.com/my-go-module
Cache dependencies
Add caching to your stage.
- Cache Intelligence
- Save and Restore Cache steps
Cache your Go module dependencies with Cache Intelligence.
Add caching.enabled.true to your stage.spec:
- stage:
    spec:
      caching:
        enabled: true
You can use built-in steps to:
Go pipelines must reference go.sum for spec.key in Save Cache and Restore Cache steps, for example:
spec:
  key: cache-{{ checksum "go.sum" }}
Additionally, spec.sourcePaths must include /go/pkg/mod and /root/.cache/go-build in the Save Cache step, for example:
spec:
  sourcePaths:
    - /go/pkg/mod
    - /root/.cache/go-build
YAML example: Save and restore cache steps
Here's an example of a pipeline with Save Cache to S3 and Restore Cache from S3 steps.
            steps:
              - step:
                  type: RestoreCacheS3
                  name: Restore Cache From S3
                  identifier: Restore_Cache_From_S3
                  spec:
                    connectorRef: AWS_Connector
                    region: us-east-1
                    bucket: your-s3-bucket
                    key: cache-{{ checksum "go.sum" }}
                    archiveFormat: Tar
              - step:
                  type: Run
                  ...
              - step:
                  type: BuildAndPushDockerRegistry
                  ...
              - step:
                  type: SaveCacheS3
                  name: Save Cache to S3
                  identifier: Save_Cache_to_S3
                  spec:
                    connectorRef: AWS_Connector
                    region: us-east-1
                    bucket: your-s3-bucket
                    key: cache-{{ checksum "go.sum" }}
                    sourcePaths:
                      - /go/pkg/mod
                      - /root/.cache/go-build
                    archiveFormat: Tar
Build and run tests
Add Run steps to build and run your tests.
- Harness Cloud
- Self-managed
- step:
    type: Run
    identifier: build
    name: Build
    spec:
      shell: Sh
      command: |-
        go build
- step:
    type: Run
    identifier: test
    name: Test
    spec:
      shell: Sh
      command: |-
        go test -v ./...
- step:
    type: Run
    identifier: build
    name: Build
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: golang:latest
      command: |-
        go build
- step:
    type: Run
    identifier: test
    name: Test
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: golang:latest
      command: |-
        go test -v ./...
Visualize test results
You can view test results on the Tests tab of your pipeline executions. Test results must be in JUnit XML format.
You can use go-junit-report to output compatible JUnit XML reports.
For your pipeline to produce test reports, you need to modify the Run step that runs your tests. Make sure the command generates JUnit XML reports and add the reports specification.
- Harness Cloud
- Self-managed
- step:
    type: Run
    identifier: test
    name: Test
    spec:
      shell: Sh
      command: |-
        export PATH=$(go env GOPATH)/bin:$PATH
        go install github.com/jstemmer/go-junit-report/v2@latest
        go test -v ./... | tee report.out
        cat report.out | go-junit-report -set-exit-code > report.xml
      reports:
        type: JUnit
        spec:
          paths:
            - report.xml
- step:
    type: Run
    identifier: test
    name: Test
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: golang
      command: |-
        go install github.com/jstemmer/go-junit-report/v2@latest
        go test -v ./... | tee report.out
        cat report.out | go-junit-report -set-exit-code > report.xml
      reports:
        type: JUnit
        spec:
          paths:
            - report.xml
Test splitting
You can use test splitting (parallelism) to improve test times.
Specify version
- Harness Cloud
- Self-managed
Go is pre-installed on Hosted Cloud runners. For details about all available tools and versions, go to Platforms and image specifications.
If your application requires a specific version of Go, add a Run step to install it.Install a specific version of Go
- step:
    type: Run
    identifier: installgo
    name: Install Go
    spec:
      shell: Sh
      # install version 1.20 of Go
      command: |-
        export PATH=$(go env GOPATH)/bin:$PATH
        go install golang.org/dl/go1.20@latest
        go1.20 downloadInstall multiple versions of Go
strategy:
  matrix:
    # matrix strategy with Go versions 1.19 and 1.20
    goVersion:
      - "1.19"
      - "1.20"
- step:
    type: Run
    identifier: installgo
    name: Install Go
    spec:
      shell: Sh
      command: |-
        export PATH=$(go env GOPATH)/bin:$PATH
        go install golang.org/dl/go<+matrix.goVersion>@latest
        go<+matrix.goVersion> download
Specify the desired Golang Docker image tag in your steps. There is no need for a separate install step when using Docker.Build using a specific version of Go
- step:
    type: Run
    identifier: build
    name: Build
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      # use version 1.20 of Go
      image: golang:1.20
      command: |-
        go buildBuild using multiple versions of Go
strategy:
  matrix:
    # matrix strategy with Go versions 1.19 and 1.20
    goVersion:
      - "1.19"
      - "1.20"
image field of your steps.- step:
    type: Run
    identifier: build
    name: Build
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: golang:<+matrix.goVersion>
      command: |-
        go build
Full pipeline examples
The following full pipeline examples are based on the partial examples above.
- Harness Cloud
- Self-managed
If you copy this example, replace the placeholder values with appropriate values for your code repo connector and repository name. Depending on your project and organization, you may also need to replace  Here is a single-stage pipeline using Cache Intelligence with steps to install Go 1.20, build, and test. Here is a single-stage pipeline using Cache Intelligence with a matrix looping strategy for Go versions 1.19 and 1.20.projectIdentifier and orgIdentifier.Pipeline with one specific Go version
pipeline:
  name: Build and test Go app
  identifier: Build_and_test_Go_app
  projectIdentifier: default
  orgIdentifier: default
  stages:
    - stage:
        name: Build
        identifier: Build
        type: CI
        spec:
          caching:
            enabled: true
          cloneCodebase: true
          execution:
            steps:
              - step:
                  type: Run
                  identifier: installgo
                  name: Install Go
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go install golang.org/dl/go1.20@latest
                      go1.20 download
              - step:
                  type: Run
                  identifier: build
                  name: Build
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go1.20 build
              - step:
                  type: Run
                  identifier: test
                  name: Test
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go1.20 install github.com/jstemmer/go-junit-report/v2@latest
                      go1.20 test -v | tee report.out
                      cat report.out | go-junit-report -set-exit-code > report.xml
                    reports:
                      type: JUnit
                      spec:
                        paths:
                          - report.xml
          platform:
            os: Linux
            arch: Amd64
          runtime:
            type: Cloud
            spec: {}
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>Pipeline with multiple Go versions
pipeline:
  name: Build and test Go app
  identifier: Build_and_test_Go_app
  projectIdentifier: default
  orgIdentifier: default
  stages:
    - stage:
        name: Build
        identifier: Build
        type: CI
        strategy:
          matrix:
            goVersion:
              - "1.19"
              - "1.20"
        spec:
          caching:
            enabled: true
          cloneCodebase: true
          execution:
            steps:
              - step:
                  type: Run
                  identifier: installgo
                  name: Install Go
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go install golang.org/dl/go<+matrix.goVersion>@latest
                      go<+matrix.goVersion> download
              - step:
                  type: Run
                  identifier: build
                  name: Build
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go<+matrix.goVersion> build
              - step:
                  type: Run
                  name: Test
                  identifier: test
                  spec:
                    shell: Sh
                    command: |-
                      export PATH=$(go env GOPATH)/bin:$PATH
                      go<+matrix.goVersion> install github.com/jstemmer/go-junit-report/v2@latest
                      go<+matrix.goVersion> test -v ./... | tee report_<+matrix.goVersion>.out
                      cat report_<+matrix.goVersion>.out | go-junit-report -set-exit-code > report_<+matrix.goVersion>.xml
                    reports:
                      type: JUnit
                      spec:
                        paths:
                          - report_*.xml
          platform:
            os: Linux
            arch: Amd64
          runtime:
            type: Cloud
            spec: {}
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>
If you copy this example, replace the placeholder values with appropriate values for your code repo connector, Kubernetes cluster connector, Kubernetes namespace, and repository name. Depending on your project and organization, you may also need to replace  Here is a single-stage pipeline, with steps to install Go 1.20, build and test. Here is a single-stage pipeline, with a matrix looping strategy for Go versions 1.19 and 1.20.projectIdentifier and orgIdentifier.Pipeline with one specific Go version
pipeline:
  name: Build and test Go app
  identifier: Build_and_test_Go_app
  projectIdentifier: default
  orgIdentifier: default
  stages:
    - stage:
        name: Build
        identifier: Build
        type: CI
        spec:
          cloneCodebase: true
          execution:
            steps:
              - step:
                  type: Run
                  identifier: build
                  name: Build
                  spec:
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: golang:1.20
                    command: |-
                      go build
              - step:
                  type: Run
                  identifier: test
                  name: Test
                  spec:
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: golang:1.20
                    command: |-
                      go install github.com/jstemmer/go-junit-report/v2@latest
                      go test -v ./... | tee report.out
                      cat report.out | go-junit-report -set-exit-code > report.xml
                    reports:
                      type: JUnit
                      spec:
                        paths:
                          - report.xml
          infrastructure:
            spec:
              connectorRef: YOUR_KUBERNETES_CONNECTOR_ID
              namespace: YOUR_KUBERNETES_NAMESPACE
            type: KubernetesDirect
          platform:
            arch: Amd64
            os: Linux
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>Pipeline with multiple Go versions
pipeline:
  name: Build and test Go app
  identifier: Build_and_test_Go_app
  projectIdentifier: default
  orgIdentifier: default
  stages:
    - stage:
        name: Build
        identifier: Build
        type: CI
        strategy:
          matrix:
            goVersion:
              - "1.19"
              - "1.20"
        spec:
          cloneCodebase: true
          execution:
            steps:
              - step:
                  type: Run
                  identifier: build
                  name: Build
                  spec:
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: golang:<+matrix.goVersion>
                    command: |-
                      go build
              - step:
                  type: Run
                  name: Test
                  identifier: test
                  spec:
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: golang:<+matrix.goVersion>
                    command: |-
                      go install github.com/jstemmer/go-junit-report/v2@latest
                      go test -v ./... | tee report_<+matrix.goVersion>.out
                      cat report_<+matrix.goVersion>.out | go-junit-report -set-exit-code > report_<+matrix.goVersion>.xml
                    reports:
                      type: JUnit
                      spec:
                        paths:
                          - report_*.xml
          infrastructure:
            spec:
              connectorRef: YOUR_KUBERNETES_CLUSTER_CONNECTOR_ID
              namespace: YOUR_KUBERNETES_NAMESPACE
            type: KubernetesDirect
          platform:
            arch: Amd64
            os: Linux
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>
Next steps
Now that you have created a pipeline that builds and tests a Go app, you could:
- Create triggers to automatically run your pipeline.
- Add steps to build and upload artifacts.
- Add a step to build and push an image to a Docker registry.