grafana/.circleci/config.yml
Arve Knudsen a6cc64290c
CI: Upgrade build pipeline tool (#27120)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
2020-08-21 11:42:57 +02:00

1325 lines
45 KiB
YAML

version: 2.1
aliases:
# Workflow filters
- &filter-only-release
branches:
only: chore/test-release-pipeline
tags:
only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
- &filter-only-master
branches:
only: master
- &filter-master-or-release
branches:
only:
- master
- chore/test-release-pipeline
tags:
only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
executors:
base:
docker:
- image: cimg/base:stable
node:
docker:
- image: cimg/node:12.18
go:
docker:
- image: cimg/go:1.14
grafana-build:
docker:
- image: grafana/build-container:1.2.24
grafana-publish:
docker:
- image: grafana/grafana-ci-deploy:1.2.5
windows-installer:
docker:
- image: grafana/wix-toolset-ci:v3
commands:
install-grabpl:
description: "Install Grafana build pipeline tool"
steps:
- run:
name: "Install Grafana build pipeline tool"
command: |
VERSION=0.5.5
curl -fLO https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v${VERSION}/grabpl
chmod +x grabpl
mv grabpl /tmp
jobs:
build-backend:
description: "Build a certain variant of Grafana back-end binaries"
parameters:
edition:
type: string
variant:
type: string
executor: grafana-build
steps:
- run:
name: Exit if enterprise and forked PR
command: |
if [[ "<< parameters.edition >>" == "enterprise" && -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Build Grafana backend
command: |
if [[ -n $CIRCLE_TAG ]]; then
# A release build
/tmp/grabpl build-backend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> \
--variants << parameters.variant >> $CIRCLE_TAG
elif [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl build-backend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> \
--variants << parameters.variant >> v7.0.0-test
else
# A master or PR build
/tmp/grabpl build-backend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> \
--variants << parameters.variant >> --build-id $CIRCLE_WORKFLOW_ID
fi
- run:
name: Move artifacts
command: mkdir -p << parameters.edition >> && mv bin << parameters.edition >>/
- persist_to_workspace:
root: .
paths:
- << parameters.edition >>/bin/*
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-frontend:
description: "Build Grafana front-end artifacts"
parameters:
edition:
type: string
resource_class: large
executor: grafana-build
steps:
- run:
name: Exit if enterprise and forked PR
command: |
if [[ "<< parameters.edition >>" == "enterprise" && -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- checkout
- restore_cache:
keys:
# Use own cache for front-end builds, since for some reason it can't be unpacked for parts of the
# pipeline
- v1-yarn-build-{{ checksum "yarn.lock" }}
# Used if checksum fails
- v1-yarn-build-
- run:
name: Increase node memory
command: |
export NODE_OPTIONS=--max_old_space_size=4096
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Install dependencies
command: yarn install --frozen-lockfile --no-progress
- save_cache:
key: v1-yarn-build-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run:
name: Build Grafana frontend
command: |
if [[ -n $CIRCLE_TAG ]]; then
# A release build
/tmp/grabpl build-frontend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> $CIRCLE_TAG
elif [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl build-frontend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> 7.0.0-test
else
# A master or PR build
/tmp/grabpl build-frontend --github-token "${GITHUB_GRAFANABOT_TOKEN}" --edition << parameters.edition >> --build-id $CIRCLE_WORKFLOW_ID
fi
- run:
name: Move artifacts
command: mkdir << parameters.edition >> && cp -r public << parameters.edition >>/
- persist_to_workspace:
root: .
paths:
- << parameters.edition >>/public/*
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-plugins:
description: "Build internal Grafana plug-ins"
parameters:
edition:
type: string
executor: grafana-build
steps:
- run:
name: Exit if enterprise and forked PR
command: |
if [[ "<< parameters.edition >>" == "enterprise" && -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Build internal Grafana plug-ins
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
# This is a forked PR, so don't sign as it requires an API secret
/tmp/grabpl build-plugins --jobs 2 --edition << parameters.edition >>
else
export GRAFANA_API_KEY=$GRAFANA_COM_API_KEY
/tmp/grabpl build-plugins --jobs 2 --edition << parameters.edition >> --sign --signing-admin
fi
- run:
name: Move artifacts
command: |
mkdir -p << parameters.edition >>/plugins-bundled
mv plugins-bundled/dist << parameters.edition >>/plugins-bundled/
- persist_to_workspace:
root: .
paths:
- << parameters.edition >>/plugins-bundled/dist/*
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-release-publisher:
description: "Build release-publisher"
executor: go
steps:
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- run:
name: Test and build Grafana.com release publisher
command: |
cd scripts/build/release_publisher
go test .
go build -o release_publisher .
- persist_to_workspace:
root: .
paths:
- scripts/build/release_publisher/release_publisher
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
shellcheck:
executor: base
steps:
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Install ShellCheck
command: |
VERSION=0.7.1
CHKSUM=beca3d7819a6bdcfbd044576df4fc284053b48f468b2f03428fe66f4ceb2c05d9b5411357fa15003cb0311406c255084cf7283a3b8fce644c340c2f6aa910b9f
curl -fLO http://storage.googleapis.com/grafana-downloads/ci-dependencies/shellcheck-v${VERSION}.linux.x86_64.tar.xz
echo $CHKSUM shellcheck-v${VERSION}.linux.x86_64.tar.xz | sha512sum --check --strict --status
tar xf shellcheck-v${VERSION}.linux.x86_64.tar.xz
sudo mv shellcheck-v${VERSION}/shellcheck /usr/local/bin/
- run:
name: ShellCheck
command: |
/tmp/grabpl shellcheck
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-oss-windows-installer:
executor: windows-installer
steps:
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- run:
name: Copy artifacts from workspace
command: cp -r /tmp/workspace/oss/dist .
- run:
name: Build Windows installer
command: ./scripts/build/ci-msi-build/ci-msi-build-oss.sh
- run:
name: Move artifacts
command: mkdir oss && mv dist oss/
- persist_to_workspace:
root: .
paths:
- oss/dist/grafana-*.msi
- oss/dist/grafana-*.msi.sha256
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-enterprise-windows-installer:
executor: windows-installer
steps:
- run:
name: Exit if forked PR
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: "./scripts/ci-job-started.sh"
- run:
name: Copy artifacts from workspace
command: cp -r /tmp/workspace/enterprise/dist enterprise-dist
- run:
name: Build Windows installer
command: ./scripts/build/ci-msi-build/ci-msi-build-ee.sh
- run:
name: Move artifacts
command: mkdir enterprise && mv enterprise-dist enterprise/dist
- persist_to_workspace:
root: .
paths:
- enterprise/dist/grafana-*.msi
- enterprise/dist/grafana-*.msi.sha256
- run:
name: CI job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: CI job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
release-next-packages:
executor: grafana-build
steps:
- run:
name: Exit if forked PR
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- run:
name: Bootstrap lerna
command: npx lerna bootstrap
- run:
name: npm - Prepare auth token
command: "echo //registry.npmjs.org/:_authToken=$NPM_TOKEN >> ~/.npmrc"
- run:
name: Release next packages
command: ./scripts/circle-release-next-packages.sh
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
package-oss:
executor: grafana-build
steps:
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Copy artifacts from workspace
command: cp -r /tmp/workspace/oss/* .
- run:
name: Package Grafana
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo Using test GPG key pair since building a forked PR
source scripts/build/gpg-test-vars.sh
fi
# Necessary for signing bundled plugins
export GRAFANA_API_KEY=$GRAFANA_COM_API_KEY
if [[ -n $CIRCLE_TAG ]]; then
# A release build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition oss --sign $CIRCLE_TAG
elif [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition oss --sign v7.0.0-test
elif [[ $CIRCLE_BRANCH == "master" ]]; then
# A master build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition oss --sign --build-id $CIRCLE_WORKFLOW_ID
elif [[ -n "$CIRCLE_PR_NUMBER" ]]; then
# A forked PR build, don't sign as it requires an API secret
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition oss --build-id $CIRCLE_WORKFLOW_ID --variants \
linux-x64,linux-x64-musl,osx64,win64
else
# A non-forked PR build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition oss --sign --build-id $CIRCLE_WORKFLOW_ID --variants \
linux-x64,linux-x64-musl,osx64,win64
fi
- run:
name: Move artifacts
command: |
mkdir -p oss
mv dist oss/
- persist_to_workspace:
root: .
paths:
- oss/dist/*
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
package-enterprise:
executor: grafana-build
steps:
- run:
name: Exit if forked PR
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Copy artifacts from workspace
command: cp -r /tmp/workspace/enterprise/* .
- run:
name: Package Grafana
command: |
# Necessary for signing bundled plugins
export GRAFANA_API_KEY=$GRAFANA_COM_API_KEY
if [[ -n $CIRCLE_TAG ]]; then
# A release build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition enterprise --sign $CIRCLE_TAG
elif [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition enterprise --sign v7.0.0-test
elif [[ $CIRCLE_BRANCH == "master" ]]; then
# A master build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition enterprise --sign --build-id $CIRCLE_WORKFLOW_ID
elif [[ -n "$CIRCLE_PR_NUMBER" ]]; then
# A forked PR build, don't sign as it requires an API secret
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition enterprise --build-id $CIRCLE_WORKFLOW_ID --variants \
linux-x64,linux-x64-musl,osx64,win64
else
# A PR build
/tmp/grabpl package --github-token "${GITHUB_GRAFANABOT_TOKEN}" --jobs 2 --edition enterprise --sign --build-id $CIRCLE_WORKFLOW_ID --variants \
linux-x64,linux-x64-musl,osx64,win64
fi
- run:
name: Move artifacts
command: |
mkdir -p enterprise
mv dist enterprise/
- persist_to_workspace:
root: .
paths:
- enterprise/dist/*
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
publish-packages:
description: "Publish packages"
parameters:
edition:
type: string
executor: grafana-publish
steps:
- run:
name: Exit if forked PR
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- install-grabpl
- run:
name: Publish packages
command: |
cp -r /tmp/workspace/<< parameters.edition >>/dist .
if [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl publish-packages --edition << parameters.edition >> \
--deb-db-bucket grafana-testing-aptly-db --deb-repo-bucket grafana-testing-repo --packages-bucket \
grafana-downloads-test --rpm-repo-bucket grafana-testing-repo --simulate-release
else
/tmp/grabpl publish-packages --edition << parameters.edition >>
fi
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
publish-storybook:
description: "Publish Storybook"
executor: grafana-publish
steps:
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- run:
name: Publish Storybook
command: |
yarn install --frozen-lockfile --no-progress
yarn storybook:build
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
if [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
echo Testing release
elif [[ $CIRCLE_BRANCH == "master" ]]; then
echo $GCP_GRAFANA_UPLOAD_KEY > /tmp/gcpkey.json
gcloud auth activate-service-account --key-file=/tmp/gcpkey.json
gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://grafana-storybook/canary
elif [[ -n $CIRCLE_TAG ]]; then
echo $GCP_GRAFANA_UPLOAD_KEY > /tmp/gcpkey.json
gcloud auth activate-service-account --key-file=/tmp/gcpkey.json
gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://grafana-storybook/latest
gsutil -m rsync -d -r ./packages/grafana-ui/dist/storybook gs://grafana-storybook/$CIRCLE_TAG
fi
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
build-docker-images:
description: "Build/publish Docker images"
parameters:
edition:
type: string
ubuntu:
type: boolean
executor: base
environment:
# Required for building cross-platform images
DOCKER_BUILDKIT: 1
steps:
- run:
name: Exit if enterprise and forked PR
command: |
if [[ "<< parameters.edition >>" == "enterprise" && -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- attach_workspace:
at: /tmp/workspace
- checkout
- run:
name: CI job started
command: ./scripts/ci-job-started.sh
- setup_remote_docker:
# This version is necessary for building cross-platform images
version: 18.09.3
- install-grabpl
- run:
name: Install gcloud SDK
command: |
VERSION=298.0.0
curl -fLO https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${VERSION}-linux-x86_64.tar.gz
echo 0d58f451331abf43d080fa997c8e580d64897627e30be74f6d8f983ccfabef1e \
google-cloud-sdk-${VERSION}-linux-x86_64.tar.gz | sha256sum --check --strict --status
tar xf google-cloud-sdk-${VERSION}-linux-x86_64.tar.gz
./google-cloud-sdk/install.sh -q
# XXX: Is this necessary?
- run: docker run --privileged linuxkit/binfmt:v0.6
- run:
name: Copy Grafana archives
command: |
cp -r /tmp/workspace/<< parameters.edition >>/dist .
- run:
name: Build Docker images
command: |
source google-cloud-sdk/path.bash.inc
if [[ -n $CIRCLE_TAG || $CIRCLE_BRANCH == "chore/test-release-pipeline" || $CIRCLE_BRANCH == "master" ]]; then
# It's a full build
/tmp/grabpl build-docker --jobs 4 --edition << parameters.edition >> \
--ubuntu=<< parameters.ubuntu >>
else
# We're testing a branch
/tmp/grabpl build-docker --jobs 4 --edition << parameters.edition >> \
--ubuntu=<< parameters.ubuntu >> --archs amd64
fi
- run:
name: Exit if PR
command: |
if [[ -z $CIRCLE_TAG && $CIRCLE_BRANCH != "chore/test-release-pipeline" && $CIRCLE_BRANCH != "master" ]]; then
echo "Nothing to do for PRs, so marking this step successful"
circleci step halt
fi
- run:
name: Publish Docker images
command: |
if [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
/tmp/grabpl publish-docker --jobs 4 --edition << parameters.edition >> --ubuntu=<< parameters.ubuntu >> --dry-run
elif [[ -n $CIRCLE_TAG ]]; then
# This is a release
/tmp/grabpl publish-docker --jobs 4 --edition << parameters.edition >> --ubuntu=<< parameters.ubuntu >>
else
/tmp/grabpl publish-docker --jobs 4 --edition << parameters.edition >> --ubuntu=<< parameters.ubuntu >>
fi
- run:
name: CI job failed
command: ./scripts/ci-job-failed.sh
when: on_fail
- run:
name: CI job succeeded
command: ./scripts/ci-job-succeeded.sh
when: on_success
end-to-end-tests:
docker:
- image: circleci/node:12-browsers
steps:
- attach_workspace:
at: /tmp/workspace
- checkout
- restore_cache:
keys:
- v2-yarn-{{ checksum "yarn.lock" }}
# Used if checksum fails
- v2-yarn-
- run:
name: yarn install
command: yarn install --frozen-lockfile --no-progress
no_output_timeout: 5m
- save_cache:
key: v2-yarn-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run:
name: Copy artifacts from workspace
command: |
mkdir -p dist
cp -r /tmp/workspace/oss/dist/*.tar.gz dist/
- run:
name: Start grafana-server
command: ./e2e/start-server
background: true
- run:
name: "Wait for Grafana to start"
command: './e2e/wait-for-grafana'
- run:
name: Run end-to-end tests
command: ./e2e/run-suite
no_output_timeout: 5m
- store_artifacts:
path: e2e/suite1/screenshots
destination: screenshots
- store_artifacts:
path: e2e/suite1/videos
destination: output-videos
- store_artifacts:
path: e2e/tmp/data/log
destination: logs
mysql-integration-test:
docker:
- image: cimg/go:1.14
- image: circleci/mysql:5.6-ram
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: grafana_tests
MYSQL_USER: grafana
MYSQL_PASSWORD: password
steps:
- checkout
- run:
name: ci job started
command: "./scripts/ci-job-started.sh"
- run: sudo apt update
- run: sudo apt install -y default-mysql-client
- run: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s
- run: cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h 127.0.0.1 -P 3306 -u root -prootpass
- run:
name: mysql integration tests
command: "./scripts/circle-test-mysql.sh"
- run:
name: ci job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: ci job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
postgres-integration-test:
docker:
- image: cimg/go:1.14
- image: circleci/postgres:9.3-ram
environment:
POSTGRES_USER: grafanatest
POSTGRES_PASSWORD: grafanatest
POSTGRES_DB: grafanatest
steps:
- checkout
- run:
name: ci job started
command: "./scripts/ci-job-started.sh"
- run: sudo apt update
- run: sudo apt install -y postgresql-client
- run: dockerize -wait tcp://127.0.0.1:5432 -timeout 120s
- run: "PGPASSWORD=grafanatest psql -p 5432 -h 127.0.0.1 -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql"
- run:
name: postgres integration tests
command: "./scripts/circle-test-postgres.sh"
- run:
name: ci job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: ci job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
codespell:
docker:
- image: cimg/python:3.8
steps:
- checkout
- run:
name: Install codespell
command: "pip install codespell"
- run:
# Important: all words have to be in lowercase, and separated by "\n".
name: exclude known exceptions
command: 'echo -e "unknwon\nreferer\nerrorstring\neror\niam" > words_to_ignore.txt'
- run:
name: check documentation spelling errors
command: "codespell -I ./words_to_ignore.txt docs/"
lint-go:
executor: go
environment:
# we need CGO because of go-sqlite3
CGO_ENABLED: 1
# Reduce golangci-lint memory usage (default is 100)
GOGC: 20
steps:
- checkout
- run:
name: Install Go linters
command: |
pushd /tmp
VERSION=1.28.0
curl -fLO https://github.com/golangci/golangci-lint/releases/download/v${VERSION}/golangci-lint-${VERSION}-linux-amd64.tar.gz
echo 179d34edf4baf6454a7081fbaaf74dc99397a3be8e1a535dee04d835a977bf76 \
golangci-lint-${VERSION}-linux-amd64.tar.gz | sha256sum --check --strict --status
tar -xf golangci-lint-${VERSION}-linux-amd64.tar.gz
sudo mv golangci-lint-${VERSION}-linux-amd64/golangci-lint /usr/local/bin/
popd
make scripts/go/bin/revive
- run:
name: Lint Go
command: |
# To save memory, run in two batches
golangci-lint run -v -j 4 --config scripts/go/configs/ci/.golangci.toml -E deadcode -E depguard -E dogsled \
-E errcheck -E goconst -E golint -E gosec -E gosimple -E govet -E exportloopref -E whitespace \
-E goprintffuncname ./pkg/...
golangci-lint run -v -j 4 --config scripts/go/configs/ci/.golangci.toml -E ineffassign -E gocritic -E nakedret \
-E rowserrcheck -E staticcheck -E structcheck -E typecheck -E unconvert -E unused -E varcheck ./pkg/...
./scripts/go/bin/revive -formatter stylish -config ./scripts/go/configs/revive.toml ./pkg/...
./scripts/go/bin/revive -formatter stylish -config ./scripts/go/configs/revive-strict.toml \
-exclude ./pkg/plugins/backendplugin/pluginextensionv2/... \
./pkg/services/alerting/... \
./pkg/services/provisioning/datasources/... \
./pkg/services/provisioning/dashboards/... \
./pkg/services/provisioning/notifiers/... \
./pkg/services/provisioning/values/... \
./pkg/plugins/backendplugin/...
test-frontend:
executor: node
steps:
- checkout
- run:
name: CI job started
command: "./scripts/ci-job-started.sh"
- restore_cache:
keys:
- v2-yarn-{{ checksum "yarn.lock" }}
# Used if checksum fails
- v2-yarn-
- run:
name: yarn install
command: "yarn install --frozen-lockfile --no-progress"
no_output_timeout: 15m
- save_cache:
key: v2-yarn-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run:
name: frontend tests
command: "./scripts/circle-test-frontend.sh"
- store_test_results:
path: reports/junit
- run:
name: CI job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: CI job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
test-backend:
executor: go
steps:
- checkout
- run:
name: CI job started
command: "./scripts/ci-job-started.sh"
- run:
name: build backend and run go tests
command: "./scripts/circle-test-backend.sh"
- run:
name: CI job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: CI job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
build-docs-website:
executor: base
steps:
- checkout
- setup_remote_docker
- run:
name: CI job started
command: "./scripts/ci-job-started.sh"
- run:
name: Build Grafana docs website
command: |
# Use latest revision here, since we want to catch if it breaks
IMAGE=grafana/docs-base:latest
# In order to copy sources into the remote container, we need to employ a trick of creating a container
# with a volume, that we copy the sources into. Then, we launch the build container, with the volume
# from the other container
docker create -v /hugo/content/docs/grafana --name docs alpine:3.11 /bin/true
docker cp ${PWD}/docs/sources docs:/hugo/content/docs/grafana/latest
docker run --volumes-from docs $IMAGE /bin/bash -c 'make prod'
- run:
name: CI job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: CI job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
deploy-to-kubernetes:
description: "Deploy Grafana master Docker image to Kubernetes"
executor: base
steps:
- attach_workspace:
at: /tmp/workspace
- install-grabpl
- run:
name: Deploy to Kubernetes
command: |
cp -r /tmp/workspace/enterprise/dist .
/tmp/grabpl deploy-to-k8s
release-packages:
executor: node
steps:
- run:
name: Exit if forked PR
command: |
if [[ -n "$CIRCLE_PR_NUMBER" ]]; then
echo "Nothing to do for forked PRs, so marking this step successful"
circleci step halt
fi
- checkout
- run:
name: CI job started
command: "./scripts/ci-job-started.sh"
- run:
name: Bootstrap lerna
command: "npx lerna bootstrap"
- run:
name: npm - Prepare auth token
command: "echo //registry.npmjs.org/:_authToken=$NPM_TOKEN >> ~/.npmrc"
- run:
name: Exit if release pipeline test
command: |
if [[ $CIRCLE_BRANCH == "chore/test-release-pipeline" ]]; then
# We're testing the release pipeline
echo "We're testing the release pipeline, so stopping before publishing"
circleci step halt
fi
- run:
name: Release packages
command: ./scripts/build/release-packages.sh "${CIRCLE_TAG}"
- run:
name: CI job failed
command: "./scripts/ci-job-failed.sh"
when: on_fail
- run:
name: CI job succeeded
command: "./scripts/ci-job-succeeded.sh"
when: on_success
scan-docker-image:
description: "Scans a docker image for vulnerabilities using trivy"
parameters:
image:
type: string
tag:
type: string
docker:
- image: circleci/buildpack-deps:stretch
steps:
- setup_remote_docker
- restore_cache:
key: vulnerability-db
- run:
name: Install trivy
command: |
VERSION=$(
curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/'
)
wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
sudo mv trivy /usr/local/bin
- run:
name: Clear trivy cache
command: trivy --clear-cache
- run:
name: Scan Docker image for unkown/low/medium vulnerabilities
command: trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM << parameters.image >>:<< parameters.tag >>
- run:
name: Scan Docker image for high/critical vulnerabilities
command: trivy --exit-code 1 --severity HIGH,CRITICAL << parameters.image >>:<< parameters.tag >>
- save_cache:
key: vulnerability-db
paths:
- $HOME/.cache/trivy
workflows:
build-pipeline:
jobs:
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: armv6
name: build-oss-backend-armv6
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: armv7
name: build-oss-backend-armv7
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: armv7-musl
name: build-oss-backend-armv7-musl
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: arm64
name: build-oss-backend-arm64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: arm64-musl
name: build-oss-backend-arm64-musl
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: osx64
name: build-oss-backend-osx64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: win64
name: build-oss-backend-win64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: linux-x64
name: build-oss-backend-linux-x64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
edition: oss
variant: linux-x64-musl
name: build-oss-backend-linux-x64-musl
requires:
- lint-go
- build-frontend:
filters: *filter-master-or-release
name: build-oss-frontend
edition: oss
- build-plugins:
filters: *filter-master-or-release
name: build-oss-plugins
edition: oss
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-armv6
edition: enterprise
variant: armv6
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-armv7
edition: enterprise
variant: armv7
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-armv7-musl
edition: enterprise
variant: armv7-musl
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-arm64
edition: enterprise
variant: arm64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-arm64-musl
edition: enterprise
variant: arm64-musl
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-osx64
edition: enterprise
variant: osx64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-win64
edition: enterprise
variant: win64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-linux-x64
edition: enterprise
variant: linux-x64
requires:
- lint-go
- build-backend:
filters: *filter-master-or-release
name: build-enterprise-backend-linux-x64-musl
edition: enterprise
variant: linux-x64-musl
requires:
- lint-go
- build-frontend:
filters: *filter-master-or-release
name: build-enterprise-frontend
edition: enterprise
- build-plugins:
filters: *filter-master-or-release
name: build-enterprise-plugins
edition: enterprise
requires:
- lint-go
- build-release-publisher:
filters: *filter-master-or-release
- codespell:
filters: *filter-master-or-release
- lint-go:
filters: *filter-master-or-release
- shellcheck:
filters: *filter-master-or-release
- test-backend:
filters: *filter-master-or-release
requires:
- lint-go
- test-frontend:
filters: *filter-master-or-release
- mysql-integration-test:
filters: *filter-master-or-release
requires:
- lint-go
- test-backend
- test-frontend
- postgres-integration-test:
filters: *filter-master-or-release
requires:
- lint-go
- test-backend
- test-frontend
- package-oss:
filters: *filter-master-or-release
requires:
- build-oss-backend-armv6
- build-oss-backend-armv7
- build-oss-backend-armv7-musl
- build-oss-backend-arm64
- build-oss-backend-arm64-musl
- build-oss-backend-osx64
- build-oss-backend-win64
- build-oss-backend-linux-x64
- build-oss-backend-linux-x64-musl
- build-oss-frontend
- test-backend
- test-frontend
- codespell
- shellcheck
- build-oss-plugins
- package-enterprise:
filters: *filter-master-or-release
requires:
- build-enterprise-backend-armv6
- build-enterprise-backend-armv7
- build-enterprise-backend-armv7-musl
- build-enterprise-backend-arm64
- build-enterprise-backend-arm64-musl
- build-enterprise-backend-osx64
- build-enterprise-backend-win64
- build-enterprise-backend-linux-x64
- build-enterprise-backend-linux-x64-musl
- build-enterprise-frontend
- test-backend
- test-frontend
- codespell
- shellcheck
- build-enterprise-plugins
- build-oss-windows-installer:
filters: *filter-master-or-release
requires:
- package-oss
- build-enterprise-windows-installer:
filters: *filter-master-or-release
requires:
- package-enterprise
- release-next-packages:
filters: *filter-only-master
requires:
- end-to-end-tests
- release-packages:
filters: *filter-only-release
requires:
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- publish-packages:
filters: *filter-master-or-release
name: publish-oss-packages
edition: oss
requires:
- package-oss
- build-oss-windows-installer
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- build-release-publisher
- publish-packages:
filters: *filter-master-or-release
name: publish-enterprise-packages
edition: enterprise
requires:
- package-enterprise
- build-enterprise-windows-installer
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- build-release-publisher
- publish-storybook:
filters: *filter-master-or-release
requires:
- test-backend
- test-frontend
- build-docker-images:
filters: *filter-master-or-release
name: build-oss-docker-images
edition: oss
ubuntu: false
requires:
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- package-oss
- build-oss-windows-installer
- build-docker-images:
filters: *filter-master-or-release
name: build-oss-ubuntu-docker-images
edition: oss
ubuntu: true
requires:
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- package-oss
- build-oss-windows-installer
- build-docker-images:
filters: *filter-master-or-release
name: build-enterprise-docker-images
edition: enterprise
ubuntu: false
requires:
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- package-enterprise
- build-enterprise-windows-installer
- build-docker-images:
filters: *filter-master-or-release
name: build-enterprise-ubuntu-docker-images
edition: enterprise
ubuntu: true
requires:
- end-to-end-tests
- mysql-integration-test
- postgres-integration-test
- package-enterprise
- build-enterprise-windows-installer
- end-to-end-tests:
filters: *filter-master-or-release
requires:
- package-oss
- deploy-to-kubernetes:
filters: *filter-only-master
requires:
- build-enterprise-docker-images
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters: *filter-only-master
jobs:
- scan-docker-image:
matrix:
parameters:
image: [grafana/grafana, grafana/grafana-enterprise]
tag: [latest, master, latest-ubuntu, master-ubuntu]