.circleci/config.yml
version: 2.1
parameters:
ssh-fingerprint:
type: string
default: ${GITHUB_SSH_FINGERPRINT}
codeclimate-reporter-id:
type: string
default: ${CC_TEST_REPORTER_ID}
aliases:
# Workflow filters
- &filter-only-master
branches:
only:
- main
- master
- &filter-only-release
branches:
only: /^v[1-9]*[0-9]+\.[1-9]*[0-9]+\.x$/
workflows:
plugin_workflow:
jobs:
- yarn_install
- build_docs:
requires:
- yarn_install
- build_frontend:
requires:
- yarn_install
- code_coverage_frontend:
requires:
- build_frontend
- upload_coverage:
requires:
- code_coverage_frontend
- package:
context:
- Plugins
requires:
- build_frontend
- build_docs
- copy_artifacts_to_gcs:
context:
- Plugins
requires:
- package
- copy_screenshots_to_gcs:
context:
- Plugins
requires:
- package
- report:
context:
- Plugins
requires:
- upload_coverage
- copy_artifacts_to_gcs
- copy_screenshots_to_gcs
- approve_release:
type: approval
requires:
- report
filters: *filter-only-release
- publish_gcs_release:
context:
- Plugins
requires:
- approve_release
filters: *filter-only-release
- publish_github_release:
context:
- Plugins
requires:
- approve_release
filters: *filter-only-release
- approve_publish_to_gcom:
context:
- Plugins
type: approval
requires:
- publish_github_release
- publish_gcs_release
filters: *filter-only-release
- publish_to_gcom:
context:
- Plugins
requires:
- approve_publish_to_gcom
filters: *filter-only-release
executors:
default_exec:
docker:
- image: grafana/grafana-plugin-ci:1.1.3-alpine
e2e_exec:
docker:
- image: grafana/grafana-plugin-ci-e2e:latest
cloud_sdk_exec:
docker:
- image: google/cloud-sdk
grafana_publisher:
docker:
- image: grafana/integration-grafana-publisher:latest
jobs:
yarn_install:
executor: default_exec
steps:
- checkout
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: |
mkdir ci
[ -f ~/project/node_modules/.bin/grafana-toolkit ] || yarn install --frozen-lockfile
- save_cache:
name: save node_modules
paths:
- ~/project/node_modules
key: build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- save_cache:
name: save cypress cache
paths:
- ~/.cache/Cypress
key: cypress-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- persist_to_workspace:
root: .
paths:
- ci
build_docs:
executor: default_exec
steps:
- checkout
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Build docs
command: |
./node_modules/.bin/grafana-toolkit plugin:ci-docs
[ -d "dist" ] || circleci-agent step halt
- persist_to_workspace:
root: .
paths:
- dist
build_frontend:
executor: default_exec
steps:
- checkout
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Build and test frontend
command: |
# hack for rxjs issue
rm -rf ./node_modules/@grafana/data/node_modules/rxjs
npx grafana-toolkit plugin:ci-build
npx grafana-toolkit plugin:ci-build --finish
- persist_to_workspace:
root: .
paths:
- ci
code_coverage_frontend:
executor: default_exec
steps:
- checkout
- attach_workspace:
at: .
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Run coverage report
command: |
/usr/local/bin/cc-test-reporter format-coverage -t lcov -o out/codeclimate.frontend.json ci/jobs/build_frontend/coverage/lcov.info
- run:
name: Install jest and jest-junit
command: yarn global add jest jest-junit --ignore-engines
- run:
name: Run tests with JUnit as reporter
command: jest --passWithNoTests --ci --runInBand --reporters=default --reporters=jest-junit
environment:
JEST_JUNIT_OUTPUT_DIR: "test-results/jest/results.xml"
- persist_to_workspace:
root: .
paths:
- out
- ci/jobs/code_coverage_frontend
- store_test_results:
path: test-results
upload_coverage:
executor: default_exec
steps:
- attach_workspace:
at: .
- run:
name: Upload coverage results to Code Climate
command: |
/usr/local/bin/cc-test-reporter sum-coverage out/codeclimate.*.json -d -p 1 -o out/codeclimate.total.json
/usr/local/bin/cc-test-reporter upload-coverage -i out/codeclimate.total.json
package:
executor: e2e_exec
steps:
- checkout
- attach_workspace:
at: .
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Package Distribution (for signing/etc)
command: |
#
# ci-package will create the zip file
#
npx grafana-toolkit plugin:ci-package
#
#
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
VERSION=`cat ci/dist/plugin.json|jq '.info.version'| sed s/\"//g`
echo "Plugin Name: ${PLUGIN_NAME}"
echo "Plugin Version: ${VERSION}"
#
# Create zip file "any" platform
#
# 1. rename to ANY package
#
mv ci/packages/${PLUGIN_NAME}-${VERSION}.zip \
ci/packages/${PLUGIN_NAME}-${VERSION}.any.zip
mv ci/packages/${PLUGIN_NAME}-${VERSION}.zip.sha1 \
ci/packages/${PLUGIN_NAME}-${VERSION}.any.zip.sha1
#
# 2. update info.json with new zip file name
#
sed -i 's/zip/any\.zip/g' ci/packages/info.json
#
# 3. move all files into ANY subdir
#
mkdir -p ci/packages/any
cp -p ci/packages/info.json ci/packages/any/info.json
cp -p ci/packages/info.json ci/packages/any/info-any.json
mv ci/packages/${PLUGIN_NAME}* ci/packages/any/
- persist_to_workspace:
root: .
paths:
- ci/dist
- ci/jobs/package
- ci/packages
- store_artifacts:
path: ci/packages
report:
executor: default_exec
steps:
- checkout
- attach_workspace:
at: .
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: Toolkit report
command: |
npx grafana-toolkit plugin:ci-report
- store_artifacts:
path: ci
copy_artifacts_to_gcs:
executor: cloud_sdk_exec
steps:
- checkout
- attach_workspace:
at: .
- run:
name: "Copy Artifacts to GCS Bucket"
command: |
ls -l ci/jobs/build_frontend/dist/plugin.json
echo "Contents of ci/jobs/build_frontend/dist/plugin.json"
cat ci/jobs/build_frontend/dist/plugin.json
ls -lR ci/packages
apt update
apt install -y jq git-lfs
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
echo "Plugin Name: ${PLUGIN_NAME}"
VERSION=`cat ci/dist/plugin.json|jq '.info.version'| sed s/\"//g`
echo "Plugin Version: ${VERSION}"
# copy
if [ -z "${GCLOUD_SERVICE_KEY}" ]; then
echo "Missing GCS Publish Key"
exit -1
fi
echo ${GCLOUD_SERVICE_KEY} | gcloud auth activate-service-account --key-file=-
echo "Contents of artifacts"
echo "Copying artifacts to ${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/${CIRCLE_SHA1}"
gsutil -m cp -r ci/packages/** gs://integration-artifacts/${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/${CIRCLE_SHA1}
echo "Cleaning latest"
gsutil rm -f gs://integration-artifacts/${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/latest/** || true
echo "Copying artifacts to ${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/latest"
gsutil -m cp -r ci/packages/** gs://integration-artifacts/${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/latest
# special handling for master
if [ ${CIRCLE_BRANCH} == "master" ]; then
echo "Cleaning master latest"
gsutil rm -f gs://integration-artifacts/${PLUGIN_NAME}/${CIRCLE_BRANCH}/latest/** || true
echo "Copying artifacts to master latest"
gsutil -m cp -r ci/packages/** gs://integration-artifacts/${PLUGIN_NAME}/${CIRCLE_BRANCH}/latest
fi
gsutil ls -r gs://integration-artifacts/${PLUGIN_NAME}
copy_screenshots_to_gcs:
executor: cloud_sdk_exec
steps:
- checkout
- attach_workspace:
at: .
- run:
name: "Copy Screenshots to GCS Bucket"
command: |
if [ ! -d src/screenshots ] && [ ! -d src/img ]; then
exit 0
fi
if [ -z "${GCLOUD_SERVICE_KEY}" ]; then
echo "Missing GCS Publish Key"
exit -1
fi
apt update
apt install -y jq git-lfs
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
echo ${GCLOUD_SERVICE_KEY} | gcloud auth activate-service-account --key-file=-
if [ -d src/screenshots ]; then
echo "Copying screenshots to gs://integration-artifacts/${PLUGIN_NAME}/screenshots/"
gsutil -m cp -r src/screenshots/** gs://integration-artifacts/${PLUGIN_NAME}/screenshots/
gsutil ls -r gs://integration-artifacts/${PLUGIN_NAME}/screenshots
fi
if [ -d src/img ]; then
echo "Copying img to gs://integration-artifacts/${PLUGIN_NAME}/img/"
gsutil -m cp -r src/img/** gs://integration-artifacts/${PLUGIN_NAME}/img
gsutil ls -r gs://integration-artifacts/${PLUGIN_NAME}/img
fi
publish_gcs_release:
executor: cloud_sdk_exec
steps:
- checkout
- attach_workspace:
at: .
- run:
name: "Copy Artifacts to GCS Release Bucket"
command: |
ls -l ci/jobs/build_frontend/dist/plugin.json
echo "Contents of ci/jobs/build_frontend/dist/plugin.json"
cat ci/jobs/build_frontend/dist/plugin.json
ls -lR ci/packages
apt update
apt install -y jq git-lfs
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
echo "Plugin Name: ${PLUGIN_NAME}"
VERSION=`cat ci/dist/plugin.json|jq '.info.version'| sed s/\"//g`
echo "Plugin Version: ${VERSION}"
# copy
if [ -z "${GCLOUD_SERVICE_KEY}" ]; then
echo "Missing GCS Publish Key"
exit -1
fi
echo ${GCLOUD_SERVICE_KEY} | gcloud auth activate-service-account --key-file=-
echo "Contents of artifacts"
echo "Copying artifacts to ${PLUGIN_NAME}/${VERSION}/${CIRCLE_BRANCH}/${CIRCLE_SHA1}"
if [ -d ci/packages/any ]; then
gsutil -m cp -r ci/packages/any/** gs://integration-artifacts/${PLUGIN_NAME}/release/${VERSION}/any
fi
publish_github_release:
docker:
- image: cibuilds/github:0.13.0
steps:
- checkout
- add_ssh_keys:
fingerprints:
- << pipeline.parameters.ssh-fingerprint >>
- attach_workspace:
at: .
- restore_cache:
name: restore node_modules
keys:
- build-cache-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- run:
name: "Publish Release on GitHub"
command: |
# copy ci artifacts
mkdir -p artifacts
if [ -d ci/packages/any ]; then
cp ci/packages/any/* artifacts
fi
apk add --update --no-cache jq git-lfs
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
echo "Plugin Name: ${PLUGIN_NAME}"
VERSION=`cat ci/dist/plugin.json|jq '.info.version'| sed s/\"//g`
echo "Plugin Version: ${VERSION}"
RELEASE_NOTES=`awk 'BEGIN {FS="##"; RS=""} FNR==4 {print; exit}' CHANGELOG.md`
git config user.email "eng@grafana.com"
git config user.name "CircleCI Automation"
git checkout -b release-${VERSION}
# add dist, it is needed to get the right plugin.json info during gcom publish
mkdir -p dist
cp -rp ci/dist/${PLUGIN_NAME}/* dist/
git add --force dist/
git commit -m "automated release $VERSION [skip ci]"
git push -f origin release-${VERSION}
git tag -f v${VERSION}
git push -f origin v${VERSION}
ghr \
-t ${GITHUB_TOKEN} \
-u ${CIRCLE_PROJECT_USERNAME} \
-r ${CIRCLE_PROJECT_REPONAME} \
-c ${CIRCLE_SHA1} \
-n "${PLUGIN_NAME} v${VERSION}" \
-b "${RELEASE_NOTES}" \
-delete \
v${VERSION} \
./artifacts/
publish_to_gcom:
executor: grafana_publisher
steps:
- checkout
- attach_workspace:
at: .
- run:
name: "Publish to GCOM"
command: |
if [ -z "${GCOM_PUBLISH_TOKEN}" ]; then
echo "Missing GCOM Publish Key"
exit -1
fi
if [ -z "${GITHUB_TOKEN}" ]; then
echo "Missing GITHUB_TOKEN"
exit -1
fi
if [ -z "${GCLOUD_SERVICE_KEY}" ]; then
echo "Missing GCLOUD_SERVICE_KEY"
exit -1
fi
PLUGIN_NAME=`cat ci/dist/plugin.json|jq '.id'| sed s/\"//g`
PLUGIN_VERSION=`cat ci/dist/plugin.json|jq '.info.version'| sed s/\"//g`
echo ${GCLOUD_SERVICE_KEY} | gcloud auth activate-service-account --key-file=-
echo "Publishing to GCOM: $PLUGIN_NAME $PLUGIN_VERSION"
/root/app/bin/grafana-publisher.js --auto publishremote $PLUGIN_NAME $PLUGIN_VERSION