Select Git revision
gitlab-ci-golang.yml
-
semantic-release-bot authored
# [4.10.0](https://gitlab.com/to-be-continuous/golang/compare/4.9.2...4.10.0) (2024-07-05) ### Features * optional installation of Go tools ([5a78d9d8](https://gitlab.com/to-be-continuous/golang/commit/5a78d9d8000b45edf165940eba35b6f196e97bf5))
semantic-release-bot authored# [4.10.0](https://gitlab.com/to-be-continuous/golang/compare/4.9.2...4.10.0) (2024-07-05) ### Features * optional installation of Go tools ([5a78d9d8](https://gitlab.com/to-be-continuous/golang/commit/5a78d9d8000b45edf165940eba35b6f196e97bf5))
gitlab-ci-golang.yml 22.87 KiB
# =========================================================================================
# Copyright (C) 2021 Orange & contributors
#
# This program is free software; you can redistribute it and/or modify it under the terms
# of the GNU Lesser General Public License as published by the Free Software Foundation;
# either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with this
# program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
# Floor, Boston, MA 02110-1301, USA.
# =========================================================================================
# default workflow rules: Merge Request pipelines
spec:
inputs:
image:
description: The Docker image used to run Go (build+test or build only) - **set the version required by your project**
default: registry.hub.docker.com/library/golang:bookworm
project-dir:
description: Go project root directory
default: .
goproxy:
description: URL of Go module proxy (see [Go env](https://golang.org/cmd/go/#hdr-Environment_variables))
default: ''
test-image:
description: Specific Docker image used to run Go tests (as a separate job)
default: ''
generate-modules:
description: "Space separated list of Go code generator modules (ex: `stringer mockery`)"
default: ''
build-flags:
description: Flags used by the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)
default: -mod=readonly
build-mode:
description: The template build mode (accepted values are `application`, `modules` and `auto`)
options:
- auto
- application
- modules
default: auto
build-linker-flags:
description: Linker flags used by the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) `-ldflags`
default: -s -w
build-packages:
description: Packages to build with the [go build command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)
default: ./...
target-os:
description: |-
The `$GOOS` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)
Fallbacks to default `$GOOS` from the Go Docker image
default: ''
target-arch:
description: |-
The `$GOARCH` target [see available values](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)
Fallbacks to default `$GOARCH` from the Go Docker image
default: ''
test-flags:
description: Flags used by the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)
default: -mod=readonly -v -race
test-packages:
description: Packages to test with the [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages)
default: ./...
list-args:
description: Arguments used by the list command
default: list -u -m -mod=readonly -json all
cobertura-flags:
description: Build flags to add to use gocover-cobertura, leave blank if not needed
default: ''
ci-lint-disabled:
description: Disable GolangCI-Lint
type: boolean
default: false
ci-lint-image:
description: The Docker image used to run `golangci-lint`
default: registry.hub.docker.com/golangci/golangci-lint:latest-alpine
ci-lint-args:
description: '`golangci-lint` [command line arguments](https://github.com/golangci/golangci-lint#command-line-options)'
default: -E gosec,goimports ./...
mod-outdated-args:
description: '`god-mod-outdated` [command line arguments](https://github.com/psampaz/go-mod-outdated#usage'
default: -update -direct
sbom-disabled:
description: Disable Software Bill of Materials
type: boolean
default: false
sbom-image:
default: registry.hub.docker.com/cyclonedx/cyclonedx-gomod:latest
sbom-opts:
description: '[@cyclonedx/cyclonedx-gomod options](https://github.com/CycloneDX/cyclonedx-gomod#usage) used for SBOM analysis'
default: -main .
vulncheck-disabled:
description: Disable Govulncheck
type: boolean
default: false
vulncheck-args:
description: '`govulncheck` [command line arguments](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck#hdr-Flags)'
default: ./...
---
workflow:
rules:
# prevent MR pipeline originating from production or integration branch(es)
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ $PROD_REF || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ $INTEG_REF'
when: never
# on non-prod, non-integration branches: prefer MR pipeline over branch pipeline
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*tag(,[^],]*)*\]/" && $CI_COMMIT_TAG'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*branch(,[^],]*)*\]/" && $CI_COMMIT_BRANCH'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*mr(,[^],]*)*\]/" && $CI_MERGE_REQUEST_ID'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*default(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $CI_DEFAULT_BRANCH'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*prod(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $PROD_REF'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*integ(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME =~ $INTEG_REF'
when: never
- if: '$CI_COMMIT_MESSAGE =~ "/\[(ci skip|skip ci) on ([^],]*,)*dev(,[^],]*)*\]/" && $CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
when: never
- when: always
# test job prototype: implement adaptive pipeline rules
.test-policy:
rules:
# on tag: auto & failing
- if: $CI_COMMIT_TAG
# on ADAPTIVE_PIPELINE_DISABLED: auto & failing
- if: '$ADAPTIVE_PIPELINE_DISABLED == "true"'
# on production or integration branch(es): auto & failing
- if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF'
# early stage (dev branch, no MR): manual & non-failing
- if: '$CI_MERGE_REQUEST_ID == null && $CI_OPEN_MERGE_REQUESTS == null'
when: manual
allow_failure: true
# Draft MR: auto & non-failing
- if: '$CI_MERGE_REQUEST_TITLE =~ /^Draft:.*/'
allow_failure: true
# else (Ready MR): auto & failing
- when: on_success
variables:
# variabilized tracking image
TBC_TRACKING_IMAGE: registry.gitlab.com/to-be-continuous/tools/tracking:master
# Default Go project root directory
GO_PROJECT_DIR: $[[ inputs.project-dir ]]
# Default Docker image (can be overridden)
GO_IMAGE: $[[ inputs.image ]]
GO_GENERATE_MODULES: $[[ inputs.generate-modules ]]
# Default flags for 'build' command
GO_BUILD_FLAGS: $[[ inputs.build-flags ]]
# Default flags for go build linker
GO_BUILD_LINKER_FLAGS: $[[ inputs.build-linker-flags ]]
# Default packages for 'build' command
GO_BUILD_PACKAGES: $[[ inputs.build-packages ]]
# Default build mode (application/modules/auto)
GO_BUILD_MODE: $[[ inputs.build-mode ]]
# Default flags for 'test' command
GO_TEST_FLAGS: $[[ inputs.test-flags ]]
# Default packages for 'test' command
GO_TEST_PACKAGES: $[[ inputs.test-packages ]]
# Default arguments for 'list' command
GO_LIST_ARGS: $[[ inputs.list-args ]]
# Default arguments for go-mod-outdated command
GO_MOD_OUTDATED_ARGS: $[[ inputs.mod-outdated-args ]]
GO_VULNCHECK_ARGS: $[[ inputs.vulncheck-args ]]
# Default golangci-lint Docker image (can be overridden)
GO_CI_LINT_IMAGE: $[[ inputs.ci-lint-image ]]
# Default arguments for golangci-lint command
GO_CI_LINT_ARGS: $[[ inputs.ci-lint-args ]]
GOPROXY: $[[ inputs.goproxy ]]
GO_TEST_IMAGE: $[[ inputs.test-image ]]
GO_TARGET_OS: $[[ inputs.target-os ]]
GO_TARGET_ARCH: $[[ inputs.target-arch ]]
GO_COBERTURA_FLAGS: $[[ inputs.cobertura-flags ]]
GO_CI_LINT_DISABLED: $[[ inputs.ci-lint-disabled ]]
GO_SBOM_DISABLED: $[[ inputs.sbom-disabled ]]
GO_VULNCHECK_DISABLED: $[[ inputs.vulncheck-disabled ]]
# Image of cyclonedx-gomod used for SBOM analysis
GO_SBOM_IMAGE: $[[ inputs.sbom-image ]]
# Options for cyclonedx-gomod used for SBOM analysis
GO_SBOM_OPTS: $[[ inputs.sbom-opts ]]
# default production ref name (pattern)
PROD_REF: /^(master|main)$/
# default integration ref name (pattern)
INTEG_REF: /^develop$/
stages:
- build
- test
- package-build
- package-test
- infra
- deploy
- acceptance
- publish
- infra-prod
- production
.go-scripts: &go-scripts |
# BEGSCRIPT
set -e
function log_info() {
>&2 echo -e "[\\e[1;94mINFO\\e[0m] $*"
}
function log_warn() {
>&2 echo -e "[\\e[1;93mWARN\\e[0m] $*"
}
function log_error() {
>&2 echo -e "[\\e[1;91mERROR\\e[0m] $*"
}
function install_ca_certs() {
certs=$1
if [[ -z "$certs" ]]
then
return
fi
# import in system
if echo "$certs" >> /etc/ssl/certs/ca-certificates.crt
then
log_info "CA certificates imported in \\e[33;1m/etc/ssl/certs/ca-certificates.crt\\e[0m"
fi
if echo "$certs" >> /etc/ssl/cert.pem
then
log_info "CA certificates imported in \\e[33;1m/etc/ssl/cert.pem\\e[0m"
fi
}
function unscope_variables() {
_scoped_vars=$(env | awk -F '=' "/^scoped__[a-zA-Z0-9_]+=/ {print \$1}" | sort)
if [[ -z "$_scoped_vars" ]]; then return; fi
log_info "Processing scoped variables..."
for _scoped_var in $_scoped_vars
do
_fields=${_scoped_var//__/:}
_condition=$(echo "$_fields" | cut -d: -f3)
case "$_condition" in
if) _not="";;
ifnot) _not=1;;
*)
log_warn "... unrecognized condition \\e[1;91m$_condition\\e[0m in \\e[33;1m${_scoped_var}\\e[0m"
continue
;;
esac
_target_var=$(echo "$_fields" | cut -d: -f2)
_cond_var=$(echo "$_fields" | cut -d: -f4)
_cond_val=$(eval echo "\$${_cond_var}")
_test_op=$(echo "$_fields" | cut -d: -f5)
case "$_test_op" in
defined)
if [[ -z "$_not" ]] && [[ -z "$_cond_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" ]]; then continue;
fi
;;
equals|startswith|endswith|contains|in|equals_ic|startswith_ic|endswith_ic|contains_ic|in_ic)
# comparison operator
# sluggify actual value
_cond_val=$(echo "$_cond_val" | tr '[:punct:]' '_')
# retrieve comparison value
_cmp_val_prefix="scoped__${_target_var}__${_condition}__${_cond_var}__${_test_op}__"
_cmp_val=${_scoped_var#"$_cmp_val_prefix"}
# manage 'ignore case'
if [[ "$_test_op" == *_ic ]]
then
# lowercase everything
_cond_val=$(echo "$_cond_val" | tr '[:upper:]' '[:lower:]')
_cmp_val=$(echo "$_cmp_val" | tr '[:upper:]' '[:lower:]')
fi
case "$_test_op" in
equals*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val" ]]; then continue;
fi
;;
startswith*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val"* ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val"* ]]; then continue;
fi
;;
endswith*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val" ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val" ]]; then continue;
fi
;;
contains*)
if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val"* ]]; then continue;
elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val"* ]]; then continue;
fi
;;
in*)
if [[ -z "$_not" ]] && [[ "__${_cmp_val}__" != *"__${_cond_val}__"* ]]; then continue;
elif [[ "$_not" ]] && [[ "__${_cmp_val}__" == *"__${_cond_val}__"* ]]; then continue;
fi
;;
esac
;;
*)
log_warn "... unrecognized test operator \\e[1;91m${_test_op}\\e[0m in \\e[33;1m${_scoped_var}\\e[0m"
continue
;;
esac
# matches
_val=$(eval echo "\$${_target_var}")
log_info "... apply \\e[32m${_target_var}\\e[0m from \\e[32m\$${_scoped_var}\\e[0m${_val:+ (\\e[33;1moverwrite\\e[0m)}"
_val=$(eval echo "\$${_scoped_var}")
export "${_target_var}"="${_val}"
done
log_info "... done"
}
function output_coverage() {
coverage_out=reports/go-coverage.native.out
if [[ -f "$coverage_out" ]]
then
log_info "--- \\e[32mCoverage report(s) found\\e[0m (\\e[33;1m${coverage_out}\\e[0m): output"
percent=$(go tool cover -func="$coverage_out" | tail -1 | awk -F" " '{print $NF}')
echo "${percent} covered"
if ! command -v gocover-cobertura > /dev/null
then
log_info "Installing gocover-cobertura.."
go install github.com/boumenot/gocover-cobertura@latest
fi
GOFLAGS="$GO_COBERTURA_FLAGS" gocover-cobertura < "$coverage_out" > reports/go-coverage.cobertura.xml
else
log_info "--- \\e[32mCoverage report(s) not found\\e[0m: skip"
fi
}
# evaluates Go build mode (manages 'auto' mode)
function go_build_mode() {
case "$GO_BUILD_MODE" in
application|modules)
echo "$GO_BUILD_MODE"
;;
auto)
go_main_src=$(find . -name "*.go" -exec grep -wl "^package main" {} \;)
if [[ "$go_main_src" ]]
then
log_info "--- build mode auto-detected: \\e[96;1mapplication\\e[0m (main package found)"
echo "application"
else
log_info "--- build mode auto-detected: \\e[96;1mmodules\\e[0m (no main package found)"
echo "modules"
fi
;;
*)
log_error "--- unsupported \\e[94;1m\$GO_BUILD_MODE\\e[0m value (expected values are \\e[96;1mapplication\\e[0m, \\e[96;1mmodules\\e[0m, \\e[96;1mauto\\e[0m)"
exit 1
;;
esac
}
function go_build() {
case "$(go_build_mode)" in
application)
go_build_application
;;
modules)
go_build_modules
;;
esac
}
function go_build_application() {
log_info "building go application"
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 -ldflags="$GO_BUILD_LINKER_FLAGS" $GO_BUILD_FLAGS -o "$target_dir" $GO_BUILD_PACKAGES
}
function go_build_modules() {
log_info "building go modules"
# shellcheck disable=SC2086
go build -ldflags="$GO_BUILD_LINKER_FLAGS" $GO_BUILD_FLAGS $GO_BUILD_PACKAGES
}
function go_test() {
mkdir -p -m 777 reports
local go_text_report="reports/go-test.native.txt"
set +e
# shellcheck disable=SC2086
go test $GO_TEST_FLAGS "-coverprofile=reports/go-coverage.native.out" $GO_TEST_PACKAGES > "$go_text_report"
test_rc=$?
set -e
# dump text report in the console
cat "$go_text_report" || (echo "Display of go test report file failed; Display of last 100 lines." && tail -n100 "$go_text_report")
# compute and dump code coverage in the console
output_coverage
# produce JUnit report (for GitLab)
install_go_junit_report
go-junit-report < "$go_text_report" > reports/go-test.xunit.xml
# produce JSON report (for SonarQube)
go tool test2json < "$go_text_report" > reports/go-test.native.json
# maybe fail
if [[ "$test_rc" != "0" ]]; then exit "$test_rc"; fi
}
function install_go_junit_report() {
if ! command -v go-junit-report > /dev/null
then
cd "$(mktemp -d)"
go mod init go-junit-report
log_info "Installing go-junit-report.."
go install github.com/jstemmer/go-junit-report@latest
cd -
fi
}
function install_go_mod_outdated() {
if ! command -v go-mod-outdated > /dev/null
then
cd "$(mktemp -d)"
go mod init go-mod-outdated
log_info "Installing go-mod-outdated.."
go install github.com/psampaz/go-mod-outdated@latest
cd -
fi
}
function install_go_govulncheck() {
if ! command -v govulncheck > /dev/null
then
cd "$(mktemp -d)"
go mod init govulncheck
go install golang.org/x/vuln/cmd/govulncheck@latest
cd -
fi
}
unscope_variables
# ENDSCRIPT
# job prototype
# defines default default docker image, tracking probe, cache policy and tags
.go-base:
image: $GO_IMAGE
services:
- name: "$TBC_TRACKING_IMAGE"
command: ["--service", "golang", "4.10.0"]
variables:
# The directory where 'go install' will install a command.
GOBIN: "$CI_PROJECT_DIR/$GO_PROJECT_DIR/bin"
# The directory where the go command will store cached information for reuse in future builds.
GOCACHE: "$CI_PROJECT_DIR/$GO_PROJECT_DIR/.cache"
cache:
key: "$CI_COMMIT_REF_SLUG-golang"
paths:
- $GO_PROJECT_DIR/.cache/
before_script:
- !reference [.go-scripts]
- |
if command -v git > /dev/null
then
git config --global url.https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}.insteadOf https://${CI_SERVER_HOST}
else
log_warn "If you need to use private repository, you should provide an image with git executable"
fi
- install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
- cd ${GO_PROJECT_DIR}
- export PATH=$GOBIN:$PATH
go-generate:
extends: .go-base
stage: .pre
script:
- go install $GO_GENERATE_MODULES
- go generate
rules:
# only if $GO_GENERATE_MODULES is set
- if: '$GO_GENERATE_MODULES != null && $GO_GENERATE_MODULES != ""'
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
# default captured paths; otherwise has to be overwritten
paths:
- "${GO_PROJECT_DIR}/**/mock/"
- "${GO_PROJECT_DIR}/**/mocks/"
- "${GO_PROJECT_DIR}/**/*mock*.go"
go-build:
extends: .go-base
stage: build
script:
- go_build
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
paths:
- $GO_PROJECT_DIR/bin/
rules:
# if $GO_TEST_IMAGE set
- if: '$GO_TEST_IMAGE != ""'
go-test:
extends: .go-base
image: $GO_TEST_IMAGE
stage: build
script:
- go_test
coverage: '/^(\d+.\d+\%) covered$/'
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
when: always
reports:
junit:
- "$GO_PROJECT_DIR/reports/go-test.xunit.xml"
coverage_report:
coverage_format: cobertura
path: "$GO_PROJECT_DIR/reports/go-coverage.cobertura.xml"
paths:
- "$GO_PROJECT_DIR/reports/go-test.*"
- "$GO_PROJECT_DIR/reports/go-coverage.*"
rules:
# if $GO_TEST_IMAGE set
- if: '$GO_TEST_IMAGE == ""'
when: never
- !reference [.test-policy, rules]
go-build-test:
extends: .go-base
stage: build
script:
- go_build
- go_test
coverage: '/^(\d+.\d+\%) covered$/'
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
when: always
expire_in: 1 day
reports:
junit:
- "$GO_PROJECT_DIR/reports/go-test.xunit.xml"
coverage_report:
coverage_format: cobertura
path: "$GO_PROJECT_DIR/reports/go-coverage.cobertura.xml"
paths:
- $GO_PROJECT_DIR/bin/
- $GO_PROJECT_DIR/reports/
- "$GO_PROJECT_DIR/reports/go-test.*"
- "$GO_PROJECT_DIR/reports/go-coverage.*"
rules:
# if $GO_TEST_IMAGE not set
- if: '$GO_TEST_IMAGE == ""'
go-ci-lint:
extends: .go-base
stage: build
image: $GO_CI_LINT_IMAGE
script:
- mkdir -p -m 777 reports
# produce all reports at once
- golangci-lint run --out-format "colored-line-number:stdout,code-climate:reports/go-ci-lint.codeclimate.json,checkstyle:reports/go-ci-lint.checkstyle.xml" $GO_CI_LINT_ARGS
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
when: always
paths:
- "$GO_PROJECT_DIR/reports/go-ci-lint.*"
reports:
codequality:
- "$GO_PROJECT_DIR/reports/go-ci-lint.codeclimate.json"
rules:
# exclude if GO_CI_LINT_DISABLED set
- if: '$GO_CI_LINT_DISABLED == "true"'
when: never
- !reference [.test-policy, rules]
go-mod-outdated:
extends: .go-base
stage: test
dependencies: []
script:
- mkdir -p -m 777 reports
# go list
- go $GO_LIST_ARGS > reports/go-list.native.json
- install_go_mod_outdated
# console output (no fail)
- go-mod-outdated $GO_MOD_OUTDATED_ARGS < reports/go-list.native.json
# text report (-ci fails)
- go-mod-outdated $GO_MOD_OUTDATED_ARGS -ci < reports/go-list.native.json > reports/go-mod-outdated.native.txt
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
when: always
paths:
- "$GO_PROJECT_DIR/reports/go-list.native.json"
- "$GO_PROJECT_DIR/reports/go-mod-outdated.native.txt"
rules:
# on schedule: auto
- if: '$CI_PIPELINE_SOURCE == "schedule"'
allow_failure: true
# else manual & non-blocking
- when: manual
allow_failure: true
go-sbom:
extends: .go-base
stage: test
image:
name: $GO_SBOM_IMAGE
entrypoint: [""]
# manage separate GitLab cache to prevent permission denied error (this image being rootless, it can't rewrite Go cache - owned by root)
# see: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/29663
cache:
key: "$CI_COMMIT_REF_SLUG-golang-sbom"
paths:
- $GO_PROJECT_DIR/.cache/
# force no dependency
dependencies: []
needs: []
script:
- mkdir -p -m 777 reports
- go_mode=$(go_build_mode)
- |
cyclonedx-gomod "${go_mode:0:3}" -json -output reports/go-sbom.cyclonedx.json $GO_SBOM_OPTS
- chmod a+r reports/go-sbom.cyclonedx.json
artifacts:
name: "SBOM for golang from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 week
when: always
paths:
- "$GO_PROJECT_DIR/reports/go-sbom.cyclonedx.json"
reports:
cyclonedx:
- "$GO_PROJECT_DIR/reports/go-sbom.cyclonedx.json"
rules:
# exclude if disabled
- if: '$GO_SBOM_DISABLED == "true"'
when: never
- !reference [.test-policy, rules]
go-govulncheck:
extends: .go-base
stage: test
dependencies: []
script:
- mkdir -p -m 777 reports
- install_go_govulncheck
- govulncheck ${GO_VULNCHECK_ARGS}
rules:
# exclude if GO_CI_LINT_DISABLED set
- if: '$GO_VULNCHECK_DISABLED == "true"'
when: never
- !reference [.test-policy, rules]