Commit b068c40e authored by Yann D'Isanto's avatar Yann D'Isanto Committed by Pierre Smeyers
Browse files

feat(build): build target platform can be specified

Build target platform can now be specified with `` and `` variables.
Supports GitLab jobs matrix feature to enable multiple build. 

BREAKING CHANGE: changed `GO_BUILD_ARGS` to `GO_BUILD_FLAGS` variable and `GO_TEST_ARGS` to `GO_TEST_FLAGS` variable. See doc.
parent 968ff83b
Loading
Loading
Loading
Loading
+35 −3
Original line number Diff line number Diff line
@@ -29,19 +29,51 @@ The Go template uses some global configuration used throughout all jobs.

### build & test jobs

The build target platform is the one defined by the docker image but it can be overriden using the `GO_TARGET_OS` and `GO_TARGET_ARCH` variables.

```yaml
variables:
  GO_TARGET_OS: "windows"
  GO_TARGET_ARCH: "amd64"
```

Build and tests can be done in separate jobs.
If `GO_TEST_IMAGE` is not set (default), the `go-build-test` job will run build and tests at once.
If `GO_TEST_IMAGE` is set, separate `go-build` and `go-test` jobs will be run in the `build` phase in parallel.

Separating `build`and `test` jobs can be useful to use different images (and hence different tools) .
Separating `build` and `test` jobs can be useful to use different images (and hence different tools) or if you want to build muli-platform binaries.

Here is a `.gitlab-ci.yml` example that triggers a build on 3 target platforms using the [parallel matrix jobs](https://docs.gitlab.com/ee/ci/yaml/#parallel-matrix-jobs) pattern:

```yaml
variables:
  GO_IMAGE: "golang:1.17-buster"
  GO_TEST_IMAGE: "golang:1.17-buster"

go-build:
  parallel:
    matrix:
      - GO_TARGET_OS: "windows"
        GO_TARGET_ARCH: "amd64"
      - GO_TARGET_OS: "linux"
        GO_TARGET_ARCH: "amd64"
      - GO_TARGET_OS: "linux"
        GO_TARGET_ARCH: "arm"
```


These jobs use the following variable:

| Name                    | description                              | default value     |
| ----------------------- | ---------------------------------------- | ----------------- |
| `GO_BUILD_ARGS`         | Arguments used by the build command      | `install -mod=readonly ./...`   |
| `GO_TEST_ARGS`          | Arguments used by the test command       | `test -mod=readonly -v -coverprofile=reports/coverage.out -race ./...` |
| `GO_BUILD_FLAGS`        | Flags used by the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)      | `-mod=readonly`   |
| `GO_BUILD_PACKAGES`     | Packages to build with the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)      | `./...`   |
| `GO_TEST_FLAGS`         | Flags used by the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)       | `-mod=readonly -v -race` |
| `GO_TEST_PACKAGES`      | Packages to test with the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)      | `./...`   |
| `GO_LIST_ARGS`          | Arguments used by the list command       | `list -u -m -mod=readonly -json all` |
| `GO_TARGET_OS`          | The `GOOS` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)         | _none_ (fallback to go docker image `GOOS`)
| `GO_TARGET_ARCH`          | The `GOARCH` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)         | _none_ (fallback to go docker image `GOARCH`)


### `go-ci-lint` job

+48 −6
Original line number Diff line number Diff line
@@ -19,12 +19,6 @@
      "description": "Specific Docker image used to run Go tests (as a separate job)",
      "advanced": true
    },
    {
      "name": "GO_BUILD_ARGS",
      "description": "Arguments used by the build command",
      "default": "install -mod=readonly ./...",
      "advanced": true
    },
    {
      "name": "GO_TEST_ARGS",
      "description": "Arguments used by the test command",
@@ -39,6 +33,54 @@
    }
  ],
  "features": [
    {
      "id": "go-build",
      "name": "go build",
      "description": "[go build](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)",
      "variables": [
        {
          "name": "GO_BUILD_FLAGS",
          "description": "Flags used by the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)",
          "default": "-mod=readonly",
          "advanced": true
        },
        {
          "name": "GO_BUILD_PACKAGES",
          "description": "Packages to build with the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)",
          "default": "./...",
          "advanced": true
        },
        {
          "name": "GO_TARGET_OS",
          "description": "The `$GOOS` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)\n\nFallbacks to default `$GOOS` from the Go Docker image",
          "advanced": true
        },
        {
          "name": "GO_TARGET_ARCH",
          "description": "The `$GOARCH` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)\n\nFallbacks to default `$GOARCH` from the Go Docker image",
          "advanced": true
        }
      ]
    },
    {
      "id": "go-test",
      "name": "go test",
      "description": "[go test](https://pkg.go.dev/cmd/go#hdr-Test_packages)",
      "variables": [
        {
          "name": "GO_TEST_FLAGS",
          "description": "Flags used by the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)",
          "default": "-mod=readonly -v -race",
          "advanced": true
        },
        {
          "name": "GO_TEST_PACKAGES",
          "description": "Packages to test with the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)",
          "default": "./...",
          "advanced": true
        }
      ]
    },
    {
      "id": "golangci-lint",
      "name": "GolangCI-Lint",
+41 −27
Original line number Diff line number Diff line
@@ -17,19 +17,23 @@ variables:
  # Default Docker image (can be overridden)
  GO_IMAGE: "golang:buster"

  # Default arguments for 'build' command
  GO_BUILD_ARGS: >-
    install
  # Default flags for 'build' command
  GO_BUILD_FLAGS: >-
    -mod=readonly

  # Default packages for 'build' command
  GO_BUILD_PACKAGES: >-
    ./...

  # Default arguments for 'test' command
  GO_TEST_ARGS: >-
    test
  # Default flags for 'test' command
  GO_TEST_FLAGS: >-
    -mod=readonly
    -v
    -coverprofile=reports/coverage.out
    -race ./...
    -race

  # Default packages for 'test' command
  GO_TEST_PACKAGES: >-
    ./...

  # Default arguments for 'list' command
  GO_LIST_ARGS : >-
@@ -87,6 +91,31 @@ stages:
    fi
  }

  function go_build() {
    GO_TARGET_OS="${GO_TARGET_OS:-$GOOS}"
    GO_TARGET_ARCH="${GO_TARGET_ARCH:-$GOARCH}"
    target_dir="$GOBIN/$GO_TARGET_OS/$GO_TARGET_ARCH"
    mkdir -p "$target_dir"
    # shellcheck disable=SC2086
    GOOS="$GO_TARGET_OS" GOARCH="$GO_TARGET_ARCH" go build $GO_BUILD_FLAGS -o "$target_dir" $GO_BUILD_PACKAGES
  }

  function go_test() {
    mkdir reports
    local go_tests_report="reports/tests-output.txt"
    local junit_tests_report="reports/junit-tests-report.xml"
    local coverage_report_opts=-coverprofile=reports/coverage.out

    # shellcheck disable=SC2086
    go test $GO_TEST_FLAGS "$coverage_report_opts" $GO_PACKAGES | tee "$go_tests_report"

    output_coverage
    install_go_junit_report
    # shellcheck disable=SC2002
    cat "$go_tests_report" | "$GOBIN/go-junit-report" > "$junit_tests_report"
    sonar_tests_report
  }

  function install_go_junit_report() {
    cd "$(mktemp -d)"
    go mod init go-junit-report
@@ -268,8 +297,7 @@ go-build:
  extends: .go-base
  stage: build
  script:
    - go $GO_BUILD_ARGS
  # keep build artifacts (see: https://docs.gitlab.com/ee/ci/yaml/#artifactsreports)
    - go_build
  artifacts:
    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 day
@@ -287,15 +315,8 @@ go-test:
  image: $GO_TEST_IMAGE
  stage: build
  script:
    - mkdir reports
    - go $GO_TEST_ARGS | tee reports/tests-output.txt
    - output_coverage
    - install_go_junit_report
    - cat reports/tests-output.txt | $GOBIN/go-junit-report > reports/junit-tests-report.xml
    - sonar_tests_report
  # code coverage RegEx
    - go_test
  coverage: '/^(\d+.\d+\%) covered$/'
  # keep test reports (see: https://docs.gitlab.com/ee/ci/yaml/#artifactsreports)
  artifacts:
    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 day
@@ -315,16 +336,9 @@ go-build-test:
  extends: .go-base
  stage: build
  script:
    - go $GO_BUILD_ARGS
    - mkdir reports
    - go $GO_TEST_ARGS | tee reports/tests-output.txt
    - output_coverage
    - install_go_junit_report
    - cat reports/tests-output.txt | $GOBIN/go-junit-report > reports/junit-tests-report.xml
    - sonar_tests_report
  # code coverage RegEx
    - go_build
    - go_test
  coverage: '/^(\d+.\d+\%) covered$/'
  # keep build artifacts and test reports (see: https://docs.gitlab.com/ee/ci/yaml/#artifactsreports)
  artifacts:
    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 day