设置您的开发环境
本指南将指导您设置 Grafana 插件开发的开发环境。包括
- 使用 Docker 运行带有您插件的开发版 Grafana 服务器
- 设置 GitHub 工作流程来自动化您的开发和发布流程
- 扩展 ESLint、Prettier、Jest、TypeScript 和 Webpack 的配置
Docker 开发环境
create-plugin
工具 包含一个具有 Docker 的开发环境。它允许您启动一个针对插件开发者运行的 Grafana 应用程序实例,您可以在其中进行编码。
为什么使用 Docker 环境
我们选择使用 Docker,因为它简化了创建、部署和运行应用程序的过程。它允许您为插件创建一致且隔离的环境。这使得管理依赖关系并确保插件在不同机器上以相同的方式运行变得容易。
使用 create-plugin
工具,Docker 容器配置了必要的变量,以便轻松访问 Grafana,并在无需签名的情况下加载插件。插件工具还添加了实时重新加载功能,允许您在前端代码更改时触发浏览器刷新,更改后端代码将使插件二进制文件自动重新加载。
Docker 环境还允许您将调试器附加到插件后端代码,使开发过程更容易。
开始使用 Docker
要开始您的插件开发项目,按照以下顺序运行以下命令
npm install
:安装前端依赖。npm run dev
:构建并监视插件前端代码。mage -v build:linux
:构建插件后端代码。每次编辑后端文件时,都需要重新运行此命令。npm run server
:启动一个运行在https://127.0.0.1:3000上的 Grafana 开发服务器。
配置 Grafana 版本
为了在不同的 Grafana 版本之间测试插件,设置一个环境变量。使用 GRAFANA_VERSION
来设置 Grafana 版本
- npm
- pnpm
- yarn
GRAFANA_VERSION=10.0.0 npm run server
GRAFANA_VERSION=10.0.0 pnpm run server
GRAFANA_VERSION=10.0.0 yarn run server
配置 Grafana 镜像
插件工具中的默认 Docker 镜像是 grafana-enterprise
。如果您想覆盖此镜像,通过更改 docker-compose.yaml
中的 grafana_image
构建参数来修改它
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}
此示例将环境变量 GRAFANA_IMAGE
分配给构建参数 grafana_image
,默认值为 grafana
。这使您在运行 docker compose
命令时可以设置值。
调试后端插件
如果您正在开发具有后端部分的插件,请以 DEVELOPMENT=true
运行 npm run server
。Docker Compose 文件暴露了端口 2345
以供调试,从运行在 Docker 环境内的无头 delve 实例。您可以将调试器客户端连接到此端口以调试后端代码。例如,在 VSCode 中,您可以添加如下所示的 launch.json
配置
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to plugin backend in docker",
"type": "go",
"request": "attach",
"mode": "remote",
"port": 2345,
"host": "127.0.0.1",
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"substitutePath": [
{
"from": "${workspaceFolder}",
"to": "/root/<your-plugin-id>"
}
]
}
]
}
您可以通过设置环境变量 GO_VERSION
和 GO_ARCH
来控制 Docker Compose 中构建您的插件使用的 go 版本和架构
version: '3.7'
services:
grafana:
container_name: 'myorg-basic-app'
build:
context: ./.config
args:
GO_VERSION: ${GO_VERSION:-1.22}
GO_ARCH: ${GO_ARCH:-amd64}
您还会注意到,docker-compose.yaml
文件还具有以下设置
security_opt:
- 'apparmor:unconfined'
- 'seccomp:unconfined'
cap_add:
- SYS_PTRACE
它们是必要的,以便 delve 能够附加到正在运行的进程并对其进行调试,并且不应在生产环境中使用。
设置 GitHub 工作流程
自动化您的开发过程以最大限度地减少错误,并使其更快、更经济高效。create-plugin
工具帮助您配置 GitHub Actions 工作流程,以帮助自动化您的开发过程。
CI 工作流程
CI(ci.yml
)工作流程旨在进行代码检查、类型检查和构建前端和后端。它还用于在您将更改推送到存储库时对您的插件进行测试。create-plugin
工具帮助在开发过程中早期捕捉任何问题,在它们成为更大的问题之前。有关 CI 工作流程中端到端测试的更多信息,请参阅我们的文档。
发布工作流程
发布(release.yml
)工作流程旨在在您准备好发布新版本时构建、测试、打包并签名您的插件。这自动化了在 GitHub 中创建发布的流程,并提供提交插件到 Grafana 插件目录的说明。
此工作流需要 Grafana Cloud API 密钥。在开始之前,请按照 生成访问策略令牌 的说明操作。
将访问策略令牌存储为 GitHub 中的仓库机密
- 访问仓库设置
- 前往您的 GitHub 仓库。
- 导航到“设置”标签。
- 在左侧边栏中,点击“机密和变量”->“操作”
- 点击“新建仓库机密”按钮。
- 添加机密信息
- 为您的机密输入名称 - GRAFANA_ACCESS_POLICY_TOKEN。
- 将访问策略令牌值粘贴到“机密”字段。
- 点击“添加机密”按钮以保存机密。
一旦机密存储,您就可以在 GitHub Actions 工作流中访问它
name: Release
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: grafana/plugin-actions/build-plugin@release
with:
grafana_token: ${{ secrets.GRAFANA_ACCESS_POLICY_TOKEN }}
在此示例中,使用 secrets.GRAFANA_ACCESS_POLICY_TOKEN
变量在 GitHub Actions 工作流中安全地访问存储的令牌。请确保根据您的具体需求和工作语言/环境调整工作流。
触发工作流
要触发发布工作流,请推送插件版本所需的 Git 标签
git tag v1.0.0
git push origin v1.0.0
兼容性检查工作流
兼容性检查(is-compatible.yml
)工作流旨在在您每次向仓库推送更改时检查您的插件与 Grafana API 的兼容性。这有助于在问题发生之前捕捉潜在的前端运行时问题。
工作流包含以下步骤
- 查找插件中的
@grafana
npm 包。 - 提取指定版本的导出类型。
- 比较该版本与最新版本之间的差异。
- 查找插件中那些更改的 API 的使用情况。
- 报告任何潜在的不兼容性。
创建插件更新工作流
创建插件更新(cp-update.yml
)工作流旨在自动保持您的插件开发环境和依赖项的最新状态。它定期检查 npm 注册表上列出的最新版本的 create-plugin 与您插件使用的版本进行比较。如果可用新版本,则工作流将运行 create-plugin update
命令,更新前端依赖项锁定文件,然后创建包含更改的 PR 以供审查。
此工作流需要内容和对您的插件仓库的拉取请求写入访问权限,以便能够推送更改和打开 PR。请从以下两个选项中选择
使用默认访问令牌
要使用此选项,您必须允许 github actions 在您的仓库设置中创建和批准拉取请求,并使用工作流中的 permissions
属性提升默认访问令牌权限,如下所示
name: Create Plugin Update
on:
workflow_dispatch:
schedule:
- cron: '0 0 1 * *' # run once a month on the 1st day
permissions:
contents: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: grafana/plugin-actions/create-plugin-update@main
使用个人访问令牌
要使用此选项,您必须创建一个具有访问插件仓库并具有读取和写入contents
和pull requests
权限的Github 细粒度个人访问令牌。一旦创建,请将其添加到插件仓库操作机密中,然后按如下方式传递给操作
name: Create Plugin Update
on:
workflow_dispatch:
schedule:
- cron: '0 0 1 * *' # run once a month on the 1st day
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: grafana/plugin-actions/create-plugin-update@main
with:
token: ${{ secrets.GH_PAT_TOKEN }}
扩展配置
.config/
目录包含用于开发、测试和构建 Grafana 插件的工具的推荐配置。虽然您可以进行更改,但我们不建议这样做。相反,按照本主题中的指南来定制您的工具配置。
不要编辑 .config/
目录或扩展工具配置。如果您尝试这样做,可能会遇到在 Grafana 中编译或加载失败等问题。直接更改文件之前,请按照本主题中的说明进行高级配置。
扩展 ESLint 配置
编辑项目根目录中的 .eslintrc
文件以扩展 ESLint 配置
示例
{
// Eslint configuration provided by @grafana/create-plugin
"extends": "./.config/.eslintrc",
"rules": {
"react/prop-types": "off"
}
}
以下示例可用于禁用弃用通知。
{
// Eslint configuration provided by @grafana/create-plugin
"extends": "./.config/.eslintrc",
"overrides": [
{
"files": ["src/**/*.{ts,tsx}"],
"rules": {
"deprecation/deprecation": "off"
}
}
]
}
扩展 Prettier 配置
编辑项目根目录中的 .prettierrc.js
文件以扩展 Prettier 配置
示例
module.exports = {
// Prettier configuration provided by @grafana/create-plugin
...require('./.config/.prettierrc.js'),
semi: false,
};
扩展 Jest 配置
项目根目录中有两个属于 Jest 的文件:jest-setup.js
和 jest.config.js
。
jest-setup.js
: 在执行套件中的每个测试文件之前,都会运行此文件。它为测试库设置 Jest DOM 并应用一些 polyfills。有关更多信息,请参阅 Jest 文档。
jest.config.js
: 这是 Jest 配置文件,它扩展了 Grafana 配置。有关更多信息,请参阅 Jest 配置文档。
Jest 的 ESM 错误
如果在运行 Jest 或 npm run test
时看到 SyntaxError: Cannot use import statement outside a module
,请参阅 故障排除。
扩展 TypeScript 配置
要扩展 TS 配置,编辑项目根目录下的 tsconfig.json
文件
示例
{
// TypeScript configuration provided by @grafana/create-plugin
"extends": "./.config/tsconfig.json",
"compilerOptions": {
"preserveConstEnums": true
}
}
扩展 Webpack 配置
按照以下步骤扩展位于 .config/
中的 Webpack 配置
1. 创建一个新的 Webpack 配置文件
在项目根目录创建一个 webpack.config.ts
文件。此文件扩展了 create-plugin
提供的 Webpack 配置。
2. 将 Grafana 配置与您的自定义配置合并
使用以下 webpack-merge 命令
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig from './.config/webpack/webpack.config';
const config = async (env): Promise<Configuration> => {
const baseConfig = await grafanaConfig(env);
return merge(baseConfig, {
// Add custom config here...
output: {
asyncChunks: true,
},
});
};
export default config;
以下替代定制通过规则排除了 "libs",除了 "node_modules"。它还提供了在 Webpack v5 中不再存在的回退。
import type { Configuration } from 'webpack';
import { mergeWithRules } from 'webpack-merge';
import grafanaConfig from './.config/webpack/webpack.config';
const config = async (env: any): Promise<Configuration> => {
const baseConfig = await grafanaConfig(env);
const customConfig = {
module: {
rules: [
{
exclude: /(node_modules|libs)/,
},
],
},
resolve: {
fallback: {
crypto: require.resolve('crypto-browserify'),
fs: false,
path: require.resolve('path-browserify'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
},
},
};
return mergeWithRules({
module: {
rules: {
exclude: 'replace',
},
},
})(baseConfig, customConfig);
};
export default config;
3. 更新 package.json
以使用新的 Webpack 配置
更新 package.json
中的 scripts
以使用扩展的 Webpack 配置
-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production",
+"build": "webpack -c ./webpack.config.ts --env production",
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
+"dev": "webpack -w -c ./webpack.config.ts --env development",