Chore: Dependency clean up
This commit is contained in:
@@ -1,331 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
aliases:
|
||||
# Workflow filters
|
||||
- &filter-not-release-or-master
|
||||
tags:
|
||||
ignore: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
|
||||
branches:
|
||||
ignore:
|
||||
- master
|
||||
- /^release-[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
|
||||
- docs
|
||||
- gh-pages
|
||||
- &filter-only-master
|
||||
branches:
|
||||
only: master
|
||||
- &filter-only-release
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
|
||||
- &filter-docs
|
||||
branches:
|
||||
only: docs
|
||||
|
||||
executors:
|
||||
e2e_exec:
|
||||
docker:
|
||||
- image: srclosson/grafana-plugin-ci-e2e:latest
|
||||
|
||||
jobs:
|
||||
build:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
environment:
|
||||
YARN_NO_PROGRESS: "true"
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-go-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: 'make install'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- save_cache:
|
||||
key: dependency-cache-go-{{ checksum "go.sum" }}
|
||||
paths:
|
||||
- ./vendor
|
||||
- /go/pkg/mod
|
||||
- run: make build
|
||||
|
||||
lint:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-go-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: 'make install'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- save_cache:
|
||||
key: dependency-cache-go-{{ checksum "go.sum" }}
|
||||
paths:
|
||||
- ./vendor
|
||||
- /go/pkg/mod
|
||||
- run: make lint
|
||||
|
||||
test:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
environment:
|
||||
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
|
||||
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
steps:
|
||||
- checkout
|
||||
# Prepare for artifact and test results collection equivalent to how it was done on 1.0.
|
||||
# In many cases you can simplify this from what is generated here.
|
||||
# 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/'
|
||||
- run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-go-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: 'make install'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- save_cache:
|
||||
key: dependency-cache-go-{{ checksum "go.sum" }}
|
||||
paths:
|
||||
- ./vendor
|
||||
- /go/pkg/mod
|
||||
- run: make test-ci
|
||||
- run: bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
|
||||
- store_test_results:
|
||||
path: /tmp/circleci-test-results
|
||||
- store_artifacts:
|
||||
path: /tmp/circleci-artifacts
|
||||
- store_artifacts:
|
||||
path: /tmp/circleci-test-results
|
||||
|
||||
get-plugin:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
environment:
|
||||
YARN_NO_PROGRESS: "true"
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-go-{{ checksum "go.sum" }}
|
||||
- persist_to_workspace:
|
||||
root: ~/alexanderzobnin/
|
||||
paths:
|
||||
- grafana-zabbix
|
||||
|
||||
package-plugin:
|
||||
executor: e2e_exec
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/alexanderzobnin
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: 'make install'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- save_cache:
|
||||
key: dependency-cache-go-{{ checksum "go.sum" }}
|
||||
paths:
|
||||
- ./vendor
|
||||
- /go/pkg/mod
|
||||
- run:
|
||||
name: Build plugin for all platforms
|
||||
command: 'make dist'
|
||||
no_output_timeout: 15m
|
||||
- run:
|
||||
name: Prepare plugin for packaging
|
||||
command: |
|
||||
mkdir -p ci/jobs/build_plugin
|
||||
mv dist/ ci/jobs/build_plugin
|
||||
cp CHANGELOG.md ci/jobs/build_plugin/dist
|
||||
- run:
|
||||
name: Package and sign plugin
|
||||
command: yarn grafana-toolkit plugin:ci-package
|
||||
no_output_timeout: 15m
|
||||
- persist_to_workspace:
|
||||
root: ~/alexanderzobnin/
|
||||
paths:
|
||||
- grafana-zabbix
|
||||
- store_artifacts:
|
||||
path: ci/packages
|
||||
|
||||
make-github-release:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
environment:
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/alexanderzobnin
|
||||
- run:
|
||||
name: Publish release
|
||||
command: 'node ./scripts/github/publishRelease.js'
|
||||
no_output_timeout: 15m
|
||||
|
||||
make-release-commit:
|
||||
working_directory: ~/alexanderzobnin/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.13-node
|
||||
environment:
|
||||
CI_GIT_USER: CircleCI
|
||||
CI_GIT_EMAIL: ci@grafana.com
|
||||
steps:
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "dc:7e:54:e0:aa:56:4d:e5:60:7b:f3:51:24:2d:d3:29"
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- dependency-cache-go-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: 'make install'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-npm-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- ./node_modules
|
||||
- save_cache:
|
||||
key: dependency-cache-go-{{ checksum "go.sum" }}
|
||||
paths:
|
||||
- ./vendor
|
||||
- /go/pkg/mod
|
||||
- run: ./.circleci/make-release.sh
|
||||
|
||||
build-docs:
|
||||
working_directory: ~/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/python:2.7
|
||||
steps:
|
||||
- run: sudo pip install --upgrade pip
|
||||
- run: sudo pip install mkdocs
|
||||
- checkout
|
||||
- run: cd docs && mkdocs build --clean
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- docs/site
|
||||
|
||||
deploy-docs:
|
||||
working_directory: ~/grafana-zabbix
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
environment:
|
||||
GH_PAGES_BRANCH: gh-pages
|
||||
CI_GIT_USER: CircleCI
|
||||
CI_GIT_EMAIL: ci@grafana.com
|
||||
steps:
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "dc:7e:54:e0:aa:56:4d:e5:60:7b:f3:51:24:2d:d3:29"
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ../gh-pages
|
||||
- run: ./.circleci/deploy-docs.sh
|
||||
|
||||
codespell:
|
||||
docker:
|
||||
- image: circleci/python
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo pip install codespell
|
||||
- run: codespell -S './.git*,./src/img*,./go.sum,./yarn.lock' -L que --ignore-words=./.codespell_ignore
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-master:
|
||||
jobs:
|
||||
- build:
|
||||
filters: *filter-only-master
|
||||
- codespell:
|
||||
filters: *filter-only-master
|
||||
- lint:
|
||||
filters: *filter-only-master
|
||||
- test:
|
||||
filters: *filter-only-master
|
||||
|
||||
build-branches-and-prs:
|
||||
jobs:
|
||||
- build:
|
||||
filters: *filter-not-release-or-master
|
||||
- codespell:
|
||||
filters: *filter-not-release-or-master
|
||||
- lint:
|
||||
filters: *filter-not-release-or-master
|
||||
- test:
|
||||
filters: *filter-not-release-or-master
|
||||
|
||||
build-release:
|
||||
jobs:
|
||||
- build:
|
||||
filters: *filter-only-release
|
||||
- codespell:
|
||||
filters: *filter-only-release
|
||||
- lint:
|
||||
filters: *filter-only-release
|
||||
- test:
|
||||
filters: *filter-only-release
|
||||
- get-plugin:
|
||||
requires:
|
||||
- build
|
||||
- codespell
|
||||
- lint
|
||||
- test
|
||||
filters: *filter-only-release
|
||||
- package-plugin:
|
||||
requires:
|
||||
- get-plugin
|
||||
filters: *filter-only-release
|
||||
- make-github-release:
|
||||
requires:
|
||||
- package-plugin
|
||||
filters: *filter-only-release
|
||||
|
||||
build-docs:
|
||||
jobs:
|
||||
- build-docs:
|
||||
filters: *filter-docs
|
||||
- deploy-docs:
|
||||
requires:
|
||||
- build-docs
|
||||
filters: *filter-docs
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit script if you try to use an uninitialized variable.
|
||||
set -o nounset
|
||||
# Exit script if a statement returns a non-true return value.
|
||||
set -o errexit
|
||||
# Use the error status of the first failure, rather than that of the last item in a pipeline.
|
||||
set -o pipefail
|
||||
|
||||
echo "current dir: $(pwd)"
|
||||
|
||||
# Setup git env
|
||||
git config --global user.email "$CI_GIT_EMAIL"
|
||||
git config --global user.name "$CI_GIT_USER"
|
||||
echo "git user is $CI_GIT_USER ($CI_GIT_EMAIL)"
|
||||
|
||||
git checkout -b "$GH_PAGES_BRANCH"
|
||||
rm -rf ./* || true
|
||||
mv ../gh-pages/docs/site/* ./
|
||||
git add --force .
|
||||
git commit -m "build docs from commit ${CIRCLE_SHA1:0:7} (branch $CIRCLE_BRANCH)"
|
||||
git log -n 3
|
||||
|
||||
git push origin "$GH_PAGES_BRANCH" --force
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit script if you try to use an uninitialized variable.
|
||||
set -o nounset
|
||||
# Exit script if a statement returns a non-true return value.
|
||||
set -o errexit
|
||||
# Use the error status of the first failure, rather than that of the last item in a pipeline.
|
||||
set -o pipefail
|
||||
|
||||
RELEASE_VER=$(echo "$CIRCLE_TAG" | grep -Po "(?<=v)[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)")
|
||||
|
||||
if [ -z "$RELEASE_VER" ]; then
|
||||
echo "No release version provided"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $RELEASE_VER =~ ^[0-9]+(\.[0-9]+){2}(-.+|[^-.]*) ]]; then
|
||||
echo "Preparing release $RELEASE_VER"
|
||||
else
|
||||
echo "Release should has format 1.2.3[-meta], got $RELEASE_VER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create zip package
|
||||
PACKAGE_NAME="grafana-zabbix-${RELEASE_VER}.zip"
|
||||
echo "packaging into $PACKAGE_NAME"
|
||||
mv ./dist alexanderzobnin-zabbix-app
|
||||
zip -r $PACKAGE_NAME ./alexanderzobnin-zabbix-app
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit script if you try to use an uninitialized variable.
|
||||
set -o nounset
|
||||
# Exit script if a statement returns a non-true return value.
|
||||
set -o errexit
|
||||
# Use the error status of the first failure, rather than that of the last item in a pipeline.
|
||||
set -o pipefail
|
||||
|
||||
# Setup git env
|
||||
git config --global user.email "$CI_GIT_EMAIL"
|
||||
git config --global user.name "$CI_GIT_USER"
|
||||
echo "git user is $CI_GIT_USER ($CI_GIT_EMAIL)"
|
||||
|
||||
RELEASE_VER=$(echo "$CIRCLE_TAG" | grep -Po "(?<=v)[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)")
|
||||
|
||||
if [ -z "$RELEASE_VER" ]; then
|
||||
echo "No release version provided"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $RELEASE_VER =~ ^[0-9]+(\.[0-9]+){2}(-.+|[^-.]*) ]]; then
|
||||
echo "Preparing release $RELEASE_VER"
|
||||
else
|
||||
echo "Release should has format 1.2.3[-meta], got $RELEASE_VER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RELEASE_BRANCH=release-$RELEASE_VER
|
||||
|
||||
# Build plugin
|
||||
git checkout -b "$RELEASE_BRANCH"
|
||||
make clean install dist
|
||||
|
||||
# Commit release
|
||||
git add --force dist/
|
||||
git commit -m "release $RELEASE_VER"
|
||||
|
||||
RELEASE_COMMIT_HASH=$(git log -n 1 | grep -Po "(?<=commit )[0-9a-z]{40}")
|
||||
echo "$RELEASE_COMMIT_HASH"
|
||||
|
||||
# Push release branch
|
||||
git push origin "$RELEASE_BRANCH"
|
||||
17
.codecov.yml
17
.codecov.yml
@@ -1,17 +0,0 @@
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: 50...100
|
||||
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 5
|
||||
patch: off
|
||||
changes: off
|
||||
|
||||
comment: off
|
||||
|
||||
ignore:
|
||||
- "dist/test/test-setup/.*"
|
||||
- "src/test-setup/.*"
|
||||
@@ -1 +0,0 @@
|
||||
hist
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||
*
|
||||
* In order to extend the configuration follow the steps in .config/README.md
|
||||
* In order to extend the configuration follow the steps in
|
||||
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-eslint-config
|
||||
*/
|
||||
{
|
||||
{
|
||||
"extends": ["@grafana/eslint-config"],
|
||||
"root": true,
|
||||
"ignorePatterns": ["**/*.js", "./src/test-setup/**/*.*"],
|
||||
"rules": {
|
||||
"react/prop-types": "off"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
ARG grafana_version=latest
|
||||
ARG grafana_image=grafana-enterprise
|
||||
|
||||
FROM grafana/grafana:${grafana_version}
|
||||
FROM grafana/${grafana_image}:${grafana_version}
|
||||
|
||||
# Make it as simple as possible to access the grafana instance for development purposes
|
||||
# Do NOT enable these settings in a public facing / production grafana instance
|
||||
@@ -12,4 +13,4 @@ ENV GF_DEFAULT_APP_MODE "development"
|
||||
|
||||
# Inject livereload script into grafana index.html
|
||||
USER root
|
||||
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html
|
||||
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html
|
||||
|
||||
@@ -60,7 +60,7 @@ A common issue found with the current jest config involves importing an npm pack
|
||||
|
||||
```javascript
|
||||
process.env.TZ = 'UTC';
|
||||
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');
|
||||
const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils');
|
||||
|
||||
module.exports = {
|
||||
// Jest configuration provided by Grafana
|
||||
@@ -139,3 +139,26 @@ We need to update the `scripts` in the `package.json` to use the extended Webpac
|
||||
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
|
||||
+"dev": "webpack -w -c ./webpack.config.ts --env development",
|
||||
```
|
||||
|
||||
### Configure grafana image to use when running docker
|
||||
|
||||
By default `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behaviour simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.
|
||||
|
||||
**Example:**
|
||||
|
||||
```yaml
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
grafana:
|
||||
container_name: 'myorg-basic-app'
|
||||
build:
|
||||
context: ./.config
|
||||
args:
|
||||
grafana_version: ${GRAFANA_VERSION:-9.1.2}
|
||||
grafana_image: ${GRAFANA_IMAGE:-grafana}
|
||||
```
|
||||
|
||||
In this example we are assigning the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will give you the possibility to set the value while running the docker-compose commands which might be convinent in some scenarios.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||
*
|
||||
* In order to extend the configuration follow the steps in .config/README.md
|
||||
* In order to extend the configuration follow the steps in
|
||||
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||
*
|
||||
* In order to extend the configuration follow the steps in .config/README.md
|
||||
* In order to extend the configuration follow the steps in
|
||||
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
@@ -24,7 +25,7 @@ module.exports = {
|
||||
'^.+\\.(t|j)sx?$': [
|
||||
'@swc/jest',
|
||||
{
|
||||
sourceMaps: true,
|
||||
sourceMaps: 'inline',
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
|
||||
@@ -8,12 +8,24 @@
|
||||
* This utility function is useful in combination with jest `transformIgnorePatterns` config
|
||||
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
|
||||
*/
|
||||
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`;
|
||||
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`;
|
||||
|
||||
// Array of known nested grafana package dependencies that only bundle an ESM version
|
||||
const grafanaESModules = ['ol', 'react-colorful', 'uuid'];
|
||||
const grafanaESModules = [
|
||||
'.pnpm', // Support using pnpm symlinked packages
|
||||
'@grafana/schema',
|
||||
'd3',
|
||||
'd3-color',
|
||||
'd3-force',
|
||||
'd3-interpolate',
|
||||
'd3-scale-chromatic',
|
||||
'ol',
|
||||
'react-colorful',
|
||||
'rxjs',
|
||||
'uuid',
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
nodeModulesToTransform,
|
||||
grafanaESModules
|
||||
}
|
||||
grafanaESModules,
|
||||
};
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
/*
|
||||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||
*
|
||||
* In order to extend the configuration follow the steps in .config/README.md
|
||||
* In order to extend the configuration follow the steps in
|
||||
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-typescript-config
|
||||
*/
|
||||
{
|
||||
{
|
||||
"compilerOptions": {
|
||||
"alwaysStrict": true,
|
||||
"declaration": false,
|
||||
"rootDir": "../src",
|
||||
"baseUrl": "../src",
|
||||
"typeRoots": ["../node_modules/@types"],
|
||||
"resolveJsonModule": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
@@ -20,6 +21,6 @@
|
||||
},
|
||||
"transpileOnly": true
|
||||
},
|
||||
"include": ["../src", "./types", "../test-setup"],
|
||||
"include": ["../src", "./types"],
|
||||
"extends": "@grafana/tsconfig"
|
||||
}
|
||||
|
||||
@@ -1,45 +1,58 @@
|
||||
import fs from 'fs';
|
||||
import process from 'process';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import util from 'util';
|
||||
import glob from 'glob';
|
||||
import { glob } from 'glob';
|
||||
import { SOURCE_DIR } from './constants';
|
||||
|
||||
const globAsync = util.promisify(glob);
|
||||
export function isWSL() {
|
||||
if (process.platform !== 'linux') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (os.release().toLowerCase().includes('microsoft')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPackageJson() {
|
||||
return require(path.resolve(process.cwd(), 'package.json'));
|
||||
}
|
||||
|
||||
export function getPluginId() {
|
||||
const { id } = require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
|
||||
|
||||
return id;
|
||||
export function getPluginJson() {
|
||||
return require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
|
||||
}
|
||||
|
||||
export function hasReadme() {
|
||||
return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md'));
|
||||
}
|
||||
|
||||
// Support bundling nested plugins by finding all plugin.json files in src directory
|
||||
// then checking for a sibling module.[jt]sx? file.
|
||||
export async function getEntries(): Promise<Record<string, string>> {
|
||||
const parent = '..';
|
||||
const pluginsJson = await globAsync('**/src/**/plugin.json');
|
||||
const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });
|
||||
|
||||
const plugins = await Promise.all(
|
||||
pluginsJson.map((pluginJson) => {
|
||||
const folder = path.dirname(pluginJson);
|
||||
return globAsync(`${folder}/module.{ts,tsx,js}`);
|
||||
return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
|
||||
})
|
||||
);
|
||||
|
||||
const entries = plugins.reduce((result, modules) => {
|
||||
return plugins.reduce((result, modules) => {
|
||||
return modules.reduce((result, module) => {
|
||||
const pluginPath = path.resolve(path.dirname(module), parent);
|
||||
const pluginName = path.basename(pluginPath);
|
||||
const entryName = plugins.length > 1 ? `${pluginName}/module` : 'module';
|
||||
const pluginPath = path.dirname(module);
|
||||
const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, '');
|
||||
const entryName = pluginName === '' ? 'module' : `${pluginName}/module`;
|
||||
|
||||
result[entryName] = path.join(parent, module);
|
||||
result[entryName] = module;
|
||||
return result;
|
||||
}, result);
|
||||
}, {});
|
||||
return entries;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
||||
*
|
||||
* In order to extend the configuration follow the steps in .config/README.md
|
||||
* In order to extend the configuration follow the steps in
|
||||
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-webpack-config
|
||||
*/
|
||||
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
@@ -12,189 +13,200 @@ import path from 'path';
|
||||
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
|
||||
import { Configuration } from 'webpack';
|
||||
|
||||
import { getPackageJson, getPluginId, hasReadme, getEntries } from './utils';
|
||||
import { getPackageJson, getPluginJson, hasReadme, getEntries, isWSL } from './utils';
|
||||
import { SOURCE_DIR, DIST_DIR } from './constants';
|
||||
|
||||
const config = async (env): Promise<Configuration> => ({
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
const pluginJson = getPluginJson();
|
||||
|
||||
const config = async (env): Promise<Configuration> => {
|
||||
const baseConfig: Configuration = {
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
context: path.join(process.cwd(), SOURCE_DIR),
|
||||
context: path.join(process.cwd(), SOURCE_DIR),
|
||||
|
||||
devtool: env.production ? 'source-map' : 'eval-source-map',
|
||||
devtool: env.production ? 'source-map' : 'eval-source-map',
|
||||
|
||||
// Entries from getEntries() work incorrect, so declare it manually in root webpack config
|
||||
// entry: await getEntries(),
|
||||
entry: await getEntries(),
|
||||
|
||||
externals: [
|
||||
'lodash',
|
||||
'jquery',
|
||||
'moment',
|
||||
'slate',
|
||||
'emotion',
|
||||
'@emotion/react',
|
||||
'@emotion/css',
|
||||
'prismjs',
|
||||
'slate-plain-serializer',
|
||||
'@grafana/slate-react',
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-redux',
|
||||
'redux',
|
||||
'rxjs',
|
||||
'react-router',
|
||||
'react-router-dom',
|
||||
'd3',
|
||||
'angular',
|
||||
'@grafana/ui',
|
||||
'@grafana/runtime',
|
||||
'@grafana/data',
|
||||
externals: [
|
||||
'lodash',
|
||||
'jquery',
|
||||
'moment',
|
||||
'slate',
|
||||
'emotion',
|
||||
'@emotion/react',
|
||||
'@emotion/css',
|
||||
'prismjs',
|
||||
'slate-plain-serializer',
|
||||
'@grafana/slate-react',
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-redux',
|
||||
'redux',
|
||||
'rxjs',
|
||||
'react-router',
|
||||
'react-router-dom',
|
||||
'd3',
|
||||
'angular',
|
||||
'@grafana/ui',
|
||||
'@grafana/runtime',
|
||||
'@grafana/data',
|
||||
|
||||
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
|
||||
({ request }, callback) => {
|
||||
const prefix = 'grafana/';
|
||||
const hasPrefix = (request) => request.indexOf(prefix) === 0;
|
||||
const stripPrefix = (request) => request.substr(prefix.length);
|
||||
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
|
||||
({ request }, callback) => {
|
||||
const prefix = 'grafana/';
|
||||
const hasPrefix = (request) => request.indexOf(prefix) === 0;
|
||||
const stripPrefix = (request) => request.substr(prefix.length);
|
||||
|
||||
if (hasPrefix(request)) {
|
||||
return callback(undefined, stripPrefix(request));
|
||||
}
|
||||
if (hasPrefix(request)) {
|
||||
return callback(undefined, stripPrefix(request));
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
],
|
||||
callback();
|
||||
},
|
||||
],
|
||||
|
||||
mode: env.production ? 'production' : 'development',
|
||||
mode: env.production ? 'production' : 'development',
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
exclude: /(node_modules)/,
|
||||
test: /\.[tj]sx?$/,
|
||||
use: {
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
jsc: {
|
||||
baseUrl: './src',
|
||||
target: 'es2015',
|
||||
loose: false,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
decorators: false,
|
||||
dynamicImport: true,
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
exclude: /(node_modules)/,
|
||||
test: /\.[tj]sx?$/,
|
||||
use: {
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
jsc: {
|
||||
baseUrl: './src',
|
||||
target: 'es2015',
|
||||
loose: false,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
decorators: false,
|
||||
dynamicImport: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
exclude: /(node_modules)/,
|
||||
test: /\.s[ac]ss$/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
// Keep publicPath relative for host.com/grafana/ deployments
|
||||
publicPath: `public/plugins/${getPluginId()}/img/`,
|
||||
outputPath: 'img/',
|
||||
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
// Keep publicPath relative for host.com/grafana/ deployments
|
||||
publicPath: `public/plugins/${getPluginId()}/fonts`,
|
||||
outputPath: 'fonts/',
|
||||
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
|
||||
{
|
||||
test: /\.s[ac]ss$/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
// Keep publicPath relative for host.com/grafana/ deployments
|
||||
publicPath: `public/plugins/${pluginJson.id}/img/`,
|
||||
outputPath: 'img/',
|
||||
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
// Keep publicPath relative for host.com/grafana/ deployments
|
||||
publicPath: `public/plugins/${pluginJson.id}/fonts/`,
|
||||
outputPath: 'fonts/',
|
||||
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
output: {
|
||||
clean: {
|
||||
keep: /gpx_.*/,
|
||||
},
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
type: 'amd',
|
||||
},
|
||||
path: path.resolve(process.cwd(), DIST_DIR),
|
||||
publicPath: '/',
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
// If src/README.md exists use it; otherwise the root README
|
||||
// To `compiler.options.output`
|
||||
{ from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true },
|
||||
{ from: 'plugin.json', to: '.' },
|
||||
{ from: '../LICENSE', to: '.' },
|
||||
{ from: '../CHANGELOG.md', to: '.', force: true },
|
||||
{ from: '**/*.json', to: '.' }, // TODO<Add an error for checking the basic structure of the repo>
|
||||
{ from: '**/*.svg', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: '**/*.png', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: '**/*.html', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'img/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'libs/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'static/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
],
|
||||
}),
|
||||
// Replace certain template-variables in the README and plugin.json
|
||||
new ReplaceInFileWebpackPlugin([
|
||||
{
|
||||
dir: DIST_DIR,
|
||||
files: ['plugin.json', 'README.md'],
|
||||
rules: [
|
||||
{
|
||||
search: /\%VERSION\%/g,
|
||||
replace: getPackageJson().version,
|
||||
},
|
||||
{
|
||||
search: /\%TODAY\%/g,
|
||||
replace: new Date().toISOString().substring(0, 10),
|
||||
},
|
||||
{
|
||||
search: /\%PLUGIN_ID\%/g,
|
||||
replace: getPluginId(),
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
async: Boolean(env.development),
|
||||
issue: {
|
||||
include: [{ file: '**/*.{ts,tsx}' }],
|
||||
},
|
||||
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
|
||||
}),
|
||||
new ESLintPlugin({
|
||||
extensions: ['.ts', '.tsx'],
|
||||
lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
|
||||
}),
|
||||
...(env.development ? [new LiveReloadPlugin()] : []),
|
||||
],
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
// handle resolving "rootDir" paths
|
||||
modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
|
||||
unsafeCache: true,
|
||||
},
|
||||
});
|
||||
output: {
|
||||
clean: {
|
||||
keep: new RegExp(`(.*?_(amd64|arm(64)?)(.exe)?|go_plugin_build_manifest)`),
|
||||
},
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
type: 'amd',
|
||||
},
|
||||
path: path.resolve(process.cwd(), DIST_DIR),
|
||||
publicPath: '/',
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
// If src/README.md exists use it; otherwise the root README
|
||||
// To `compiler.options.output`
|
||||
{ from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true },
|
||||
{ from: 'plugin.json', to: '.' },
|
||||
{ from: '../LICENSE', to: '.' },
|
||||
{ from: '../CHANGELOG.md', to: '.', force: true },
|
||||
{ from: '**/*.json', to: '.' }, // TODO<Add an error for checking the basic structure of the repo>
|
||||
{ from: '**/*.svg', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: '**/*.png', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: '**/*.html', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'img/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'libs/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
{ from: 'static/**/*', to: '.', noErrorOnMissing: true }, // Optional
|
||||
],
|
||||
}),
|
||||
// Replace certain template-variables in the README and plugin.json
|
||||
new ReplaceInFileWebpackPlugin([
|
||||
{
|
||||
dir: DIST_DIR,
|
||||
files: ['plugin.json', 'README.md'],
|
||||
rules: [
|
||||
{
|
||||
search: /\%VERSION\%/g,
|
||||
replace: getPackageJson().version,
|
||||
},
|
||||
{
|
||||
search: /\%TODAY\%/g,
|
||||
replace: new Date().toISOString().substring(0, 10),
|
||||
},
|
||||
{
|
||||
search: /\%PLUGIN_ID\%/g,
|
||||
replace: pluginJson.id,
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
async: Boolean(env.development),
|
||||
issue: {
|
||||
include: [{ file: '**/*.{ts,tsx}' }],
|
||||
},
|
||||
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
|
||||
}),
|
||||
new ESLintPlugin({
|
||||
extensions: ['.ts', '.tsx'],
|
||||
lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
|
||||
}),
|
||||
...(env.development ? [new LiveReloadPlugin()] : []),
|
||||
],
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
// handle resolving "rootDir" paths
|
||||
modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
|
||||
unsafeCache: true,
|
||||
},
|
||||
};
|
||||
|
||||
if (isWSL()) {
|
||||
baseConfig.watchOptions = {
|
||||
poll: 3000,
|
||||
ignored: /node_modules/,
|
||||
};
|
||||
}
|
||||
|
||||
return baseConfig;
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": "./.config/.eslintrc",
|
||||
"ignorePatterns": ["/src/test-setup/**/*"],
|
||||
"rules": {
|
||||
"react-hooks/exhaustive-deps": "off"
|
||||
}
|
||||
|
||||
193
.github/workflows/ci.yml
vendored
193
.github/workflows/ci.yml
vendored
@@ -1,193 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Setup Go environment
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.19'
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- name: Cache yarn cache
|
||||
uses: actions/cache@v2
|
||||
id: cache-yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: Cache node_modules
|
||||
id: cache-node-modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.node-version }}-nodemodules-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Build frontend
|
||||
run: yarn build
|
||||
|
||||
- name: Build backend
|
||||
if: steps.check-for-backend.outputs.has-backend == 'true'
|
||||
uses: magefile/mage-action@v1
|
||||
with:
|
||||
version: latest
|
||||
args: buildAll
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Setup Go environment
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.19'
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: Cache yarn cache
|
||||
uses: actions/cache@v2
|
||||
id: cache-yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: Cache node_modules
|
||||
id: cache-node-modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.node-version }}-nodemodules-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Test backend
|
||||
if: steps.check-for-backend.outputs.has-backend == 'true'
|
||||
uses: magefile/mage-action@v1
|
||||
with:
|
||||
version: latest
|
||||
args: coverage
|
||||
|
||||
- name: Test frontend
|
||||
run: yarn test:ci
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable --prefer-offline
|
||||
|
||||
- name: Build frontend
|
||||
run: yarn build
|
||||
|
||||
- name: Setup Go environment
|
||||
if: steps.check-for-backend.outputs.has-backend == 'true'
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.19'
|
||||
|
||||
- name: Build backend
|
||||
if: steps.check-for-backend.outputs.has-backend == 'true'
|
||||
uses: magefile/mage-action@v1
|
||||
with:
|
||||
version: latest
|
||||
args: buildAll
|
||||
|
||||
- name: Start grafana docker
|
||||
run: yarn server -d
|
||||
|
||||
- name: Run e2e tests
|
||||
run: yarn e2e
|
||||
|
||||
- name: Stop grafana docker
|
||||
run: yarn server:stop
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Setup Go environment
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.19'
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: Cache yarn cache
|
||||
uses: actions/cache@v2
|
||||
id: cache-yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: Cache node_modules
|
||||
id: cache-node-modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.node-version }}-nodemodules-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Install golint
|
||||
run: GO111MODULE=off go get -u golang.org/x/lint/golint
|
||||
|
||||
- name: Lint frontend
|
||||
run: yarn lint
|
||||
|
||||
- name: Lint backend
|
||||
run: golint -min_confidence=1.1 -set_exit_status pkg/...
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -41,8 +41,7 @@ dist/
|
||||
ci/
|
||||
alexanderzobnin-zabbix-app.zip
|
||||
|
||||
# Grafana toolkit configs
|
||||
# .prettierrc.js
|
||||
.eslintcache
|
||||
|
||||
# locally required config files
|
||||
public/css/*.min.css
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { e2e } from '@grafana/e2e';
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Smoke test',
|
||||
itName: 'Smoke test',
|
||||
scenario: () => {
|
||||
e2e.pages.Home.visit();
|
||||
e2e().contains('Welcome to Grafana').should('be.visible');
|
||||
},
|
||||
});
|
||||
@@ -3,7 +3,7 @@ version: "3"
|
||||
services:
|
||||
# Grafana
|
||||
grafana:
|
||||
image: grafana/grafana:8.4.7
|
||||
image: grafana/grafana:10.1.2
|
||||
ports:
|
||||
- "3001:3000"
|
||||
volumes:
|
||||
@@ -48,7 +48,7 @@ services:
|
||||
POSTGRES_DB: zabbix
|
||||
|
||||
database:
|
||||
image: postgres
|
||||
image: postgres:15
|
||||
ports:
|
||||
- "15432:5432"
|
||||
command: postgres -c 'max_connections=1000'
|
||||
|
||||
159
package.json
159
package.json
@@ -1,137 +1,98 @@
|
||||
{
|
||||
"name": "grafana-zabbix",
|
||||
"private": false,
|
||||
"version": "4.4.1",
|
||||
"description": "Zabbix plugin for Grafana",
|
||||
"homepage": "http://grafana-zabbix.org",
|
||||
"scripts": {
|
||||
"build": "webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "webpack -w -c ./webpack.config.ts --env development",
|
||||
"test": "jest --watch --onlyChanged",
|
||||
"test:ci": "jest --maxWorkers 4",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
|
||||
"lint:fix": "yarn lint --fix",
|
||||
"e2e": "yarn cypress install && yarn grafana-e2e run",
|
||||
"e2e:update": "yarn cypress install && yarn grafana-e2e run --update-screenshots",
|
||||
"server": "docker-compose --file ./devenv/default/docker-compose.yml up --build",
|
||||
"server:stop": "docker-compose --file ./devenv/default/docker-compose.yml stop",
|
||||
"server:down": "docker-compose --file ./devenv/default/docker-compose.yml down",
|
||||
"sign": "grafana-toolkit plugin:sign",
|
||||
"spellcheck": "cspell -c cspell.config.json \"**/*.{ts,tsx,js,go,md,mdx,yml,yaml,json,scss,css}\""
|
||||
"bugs": {
|
||||
"url": "https://github.com/alexanderzobnin/grafana-zabbix/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/alexanderzobnin/grafana-zabbix.git"
|
||||
},
|
||||
"author": "Alexander Zobnin",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/alexanderzobnin/grafana-zabbix/issues"
|
||||
"author": "Alexander Zobnin",
|
||||
"scripts": {
|
||||
"build": "webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "webpack -w -c ./webpack.config.ts --env development",
|
||||
"e2e": "yarn exec cypress install && yarn exec grafana-e2e run",
|
||||
"e2e:update": "yarn exec cypress install && yarn exec grafana-e2e run --update-screenshots",
|
||||
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
|
||||
"lint:fix": "yarn run lint --fix",
|
||||
"server": "docker-compose up --build",
|
||||
"server:down": "docker-compose --file ./devenv/default/docker-compose.yml down",
|
||||
"server:stop": "docker-compose --file ./devenv/default/docker-compose.yml stop",
|
||||
"sign": "npx --yes @grafana/sign-plugin@latest",
|
||||
"spellcheck": "cspell -c cspell.config.json \"**/*.{ts,tsx,js,go,md,mdx,yml,yaml,json,scss,css}\"",
|
||||
"test": "jest --watch --onlyChanged",
|
||||
"test:ci": "jest --passWithNoTests --maxWorkers 4",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/css": "^11.1.3",
|
||||
"@grafana/data": "10.1.2",
|
||||
"@grafana/runtime": "10.1.2",
|
||||
"@grafana/ui": "10.1.2",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"tslib": "2.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/css": "11.1.3",
|
||||
"@emotion/react": "11.1.5",
|
||||
"@grafana/data": "9.3.2",
|
||||
"@grafana/e2e": "9.2.5",
|
||||
"@grafana/e2e-selectors": "9.2.5",
|
||||
"@grafana/eslint-config": "^5.1.0",
|
||||
"@grafana/runtime": "9.3.2",
|
||||
"@grafana/toolkit": "9.1.2",
|
||||
"@babel/core": "^7.21.4",
|
||||
"@grafana/eslint-config": "^6.0.0",
|
||||
"@grafana/tsconfig": "^1.2.0-rc1",
|
||||
"@grafana/ui": "9.3.2",
|
||||
"@popperjs/core": "2.4.0",
|
||||
"@swc/core": "^1.2.144",
|
||||
"@swc/helpers": "^0.4.12",
|
||||
"@swc/jest": "^0.2.23",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@swc/core": "1.3.75",
|
||||
"@swc/helpers": "^0.5.0",
|
||||
"@swc/jest": "^0.2.26",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^12.1.4",
|
||||
"@types/classnames": "2.2.9",
|
||||
"@types/glob": "^8.0.0",
|
||||
"@types/grafana": "github:CorpGlory/types-grafana",
|
||||
"@types/jest": "^29.2.2",
|
||||
"@types/jquery": "3.3.32",
|
||||
"@types/lodash": "^4.14.188",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "17.0.42",
|
||||
"@types/react-dom": "17.0.14",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-transition-group": "4.2.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
||||
"@typescript-eslint/parser": "^5.42.1",
|
||||
"@types/jest": "^29.5.0",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/node": "^18.15.11",
|
||||
"@typescript-eslint/eslint-plugin": "5.59.5",
|
||||
"@typescript-eslint/parser": "5.59.5",
|
||||
"autoprefixer": "10.4.7",
|
||||
"axios": "^0.21.1",
|
||||
"benchmark": "^2.1.4",
|
||||
"classnames": "2.2.6",
|
||||
"clean-webpack-plugin": "^0.1.19",
|
||||
"codecov": "^3.1.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"cspell": "6.13.3",
|
||||
"css-loader": "^6.7.1",
|
||||
"eslint": "8.26.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-jsdoc": "^39.6.2",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.26.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-webpack-plugin": "^3.1.1",
|
||||
"fork-ts-checker-webpack-plugin": "^7.2.0",
|
||||
"glob": "^8.0.3",
|
||||
"css-loader": "^6.7.3",
|
||||
"eslint": "8.42.0",
|
||||
"eslint-plugin-jsdoc": "^46.8.2",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-webpack-plugin": "^4.0.1",
|
||||
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
||||
"glob": "^10.2.7",
|
||||
"html-loader": "0.5.5",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "^29.3.1",
|
||||
"jest-environment-jsdom": "^29.3.1",
|
||||
"jest-environment-jsdom-fifteen": "^1.0.2",
|
||||
"jscs": "^3.0.7",
|
||||
"jsdom": "~11.3.0",
|
||||
"jshint": "^2.9.6",
|
||||
"jshint-stylish": "^2.1.0",
|
||||
"jest": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"lodash": "4.17.21",
|
||||
"memoize-one": "5.1.1",
|
||||
"mini-css-extract-plugin": "2.6.1",
|
||||
"moment": "2.24.0",
|
||||
"node-sass": "^7.0.1",
|
||||
"moment": "2.29.4",
|
||||
"postcss": "8.4.14",
|
||||
"postcss-loader": "7.0.1",
|
||||
"postcss-reporter": "7.0.5",
|
||||
"postcss-scss": "4.0.4",
|
||||
"prettier": "^2.5.0",
|
||||
"prettier": "^2.8.7",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-popper": "^2.2.3",
|
||||
"react-table-6": "6.11.0",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"react-transition-group": "4.3.0",
|
||||
"react-use": "17.4.0",
|
||||
"replace-in-file-webpack-plugin": "^1.0.6",
|
||||
"rxjs": "6.6.3",
|
||||
"sass": "1.56.1",
|
||||
"sass-loader": "13.2.0",
|
||||
"semver": "^7.3.2",
|
||||
"style-loader": "3.3.1",
|
||||
"sass": "1.63.2",
|
||||
"sass-loader": "13.3.1",
|
||||
"semver": "7.5.4",
|
||||
"style-loader": "3.3.3",
|
||||
"swc-loader": "^0.2.3",
|
||||
"tether-drop": "^1.4.2",
|
||||
"ts-jest": "26.4.1",
|
||||
"ts-loader": "4.4.1",
|
||||
"ts-node": "^10.5.0",
|
||||
"tsconfig-paths": "^4.1.0",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "4.8.2",
|
||||
"webpack": "^5.69.1",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "4.8.4",
|
||||
"webpack": "^5.86.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-livereload-plugin": "^3.0.2",
|
||||
"webpack-remove-empty-scripts": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"resolutions": {
|
||||
"js-yaml": "^3.13.1",
|
||||
"lodash": "~4.17.13",
|
||||
"set-value": "^2.0.1",
|
||||
"mixin-deep": "^1.3.2",
|
||||
"minimatch": "^3.0.2",
|
||||
"fstream": "^1.0.12"
|
||||
}
|
||||
"packageManager": "yarn@1.22.19"
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
const githubURL = (owner, repo) => `https://api.github.com/repos/${owner}/${repo}`;
|
||||
|
||||
class GithubClient {
|
||||
constructor(owner, repo, required = false) {
|
||||
const username = process.env.GITHUB_USERNAME;
|
||||
const token = process.env.GITHUB_ACCESS_TOKEN;
|
||||
|
||||
const clientConfig = {
|
||||
baseURL: githubURL(owner, repo),
|
||||
timeout: 30000,
|
||||
};
|
||||
|
||||
if (required && (!username || !token)) {
|
||||
throw new Error('operation needs a GITHUB_USERNAME and GITHUB_ACCESS_TOKEN environment variables');
|
||||
}
|
||||
|
||||
if (username && token) {
|
||||
clientConfig.auth = { username: username, password: token };
|
||||
}
|
||||
|
||||
this.client = this.createClient(clientConfig);
|
||||
}
|
||||
|
||||
createClient(clientConfig) {
|
||||
return axios.create(clientConfig);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GithubClient;
|
||||
@@ -1,153 +0,0 @@
|
||||
const GithubClient = require('./githubClient');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const GRAFANA_ZABBIX_OWNER = 'grafana';
|
||||
const GRAFANA_ZABBIX_REPO = 'grafana-zabbix';
|
||||
|
||||
const github = new GithubClient(GRAFANA_ZABBIX_OWNER, GRAFANA_ZABBIX_REPO, true);
|
||||
|
||||
async function main() {
|
||||
let releaseVersion = '';
|
||||
if (process.env.CIRCLE_TAG) {
|
||||
const tag = process.env.CIRCLE_TAG;
|
||||
const tagRegex = /v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)/;
|
||||
if (!tagRegex.test(tag)) {
|
||||
console.error(`Release tag should has format v1.2.3[-meta], got ${tag}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
releaseVersion = tag.slice(1);
|
||||
} else {
|
||||
releaseVersion = getPluginVersion();
|
||||
}
|
||||
|
||||
console.log('Release version', releaseVersion);
|
||||
if (!releaseVersion) {
|
||||
console.error('Release not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const releaseNotes = `# Grafana-Zabbix ${releaseVersion}`;
|
||||
const preRelease = /(alpha|beta)/.test(releaseVersion);
|
||||
|
||||
let releaseId;
|
||||
try {
|
||||
const latestRelease = await github.client.get(`releases/tags/v${releaseVersion}`);
|
||||
releaseId = latestRelease.data.id;
|
||||
console.log('Release found', releaseId);
|
||||
} catch (reason) {
|
||||
if (reason.response.status !== 404) {
|
||||
// 404 just means no release found. Not an error. Anything else though, re throw the error
|
||||
console.error(reason.response.data);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!releaseId) {
|
||||
console.log('No release exist, finding a tag');
|
||||
let releaseCommitHash;
|
||||
try {
|
||||
const tags = await github.client.get(`tags`);
|
||||
const releaseTag = tags.data.find((t) => t.name === `v${releaseVersion}`);
|
||||
releaseCommitHash = releaseTag.commit.sha;
|
||||
console.log('Tag found', releaseTag.name, releaseCommitHash);
|
||||
} catch (reason) {
|
||||
if (reason.response.status !== 404) {
|
||||
// 404 just means no release found. Not an error. Anything else though, re throw the error
|
||||
console.error(reason.response.data);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.error('No release tag found');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const newReleaseResponse = await github.client.post('releases', {
|
||||
tag_name: `v${releaseVersion}`,
|
||||
target_commitish: releaseCommitHash,
|
||||
name: `${releaseVersion}`,
|
||||
body: releaseNotes,
|
||||
draft: false,
|
||||
prerelease: preRelease,
|
||||
});
|
||||
|
||||
releaseId = newReleaseResponse.data.id;
|
||||
console.log('Release published with id', releaseId);
|
||||
} catch (reason) {
|
||||
console.error(reason.response.data);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
github.client.patch(`releases/${releaseId}`, {
|
||||
tag_name: `v${releaseVersion}`,
|
||||
name: `${releaseVersion}`,
|
||||
body: releaseNotes,
|
||||
draft: false,
|
||||
prerelease: preRelease,
|
||||
});
|
||||
} catch (reason) {
|
||||
console.error(reason.response.data);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await publishAssets(
|
||||
`alexanderzobnin-zabbix-app-${releaseVersion}.zip`,
|
||||
`https://uploads.github.com/repos/${GRAFANA_ZABBIX_OWNER}/${GRAFANA_ZABBIX_REPO}/releases/${releaseId}/assets`
|
||||
);
|
||||
// Upload package info with md5 checksum
|
||||
await publishAssets(
|
||||
`info.json`,
|
||||
`https://uploads.github.com/repos/${GRAFANA_ZABBIX_OWNER}/${GRAFANA_ZABBIX_REPO}/releases/${releaseId}/assets`
|
||||
);
|
||||
} catch (reason) {
|
||||
console.error(reason);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function publishAssets(fileName, destUrl) {
|
||||
// Add the assets. Loop through files in the ci/dist folder and upload each asset.
|
||||
|
||||
const fileStat = fs.statSync(`${__dirname}/../../ci/packages/${fileName}`);
|
||||
const fileData = fs.readFileSync(`${__dirname}/../../ci/packages/${fileName}`);
|
||||
return await github.client.post(`${destUrl}?name=${fileName}`, fileData, {
|
||||
headers: {
|
||||
'Content-Type': resolveContentType(path.extname(fileName)),
|
||||
'Content-Length': fileStat.size,
|
||||
},
|
||||
maxContentLength: fileStat.size * 2 * 1024 * 1024,
|
||||
maxBodyLength: fileStat.size * 2 * 1024 * 1024,
|
||||
});
|
||||
}
|
||||
|
||||
const resolveContentType = (extension) => {
|
||||
if (extension.startsWith('.')) {
|
||||
extension = extension.substr(1);
|
||||
}
|
||||
switch (extension) {
|
||||
case 'zip':
|
||||
return 'application/zip';
|
||||
case 'json':
|
||||
return 'application/json';
|
||||
case 'sha1':
|
||||
return 'text/plain';
|
||||
default:
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
};
|
||||
|
||||
const getPluginVersion = () => {
|
||||
const pkg = fs.readFileSync(`${__dirname}/../../package.json`, 'utf8');
|
||||
const { version } = JSON.parse(pkg);
|
||||
if (!version) {
|
||||
throw `Could not find the toolkit version`;
|
||||
}
|
||||
return version;
|
||||
};
|
||||
|
||||
main();
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit script if a statement returns a non-true return value.
|
||||
set -o errexit
|
||||
# Use the error status of the first failure, rather than that of the last item in a pipeline.
|
||||
set -o pipefail
|
||||
|
||||
node ./scripts/github/publishRelease.js
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit script if a statement returns a non-true return value.
|
||||
set -o errexit
|
||||
# Use the error status of the first failure, rather than that of the last item in a pipeline.
|
||||
set -o pipefail
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
if [ -z "$GRAFANA_API_KEY" ]
|
||||
then
|
||||
echo -e "${RED}Error: \$GRAFANA_API_KEY variable should be set to sign plugin${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install Dependencies
|
||||
echo -e "${GREEN}Installing dependencies${NC}"
|
||||
make install
|
||||
|
||||
# Build plugin for all platforms
|
||||
echo -e "${GREEN}Building plugin for all platforms${NC}"
|
||||
make dist
|
||||
|
||||
# Prepare plugin for packaging
|
||||
echo -e "${GREEN}Preparing plugin for packaging${NC}"
|
||||
rm -rf ci/jobs/build_plugin/dist
|
||||
mkdir -p ci/jobs/build_plugin
|
||||
mv dist/ ci/jobs/build_plugin
|
||||
cp CHANGELOG.md ci/jobs/build_plugin/dist
|
||||
|
||||
# Package and sign plugin
|
||||
echo -e "${GREEN}Packaging and signing plugin${NC}"
|
||||
yarn grafana-toolkit plugin:ci-package
|
||||
|
||||
echo -e "${GREEN}Packaged plugin located in ${BLUE}ci/packages${NC}"
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { FC } from 'react';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { cx, css } from '@emotion/css';
|
||||
import { stylesFactory, useTheme, Tooltip } from '@grafana/ui';
|
||||
import { GrafanaTheme, GrafanaThemeType } from '@grafana/data';
|
||||
@@ -12,14 +12,16 @@ interface Props {
|
||||
onClick(event: React.MouseEvent<HTMLButtonElement>): void;
|
||||
}
|
||||
|
||||
export const ActionButton: FC<Props> = ({ icon, width, tooltip, className, children, onClick }) => {
|
||||
export const ActionButton = ({ icon, width, tooltip, className, children, onClick }: PropsWithChildren<Props>) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme);
|
||||
const buttonClass = cx(
|
||||
'btn',
|
||||
styles.button,
|
||||
css`width: ${width || 3}rem`,
|
||||
className,
|
||||
css`
|
||||
width: ${width || 3}rem;
|
||||
`,
|
||||
className
|
||||
);
|
||||
|
||||
let button = (
|
||||
|
||||
@@ -25,8 +25,10 @@ jest.mock('../components/AnnotationQueryEditor', () => ({
|
||||
|
||||
describe('ZabbixDatasource', () => {
|
||||
let ctx: any = {};
|
||||
let consoleSpy: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
ctx.instanceSettings = {
|
||||
jsonData: {
|
||||
alerting: false,
|
||||
@@ -60,6 +62,10 @@ describe('ZabbixDatasource', () => {
|
||||
ctx.ds.templateSrv = templateSrvMock;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
describe('When querying text data', () => {
|
||||
beforeEach(() => {
|
||||
ctx.ds.replaceTemplateVars = (str) => str;
|
||||
|
||||
@@ -56,7 +56,6 @@ export class CachingProxy {
|
||||
* with same params when waiting for result.
|
||||
*/
|
||||
function callOnce(func, promiseKeeper, funcScope) {
|
||||
// tslint:disable-next-line: only-arrow-functions
|
||||
return function () {
|
||||
const hash = getRequestHash(arguments);
|
||||
if (!promiseKeeper[hash]) {
|
||||
@@ -78,7 +77,6 @@ function callOnce(func, promiseKeeper, funcScope) {
|
||||
}
|
||||
|
||||
function cacheRequest(func, funcName, funcScope, self) {
|
||||
// tslint:disable-next-line: only-arrow-functions
|
||||
return function () {
|
||||
if (!self.cache[funcName]) {
|
||||
self.cache[funcName] = {};
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
import { Zabbix } from './zabbix';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
getBackendSrv: () => ({
|
||||
datasourceRequest: jest.fn().mockResolvedValue({data: {result: ''}}),
|
||||
}),
|
||||
getBackendSrv: () => ({
|
||||
datasourceRequest: jest.fn().mockResolvedValue({ data: { result: '' } }),
|
||||
fetch: () => ({
|
||||
toPromise: () => jest.fn().mockResolvedValue({ data: { result: '' } })
|
||||
}),
|
||||
}),
|
||||
}), {virtual: true});
|
||||
|
||||
describe('Zabbix', () => {
|
||||
let ctx = {};
|
||||
let zabbix;
|
||||
let options = {
|
||||
url: 'http://localhost',
|
||||
username: 'zabbix',
|
||||
password: 'zabbix',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.options = options;
|
||||
// ctx.backendSrv = mocks.backendSrvMock;
|
||||
// ctx.datasourceSrv = mocks.datasourceSrvMock;
|
||||
zabbix = new Zabbix(ctx.options);
|
||||
});
|
||||
|
||||
describe('When querying proxies', () => {
|
||||
beforeEach(() => {
|
||||
zabbix.zabbixAPI.getProxies = jest.fn().mockResolvedValue([
|
||||
{ host: 'proxy-foo', proxyid: '10101' },
|
||||
{ host: 'proxy-bar', proxyid: '10102' },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should return all proxies if filter set to /.*/", done => {
|
||||
zabbix.getFilteredProxies('/.*/').then(proxies => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-foo' }, { host: 'proxy-bar' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should return matched proxies if regex filter used", done => {
|
||||
zabbix.getFilteredProxies('/.*-foo/').then(proxies => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-foo' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should return matched proxies if simple filter used", done => {
|
||||
zabbix.getFilteredProxies('proxy-bar').then(proxies => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-bar' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should return empty list for empty filter", done => {
|
||||
zabbix.getFilteredProxies('').then(proxies => {
|
||||
expect(proxies).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When filtering triggers by proxy', () => {
|
||||
beforeEach(() => {
|
||||
zabbix.zabbixAPI.getProxies = jest.fn().mockResolvedValue([
|
||||
{ host: 'proxy-foo', proxyid: '10101' },
|
||||
{ host: 'proxy-bar', proxyid: '10102' },
|
||||
]);
|
||||
ctx.triggers = [
|
||||
{ triggerid: '1', hosts: [{ name: 'backend01', proxy_hostid: '0' }] },
|
||||
{ triggerid: '2', hosts: [{ name: 'backend02', proxy_hostid: '0' }] },
|
||||
{ triggerid: '3', hosts: [{ name: 'frontend01', proxy_hostid: '10101' }] },
|
||||
{ triggerid: '4', hosts: [{ name: 'frontend02', proxy_hostid: '10101' }] },
|
||||
{ triggerid: '5', hosts: [{ name: 'db01', proxy_hostid: '10102' }] },
|
||||
{ triggerid: '6', hosts: [{ name: 'db02', proxy_hostid: '10102' }] },
|
||||
];
|
||||
});
|
||||
|
||||
it("should return all triggers for empty filter", done => {
|
||||
zabbix.filterTriggersByProxy(ctx.triggers, '').then(triggers => {
|
||||
const triggerids = triggers.map(t => t.triggerid);
|
||||
expect(triggerids).toEqual(['1', '2', '3', '4', '5', '6']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should return triggers belonging proxy matched regex filter", done => {
|
||||
zabbix.filterTriggersByProxy(ctx.triggers, '/.*-foo/').then(triggers => {
|
||||
const triggerids = triggers.map(t => t.triggerid);
|
||||
expect(triggerids).toEqual(['3', '4']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should return triggers belonging proxy matched name filter", done => {
|
||||
zabbix.filterTriggersByProxy(ctx.triggers, 'proxy-bar').then(triggers => {
|
||||
const triggerids = triggers.map(t => t.triggerid);
|
||||
expect(triggerids).toEqual(['5', '6']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
113
src/datasource/zabbix/zabbix.test.ts
Normal file
113
src/datasource/zabbix/zabbix.test.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { Zabbix } from './zabbix';
|
||||
|
||||
jest.mock(
|
||||
'@grafana/runtime',
|
||||
() => ({
|
||||
getBackendSrv: () => ({
|
||||
datasourceRequest: jest.fn().mockResolvedValue({ data: { result: '' } }),
|
||||
fetch: () => ({
|
||||
toPromise: () => jest.fn().mockResolvedValue({ data: { result: '' } }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
{ virtual: true }
|
||||
);
|
||||
|
||||
describe('Zabbix', () => {
|
||||
let consoleSpy: jest.SpyInstance;
|
||||
let ctx = {
|
||||
options: {
|
||||
url: 'http://localhost',
|
||||
username: 'zabbix',
|
||||
password: 'zabbix',
|
||||
},
|
||||
};
|
||||
let zabbix;
|
||||
|
||||
beforeEach(() => {
|
||||
zabbix = new Zabbix(ctx.options);
|
||||
consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
describe('When querying proxies', () => {
|
||||
beforeEach(() => {
|
||||
zabbix.zabbixAPI.getProxies = jest.fn().mockResolvedValue([
|
||||
{ host: 'proxy-foo', proxyid: '10101' },
|
||||
{ host: 'proxy-bar', proxyid: '10102' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return all proxies if filter set to /.*/', (done) => {
|
||||
zabbix.getFilteredProxies('/.*/').then((proxies) => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-foo' }, { host: 'proxy-bar' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return matched proxies if regex filter used', (done) => {
|
||||
zabbix.getFilteredProxies('/.*-foo/').then((proxies) => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-foo' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return matched proxies if simple filter used', (done) => {
|
||||
zabbix.getFilteredProxies('proxy-bar').then((proxies) => {
|
||||
expect(proxies).toMatchObject([{ host: 'proxy-bar' }]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return empty list for empty filter', (done) => {
|
||||
zabbix.getFilteredProxies('').then((proxies) => {
|
||||
expect(proxies).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When filtering triggers by proxy', () => {
|
||||
const triggers = [
|
||||
{ triggerid: '1', hosts: [{ name: 'backend01', proxy_hostid: '0' }] },
|
||||
{ triggerid: '2', hosts: [{ name: 'backend02', proxy_hostid: '0' }] },
|
||||
{ triggerid: '3', hosts: [{ name: 'frontend01', proxy_hostid: '10101' }] },
|
||||
{ triggerid: '4', hosts: [{ name: 'frontend02', proxy_hostid: '10101' }] },
|
||||
{ triggerid: '5', hosts: [{ name: 'db01', proxy_hostid: '10102' }] },
|
||||
{ triggerid: '6', hosts: [{ name: 'db02', proxy_hostid: '10102' }] },
|
||||
];
|
||||
beforeEach(() => {
|
||||
zabbix.zabbixAPI.getProxies = jest.fn().mockResolvedValue([
|
||||
{ host: 'proxy-foo', proxyid: '10101' },
|
||||
{ host: 'proxy-bar', proxyid: '10102' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return all triggers for empty filter', (done) => {
|
||||
zabbix.filterTriggersByProxy(triggers, '').then((triggers) => {
|
||||
const triggerids = triggers.map((t) => t.triggerid);
|
||||
expect(triggerids).toEqual(['1', '2', '3', '4', '5', '6']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return triggers belonging proxy matched regex filter', (done) => {
|
||||
zabbix.filterTriggersByProxy(triggers, '/.*-foo/').then((triggers) => {
|
||||
const triggerids = triggers.map((t) => t.triggerid);
|
||||
expect(triggerids).toEqual(['3', '4']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return triggers belonging proxy matched name filter', (done) => {
|
||||
zabbix.filterTriggersByProxy(triggers, 'proxy-bar').then((triggers) => {
|
||||
const triggerids = triggers.map((t) => t.triggerid);
|
||||
expect(triggerids).toEqual(['5', '6']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,8 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { cx } from '@emotion/css';
|
||||
import ReactTable from 'react-table-6';
|
||||
import _ from 'lodash';
|
||||
// eslint-disable-next-line
|
||||
import moment from 'moment';
|
||||
import moment from 'moment-timezone';
|
||||
import { isNewProblem } from '../../utils';
|
||||
import { EventTag } from '../EventTag';
|
||||
import { ProblemDetails } from './ProblemDetails';
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
// JSHint options
|
||||
/* globals global: false */
|
||||
|
||||
import { JSDOM } from 'jsdom';
|
||||
import { PanelCtrl, MetricsPanelCtrl } from './panelStub';
|
||||
|
||||
// Suppress messages
|
||||
console.log = () => {};
|
||||
|
||||
jest.mock('grafana/app/features/templating/template_srv', () => {
|
||||
return {};
|
||||
}, {virtual: true});
|
||||
@@ -82,8 +75,6 @@ jest.mock('grafana/app/core/config', () => {
|
||||
};
|
||||
}, {virtual: true});
|
||||
|
||||
jest.mock('jquery', () => 'module not found', {virtual: true});
|
||||
|
||||
jest.mock('grafana/app/core/utils/kbn', () => {
|
||||
return {
|
||||
round_interval: n => n,
|
||||
@@ -91,12 +82,6 @@ jest.mock('grafana/app/core/utils/kbn', () => {
|
||||
};
|
||||
}, {virtual: true});
|
||||
|
||||
// Setup jsdom
|
||||
let dom = new JSDOM('<html><head><script></script></head><body></body></html>');
|
||||
global.window = dom.window;
|
||||
global.document = global.window.document;
|
||||
global.Node = window.Node;
|
||||
|
||||
// Mock Canvas.getContext(), fixes
|
||||
// Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
|
||||
window.HTMLCanvasElement.prototype.getContext = () => {};
|
||||
// window.HTMLCanvasElement.prototype.getContext = () => {};
|
||||
|
||||
Reference in New Issue
Block a user