feat: 添加云端构建功能,支持参数配置和环境变量
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import { Result } from '@kevisual/query';
|
||||
import { CNB } from '../../src/index.ts';
|
||||
import { useKey } from '@kevisual/context';
|
||||
export const getConfig = async (opts: { token?: string }) => {
|
||||
const res = await fetch('https://kevisual.cn/api/router', {
|
||||
const kevisualEnv = useKey('KEVISUAL_ENV')
|
||||
const baseUrl = kevisualEnv === 'production' ? 'https://kevisual.cn/api/router' : 'https://kevisual.xiongxiao.me/api/router';
|
||||
const res = await fetch(baseUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
path: 'config',
|
||||
@@ -51,6 +54,7 @@ export class CNBManager {
|
||||
cnbItem.runAt = Date.now()
|
||||
return cnbItem
|
||||
}
|
||||
|
||||
const res = await getConfig({ token: opts?.kevisualToken })
|
||||
if (res.code === 200) {
|
||||
const cookie = res.data?.data?.CNB_COOKIE
|
||||
|
||||
@@ -43,6 +43,27 @@ app.route({
|
||||
}
|
||||
}).addTo(app);
|
||||
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'get-repo',
|
||||
description: '获取代码仓库详情, 参数name',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
args: {
|
||||
name: tool.schema.string().describe('代码仓库名称, 如 my-user/my-repo'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const cnb = await cnbManager.getContext(ctx);
|
||||
const name = ctx.query?.name;
|
||||
|
||||
if (!name) {
|
||||
ctx.throw(400, '缺少参数 name');
|
||||
}
|
||||
const res = await cnb.repo.getRepo(name);
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'create-repo-file',
|
||||
@@ -106,7 +127,56 @@ app.route({
|
||||
if (!name) {
|
||||
ctx.throw(400, '缺少参数 name');
|
||||
}
|
||||
try {
|
||||
const resCookie = await cnb.user.checkCookieValid()
|
||||
if (resCookie.code !== 200) {
|
||||
ctx.throw(401, 'Cookie 无效或已过期');
|
||||
}
|
||||
const res = await cnb.repo.deleteRepoCookie(name);
|
||||
ctx.forward(res);
|
||||
} catch (error) {
|
||||
ctx.code = 200
|
||||
ctx.body = { content: '已经删除' }
|
||||
}
|
||||
}).addTo(app);
|
||||
|
||||
const res = await cnb.repo.deleteRepoCookie(name);
|
||||
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'update-repo-info',
|
||||
description: '更新代码仓库信息, 参数name, description',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'update-repo-info',
|
||||
title: '更新代码仓库信息',
|
||||
args: {
|
||||
name: tool.schema.string().describe('代码仓库名称'),
|
||||
description: tool.schema.string().describe('代码仓库描述'),
|
||||
license: tool.schema.string().describe('代码仓库许可证类型,如 MIT').optional(),
|
||||
site: tool.schema.string().describe('代码仓库主页链接').optional(),
|
||||
topics: tool.schema.array(tool.schema.string()).describe('代码仓库话题标签列表').optional(),
|
||||
},
|
||||
summary: '更新代码仓库的信息',
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const cnb = await cnbManager.getContext(ctx);
|
||||
const name = ctx.query?.name;
|
||||
const description = ctx.query?.description;
|
||||
const license = ctx.query?.license;
|
||||
const site = ctx.query?.site;
|
||||
const topics = ctx.query?.topics;
|
||||
|
||||
if (!name) {
|
||||
ctx.throw(400, '缺少参数 name');
|
||||
}
|
||||
if (!description) {
|
||||
ctx.throw(400, '缺少参数 description');
|
||||
}
|
||||
|
||||
const res = await cnb.repo.updateRepoInfo(name, { description, license, site, topics });
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
}).addTo(app);
|
||||
|
||||
|
||||
43
agent/routes/workspace/build.ts
Normal file
43
agent/routes/workspace/build.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { createSkill, tool } from '@kevisual/router';
|
||||
|
||||
import { app, cnbManager, notCNBCheck } from '../../app.ts';
|
||||
|
||||
// 启动工作空间
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'cloud-build',
|
||||
description: '云端构建,参数 event, repo, branch, ref, config, env',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'cloud-build',
|
||||
title: '云端构建',
|
||||
summary: '在云端构建代码仓库,参数包括 event, repo, branch, ref, config, env',
|
||||
args: {
|
||||
env: tool.schema.any().optional().describe('构建环境变量,格式为 { "KEY": "VALUE" }'),
|
||||
event: tool.schema.string().optional().describe('触发事件类型,例如 api_trigger_event'),
|
||||
branch: tool.schema.string().optional().describe('分支名称,默认主分支'),
|
||||
config: tool.schema.string().describe('构建config文件内容,例如 cloudbuild.yaml对应的yml的内容'),
|
||||
repo: tool.schema.string().describe('代码仓库路径,例如 user/repo'),
|
||||
},
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const cnb = await cnbManager.getContext(ctx);
|
||||
const repo = ctx.query?.repo;
|
||||
const branch = ctx.query?.branch || 'main';
|
||||
const config = ctx.query?.config;
|
||||
const event = ctx.query?.event || 'api_trigger_event';
|
||||
const env = ctx.query?.env ?? {};
|
||||
if (!repo) {
|
||||
ctx.throw(400, '缺少参数 repo');
|
||||
}
|
||||
const res = await cnb.build.startBuild(repo, {
|
||||
branch,
|
||||
config,
|
||||
event,
|
||||
env,
|
||||
});
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
@@ -3,6 +3,7 @@ import { app, cnbManager, notCNBCheck } from '../../app.ts';
|
||||
import z from 'zod';
|
||||
import './skills.ts';
|
||||
import './keep.ts';
|
||||
import './build.ts';
|
||||
|
||||
// 启动工作空间
|
||||
app.route({
|
||||
@@ -67,7 +68,7 @@ app.route({
|
||||
page: page ?? 1,
|
||||
pageSize: pageSize ?? 100,
|
||||
});
|
||||
ctx.forward({ code: 200, message: 'success', data: res });
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
|
||||
// 获取工作空间详情
|
||||
@@ -99,7 +100,7 @@ app.route({
|
||||
ctx.throw(400, '缺少参数 sn');
|
||||
}
|
||||
const res = await cnb.workspace.getDetail(repo, sn);
|
||||
ctx.forward({ code: 200, message: 'success', data: res });
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
|
||||
// 删除工作空间
|
||||
@@ -161,7 +162,6 @@ app.route({
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
if (notCNBCheck(ctx)) { return; }
|
||||
const cnb = await cnbManager.getContext(ctx);
|
||||
const pipelineId = ctx.query?.pipelineId;
|
||||
const sn = ctx.query?.sn;
|
||||
@@ -169,6 +169,7 @@ app.route({
|
||||
ctx.throw(400, 'pipelineId 和 sn 必须提供其中一个');
|
||||
}
|
||||
const res = await cnb.workspace.stopWorkspace({ pipelineId, sn });
|
||||
ctx.forward({ code: 200, message: 'success', data: res });
|
||||
ctx.forward(res);
|
||||
}).addTo(app);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user