From 147952f9c20724a5c1658f14ad52c253b80c6425 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Fri, 27 Oct 2023 00:12:18 +0800 Subject: [PATCH] docs: improve documentations of plugin development (#271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 Halo 插件开发文档。 /kind documentation ```release-note None ``` --- .../plugin/api-reference/extension.md | 8 +- .../plugin/api-reference/reverseproxy.md | 28 +-- .../plugin/api-reference/role-template.md | 34 ++-- .../plugin/examples/todolist.md | 177 +++++------------- docs/developer-guide/plugin/hello-world.md | 23 ++- docs/developer-guide/plugin/introduction.md | 3 +- docs/developer-guide/plugin/lifecycle.md | 28 +-- docs/developer-guide/plugin/manifest.md | 51 ++--- docs/developer-guide/plugin/prepare.md | 12 +- docs/developer-guide/plugin/publish.md | 137 +++++++++++++- docs/developer-guide/plugin/runtime-mode.md | 17 +- docs/developer-guide/plugin/structure.md | 74 ++++---- .../plugin/api-reference/extension.md | 8 +- .../plugin/api-reference/reverseproxy.md | 28 +-- .../plugin/api-reference/role-template.md | 34 ++-- .../plugin/examples/todolist.md | 177 +++++------------- .../developer-guide/plugin/hello-world.md | 23 ++- .../developer-guide/plugin/introduction.md | 3 +- .../developer-guide/plugin/lifecycle.md | 28 +-- .../developer-guide/plugin/manifest.md | 51 ++--- .../developer-guide/plugin/prepare.md | 12 +- .../developer-guide/plugin/publish.md | 137 +++++++++++++- .../developer-guide/plugin/runtime-mode.md | 17 +- .../developer-guide/plugin/structure.md | 74 ++++---- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- .../developer-guide/plugin/publish.md | 2 +- 32 files changed, 640 insertions(+), 560 deletions(-) diff --git a/docs/developer-guide/plugin/api-reference/extension.md b/docs/developer-guide/plugin/api-reference/extension.md index 8f06d0de..a0fe06b3 100644 --- a/docs/developer-guide/plugin/api-reference/extension.md +++ b/docs/developer-guide/plugin/api-reference/extension.md @@ -74,10 +74,10 @@ gender: male - @GVK:此注解标识该类为一个自定义模型,同时必须继承 `AbstractExtension`。 - kind:表示自定义模型所表示的 REST 资源。 - - group:表示一组公开的资源,通常采用域名形式,Halo 项目保留使用空组和任何以“*.halo.run”结尾的组名供其单独使用。 - 选择群组名称时,我们建议选择你的群组或组织拥有的子域,例如“widget.mycompany.com”。 - - version:API 的版本,它与 group 组合使用为 apiVersion=“GROUP/VERSION”,例如“api.halo.run/v1alpha1”。 - - singular: 资源的单数名称,这允许客户端不透明地处理复数和单数,必须全部小写。通常为小写的“kind”。 + - group:表示一组公开的资源,通常采用域名形式,Halo 项目保留使用空组和任何以 `*.halo.run` 结尾的组名供其单独使用。 + 选择群组名称时,我们建议选择你的群组或组织拥有的子域,例如 `widget.mycompany.com`。 + - version:API 的版本,它与 group 组合使用为 `apiVersion=GROUP/VERSION`,例如`api.halo.run/v1alpha1`。 + - singular: 资源的单数名称,这允许客户端不透明地处理复数和单数,必须全部小写,通常为小写的 `kind`。 - plural: 资源的复数名称,自定义资源在 `/apis///.../` 下提供,必须为全部小写。 - @Schema:属性校验注解,会在创建/修改资源前对资源校验,参考 [schema-validator](https://www.openapi4j.org/schema-validator.html)。 ::: diff --git a/docs/developer-guide/plugin/api-reference/reverseproxy.md b/docs/developer-guide/plugin/api-reference/reverseproxy.md index ea261805..3ba86af1 100644 --- a/docs/developer-guide/plugin/api-reference/reverseproxy.md +++ b/docs/developer-guide/plugin/api-reference/reverseproxy.md @@ -8,21 +8,21 @@ description: 了解如果使用静态资源代理来访问插件中的静态资 例如 `src/main/resources` 下的 `static` 目录下有一张 `halo.jpg`: 1. 首先需要在 `src/main/resources/extensions` 下创建一个 `yaml`,文件名可以任意。 -2. 示例配置如下。 +2. 示例配置如下: -```yaml -apiVersion: plugin.halo.run/v1alpha1 -kind: ReverseProxy -metadata: - # name 为此资源的唯一标识名称,不允许重复,为了避免与其他插件冲突,推荐带上插件名称前缀 - name: my-plugin-fake-reverse-proxy -rules: - - path: /res/** - file: - directory: static - # 如果想代理 static 下所有静态资源则省略 filename 配置 - filename: halo.jpg -``` + ```yaml + apiVersion: plugin.halo.run/v1alpha1 + kind: ReverseProxy + metadata: + # name 为此资源的唯一标识名称,不允许重复,为了避免与其他插件冲突,推荐带上插件名称前缀 + name: my-plugin-fake-reverse-proxy + rules: + - path: /res/** + file: + directory: static + # 如果想代理 static 下所有静态资源则省略 filename 配置 + filename: halo.jpg + ``` 插件启动后会根据 `/plugins/{plugin-name}/assets/**` 规则生成 API。 因此该 `ReverseProxy` 的访问路径为: `/plugins/my-plugin/assets/res/halo.jpg`。 diff --git a/docs/developer-guide/plugin/api-reference/role-template.md b/docs/developer-guide/plugin/api-reference/role-template.md index a92f2c24..c5d09fd2 100644 --- a/docs/developer-guide/plugin/api-reference/role-template.md +++ b/docs/developer-guide/plugin/api-reference/role-template.md @@ -58,15 +58,15 @@ rules: - `resources` 对应 API 中的 resource 部分,`my-plugin` 表示插件名称。 - `verbs` 表示请求动词,可选值为 "create", "delete", "deletecollection", "get", "list", "patch", "update"。对应的 HTTP 请求方式如下表所示: -| HTTP verb | request verb | -| --------- | ------------------------------------------------------------ | -| POST | create | -| GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | -| PUT | update | -| PATCH | patch | -| DELETE | delete (for individual resources), deletecollection (for collections) | + | HTTP verb | request verb | + | --------- | ------------------------------------------------------------ | + | POST | create | + | GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | + | PUT | update | + | PATCH | patch | + | DELETE | delete (for individual resources), deletecollection (for collections) | -`metadata.labels` 中必须包含 `halo.run/role-template: "true"` 以表示它此资源要作为角色模板。 + `metadata.labels` 中必须包含 `halo.run/role-template: "true"` 以表示它此资源要作为角色模板。 `metadata.annotations` 中: @@ -75,16 +75,16 @@ rules: - `rbac.authorization.halo.run/display-name`:模板角色的显示名称,用于展示为用户可读的名称信息。 - `rbac.authorization.halo.run/ui-permissions`:用于控制 UI 权限,规则为 `plugin:{your-plugin-name}:scope-name`,使用示例为在插件前端部分入口文件 `index.ts` 中用于控制菜单是否显示或者控制页面按钮是否展示: -```javascript -{ - path: "", - name: "HelloWorld", - component: DefaultView, - meta: { - permissions: ["plugin:my-plugin:person:view"] + ```javascript + { + path: "", + name: "HelloWorld", + component: DefaultView, + meta: { + permissions: ["plugin:my-plugin:person:view"] + } } -} -``` + ``` 以上定义角色模板的方式适合资源型请求,即需要符合以下规则 diff --git a/docs/developer-guide/plugin/examples/todolist.md b/docs/developer-guide/plugin/examples/todolist.md index 039e554d..5e98688d 100644 --- a/docs/developer-guide/plugin/examples/todolist.md +++ b/docs/developer-guide/plugin/examples/todolist.md @@ -55,51 +55,52 @@ description: 这个例子展示了如何开发 Todo List 插件 1. 在 `src/main/java` 下创建包,如 `run.halo.tutorial`,在创建一个类 `TodoListPlugin`,它继承自 `BasePlugin` 类内容如下: -```java -package run.halo.tutorial; - -import org.pf4j.PluginWrapper; -import org.springframework.stereotype.Component; -import run.halo.app.plugin.BasePlugin; - -@Component -public class TodoListPlugin extends BasePlugin { - public TodoListPlugin(PluginWrapper wrapper) { - super(wrapper); - } -} -``` - -`src/main/java` 下的文件结构如下: - -```text -. -└── run - └── halo - └── tutorial - └── TodoListPlugin.java -``` - -然后在项目目录执行命令 + ```java + package run.halo.tutorial; + + import org.pf4j.PluginWrapper; + import org.springframework.stereotype.Component; + import run.halo.app.plugin.BasePlugin; + + @Component + public class TodoListPlugin extends BasePlugin { + public TodoListPlugin(PluginWrapper wrapper) { + super(wrapper); + } + } + ``` + + `src/main/java` 下的文件结构如下: + + ```text + . + └── run + └── halo + └── tutorial + └── TodoListPlugin.java + ``` + +2. 然后在项目目录执行命令 + + ```shell + ./gradlew build + ``` -```shell -./gradlew build -``` +3. 使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径: -使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径: + ```yaml + halo: + plugin: + runtime-mode: development + fixed-plugin-path: + # 配置为插件绝对路径 + - /Users/guqing/halo-plugin-todolist + ``` -```yaml -halo: - plugin: - runtime-mode: development - fixed-plugin-path: - # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-todolist -``` +4. 启动 Halo,然后访问 `http://localhost:8090/console` -启动 Halo,然后访问 `http://localhost:8090/console` +在插件列表将能看到插件已经被正确启用: -在插件列表将能看到插件已经被正确启用 ![plugin-todolist-in-list-view](/img/todolist-in-list.png) ## 创建一个自定义模型 @@ -283,13 +284,13 @@ export default definePlugin({ 2. ` pnpm install todomvc-app-css `。 3. 修改 `console/src/views/DefaultView.vue` 最底部的 `style` 标签。 -```diff -- -``` + ```diff + - + ``` 4. 重新 Build 后刷新页面,便能看到目标图所示效果。 @@ -307,7 +308,7 @@ pnpm install axios 为了符合最佳实践,将用 TypeScript 改造之前的 todomvc 示例: -1. 创建 types 文件 `console/src/types/index.ts` +创建 types 文件 `console/src/types/index.ts` ```typescript export interface Metadata { @@ -575,87 +576,9 @@ const handleDelete = (todo: Todo) => { 至此我们就完成了与插件后端 APIs 实现 Todo List 数据交互的部分。 -### 使用 Icon - -目前 Todo 的菜单还是默认的网格样式 Icon,在 `console/src/index.ts` 文件中配置有一个 `icon: markRaw(IconGrid)`。以此为例说明该如何使用其他 `Icon`。 - -1. 安装 [unplugin-icons](https://github.com/antfu/unplugin-icons)。 - -```shell -pnpm install -D unplugin-icons -pnpm install -D @iconify/json -pnpm install -D @vue/compiler-sfc -``` - -2. 编辑 `console/vite.config.ts`,在 `defineConfig` 的 `plugins` 中添加配置,修改如下。 - -```diff -+ import Icons from "unplugin-icons/vite"; - -// https://vitejs.dev/config/ -export default defineConfig({ -- plugins: [vue(), vueJsx()], -+ plugins: [vue(), vueJsx(), Icons({ compiler: "vue3" })], -``` - -3. 在 `console/tsconfig.app.json` 中加入 `unplugni-icons` 的 `types` 配置。 - -```diff -{ - // ... - "compilerOptions": { - // ... - "paths": { - "@/*": ["./src/*"] -- } -+ }, -+ "types": ["unplugin-icons/types/vue"] - } -} -``` - -4. 到 [icones](https://icones.js.org/) 搜索你想要使用的图标,并点击它,然后选择 `Unplugin Icons`,会复制到剪贴板。 - -![unplugin icons selector](/img/unplugin-icons-example.png) - -5. 编辑 `console/src/index.ts` 在 `import` 区域粘贴,并 `icon` 属性。 - -```diff -- import { IconGrid } from "@halo-dev/components"; -+ import VscodeIconsFileTypeLightTodo from "~icons/vscode-icons/file-type-light-todo"; - -export default definePlugin({ - routes: [ - { - // ... - route: { - path: "/todos", - children: [ - { - // ... - meta: { - // ... - menu: { - // ... -- icon: markRaw(IconGrid), -+ icon: markRaw(VscodeIconsFileTypeLightTodo), - priority: 0, - }, - }, - }, - ], - }, - }, - ], - // ... -}); -``` - ### 用户界面使用静态资源 -如果你想在用户界面中使用图片,你可以放到 `console/src/assets` 中,例如 `logo.png`,并将其作为 Todo 的 Logo 放到标题旁边 - -![todo logo example](/img/todo-logo-check-48.png) +如果你想在用户界面中使用图片,你可以放到 `console/src/assets` 中,例如 `logo.png`,并将其作为 Todo 的 Logo 放到标题旁边。 需要修改 `console/src/views/DefaultView.vue` 示例如下: diff --git a/docs/developer-guide/plugin/hello-world.md b/docs/developer-guide/plugin/hello-world.md index e09fad11..496a9095 100644 --- a/docs/developer-guide/plugin/hello-world.md +++ b/docs/developer-guide/plugin/hello-world.md @@ -3,14 +3,20 @@ title: 入门 description: 了解如何构建你的第一个插件并在 Halo 中使用它。 --- -Halo 提供了一个模板仓库用于创建插件: +此文档将帮助你了解如何构建你的第一个插件并在 Halo 中安装和启用。 + +## 创建插件项目 + +1. 打开 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter)。 + + > 这是一个插件的初始模板,你可以基于它来开发自己的插件。 -1. 打开 [plugin-starter](https://github.com/halo-dev/plugin-starter)。 2. 点击 `Use this template` -> `Create a new repository`。 3. 如图所示填写仓库名后点击 `Create repository from template`。 -![create-repository-for-hello-world-plugin](/img/create-repository-for-hello-world-plugin.png) -你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它 `git clone` 到你的计算机上并使用 `IntelliJ IDEA` 打开它。 + ![create-repository-for-hello-world-plugin](/img/create-repository-for-hello-world-plugin.png) + +你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它克隆到你的计算机上并使用 `IntelliJ IDEA` 打开它。 ## 运行插件 @@ -24,10 +30,7 @@ Halo 提供了一个模板仓库用于创建插件: 或者使用 `IntelliJ IDEA` 提供的 `Gradle build` 即可完成插件项目的构建。 -第二步就是使用它。 - -使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../core/run.md)。 -然后在 `src/main/resources` 下创建一个 `application-local.yaml` 文件并做如下配置: +然后使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../core/run.md),在 `src/main/resources` 下创建一个 `application-local.yaml` 文件并做如下配置: ```yaml # macOS / Linux @@ -36,7 +39,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-hello-world + - /path/to/halo-plugin-hello-world # Windows halo: @@ -44,7 +47,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - C:\Users\guqing\halo-plugin-hello-world + - C:\path\to\halo-plugin-hello-world ``` 使用此 local profile 启动 Halo: diff --git a/docs/developer-guide/plugin/introduction.md b/docs/developer-guide/plugin/introduction.md index 43f7f415..40bbeffb 100644 --- a/docs/developer-guide/plugin/introduction.md +++ b/docs/developer-guide/plugin/introduction.md @@ -2,7 +2,8 @@ title: 介绍 description: 插件开发的准备工作 --- -插件是由社区创建的程序或应用程序,用于扩展 Halo 的功能。插件在 Halo 中运行并执行一项或多项用户操作。它们允许用户根据自己的喜好扩展或修改 Halo。 + +Halo 采用可插拔架构,功能模块之间耦合度低、灵活性提高,支持用户按需安装、卸载插件,操作便捷。同时提供插件开发接口以确保较高扩展性和可维护性,这个系列的文档将帮助你了解如何开发 Halo 插件。 ## 插件管理 diff --git a/docs/developer-guide/plugin/lifecycle.md b/docs/developer-guide/plugin/lifecycle.md index 11f8a840..714a0d75 100644 --- a/docs/developer-guide/plugin/lifecycle.md +++ b/docs/developer-guide/plugin/lifecycle.md @@ -6,20 +6,20 @@ description: 了解插件从启动到卸载的过程 根据[插件项目文件结构](./structure.md)所展示的 `StarterPlugin.java` 中,具有如下方法: ```java - @Override - public void start() { - System.out.println("插件启动成功!"); - } - - @Override - public void stop() { - System.out.println("插件停止!"); - } - - @Override - public void delete() { - System.out.println("插件被删除!"); - } +@Override +public void start() { + System.out.println("插件启动成功!"); +} + +@Override +public void stop() { + System.out.println("插件停止!"); +} + +@Override +public void delete() { + System.out.println("插件被删除!"); +} ``` ### 插件启动 diff --git a/docs/developer-guide/plugin/manifest.md b/docs/developer-guide/plugin/manifest.md index 09226b43..8ac899f8 100644 --- a/docs/developer-guide/plugin/manifest.md +++ b/docs/developer-guide/plugin/manifest.md @@ -6,39 +6,40 @@ description: 了解插件资源文件 plugin.yaml 如何配置 一个典型的插件资源文件 plugin.yaml 如下所示: ```yaml - apiVersion: plugin.halo.run/v1alpha1 - kind: Plugin - metadata: - name: hello-world - spec: - enabled: true - requires: ">=2.0.0" - author: - name: halo-dev - website: https://halo.run - logo: https://halo.run/logo - # settingName: hello-world-settings - # configMapName: hello-world-configmap - homepage: https://github.com/guqing/halo-plugin-hello-world - displayName: "插件 Hello world" - description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件" - license: - - name: "MIT" +apiVersion: plugin.halo.run/v1alpha1 +kind: Plugin +metadata: + name: hello-world +spec: + enabled: true + requires: ">=2.0.0" + author: + name: halo-dev + website: https://halo.run + logo: https://halo.run/logo + # settingName: hello-world-settings + # configMapName: hello-world-configmap + homepage: https://github.com/guqing/halo-plugin-hello-world + displayName: "插件 Hello world" + description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件" + license: + - name: "MIT" ``` - `apiVersion` 和 `kind`:为固定写法,每个插件写法都是一样的不可变更。 -- `metadata.name`:它是插件的唯一标识名,包含不超过 253 个字符,仅包含小写字母、数字或“-”,以字母或数字开头,以字母或数字结尾。 +- `metadata.name`:它是插件的唯一标识名,包含不超过 253 个字符,仅包含小写字母、数字或`-`,以字母或数字开头,以字母或数字结尾。 - `spec.enabled`:表示是否要在安装时自动启用插件,仅在插件开发模式下有效。 -- `spec.requires`:支持的 Halo 版本,SemVer expression, e.g. ">=2.0.0" +- `spec.requires`:支持的 Halo 版本,遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/) 规范。 - `spec.author`:插件作者的名称和可获得支持的网站地址。 -- `spec.logo`:插件 logo,可以是域名或相对于项目 src/main/resources 目录的相对文件路径。 +- `spec.logo`:插件 logo,可以是域名或相对于项目 `src/main/resources` 目录的相对文件路径。 - `spec.settingName`:插件配置表单名称,参考表单定义,不需要表单设置则可删除。 - `spec.configMapName`:表单定义对应的值标识名, 推荐命名为 "插件名-configmap",没有配置 `settingName` 则不需要配置此项。 + + :::tip + 如果你在 plugin.yaml 中配置了 `settingName` 但确没有对应的 `Setting` 自定义模型资源文件,会导致插件无法启动,原因是 `Setting` 模型 `metadata.name` 为你配置的 `settingName` 的资源无法找到。 + ::: + - `spec.homepage`:通常为插件的 GitHub 仓库链接,或可联系到插件作者或插件官网或帮助中心链接等。 - `spec.displayName`:插件的显示名称,它通常是以少数几个字来概括插件的用途。 - `spec.description`:插件描述,用一段话来介绍插件的用途。 - `spec.license`:插件使用的软件协议,参考:。 - -:::tip Note -如果你在 plugin.yaml 中配置了 `settingName` 但确没有对应的 `Setting` 自定义模型资源文件,会导致插件无法启动,原因是 `Setting` 模型 `metadata.name` 为你配置的 `settingName` 的资源无法找到。 -::: diff --git a/docs/developer-guide/plugin/prepare.md b/docs/developer-guide/plugin/prepare.md index 0de0cf4d..70a0ae4c 100644 --- a/docs/developer-guide/plugin/prepare.md +++ b/docs/developer-guide/plugin/prepare.md @@ -3,13 +3,13 @@ title: 准备工作 description: 插件开发的准备工作 --- -在 Halo 中,插件是使用 Java 和 JavaScript 编写的,UI 使用 [Vuejs](https://vuejs.org) 编写。 +在 Halo 中,插件是使用 Java 和 JavaScript / TypeScript 编写的,UI 使用 [Vuejs](https://vuejs.org) 编写。 在创建你的第一个插件之前,请确保你具备以下条件: -- 你能成功[运行 Halo 2.0.0 及以上版本](../core/run.md)。 -- 你应该能够熟练使用 [IntelliJ IDEA](https://www.jetbrains.com/idea/old)。 -- 你需要在计算机上安装最新的 LTS 版本的 Node.js。如果你还没有Node.js安装,你可以在这里下载 [Node.js 16 LTS](https://nodejs.org/)。 +- 你能成功在[开发环境运行 Halo](../core/run.md)。 +- 你应该能够熟练使用 [IntelliJ IDEA](https://www.jetbrains.com/idea)。 +- 你需要在计算机上安装最新的 LTS 版本的 Node.js,如果你还没有Node.js安装,你可以在这里下载 [Node.js 18 LTS](https://nodejs.org/)。 - 你熟悉 Vue 和 TypeScript。 -- 你应该熟悉使用 PNPM 进行包管理,你可以在这里下载 [pnpm 7](https://pnpm.io/)。 -- Git 是一个版本控制系统,用于跟踪代码的更改。您需要 Git 来下载示例插件并发布插件。 +- 你应该熟悉使用 Node.js 包管理器。 +- Git 是一个版本控制系统,用于跟踪代码的更改,您需要 Git 来下载示例插件并发布插件。 diff --git a/docs/developer-guide/plugin/publish.md b/docs/developer-guide/plugin/publish.md index f591a019..fe04b128 100644 --- a/docs/developer-guide/plugin/publish.md +++ b/docs/developer-guide/plugin/publish.md @@ -2,18 +2,139 @@ title: 发布插件 description: 了解如何与我们的社区分享你的插件 --- -> 了解如何与我们的社区分享您的扩展。 -## 创建你的 Release +了解如何与我们的社区分享你的插件。 -当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 +## 创建 Release -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +当你完成了你的插件并进行充分测试后,就可以在 GitHub 上创建新的 Release,其中版本规范可以参考[版本控制](./introduction.md#版本控制)。 -## 分享你的插件 +## 自动构建 -用户可以在你的仓库 Release 下载使用,但为了方便让社区用户看到,你可以在我们的 [awesome-halo](https://github.com/halo-sigs/awesome-halo) 仓库发起一个 Pull Request,为此你需要先 Fork [awesome-halo](https://github.com/halo-sigs/awesome-halo) 并按照此仓库的要求添加一行记录是关于你的插件仓库地址和功能描述的,然后推送你的更改并通过 GitHub 向 [awesome-halo](https://github.com/halo-sigs/awesome-halo) 的 `main` 分支发起 Pull Request。 +如果你是基于 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `workflow.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例: -## 等待审核 +```yaml +name: Build Plugin JAR File -在你发起 Pull Request 后,我们将审查的你的插件并在需要时请求更改。一旦被接受,Pull Request 将被合并。 +on: + push: + branches: + - main + paths: + - "**" + - "!**.md" + release: + types: + - created + pull_request: + branches: + - main + paths: + - "**" + - "!**.md" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + cache: 'gradle' + java-version: 17 + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + - uses: pnpm/action-setup@v2.0.1 + name: Install pnpm + id: pnpm-install + with: + version: 8 + run_install: false + - name: Get pnpm store directory + id: pnpm-cache + run: | + echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/widget/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install Frontend Dependencies + run: | + ./gradlew pnpmInstall + - name: Build with Gradle + run: | + # Set the version with tag name when releasing + version=${{ github.event.release.tag_name }} + version=${version#v} + sed -i "s/version=.*-SNAPSHOT$/version=$version/1" gradle.properties + ./gradlew clean build -x test + - name: Archive plugin-starter jar + uses: actions/upload-artifact@v2 + with: + name: plugin-starter + path: | + build/libs/*.jar + retention-days: 1 + + github-release: + runs-on: ubuntu-latest + needs: build + if: github.event_name == 'release' + steps: + - name: Download plugin-starter jar + uses: actions/download-artifact@v2 + with: + name: plugin-starter + path: build/libs + - name: Get Name of Artifact + id: get_artifact + run: | + ARTIFACT_PATHNAME=$(ls build/libs/*.jar | head -n 1) + ARTIFACT_NAME=$(basename ${ARTIFACT_PATHNAME}) + echo "Artifact pathname: ${ARTIFACT_PATHNAME}" + echo "Artifact name: ${ARTIFACT_NAME}" + echo "ARTIFACT_PATHNAME=${ARTIFACT_PATHNAME}" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV + echo "RELEASE_ID=${{ github.event.release.id }}" >> $GITHUB_ENV + - name: Upload a Release Asset + uses: actions/github-script@v2 + if: github.event_name == 'release' + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + console.log('environment', process.versions); + + const fs = require('fs').promises; + + const { repo: { owner, repo }, sha } = context; + console.log({ owner, repo, sha }); + + const releaseId = process.env.RELEASE_ID + const artifactPathName = process.env.ARTIFACT_PATHNAME + const artifactName = process.env.ARTIFACT_NAME + console.log('Releasing', releaseId, artifactPathName, artifactName) + + await github.repos.uploadReleaseAsset({ + owner, repo, + release_id: releaseId, + name: artifactName, + data: await fs.readFile(artifactPathName) + }); +``` + +## 发布你的插件 + +用户可以在你的仓库 Release 下载使用,但为了方便让 Halo 的用户知道你的插件,可以在以下渠道发布: + +1. [halo-sigs/awesome-halo](https://github.com/halo-sigs/awesome-halo):你可以向这个仓库发起一个 PR 提交的插件的信息即可。 +2. [Halo 应用市场](https://www.halo.run/store/apps):Halo 官方的应用市场,但目前还不支持开发者注册和发布,如果你想发布到应用市场,可以在 PR 上说明以下,我们会暂时帮你发布。 +3. [Halo 论坛](https://bbs.halo.run/t/plugins):你可以在 Halo 官方社区的插件板块发布你的插件。 diff --git a/docs/developer-guide/plugin/runtime-mode.md b/docs/developer-guide/plugin/runtime-mode.md index 811e782f..d914bf99 100644 --- a/docs/developer-guide/plugin/runtime-mode.md +++ b/docs/developer-guide/plugin/runtime-mode.md @@ -2,15 +2,16 @@ title: 插件运行模式 description: 了解插件的运行方式 --- -Halo 的插件可以在两种模式下运行:`DEVELOPMENT` 和 `DEPLOYMENT`。 -`DEPLOYMENT`(默认)模式是插件创建的标准工作流程:为每个插件创建一个新的 Gradle 项目,编码插件(声明新的扩展点和/或添加新的扩展),将插件打包成一个 JAR 文件,部署 JAR 文件到 Halo。 -这些操作非常耗时,因此引入了 `DEVELOPMENT` 运行时模式。 -对于插件开发人员来说,`DEVELOPMENT` 运行时模式的主要优点是不必打包和部署插件。在开发模式下,您可以以简单快速的模式开发插件。 +Halo 的插件可以在两种模式下运行:`development` 和 `deployment`。 +`deployment`(默认)模式是插件创建的标准工作流程:为每个插件创建一个新的 Gradle 项目,编码插件(声明新的扩展点和/或添加新的扩展),将插件打包成一个 JAR 文件,部署 JAR 文件到 Halo。 +这些操作非常耗时,因此引入了 `development` 运行时模式。 + +对于插件开发人员来说,`development` 运行时模式的主要优点是不必打包和部署插件。在开发模式下,您可以以简单快速的模式开发插件。 ### 配置 -如果你想以 `DEPLOYMENT` 运行插件则做如下配置: +如果你想以 `deployment` 运行插件则做如下配置: ```yaml halo: @@ -20,7 +21,7 @@ halo: 插件的 `deployment` 模式只允许通过安装 JAR 文件的方式运行插件。 -而如果你想以 `DEVELOPMENT` 运行插件或开发插件则将 `runtime-mode` 修改为 `development`,同时配置 `fixed-plugin-path` 为插件项目路径,可以配置多个。 +而如果你想以 `development` 运行插件或开发插件则将 `runtime-mode` 修改为 `development`,同时配置 `fixed-plugin-path` 为插件项目路径,可以配置多个。 ```yaml # macOS / Linux @@ -28,7 +29,7 @@ plugin: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-hello-world + - /path/to/halo-plugin-hello-world # Windows halo: @@ -36,7 +37,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - C:\Users\guqing\halo-plugin-hello-world + - C:\path\to\halo-plugin-hello-world ``` :::tip Note diff --git a/docs/developer-guide/plugin/structure.md b/docs/developer-guide/plugin/structure.md index 3827c7e5..3c241aa6 100644 --- a/docs/developer-guide/plugin/structure.md +++ b/docs/developer-guide/plugin/structure.md @@ -6,48 +6,42 @@ description: 了解插件的文件结构 新创建的插件项目典型的目录结构如下所示: ```text -. -├── LICENSE -├── README.md +├── console +│ ├── src +│ │ ├── assets +│ │ │ └── logo.svg +│ │ ├── views +│ │ │ └── HomeView.vue +│ │ └── index.ts +│ ├── env.d.ts +│ ├── package.json +│ ├── pnpm-lock.yaml +│ ├── tsconfig.app.json +│ ├── tsconfig.config.json +│ ├── tsconfig.json +│ ├── tsconfig.vitest.json +│ └── vite.config.ts ├── gradle -│   └── . -├── lib -│   └── halo-2.0.0-SNAPSHOT-plain.jar ├── src -│   ├── main -│   │   ├── java -│   │   │   └── run -│   │   │   └── halo -│   │   │   └── starter -│   │   │   └── StarterPlugin.java -│   │   └── resources -│   │   ├── console -│   │   │   ├── main.js -│   │   │   └── style.css -│   │   └── plugin.yaml +│ └── main +│ ├── java +│ │ └── run +│ │ └── halo +│ │ └── starter +│ │ └── StarterPlugin.java +│ └── resources +│ ├── console +│ │ ├── main.js +│ │ └── style.css +│ └── plugin.yaml +├── LICENSE +├── OWNERS +├── README.md +├── build.gradle +├── gradle.properties ├── gradlew ├── gradlew.bat -├── gradle.properties -├── settings.gradle -├── build.gradle -├── console -│   ├── package.json -│   ├── pnpm-lock.yaml -│   ├── src -│   │   ├── assets -│   │   │   └── logo.svg -│   │   ├── components -│   │   │   └── HelloWorld.vue -│   │   ├── index.ts -│   │   ├── styles -│   │   │   └── index.css -│   │   └── views -│   │   └── DefaultView.vue -│   ├── tsconfig.app.json -│   ├── tsconfig.config.json -│   ├── tsconfig.json -│   ├── tsconfig.vitest.json -│   └── vite.config.ts +└── settings.gradle ``` 该目录包含了前端和后端两个部分,让我们依次看一下它们中的每一个。 @@ -57,13 +51,9 @@ description: 了解插件的文件结构 所有的后端代码都放在 `src` 目录下,它是一个常规的 `Java` 项目目录结构。 - `StarterPlugin.java` 为插件的后端入口文件。 - - `resources` 下的 `plugin.yaml` 为插件的资源描述文件,它是必须的。 - - `resources/console` 下的两个文件 `main.js` 和 `style.css` 是前端插件部分打包时输出的产物。一个插件可以没有前端部分,因此 `resources/console` 同样可以不存在。 -`lib/halo-2.0.0-SNAPSHOT-plain.jar` 它是 Halo 的类型依赖,目前使用 `JAR` 文件的方式引入依赖只是暂时的,后续将会改进它,它只作为编译时依赖使用。 - ### 前端部分 `console` 目录下为插件的前端部分的工程目录,包括了源码、配置文件和静态资源文件。 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/extension.md b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/extension.md index 8f06d0de..a0fe06b3 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/extension.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/extension.md @@ -74,10 +74,10 @@ gender: male - @GVK:此注解标识该类为一个自定义模型,同时必须继承 `AbstractExtension`。 - kind:表示自定义模型所表示的 REST 资源。 - - group:表示一组公开的资源,通常采用域名形式,Halo 项目保留使用空组和任何以“*.halo.run”结尾的组名供其单独使用。 - 选择群组名称时,我们建议选择你的群组或组织拥有的子域,例如“widget.mycompany.com”。 - - version:API 的版本,它与 group 组合使用为 apiVersion=“GROUP/VERSION”,例如“api.halo.run/v1alpha1”。 - - singular: 资源的单数名称,这允许客户端不透明地处理复数和单数,必须全部小写。通常为小写的“kind”。 + - group:表示一组公开的资源,通常采用域名形式,Halo 项目保留使用空组和任何以 `*.halo.run` 结尾的组名供其单独使用。 + 选择群组名称时,我们建议选择你的群组或组织拥有的子域,例如 `widget.mycompany.com`。 + - version:API 的版本,它与 group 组合使用为 `apiVersion=GROUP/VERSION`,例如`api.halo.run/v1alpha1`。 + - singular: 资源的单数名称,这允许客户端不透明地处理复数和单数,必须全部小写,通常为小写的 `kind`。 - plural: 资源的复数名称,自定义资源在 `/apis///.../` 下提供,必须为全部小写。 - @Schema:属性校验注解,会在创建/修改资源前对资源校验,参考 [schema-validator](https://www.openapi4j.org/schema-validator.html)。 ::: diff --git a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/reverseproxy.md b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/reverseproxy.md index ea261805..3ba86af1 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/reverseproxy.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/reverseproxy.md @@ -8,21 +8,21 @@ description: 了解如果使用静态资源代理来访问插件中的静态资 例如 `src/main/resources` 下的 `static` 目录下有一张 `halo.jpg`: 1. 首先需要在 `src/main/resources/extensions` 下创建一个 `yaml`,文件名可以任意。 -2. 示例配置如下。 +2. 示例配置如下: -```yaml -apiVersion: plugin.halo.run/v1alpha1 -kind: ReverseProxy -metadata: - # name 为此资源的唯一标识名称,不允许重复,为了避免与其他插件冲突,推荐带上插件名称前缀 - name: my-plugin-fake-reverse-proxy -rules: - - path: /res/** - file: - directory: static - # 如果想代理 static 下所有静态资源则省略 filename 配置 - filename: halo.jpg -``` + ```yaml + apiVersion: plugin.halo.run/v1alpha1 + kind: ReverseProxy + metadata: + # name 为此资源的唯一标识名称,不允许重复,为了避免与其他插件冲突,推荐带上插件名称前缀 + name: my-plugin-fake-reverse-proxy + rules: + - path: /res/** + file: + directory: static + # 如果想代理 static 下所有静态资源则省略 filename 配置 + filename: halo.jpg + ``` 插件启动后会根据 `/plugins/{plugin-name}/assets/**` 规则生成 API。 因此该 `ReverseProxy` 的访问路径为: `/plugins/my-plugin/assets/res/halo.jpg`。 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/role-template.md b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/role-template.md index a92f2c24..c5d09fd2 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/api-reference/role-template.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/api-reference/role-template.md @@ -58,15 +58,15 @@ rules: - `resources` 对应 API 中的 resource 部分,`my-plugin` 表示插件名称。 - `verbs` 表示请求动词,可选值为 "create", "delete", "deletecollection", "get", "list", "patch", "update"。对应的 HTTP 请求方式如下表所示: -| HTTP verb | request verb | -| --------- | ------------------------------------------------------------ | -| POST | create | -| GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | -| PUT | update | -| PATCH | patch | -| DELETE | delete (for individual resources), deletecollection (for collections) | + | HTTP verb | request verb | + | --------- | ------------------------------------------------------------ | + | POST | create | + | GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) | + | PUT | update | + | PATCH | patch | + | DELETE | delete (for individual resources), deletecollection (for collections) | -`metadata.labels` 中必须包含 `halo.run/role-template: "true"` 以表示它此资源要作为角色模板。 + `metadata.labels` 中必须包含 `halo.run/role-template: "true"` 以表示它此资源要作为角色模板。 `metadata.annotations` 中: @@ -75,16 +75,16 @@ rules: - `rbac.authorization.halo.run/display-name`:模板角色的显示名称,用于展示为用户可读的名称信息。 - `rbac.authorization.halo.run/ui-permissions`:用于控制 UI 权限,规则为 `plugin:{your-plugin-name}:scope-name`,使用示例为在插件前端部分入口文件 `index.ts` 中用于控制菜单是否显示或者控制页面按钮是否展示: -```javascript -{ - path: "", - name: "HelloWorld", - component: DefaultView, - meta: { - permissions: ["plugin:my-plugin:person:view"] + ```javascript + { + path: "", + name: "HelloWorld", + component: DefaultView, + meta: { + permissions: ["plugin:my-plugin:person:view"] + } } -} -``` + ``` 以上定义角色模板的方式适合资源型请求,即需要符合以下规则 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/examples/todolist.md b/versioned_docs/version-2.10/developer-guide/plugin/examples/todolist.md index 039e554d..5e98688d 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/examples/todolist.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/examples/todolist.md @@ -55,51 +55,52 @@ description: 这个例子展示了如何开发 Todo List 插件 1. 在 `src/main/java` 下创建包,如 `run.halo.tutorial`,在创建一个类 `TodoListPlugin`,它继承自 `BasePlugin` 类内容如下: -```java -package run.halo.tutorial; - -import org.pf4j.PluginWrapper; -import org.springframework.stereotype.Component; -import run.halo.app.plugin.BasePlugin; - -@Component -public class TodoListPlugin extends BasePlugin { - public TodoListPlugin(PluginWrapper wrapper) { - super(wrapper); - } -} -``` - -`src/main/java` 下的文件结构如下: - -```text -. -└── run - └── halo - └── tutorial - └── TodoListPlugin.java -``` - -然后在项目目录执行命令 + ```java + package run.halo.tutorial; + + import org.pf4j.PluginWrapper; + import org.springframework.stereotype.Component; + import run.halo.app.plugin.BasePlugin; + + @Component + public class TodoListPlugin extends BasePlugin { + public TodoListPlugin(PluginWrapper wrapper) { + super(wrapper); + } + } + ``` + + `src/main/java` 下的文件结构如下: + + ```text + . + └── run + └── halo + └── tutorial + └── TodoListPlugin.java + ``` + +2. 然后在项目目录执行命令 + + ```shell + ./gradlew build + ``` -```shell -./gradlew build -``` +3. 使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径: -使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径: + ```yaml + halo: + plugin: + runtime-mode: development + fixed-plugin-path: + # 配置为插件绝对路径 + - /Users/guqing/halo-plugin-todolist + ``` -```yaml -halo: - plugin: - runtime-mode: development - fixed-plugin-path: - # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-todolist -``` +4. 启动 Halo,然后访问 `http://localhost:8090/console` -启动 Halo,然后访问 `http://localhost:8090/console` +在插件列表将能看到插件已经被正确启用: -在插件列表将能看到插件已经被正确启用 ![plugin-todolist-in-list-view](/img/todolist-in-list.png) ## 创建一个自定义模型 @@ -283,13 +284,13 @@ export default definePlugin({ 2. ` pnpm install todomvc-app-css `。 3. 修改 `console/src/views/DefaultView.vue` 最底部的 `style` 标签。 -```diff -- -``` + ```diff + - + ``` 4. 重新 Build 后刷新页面,便能看到目标图所示效果。 @@ -307,7 +308,7 @@ pnpm install axios 为了符合最佳实践,将用 TypeScript 改造之前的 todomvc 示例: -1. 创建 types 文件 `console/src/types/index.ts` +创建 types 文件 `console/src/types/index.ts` ```typescript export interface Metadata { @@ -575,87 +576,9 @@ const handleDelete = (todo: Todo) => { 至此我们就完成了与插件后端 APIs 实现 Todo List 数据交互的部分。 -### 使用 Icon - -目前 Todo 的菜单还是默认的网格样式 Icon,在 `console/src/index.ts` 文件中配置有一个 `icon: markRaw(IconGrid)`。以此为例说明该如何使用其他 `Icon`。 - -1. 安装 [unplugin-icons](https://github.com/antfu/unplugin-icons)。 - -```shell -pnpm install -D unplugin-icons -pnpm install -D @iconify/json -pnpm install -D @vue/compiler-sfc -``` - -2. 编辑 `console/vite.config.ts`,在 `defineConfig` 的 `plugins` 中添加配置,修改如下。 - -```diff -+ import Icons from "unplugin-icons/vite"; - -// https://vitejs.dev/config/ -export default defineConfig({ -- plugins: [vue(), vueJsx()], -+ plugins: [vue(), vueJsx(), Icons({ compiler: "vue3" })], -``` - -3. 在 `console/tsconfig.app.json` 中加入 `unplugni-icons` 的 `types` 配置。 - -```diff -{ - // ... - "compilerOptions": { - // ... - "paths": { - "@/*": ["./src/*"] -- } -+ }, -+ "types": ["unplugin-icons/types/vue"] - } -} -``` - -4. 到 [icones](https://icones.js.org/) 搜索你想要使用的图标,并点击它,然后选择 `Unplugin Icons`,会复制到剪贴板。 - -![unplugin icons selector](/img/unplugin-icons-example.png) - -5. 编辑 `console/src/index.ts` 在 `import` 区域粘贴,并 `icon` 属性。 - -```diff -- import { IconGrid } from "@halo-dev/components"; -+ import VscodeIconsFileTypeLightTodo from "~icons/vscode-icons/file-type-light-todo"; - -export default definePlugin({ - routes: [ - { - // ... - route: { - path: "/todos", - children: [ - { - // ... - meta: { - // ... - menu: { - // ... -- icon: markRaw(IconGrid), -+ icon: markRaw(VscodeIconsFileTypeLightTodo), - priority: 0, - }, - }, - }, - ], - }, - }, - ], - // ... -}); -``` - ### 用户界面使用静态资源 -如果你想在用户界面中使用图片,你可以放到 `console/src/assets` 中,例如 `logo.png`,并将其作为 Todo 的 Logo 放到标题旁边 - -![todo logo example](/img/todo-logo-check-48.png) +如果你想在用户界面中使用图片,你可以放到 `console/src/assets` 中,例如 `logo.png`,并将其作为 Todo 的 Logo 放到标题旁边。 需要修改 `console/src/views/DefaultView.vue` 示例如下: diff --git a/versioned_docs/version-2.10/developer-guide/plugin/hello-world.md b/versioned_docs/version-2.10/developer-guide/plugin/hello-world.md index e09fad11..496a9095 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/hello-world.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/hello-world.md @@ -3,14 +3,20 @@ title: 入门 description: 了解如何构建你的第一个插件并在 Halo 中使用它。 --- -Halo 提供了一个模板仓库用于创建插件: +此文档将帮助你了解如何构建你的第一个插件并在 Halo 中安装和启用。 + +## 创建插件项目 + +1. 打开 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter)。 + + > 这是一个插件的初始模板,你可以基于它来开发自己的插件。 -1. 打开 [plugin-starter](https://github.com/halo-dev/plugin-starter)。 2. 点击 `Use this template` -> `Create a new repository`。 3. 如图所示填写仓库名后点击 `Create repository from template`。 -![create-repository-for-hello-world-plugin](/img/create-repository-for-hello-world-plugin.png) -你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它 `git clone` 到你的计算机上并使用 `IntelliJ IDEA` 打开它。 + ![create-repository-for-hello-world-plugin](/img/create-repository-for-hello-world-plugin.png) + +你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它克隆到你的计算机上并使用 `IntelliJ IDEA` 打开它。 ## 运行插件 @@ -24,10 +30,7 @@ Halo 提供了一个模板仓库用于创建插件: 或者使用 `IntelliJ IDEA` 提供的 `Gradle build` 即可完成插件项目的构建。 -第二步就是使用它。 - -使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../core/run.md)。 -然后在 `src/main/resources` 下创建一个 `application-local.yaml` 文件并做如下配置: +然后使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../core/run.md),在 `src/main/resources` 下创建一个 `application-local.yaml` 文件并做如下配置: ```yaml # macOS / Linux @@ -36,7 +39,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-hello-world + - /path/to/halo-plugin-hello-world # Windows halo: @@ -44,7 +47,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - C:\Users\guqing\halo-plugin-hello-world + - C:\path\to\halo-plugin-hello-world ``` 使用此 local profile 启动 Halo: diff --git a/versioned_docs/version-2.10/developer-guide/plugin/introduction.md b/versioned_docs/version-2.10/developer-guide/plugin/introduction.md index 43f7f415..40bbeffb 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/introduction.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/introduction.md @@ -2,7 +2,8 @@ title: 介绍 description: 插件开发的准备工作 --- -插件是由社区创建的程序或应用程序,用于扩展 Halo 的功能。插件在 Halo 中运行并执行一项或多项用户操作。它们允许用户根据自己的喜好扩展或修改 Halo。 + +Halo 采用可插拔架构,功能模块之间耦合度低、灵活性提高,支持用户按需安装、卸载插件,操作便捷。同时提供插件开发接口以确保较高扩展性和可维护性,这个系列的文档将帮助你了解如何开发 Halo 插件。 ## 插件管理 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/lifecycle.md b/versioned_docs/version-2.10/developer-guide/plugin/lifecycle.md index 11f8a840..714a0d75 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/lifecycle.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/lifecycle.md @@ -6,20 +6,20 @@ description: 了解插件从启动到卸载的过程 根据[插件项目文件结构](./structure.md)所展示的 `StarterPlugin.java` 中,具有如下方法: ```java - @Override - public void start() { - System.out.println("插件启动成功!"); - } - - @Override - public void stop() { - System.out.println("插件停止!"); - } - - @Override - public void delete() { - System.out.println("插件被删除!"); - } +@Override +public void start() { + System.out.println("插件启动成功!"); +} + +@Override +public void stop() { + System.out.println("插件停止!"); +} + +@Override +public void delete() { + System.out.println("插件被删除!"); +} ``` ### 插件启动 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/manifest.md b/versioned_docs/version-2.10/developer-guide/plugin/manifest.md index 09226b43..8ac899f8 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/manifest.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/manifest.md @@ -6,39 +6,40 @@ description: 了解插件资源文件 plugin.yaml 如何配置 一个典型的插件资源文件 plugin.yaml 如下所示: ```yaml - apiVersion: plugin.halo.run/v1alpha1 - kind: Plugin - metadata: - name: hello-world - spec: - enabled: true - requires: ">=2.0.0" - author: - name: halo-dev - website: https://halo.run - logo: https://halo.run/logo - # settingName: hello-world-settings - # configMapName: hello-world-configmap - homepage: https://github.com/guqing/halo-plugin-hello-world - displayName: "插件 Hello world" - description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件" - license: - - name: "MIT" +apiVersion: plugin.halo.run/v1alpha1 +kind: Plugin +metadata: + name: hello-world +spec: + enabled: true + requires: ">=2.0.0" + author: + name: halo-dev + website: https://halo.run + logo: https://halo.run/logo + # settingName: hello-world-settings + # configMapName: hello-world-configmap + homepage: https://github.com/guqing/halo-plugin-hello-world + displayName: "插件 Hello world" + description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件" + license: + - name: "MIT" ``` - `apiVersion` 和 `kind`:为固定写法,每个插件写法都是一样的不可变更。 -- `metadata.name`:它是插件的唯一标识名,包含不超过 253 个字符,仅包含小写字母、数字或“-”,以字母或数字开头,以字母或数字结尾。 +- `metadata.name`:它是插件的唯一标识名,包含不超过 253 个字符,仅包含小写字母、数字或`-`,以字母或数字开头,以字母或数字结尾。 - `spec.enabled`:表示是否要在安装时自动启用插件,仅在插件开发模式下有效。 -- `spec.requires`:支持的 Halo 版本,SemVer expression, e.g. ">=2.0.0" +- `spec.requires`:支持的 Halo 版本,遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/) 规范。 - `spec.author`:插件作者的名称和可获得支持的网站地址。 -- `spec.logo`:插件 logo,可以是域名或相对于项目 src/main/resources 目录的相对文件路径。 +- `spec.logo`:插件 logo,可以是域名或相对于项目 `src/main/resources` 目录的相对文件路径。 - `spec.settingName`:插件配置表单名称,参考表单定义,不需要表单设置则可删除。 - `spec.configMapName`:表单定义对应的值标识名, 推荐命名为 "插件名-configmap",没有配置 `settingName` 则不需要配置此项。 + + :::tip + 如果你在 plugin.yaml 中配置了 `settingName` 但确没有对应的 `Setting` 自定义模型资源文件,会导致插件无法启动,原因是 `Setting` 模型 `metadata.name` 为你配置的 `settingName` 的资源无法找到。 + ::: + - `spec.homepage`:通常为插件的 GitHub 仓库链接,或可联系到插件作者或插件官网或帮助中心链接等。 - `spec.displayName`:插件的显示名称,它通常是以少数几个字来概括插件的用途。 - `spec.description`:插件描述,用一段话来介绍插件的用途。 - `spec.license`:插件使用的软件协议,参考:。 - -:::tip Note -如果你在 plugin.yaml 中配置了 `settingName` 但确没有对应的 `Setting` 自定义模型资源文件,会导致插件无法启动,原因是 `Setting` 模型 `metadata.name` 为你配置的 `settingName` 的资源无法找到。 -::: diff --git a/versioned_docs/version-2.10/developer-guide/plugin/prepare.md b/versioned_docs/version-2.10/developer-guide/plugin/prepare.md index 0de0cf4d..70a0ae4c 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/prepare.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/prepare.md @@ -3,13 +3,13 @@ title: 准备工作 description: 插件开发的准备工作 --- -在 Halo 中,插件是使用 Java 和 JavaScript 编写的,UI 使用 [Vuejs](https://vuejs.org) 编写。 +在 Halo 中,插件是使用 Java 和 JavaScript / TypeScript 编写的,UI 使用 [Vuejs](https://vuejs.org) 编写。 在创建你的第一个插件之前,请确保你具备以下条件: -- 你能成功[运行 Halo 2.0.0 及以上版本](../core/run.md)。 -- 你应该能够熟练使用 [IntelliJ IDEA](https://www.jetbrains.com/idea/old)。 -- 你需要在计算机上安装最新的 LTS 版本的 Node.js。如果你还没有Node.js安装,你可以在这里下载 [Node.js 16 LTS](https://nodejs.org/)。 +- 你能成功在[开发环境运行 Halo](../core/run.md)。 +- 你应该能够熟练使用 [IntelliJ IDEA](https://www.jetbrains.com/idea)。 +- 你需要在计算机上安装最新的 LTS 版本的 Node.js,如果你还没有Node.js安装,你可以在这里下载 [Node.js 18 LTS](https://nodejs.org/)。 - 你熟悉 Vue 和 TypeScript。 -- 你应该熟悉使用 PNPM 进行包管理,你可以在这里下载 [pnpm 7](https://pnpm.io/)。 -- Git 是一个版本控制系统,用于跟踪代码的更改。您需要 Git 来下载示例插件并发布插件。 +- 你应该熟悉使用 Node.js 包管理器。 +- Git 是一个版本控制系统,用于跟踪代码的更改,您需要 Git 来下载示例插件并发布插件。 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/publish.md b/versioned_docs/version-2.10/developer-guide/plugin/publish.md index f591a019..fe04b128 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/publish.md @@ -2,18 +2,139 @@ title: 发布插件 description: 了解如何与我们的社区分享你的插件 --- -> 了解如何与我们的社区分享您的扩展。 -## 创建你的 Release +了解如何与我们的社区分享你的插件。 -当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 +## 创建 Release -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +当你完成了你的插件并进行充分测试后,就可以在 GitHub 上创建新的 Release,其中版本规范可以参考[版本控制](./introduction.md#版本控制)。 -## 分享你的插件 +## 自动构建 -用户可以在你的仓库 Release 下载使用,但为了方便让社区用户看到,你可以在我们的 [awesome-halo](https://github.com/halo-sigs/awesome-halo) 仓库发起一个 Pull Request,为此你需要先 Fork [awesome-halo](https://github.com/halo-sigs/awesome-halo) 并按照此仓库的要求添加一行记录是关于你的插件仓库地址和功能描述的,然后推送你的更改并通过 GitHub 向 [awesome-halo](https://github.com/halo-sigs/awesome-halo) 的 `main` 分支发起 Pull Request。 +如果你是基于 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `workflow.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例: -## 等待审核 +```yaml +name: Build Plugin JAR File -在你发起 Pull Request 后,我们将审查的你的插件并在需要时请求更改。一旦被接受,Pull Request 将被合并。 +on: + push: + branches: + - main + paths: + - "**" + - "!**.md" + release: + types: + - created + pull_request: + branches: + - main + paths: + - "**" + - "!**.md" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + cache: 'gradle' + java-version: 17 + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + - uses: pnpm/action-setup@v2.0.1 + name: Install pnpm + id: pnpm-install + with: + version: 8 + run_install: false + - name: Get pnpm store directory + id: pnpm-cache + run: | + echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/widget/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install Frontend Dependencies + run: | + ./gradlew pnpmInstall + - name: Build with Gradle + run: | + # Set the version with tag name when releasing + version=${{ github.event.release.tag_name }} + version=${version#v} + sed -i "s/version=.*-SNAPSHOT$/version=$version/1" gradle.properties + ./gradlew clean build -x test + - name: Archive plugin-starter jar + uses: actions/upload-artifact@v2 + with: + name: plugin-starter + path: | + build/libs/*.jar + retention-days: 1 + + github-release: + runs-on: ubuntu-latest + needs: build + if: github.event_name == 'release' + steps: + - name: Download plugin-starter jar + uses: actions/download-artifact@v2 + with: + name: plugin-starter + path: build/libs + - name: Get Name of Artifact + id: get_artifact + run: | + ARTIFACT_PATHNAME=$(ls build/libs/*.jar | head -n 1) + ARTIFACT_NAME=$(basename ${ARTIFACT_PATHNAME}) + echo "Artifact pathname: ${ARTIFACT_PATHNAME}" + echo "Artifact name: ${ARTIFACT_NAME}" + echo "ARTIFACT_PATHNAME=${ARTIFACT_PATHNAME}" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV + echo "RELEASE_ID=${{ github.event.release.id }}" >> $GITHUB_ENV + - name: Upload a Release Asset + uses: actions/github-script@v2 + if: github.event_name == 'release' + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + console.log('environment', process.versions); + + const fs = require('fs').promises; + + const { repo: { owner, repo }, sha } = context; + console.log({ owner, repo, sha }); + + const releaseId = process.env.RELEASE_ID + const artifactPathName = process.env.ARTIFACT_PATHNAME + const artifactName = process.env.ARTIFACT_NAME + console.log('Releasing', releaseId, artifactPathName, artifactName) + + await github.repos.uploadReleaseAsset({ + owner, repo, + release_id: releaseId, + name: artifactName, + data: await fs.readFile(artifactPathName) + }); +``` + +## 发布你的插件 + +用户可以在你的仓库 Release 下载使用,但为了方便让 Halo 的用户知道你的插件,可以在以下渠道发布: + +1. [halo-sigs/awesome-halo](https://github.com/halo-sigs/awesome-halo):你可以向这个仓库发起一个 PR 提交的插件的信息即可。 +2. [Halo 应用市场](https://www.halo.run/store/apps):Halo 官方的应用市场,但目前还不支持开发者注册和发布,如果你想发布到应用市场,可以在 PR 上说明以下,我们会暂时帮你发布。 +3. [Halo 论坛](https://bbs.halo.run/t/plugins):你可以在 Halo 官方社区的插件板块发布你的插件。 diff --git a/versioned_docs/version-2.10/developer-guide/plugin/runtime-mode.md b/versioned_docs/version-2.10/developer-guide/plugin/runtime-mode.md index 811e782f..d914bf99 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/runtime-mode.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/runtime-mode.md @@ -2,15 +2,16 @@ title: 插件运行模式 description: 了解插件的运行方式 --- -Halo 的插件可以在两种模式下运行:`DEVELOPMENT` 和 `DEPLOYMENT`。 -`DEPLOYMENT`(默认)模式是插件创建的标准工作流程:为每个插件创建一个新的 Gradle 项目,编码插件(声明新的扩展点和/或添加新的扩展),将插件打包成一个 JAR 文件,部署 JAR 文件到 Halo。 -这些操作非常耗时,因此引入了 `DEVELOPMENT` 运行时模式。 -对于插件开发人员来说,`DEVELOPMENT` 运行时模式的主要优点是不必打包和部署插件。在开发模式下,您可以以简单快速的模式开发插件。 +Halo 的插件可以在两种模式下运行:`development` 和 `deployment`。 +`deployment`(默认)模式是插件创建的标准工作流程:为每个插件创建一个新的 Gradle 项目,编码插件(声明新的扩展点和/或添加新的扩展),将插件打包成一个 JAR 文件,部署 JAR 文件到 Halo。 +这些操作非常耗时,因此引入了 `development` 运行时模式。 + +对于插件开发人员来说,`development` 运行时模式的主要优点是不必打包和部署插件。在开发模式下,您可以以简单快速的模式开发插件。 ### 配置 -如果你想以 `DEPLOYMENT` 运行插件则做如下配置: +如果你想以 `deployment` 运行插件则做如下配置: ```yaml halo: @@ -20,7 +21,7 @@ halo: 插件的 `deployment` 模式只允许通过安装 JAR 文件的方式运行插件。 -而如果你想以 `DEVELOPMENT` 运行插件或开发插件则将 `runtime-mode` 修改为 `development`,同时配置 `fixed-plugin-path` 为插件项目路径,可以配置多个。 +而如果你想以 `development` 运行插件或开发插件则将 `runtime-mode` 修改为 `development`,同时配置 `fixed-plugin-path` 为插件项目路径,可以配置多个。 ```yaml # macOS / Linux @@ -28,7 +29,7 @@ plugin: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - /Users/guqing/halo-plugin-hello-world + - /path/to/halo-plugin-hello-world # Windows halo: @@ -36,7 +37,7 @@ halo: runtime-mode: development fixed-plugin-path: # 配置为插件绝对路径 - - C:\Users\guqing\halo-plugin-hello-world + - C:\path\to\halo-plugin-hello-world ``` :::tip Note diff --git a/versioned_docs/version-2.10/developer-guide/plugin/structure.md b/versioned_docs/version-2.10/developer-guide/plugin/structure.md index 3827c7e5..3c241aa6 100644 --- a/versioned_docs/version-2.10/developer-guide/plugin/structure.md +++ b/versioned_docs/version-2.10/developer-guide/plugin/structure.md @@ -6,48 +6,42 @@ description: 了解插件的文件结构 新创建的插件项目典型的目录结构如下所示: ```text -. -├── LICENSE -├── README.md +├── console +│ ├── src +│ │ ├── assets +│ │ │ └── logo.svg +│ │ ├── views +│ │ │ └── HomeView.vue +│ │ └── index.ts +│ ├── env.d.ts +│ ├── package.json +│ ├── pnpm-lock.yaml +│ ├── tsconfig.app.json +│ ├── tsconfig.config.json +│ ├── tsconfig.json +│ ├── tsconfig.vitest.json +│ └── vite.config.ts ├── gradle -│   └── . -├── lib -│   └── halo-2.0.0-SNAPSHOT-plain.jar ├── src -│   ├── main -│   │   ├── java -│   │   │   └── run -│   │   │   └── halo -│   │   │   └── starter -│   │   │   └── StarterPlugin.java -│   │   └── resources -│   │   ├── console -│   │   │   ├── main.js -│   │   │   └── style.css -│   │   └── plugin.yaml +│ └── main +│ ├── java +│ │ └── run +│ │ └── halo +│ │ └── starter +│ │ └── StarterPlugin.java +│ └── resources +│ ├── console +│ │ ├── main.js +│ │ └── style.css +│ └── plugin.yaml +├── LICENSE +├── OWNERS +├── README.md +├── build.gradle +├── gradle.properties ├── gradlew ├── gradlew.bat -├── gradle.properties -├── settings.gradle -├── build.gradle -├── console -│   ├── package.json -│   ├── pnpm-lock.yaml -│   ├── src -│   │   ├── assets -│   │   │   └── logo.svg -│   │   ├── components -│   │   │   └── HelloWorld.vue -│   │   ├── index.ts -│   │   ├── styles -│   │   │   └── index.css -│   │   └── views -│   │   └── DefaultView.vue -│   ├── tsconfig.app.json -│   ├── tsconfig.config.json -│   ├── tsconfig.json -│   ├── tsconfig.vitest.json -│   └── vite.config.ts +└── settings.gradle ``` 该目录包含了前端和后端两个部分,让我们依次看一下它们中的每一个。 @@ -57,13 +51,9 @@ description: 了解插件的文件结构 所有的后端代码都放在 `src` 目录下,它是一个常规的 `Java` 项目目录结构。 - `StarterPlugin.java` 为插件的后端入口文件。 - - `resources` 下的 `plugin.yaml` 为插件的资源描述文件,它是必须的。 - - `resources/console` 下的两个文件 `main.js` 和 `style.css` 是前端插件部分打包时输出的产物。一个插件可以没有前端部分,因此 `resources/console` 同样可以不存在。 -`lib/halo-2.0.0-SNAPSHOT-plain.jar` 它是 Halo 的类型依赖,目前使用 `JAR` 文件的方式引入依赖只是暂时的,后续将会改进它,它只作为编译时依赖使用。 - ### 前端部分 `console` 目录下为插件的前端部分的工程目录,包括了源码、配置文件和静态资源文件。 diff --git a/versioned_docs/version-2.2/developer-guide/plugin/publish.md b/versioned_docs/version-2.2/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.2/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.2/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.3/developer-guide/plugin/publish.md b/versioned_docs/version-2.3/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.3/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.3/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.4/developer-guide/plugin/publish.md b/versioned_docs/version-2.4/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.4/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.4/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.5/developer-guide/plugin/publish.md b/versioned_docs/version-2.5/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.5/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.5/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.6/developer-guide/plugin/publish.md b/versioned_docs/version-2.6/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.6/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.6/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.7/developer-guide/plugin/publish.md b/versioned_docs/version-2.7/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.7/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.7/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.8/developer-guide/plugin/publish.md b/versioned_docs/version-2.8/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.8/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.8/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件 diff --git a/versioned_docs/version-2.9/developer-guide/plugin/publish.md b/versioned_docs/version-2.9/developer-guide/plugin/publish.md index f591a019..1b4ea92c 100644 --- a/versioned_docs/version-2.9/developer-guide/plugin/publish.md +++ b/versioned_docs/version-2.9/developer-guide/plugin/publish.md @@ -8,7 +8,7 @@ description: 了解如何与我们的社区分享你的插件 当你完成了你的插件并进行充分测试后,切换到插件目录 Build 一次,当没有发生任何错误你就可以推送到 GitHub 并 `Create a new release`。 -然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Asserts` 中包含打包产物--插件的 JAR 文件。 +然后填写 `Release Tag` 和描述点击创建,项目目录下的 `.github/workflows/workflow.yaml` 文件会被 `GitHub Action` 触发并执行,脚本会自动根据你的 `Release Tag` 修改插件版本号然后在 `Release` 的 `Assets` 中包含打包产物--插件的 JAR 文件。 ## 分享你的插件