This commit is contained in:
2026-03-11 15:38:59 +08:00
parent 8379be1630
commit fc6a5bd73c
5 changed files with 482 additions and 295 deletions

View File

@@ -1,3 +1,38 @@
import { app } from './index.ts';
import { getN } from '../src/index.ts'
import { useIssueEnv, useCommentEnv, useRepoInfoEnv } from '../src/index.ts'
import { pick } from 'es-toolkit';
const main = async () => {
const repoInfoEnv = useRepoInfoEnv();
const commentEnv = useCommentEnv();
const issueEnv = useIssueEnv();
const pickCommentEnv = pick(commentEnv, ['commentId', 'commentIdLabel']);
const pickIssueEnv = pick(issueEnv, ['issueId', 'issueIdLabel', 'issueIid', 'issueIidLabel', 'issueTitle', 'issueTitleLabel', 'issueDescription', 'issueDescriptionLabel']);
const pickRepoInfoEnv = pick(repoInfoEnv, ['repoId', 'repoIdLabel', 'repoName', 'repoNameLabel', 'repoSlug', 'repoSlugLabel']);
const messages = [
{
role: 'system',
content: `你是一个智能的代码助手, 根据用户提供的上下文信息提供有用的建议和帮助。并把最后的结果提交一个评论到对应的issue中。用户提供的上下文信息如下`
},
{
role: 'system',
content: `相关变量:${JSON.stringify({ ...pickCommentEnv, ...pickIssueEnv, ...pickRepoInfoEnv })}`
}, {
role: 'user',
content: commentEnv.commentBody || pickIssueEnv.issueDescription || '无'
}
]
const result = await app.run({
path: 'cnb',
key: 'chat',
payload: {
messages
}
})
if (result.code === 200) {
console.log('执行完成')
}
}
main();

217
src/issue/npc/build-env.ts Normal file
View File

@@ -0,0 +1,217 @@
import { useKey } from "@kevisual/context";
// CNB_BUILD_ID cnb-75b-1jj9hnk99 当前构建的流水号,全局唯一
// CNB_BUILD_WEB_URL https://cnb.cool/kevision/dev-cnb/-/build/logs/cnb-75b-1jj9hnk99 当前构建的日志地址
// CNB_BUILD_START_TIME 2026-03-09T14:59:01.550Z 当前构建的开始时间UTC 格式,示例 2025-08-21T09:13:45.803Z
// CNB_BUILD_USER xiongxiao 当前构建的触发者用户名
// CNB_BUILD_USER_NICKNAME 小熊猫呜呜呜 当前构建的触发者昵称
// CNB_BUILD_USER_EMAIL kevisual@xiongxiao.me 当前构建的触发者邮箱
// CNB_BUILD_USER_ID 1935321989751226368 当前构建的触发者 id
// CNB_BUILD_USER_NPC_SLUG 当前构建若为 NPC 触发,则为 NPC 所属仓库的路径
// CNB_BUILD_USER_NPC_NAME 当前构建若为 NPC 触发,则为 NPC 角色名
// CNB_BUILD_STAGE_NAME 初始化开发机 当前构建的 stage 名称
// CNB_BUILD_JOB_NAME 初始化开发机 当前构建的 job 名称
// CNB_BUILD_JOB_KEY job-0 当前构建的 job key同 stage 下唯一
// CNB_BUILD_WORKSPACE /workspace/ 自定义 shell 脚本执行的工作空间根目录
// CNB_BUILD_FAILED_MSG 流水线构建失败的错误信息,可在 failStages 中使用
// CNB_BUILD_FAILED_STAGE_NAME 流水线构建失败的 stage 的名称,可在 failStages 中使用
// CNB_PIPELINE_NAME pipeline-1 当前 pipeline 的 name没声明时为空
// CNB_PIPELINE_KEY pipeline-1 当前 pipeline 的索引 key例如 pipeline-0
// CNB_PIPELINE_ID cnb-75b-1jj9hnk99-001 当前 pipeline 的 id全局唯一字符串
// CNB_PIPELINE_DOCKER_IMAGE docker.cnb.cool/kevisual/dev-env:latest 当前 pipeline 所使用的 docker imagealpine:latest
// CNB_PIPELINE_STATUS 当前流水线的构建状态,可在 endStages 中查看其可能的值包括success、error、cancel
// CNB_PIPELINE_MAX_RUN_TIME 72000000 流水线最大运行时间,单位为毫秒
// CNB_RUNNER_IP 10.235.16.3 当前 pipeline 所在 Runner 的 ip
// CNB_CPUS 16 当前构建流水线可以使用的最大 CPU 核数
// CNB_MEMORY 32 当前构建流水线可以使用的最大内存大小,单位为 GiB
// CNB_IS_RETRY false 当前构建是否由 rebuild 触发
// HUSKY_SKIP_INSTALL 1 兼容 ci 环境下 husky
export const useBuildEnv = () => {
const buildId = useKey("CNB_BUILD_ID");
const buildWebUrl = useKey("CNB_BUILD_WEB_URL");
const buildStartTime = useKey("CNB_BUILD_START_TIME");
const buildUser = useKey("CNB_BUILD_USER");
const buildUserNickname = useKey("CNB_BUILD_USER_NICKNAME");
const buildUserEmail = useKey("CNB_BUILD_USER_EMAIL");
const buildUserId = useKey("CNB_BUILD_USER_ID");
const buildUserNpcSlug = useKey("CNB_BUILD_USER_NPC_SLUG");
const buildUserNpcName = useKey("CNB_BUILD_USER_NPC_NAME");
const buildStageName = useKey("CNB_BUILD_STAGE_NAME");
const buildJobName = useKey("CNB_BUILD_JOB_NAME");
const buildJobKey = useKey("CNB_BUILD_JOB_KEY");
const buildWorkspace = useKey("CNB_BUILD_WORKSPACE");
const buildFailedMsg = useKey("CNB_BUILD_FAILED_MSG");
const buildFailedStageName = useKey("CNB_BUILD_FAILED_STAGE_NAME");
const pipelineName = useKey("CNB_PIPELINE_NAME");
const pipelineKey = useKey("CNB_PIPELINE_KEY");
const pipelineId = useKey("CNB_PIPELINE_ID");
const pipelineDockerImage = useKey("CNB_PIPELINE_DOCKER_IMAGE");
const pipelineStatus = useKey("CNB_PIPELINE_STATUS");
const pipelineMaxRunTime = useKey("CNB_PIPELINE_MAX_RUN_TIME");
const runnerIp = useKey("CNB_RUNNER_IP");
const cpus = useKey("CNB_CPUS");
const memory = useKey("CNB_MEMORY");
const isRetry = useKey("CNB_IS_RETRY");
const huskySkipInstall = useKey("HUSKY_SKIP_INSTALL");
return {
/**
* @key CNB_BUILD_ID
* @description:当前构建的流水号,全局唯一
*/
buildId,
buildIdLabel: "当前构建的流水号,全局唯一",
/**
* @key CNB_BUILD_WEB_URL
* @description:当前构建的日志地址
*/
buildWebUrl,
buildWebUrlLabel: "当前构建的日志地址",
/**
* @key CNB_BUILD_START_TIME
* @description:当前构建的开始时间UTC 格式
*/
buildStartTime,
buildStartTimeLabel: "当前构建的开始时间UTC 格式",
/**
* @key CNB_BUILD_USER
* @description:当前构建的触发者用户名
*/
buildUser,
buildUserLabel: "当前构建的触发者用户名",
/**
* @key CNB_BUILD_USER_NICKNAME
* @description:当前构建的触发者昵称
*/
buildUserNickname,
buildUserNicknameLabel: "当前构建的触发者昵称",
/**
* @key CNB_BUILD_USER_EMAIL
* @description:当前构建的触发者邮箱
*/
buildUserEmail,
buildUserEmailLabel: "当前构建的触发者邮箱",
/**
* @key CNB_BUILD_USER_ID
* @description:当前构建的触发者 id
*/
buildUserId,
buildUserIdLabel: "当前构建的触发者 id",
/**
* @key CNB_BUILD_USER_NPC_SLUG
* @description:当前构建若为 NPC 触发,则为 NPC 所属仓库的路径
*/
buildUserNpcSlug,
buildUserNpcSlugLabel: "当前构建若为 NPC 触发,则为 NPC 所属仓库的路径",
/**
* @key CNB_BUILD_USER_NPC_NAME
* @description:当前构建若为 NPC 触发,则为 NPC 角色名
*/
buildUserNpcName,
buildUserNpcNameLabel: "当前构建若为 NPC 触发,则为 NPC 角色名",
/**
* @key CNB_BUILD_STAGE_NAME
* @description:当前构建的 stage 名称
*/
buildStageName,
buildStageNameLabel: "当前构建的 stage 名称",
/**
* @key CNB_BUILD_JOB_NAME
* @description:当前构建的 job 名称
*/
buildJobName,
buildJobNameLabel: "当前构建的 job 名称",
/**
* @key CNB_BUILD_JOB_KEY
* @description:当前构建的 job key同 stage 下唯一
*/
buildJobKey,
buildJobKeyLabel: "当前构建的 job key同 stage 下唯一",
/**
* @key CNB_BUILD_WORKSPACE
* @description:自定义 shell 脚本执行的工作空间根目录
*/
buildWorkspace,
buildWorkspaceLabel: "自定义 shell 脚本执行的工作空间根目录",
/**
* @key CNB_BUILD_FAILED_MSG
* @description:流水线构建失败的错误信息
*/
buildFailedMsg,
buildFailedMsgLabel: "流水线构建失败的错误信息",
/**
* @key CNB_BUILD_FAILED_STAGE_NAME
* @description:流水线构建失败的 stage 的名称
*/
buildFailedStageName,
buildFailedStageNameLabel: "流水线构建失败的 stage 的名称",
/**
* @key CNB_PIPELINE_NAME
* @description:当前 pipeline 的 name
*/
pipelineName,
pipelineNameLabel: "当前 pipeline 的 name",
/**
* @key CNB_PIPELINE_KEY
* @description:当前 pipeline 的索引 key
*/
pipelineKey,
pipelineKeyLabel: "当前 pipeline 的索引 key",
/**
* @key CNB_PIPELINE_ID
* @description:当前 pipeline 的 id
*/
pipelineId,
pipelineIdLabel: "当前 pipeline 的 id",
/**
* @key CNB_PIPELINE_DOCKER_IMAGE
* @description:当前 pipeline 所使用的 docker image
*/
pipelineDockerImage,
pipelineDockerImageLabel: "当前 pipeline 所使用的 docker image",
/**
* @key CNB_PIPELINE_STATUS
* @description:当前流水线的构建状态可能的值包括success、error、cancel
*/
pipelineStatus,
pipelineStatusLabel: "当前流水线的构建状态可能的值包括success、error、cancel",
/**
* @key CNB_PIPELINE_MAX_RUN_TIME
* @description:流水线最大运行时间,单位为毫秒
*/
pipelineMaxRunTime,
pipelineMaxRunTimeLabel: "流水线最大运行时间,单位为毫秒",
/**
* @key CNB_RUNNER_IP
* @description:当前 pipeline 所在 Runner 的 ip
*/
runnerIp,
runnerIpLabel: "当前 pipeline 所在 Runner 的 ip",
/**
* @key CNB_CPUS
* @description:当前构建流水线可以使用的最大 CPU 核数
*/
cpus,
cpusLabel: "当前构建流水线可以使用的最大 CPU 核数",
/**
* @key CNB_MEMORY
* @description:当前构建流水线可以使用的最大内存大小,单位为 GiB
*/
memory,
memoryLabel: "当前构建流水线可以使用的最大内存大小,单位为 GiB",
/**
* @key CNB_IS_RETRY
* @description:当前构建是否由 rebuild 触发
*/
isRetry,
isRetryLabel: "当前构建是否由 rebuild 触发",
/**
* @key HUSKY_SKIP_INSTALL
* @description:兼容 ci 环境下 husky
*/
huskySkipInstall,
huskySkipInstallLabel: "兼容 ci 环境下 husky"
};
}

View File

@@ -20,31 +20,37 @@ export function useNPCEnv() {
* @description:对于 @ 知识库角色触发的 NPC 事件,值为 NPC 所属仓库路径,否则为空字符串
*/
npcSlug,
npcSlugLabel: "对于 @ 知识库角色触发的 NPC 事件,值为 NPC 所属仓库路径,否则为空字符串",
/**
* @key CNB_NPC_NAME
* @description:对于 NPC 事件触发的构建,值为 NPC 角色名,否则为空字符串
*/
npcName,
npcNameLabel: "对于 NPC 事件触发的构建,值为 NPC 角色名,否则为空字符串",
/**
* @key CNB_NPC_SHA
* @description:对于 @ 知识库角色触发的 NPC 事件,值为 NPC 所属仓库默认分支最新提交的 sha否则为空字符串
*/
npcSha,
npcShaLabel: "对于 @ 知识库角色触发的 NPC 事件,值为 NPC 所属仓库默认分支最新提交的 sha否则为空字符串",
/**
* @key CNB_NPC_PROMPT
* @description:对于 @ 知识库角色触发的 NPC 事件,值为 NPC 角色 Prompt否则为空字符串
*/
npcPrompt,
npcPromptLabel: "对于 @ 知识库角色触发的 NPC 事件,值为 NPC 角色 Prompt否则为空字符串",
/**
* @key CNB_NPC_AVATAR
* @description:对于 @ 知识库角色触发的 NPC 事件,值为 NPC 角色头像,否则为空字符串
*/
npcAvatar,
npcAvatarLabel: "对于 @ 知识库角色触发的 NPC 事件,值为 NPC 角色头像,否则为空字符串",
/**
* @key CNB_NPC_ENABLE_THINKING
* @description:对于 @npc 事件触发的构建,值为 NPC 角色是否开启思考,否则为空字符串
*/
npcEnableThinking
npcEnableThinking,
npcEnableThinkingLabel: "对于 @npc 事件触发的构建,值为 NPC 角色是否开启思考,否则为空字符串"
};
}
@@ -69,349 +75,127 @@ export function useCommentEnv() {
* @description:对于评论事件触发的构建,值为评论全局唯一 ID否则为空字符串
*/
commentId,
commentIdLabel: "对于评论事件触发的构建,值为评论全局唯一 ID否则为空字符串",
/**
* @key CNB_COMMENT_BODY
* @description:对于评论事件触发的构建,值为评论内容,否则为空字符串
*/
commentBody,
commentBodyLabel: "对于评论事件触发的构建,值为评论内容,否则为空字符串",
/**
* @key CNB_COMMENT_TYPE
* @description:note 对于 PR 代码评审评论,值为 diff_note对于 PR 非代码评审评论以及 Issue 评论,值为 note否则为空字符串
*/
commentType,
commentTypeLabel: "对于 PR 代码评审评论,值为 diff_note对于 PR 非代码评审评论以及 Issue 评论,值为 note否则为空字符串",
/**
* @key CNB_COMMENT_FILE_PATH
* @description:对于 PR 代码评审评论,值为评论所在文件,否则为空字符串
*/
commentFilePath,
commentFilePathLabel: "对于 PR 代码评审评论,值为评论所在文件,否则为空字符串",
/**
* @key CNB_COMMENT_RANGE
* @description:对于 PR 代码评审评论,值为评论所在代码行。如,单行为 L12多行为 L13-L16否则为空字符串
*/
commentRange,
commentRangeLabel: "对于 PR 代码评审评论,值为评论所在代码行。如,单行为 L12多行为 L13-L16否则为空字符串",
/**
* @key CNB_REVIEW_ID
* @description:对于 PR 代码评审,值为评审 ID否则为空字符串
*/
reviewId
reviewId,
reviewIdLabel: "对于 PR 代码评审,值为评审 ID否则为空字符串"
};
}
// CNB_BUILD_ID cnb-75b-1jj9hnk99 当前构建的流水号,全局唯一
// CNB_BUILD_WEB_URL https://cnb.cool/kevision/dev-cnb/-/build/logs/cnb-75b-1jj9hnk99 当前构建的日志地址
// CNB_BUILD_START_TIME 2026-03-09T14:59:01.550Z 当前构建的开始时间UTC 格式,示例 2025-08-21T09:13:45.803Z
// CNB_BUILD_USER xiongxiao 当前构建的触发者用户名
// CNB_BUILD_USER_NICKNAME 小熊猫呜呜呜 当前构建的触发者昵称
// CNB_BUILD_USER_EMAIL kevisual@xiongxiao.me 当前构建的触发者邮箱
// CNB_BUILD_USER_ID 1935321989751226368 当前构建的触发者 id
// CNB_BUILD_USER_NPC_SLUG 当前构建若为 NPC 触发,则为 NPC 所属仓库的路径
// CNB_BUILD_USER_NPC_NAME 当前构建若为 NPC 触发,则为 NPC 角色名
// CNB_BUILD_STAGE_NAME 初始化开发机 当前构建的 stage 名称
// CNB_BUILD_JOB_NAME 初始化开发机 当前构建的 job 名称
// CNB_BUILD_JOB_KEY job-0 当前构建的 job key同 stage 下唯一
// CNB_BUILD_WORKSPACE /workspace/ 自定义 shell 脚本执行的工作空间根目录
// CNB_BUILD_FAILED_MSG 流水线构建失败的错误信息,可在 failStages 中使用
// CNB_BUILD_FAILED_STAGE_NAME 流水线构建失败的 stage 的名称,可在 failStages 中使用
// CNB_PIPELINE_NAME pipeline-1 当前 pipeline 的 name没声明时为空
// CNB_PIPELINE_KEY pipeline-1 当前 pipeline 的索引 key例如 pipeline-0
// CNB_PIPELINE_ID cnb-75b-1jj9hnk99-001 当前 pipeline 的 id全局唯一字符串
// CNB_PIPELINE_DOCKER_IMAGE docker.cnb.cool/kevisual/dev-env:latest 当前 pipeline 所使用的 docker imagealpine:latest
// CNB_PIPELINE_STATUS 当前流水线的构建状态,可在 endStages 中查看其可能的值包括success、error、cancel
// CNB_PIPELINE_MAX_RUN_TIME 72000000 流水线最大运行时间,单位为毫秒
// CNB_RUNNER_IP 10.235.16.3 当前 pipeline 所在 Runner 的 ip
// CNB_CPUS 16 当前构建流水线可以使用的最大 CPU 核数
// CNB_MEMORY 32 当前构建流水线可以使用的最大内存大小,单位为 GiB
// CNB_IS_RETRY false 当前构建是否由 rebuild 触发
// HUSKY_SKIP_INSTALL 1 兼容 ci 环境下 husky
export const useBuildEnv = () => {
const buildId = useKey("CNB_BUILD_ID");
const buildWebUrl = useKey("CNB_BUILD_WEB_URL");
const buildStartTime = useKey("CNB_BUILD_START_TIME");
const buildUser = useKey("CNB_BUILD_USER");
const buildUserNickname = useKey("CNB_BUILD_USER_NICKNAME");
const buildUserEmail = useKey("CNB_BUILD_USER_EMAIL");
const buildUserId = useKey("CNB_BUILD_USER_ID");
const buildUserNpcSlug = useKey("CNB_BUILD_USER_NPC_SLUG");
const buildUserNpcName = useKey("CNB_BUILD_USER_NPC_NAME");
const buildStageName = useKey("CNB_BUILD_STAGE_NAME");
const buildJobName = useKey("CNB_BUILD_JOB_NAME");
const buildJobKey = useKey("CNB_BUILD_JOB_KEY");
const buildWorkspace = useKey("CNB_BUILD_WORKSPACE");
const buildFailedMsg = useKey("CNB_BUILD_FAILED_MSG");
const buildFailedStageName = useKey("CNB_BUILD_FAILED_STAGE_NAME");
const pipelineName = useKey("CNB_PIPELINE_NAME");
const pipelineKey = useKey("CNB_PIPELINE_KEY");
const pipelineId = useKey("CNB_PIPELINE_ID");
const pipelineDockerImage = useKey("CNB_PIPELINE_DOCKER_IMAGE");
const pipelineStatus = useKey("CNB_PIPELINE_STATUS");
const pipelineMaxRunTime = useKey("CNB_PIPELINE_MAX_RUN_TIME");
const runnerIp = useKey("CNB_RUNNER_IP");
const cpus = useKey("CNB_CPUS");
const memory = useKey("CNB_MEMORY");
const isRetry = useKey("CNB_IS_RETRY");
const huskySkipInstall = useKey("HUSKY_SKIP_INSTALL");
// CNB_ISSUE_ID Issue 全局唯一 ID
// CNB_ISSUE_IID Issue 仓库编号
// CNB_ISSUE_TITLE Issue 标题
// CNB_ISSUE_DESCRIPTION Issue 描述
// CNB_ISSUE_OWNER Issue 作者
// CNB_ISSUE_STATE Issue 状态
// CNB_ISSUE_IS_RESOLVED Issue 是否已解决
// CNB_ISSUE_ASSIGNEES Issue 处理人列表
// CNB_ISSUE_LABELS Issue 标签列表
// CNB_ISSUE_PRIORITY Issue 优先级
export const useIssueEnv = () => {
const issueId = useKey("CNB_ISSUE_ID");
const issueIid = useKey("CNB_ISSUE_IID");
const issueTitle = useKey("CNB_ISSUE_TITLE");
const issueDescription = useKey("CNB_ISSUE_DESCRIPTION");
const issueOwner = useKey("CNB_ISSUE_OWNER");
const issueState = useKey("CNB_ISSUE_STATE");
const issueIsResolved = useKey("CNB_ISSUE_IS_RESOLVED");
const issueAssignees = useKey("CNB_ISSUE_ASSIGNEES");
const issueLabels = useKey("CNB_ISSUE_LABELS");
const issuePriority = useKey("CNB_ISSUE_PRIORITY");
return {
/**
* @key CNB_BUILD_ID
* @description:当前构建的流水号,全局唯一
* @key CNB_ISSUE_ID
* @description:Issue 全局唯一 ID
*/
buildId,
issueId,
issueIdLabel: "Issue 全局唯一 ID",
/**
* @key CNB_BUILD_WEB_URL
* @description:当前构建的日志地址
* @key CNB_ISSUE_IID
* @description:Issue 仓库编号
*/
buildWebUrl,
issueIid,
issueIidLabel: "Issue 仓库编号",
/**
* @key CNB_BUILD_START_TIME
* @description:当前构建的开始时间UTC 格式
* @key CNB_ISSUE_TITLE
* @description:Issue 标题
*/
buildStartTime,
issueTitle,
issueTitleLabel: "Issue 标题",
/**
* @key CNB_BUILD_USER
* @description:当前构建的触发者用户名
* @key CNB_ISSUE_DESCRIPTION
* @description:Issue 描述
*/
buildUser,
issueDescription,
issueDescriptionLabel: "Issue 描述",
/**
* @key CNB_BUILD_USER_NICKNAME
* @description:当前构建的触发者昵称
* @key CNB_ISSUE_OWNER
* @description:Issue 作者
*/
buildUserNickname,
issueOwner,
issueOwnerLabel: "Issue 作者",
/**
* @key CNB_BUILD_USER_EMAIL
* @description:当前构建的触发者邮箱
* @key CNB_ISSUE_STATE
* @description:Issue 状态
*/
buildUserEmail,
issueState,
issueStateLabel: "Issue 状态",
/**
* @key CNB_BUILD_USER_ID
* @description:当前构建的触发者 id
* @key CNB_ISSUE_IS_RESOLVED
* @description:Issue 是否已解决
*/
buildUserId,
issueIsResolved,
issueIsResolvedLabel: "Issue 是否已解决",
/**
* @key CNB_BUILD_USER_NPC_SLUG
* @description:当前构建若为 NPC 触发,则为 NPC 所属仓库的路径
* @key CNB_ISSUE_ASSIGNEES
* @description:Issue 处理人列表
*/
buildUserNpcSlug,
issueAssignees,
issueAssigneesLabel: "Issue 处理人列表",
/**
* @key CNB_BUILD_USER_NPC_NAME
* @description:当前构建若为 NPC 触发,则为 NPC 角色名
* @key CNB_ISSUE_LABELS
* @description:Issue 标签列表
*/
buildUserNpcName,
issueLabels,
issueLabelsLabel: "Issue 标签列表",
/**
* @key CNB_BUILD_STAGE_NAME
* @description:当前构建的 stage 名称
* @key CNB_ISSUE_PRIORITY
* @description:Issue 优先级
*/
buildStageName,
/**
* @key CNB_BUILD_JOB_NAME
* @description:当前构建的 job 名称
*/
buildJobName,
/**
* @key CNB_BUILD_JOB_KEY
* @description:当前构建的 job key同 stage 下唯一
*/
buildJobKey,
/**
* @key CNB_BUILD_WORKSPACE
* @description:自定义 shell 脚本执行的工作空间根目录
*/
buildWorkspace,
/**
* @key CNB_BUILD_FAILED_MSG
* @description:流水线构建失败的错误信息
*/
buildFailedMsg,
/**
* @key CNB_BUILD_FAILED_STAGE_NAME
* @description:流水线构建失败的 stage 的名称
*/
buildFailedStageName,
/**
* @key CNB_PIPELINE_NAME
* @description:当前 pipeline 的 name
*/
pipelineName,
/**
* @key CNB_PIPELINE_KEY
* @description:当前 pipeline 的索引 key
*/
pipelineKey,
/**
* @key CNB_PIPELINE_ID
* @description:当前 pipeline 的 id
*/
pipelineId,
/**
* @key CNB_PIPELINE_DOCKER_IMAGE
* @description:当前 pipeline 所使用的 docker image
*/
pipelineDockerImage,
/**
* @key CNB_PIPELINE_STATUS
* @description:当前流水线的构建状态可能的值包括success、error、cancel
*/
pipelineStatus,
/**
* @key CNB_PIPELINE_MAX_RUN_TIME
* @description:流水线最大运行时间,单位为毫秒
*/
pipelineMaxRunTime,
/**
* @key CNB_RUNNER_IP
* @description:当前 pipeline 所在 Runner 的 ip
*/
runnerIp,
/**
* @key CNB_CPUS
* @description:当前构建流水线可以使用的最大 CPU 核数
*/
cpus,
/**
* @key CNB_MEMORY
* @description:当前构建流水线可以使用的最大内存大小,单位为 GiB
*/
memory,
/**
* @key CNB_IS_RETRY
* @description:当前构建是否由 rebuild 触发
*/
isRetry,
/**
* @key HUSKY_SKIP_INSTALL
* @description:兼容 ci 环境下 husky
*/
huskySkipInstall
issuePriority,
issuePriorityLabel: "Issue 优先级"
};
}
// CNB_PULL_REQUEST false 对于由 pull_request、pull_request.update、pull_request.target 触发的构建,值为 true否则为 false
// CNB_PULL_REQUEST_LIKE false 对于由 合并类事件 触发的构建,值为 true否则为 false
// CNB_PULL_REQUEST_PROPOSER 对于由 合并类事件 触发的构建,值为提出 PR 者名称,否则为空字符串
// CNB_PULL_REQUEST_TITLE 对于由 合并类事件 触发的构建,值为提 PR 时候填写的标题,否则为空字符串
// CNB_PULL_REQUEST_BRANCH 对于由 合并类事件 触发的构建,值为发起 PR 的源分支名称,否则为空字符串
// CNB_PULL_REQUEST_SHA 对于由 合并类事件 触发的构建,值为当前 PR 源分支最新的提交 sha否则为空字符串
// CNB_PULL_REQUEST_TARGET_SHA 对于由 合并类事件 触发的构建,值为当前 PR 目标分支最新的提交 sha否则为空字符串
// CNB_PULL_REQUEST_MERGE_SHA 对于由 pull_request.merged 触发的构建,值为合并后的 sha对于 pull_request 等触发的构建,值为预合并后的 sha否则为空字符串
// CNB_PULL_REQUEST_SLUG 对于由 合并类事件 触发的构建,值为源仓库的仓库 slug如 group_slug/repo_name否则为空字符串
// CNB_PULL_REQUEST_ACTION 对于由 合并类事件 触发的构建可能的值有created(新建PR)、code_update(源分支push)、status_update(评审通过或CI状态变更),否则为空字符串
// CNB_PULL_REQUEST_ID 对于由 合并类事件 触发的构建,值为当前或者关联 PR 的全局唯一 id否则为空字符串
export const usePullRequestEnv = () => {
const pullRequest = useKey("CNB_PULL_REQUEST");
const pullRequestLike = useKey("CNB_PULL_REQUEST_LIKE");
const pullRequestProposer = useKey("CNB_PULL_REQUEST_PROPOSER");
const pullRequestTitle = useKey("CNB_PULL_REQUEST_TITLE");
const pullRequestBranch = useKey("CNB_PULL_REQUEST_BRANCH");
const pullRequestSha = useKey("CNB_PULL_REQUEST_SHA");
const pullRequestTargetSha = useKey("CNB_PULL_REQUEST_TARGET_SHA");
const pullRequestMergeSha = useKey("CNB_PULL_REQUEST_MERGE_SHA");
const pullRequestSlug = useKey("CNB_PULL_REQUEST_SLUG");
const pullRequestAction = useKey("CNB_PULL_REQUEST_ACTION");
const pullRequestId = useKey("CNB_PULL_REQUEST_ID");
return {
/**
* @key CNB_PULL_REQUEST
* @description:对于由 pull_request、pull_request.update、pull_request.target 触发的构建,值为 true否则为 false
*/
pullRequest,
/**
* @key CNB_PULL_REQUEST_LIKE
* @description:对于由 合并类事件 触发的构建,值为 true否则为 false
*/
pullRequestLike,
/**
* @key CNB_PULL_REQUEST_PROPOSER
* @description:对于由 合并类事件 触发的构建,值为提出 PR 者名称,否则为空字符串
*/
pullRequestProposer,
/**
* @key CNB_PULL_REQUEST_TITLE
* @description:对于由 合并类事件 触发的构建,值为提 PR 时候填写的标题,否则为空字符串
*/
pullRequestTitle,
/**
* @key CNB_PULL_REQUEST_BRANCH
* @description:对于由 合并类事件 触发的构建,值为发起 PR 的源分支名称,否则为空字符串
*/
pullRequestBranch,
/**
* @key CNB_PULL_REQUEST_SHA
* @description:对于由 合并类事件 触发的构建,值为当前 PR 源分支最新的提交 sha否则为空字符串
*/
pullRequestSha,
/**
* @key CNB_PULL_REQUEST_TARGET_SHA
* @description:对于由 合并类事件 触发的构建,值为当前 PR 目标分支最新的提交 sha否则为空字符串
*/
pullRequestTargetSha,
/**
* @key CNB_PULL_REQUEST_MERGE_SHA
* @description:对于由 pull_request.merged 触发的构建,值为合并后的 sha对于 pull_request 等触发的构建,值为预合并后的 sha否则为空字符串
*/
pullRequestMergeSha,
/**
* @key CNB_PULL_REQUEST_SLUG
* @description:对于由 合并类事件 触发的构建,值为源仓库的仓库 slug如 group_slug/repo_name否则为空字符串
*/
pullRequestSlug,
/**
* @key CNB_PULL_REQUEST_ACTION
* @description:对于由 合并类事件 触发的构建可能的值有created(新建PR)、code_update(源分支push)、status_update(评审通过或CI状态变更),否则为空字符串
*/
pullRequestAction,
/**
* @key CNB_PULL_REQUEST_ID
* @description:对于由 合并类事件 触发的构建,值为当前或者关联 PR 的全局唯一 id否则为空字符串
*/
pullRequestId
};
}
// CNB_REPO_SLUG kevision/dev-cnb 目标仓库路径,格式为 group_slug / repo_namegroup_slug / sub_gourp_slug /.../repo_name
// CNB_REPO_SLUG_LOWERCASE kevision/dev-cnb 目标仓库路径小写格式
// CNB_REPO_NAME dev-cnb 目标仓库名称
// CNB_REPO_NAME_LOWERCASE dev-cnb 目标仓库名称小写格式
// CNB_REPO_ID 2026263219584110592 目标仓库的 id
// CNB_REPO_URL_HTTPS 目标仓库 https 地址
export const useRepoInfoEnv = () => {
const repoSlug = useKey("CNB_REPO_SLUG");
const repoSlugLowercase = useKey("CNB_REPO_SLUG_LOWERCASE");
const repoName = useKey("CNB_REPO_NAME");
const repoNameLowercase = useKey("CNB_REPO_NAME_LOWERCASE");
const repoId = useKey("CNB_REPO_ID");
const repoUrlHttps = useKey("CNB_REPO_URL_HTTPS");
return {
/**
* @key CNB_REPO_SLUG
* @description:目标仓库路径,格式为 group_slug/repo_namegroup_slug/sub_group_slug/.../repo_name
*/
repoSlug,
/**
* @key CNB_REPO_SLUG_LOWERCASE
* @description:目标仓库路径小写格式
*/
repoSlugLowercase,
/**
* @key CNB_REPO_NAME
* @description:目标仓库名称
*/
repoName,
/**
* @key CNB_REPO_NAME_LOWERCASE
* @description:目标仓库名称小写格式
*/
repoNameLowercase,
/**
* @key CNB_REPO_ID
* @description:目标仓库的 id
*/
repoId,
/**
* @key CNB_REPO_URL_HTTPS
* @description:目标仓库 https 地址
*/
repoUrlHttps
};
}
export * from './build-env.ts'
export * from './pr-env.ts'
export * from './repo-env.ts'

95
src/issue/npc/pr-env.ts Normal file
View File

@@ -0,0 +1,95 @@
import { useKey } from "@kevisual/context";
// CNB_PULL_REQUEST false 对于由 pull_request、pull_request.update、pull_request.target 触发的构建,值为 true否则为 false
// CNB_PULL_REQUEST_LIKE false 对于由 合并类事件 触发的构建,值为 true否则为 false
// CNB_PULL_REQUEST_PROPOSER 对于由 合并类事件 触发的构建,值为提出 PR 者名称,否则为空字符串
// CNB_PULL_REQUEST_TITLE 对于由 合并类事件 触发的构建,值为提 PR 时候填写的标题,否则为空字符串
// CNB_PULL_REQUEST_BRANCH 对于由 合并类事件 触发的构建,值为发起 PR 的源分支名称,否则为空字符串
// CNB_PULL_REQUEST_SHA 对于由 合并类事件 触发的构建,值为当前 PR 源分支最新的提交 sha否则为空字符串
// CNB_PULL_REQUEST_TARGET_SHA 对于由 合并类事件 触发的构建,值为当前 PR 目标分支最新的提交 sha否则为空字符串
// CNB_PULL_REQUEST_MERGE_SHA 对于由 pull_request.merged 触发的构建,值为合并后的 sha对于 pull_request 等触发的构建,值为预合并后的 sha否则为空字符串
// CNB_PULL_REQUEST_SLUG 对于由 合并类事件 触发的构建,值为源仓库的仓库 slug如 group_slug/repo_name否则为空字符串
// CNB_PULL_REQUEST_ACTION 对于由 合并类事件 触发的构建可能的值有created(新建PR)、code_update(源分支push)、status_update(评审通过或CI状态变更),否则为空字符串
// CNB_PULL_REQUEST_ID 对于由 合并类事件 触发的构建,值为当前或者关联 PR 的全局唯一 id否则为空字符串
export const usePullRequestEnv = () => {
const pullRequest = useKey("CNB_PULL_REQUEST");
const pullRequestLike = useKey("CNB_PULL_REQUEST_LIKE");
const pullRequestProposer = useKey("CNB_PULL_REQUEST_PROPOSER");
const pullRequestTitle = useKey("CNB_PULL_REQUEST_TITLE");
const pullRequestBranch = useKey("CNB_PULL_REQUEST_BRANCH");
const pullRequestSha = useKey("CNB_PULL_REQUEST_SHA");
const pullRequestTargetSha = useKey("CNB_PULL_REQUEST_TARGET_SHA");
const pullRequestMergeSha = useKey("CNB_PULL_REQUEST_MERGE_SHA");
const pullRequestSlug = useKey("CNB_PULL_REQUEST_SLUG");
const pullRequestAction = useKey("CNB_PULL_REQUEST_ACTION");
const pullRequestId = useKey("CNB_PULL_REQUEST_ID");
return {
/**
* @key CNB_PULL_REQUEST
* @description:对于由 pull_request、pull_request.update、pull_request.target 触发的构建,值为 true否则为 false
*/
pullRequest,
pullRequestLabel: "对于由 pull_request、pull_request.update、pull_request.target 触发的构建,值为 true否则为 false",
/**
* @key CNB_PULL_REQUEST_LIKE
* @description:对于由 合并类事件 触发的构建,值为 true否则为 false
*/
pullRequestLike,
pullRequestLikeLabel: "对于由 合并类事件 触发的构建,值为 true否则为 false",
/**
* @key CNB_PULL_REQUEST_PROPOSER
* @description:对于由 合并类事件 触发的构建,值为提出 PR 者名称,否则为空字符串
*/
pullRequestProposer,
pullRequestProposerLabel: "对于由 合并类事件 触发的构建,值为提出 PR 者名称,否则为空字符串",
/**
* @key CNB_PULL_REQUEST_TITLE
* @description:对于由 合并类事件 触发的构建,值为提 PR 时候填写的标题,否则为空字符串
*/
pullRequestTitle,
pullRequestTitleLabel: "对于由 合并类事件 触发的构建,值为提 PR 时候填写的标题,否则为空字符串",
/**
* @key CNB_PULL_REQUEST_BRANCH
* @description:对于由 合并类事件 触发的构建,值为发起 PR 的源分支名称,否则为空字符串
*/
pullRequestBranch,
pullRequestBranchLabel: "对于由 合并类事件 触发的构建,值为发起 PR 的源分支名称,否则为空字符串",
/**
* @key CNB_PULL_REQUEST_SHA
* @description:对于由 合并类事件 触发的构建,值为当前 PR 源分支最新的提交 sha否则为空字符串
*/
pullRequestSha,
pullRequestShaLabel: "对于由 合并类事件 触发的构建,值为当前 PR 源分支最新的提交 sha否则为空字符串",
/**
* @key CNB_PULL_REQUEST_TARGET_SHA
* @description:对于由 合并类事件 触发的构建,值为当前 PR 目标分支最新的提交 sha否则为空字符串
*/
pullRequestTargetSha,
pullRequestTargetShaLabel: "对于由 合并类事件 触发的构建,值为当前 PR 目标分支最新的提交 sha否则为空字符串",
/**
* @key CNB_PULL_REQUEST_MERGE_SHA
* @description:对于由 pull_request.merged 触发的构建,值为合并后的 sha对于 pull_request 等触发的构建,值为预合并后的 sha否则为空字符串
*/
pullRequestMergeSha,
pullRequestMergeShaLabel: "对于由 pull_request.merged 触发的构建,值为合并后的 sha对于 pull_request 等触发的构建,值为预合并后的 sha否则为空字符串",
/**
* @key CNB_PULL_REQUEST_SLUG
* @description:对于由 合并类事件 触发的构建,值为源仓库的仓库 slug如 group_slug/repo_name否则为空字符串
*/
pullRequestSlug,
pullRequestSlugLabel: "对于由 合并类事件 触发的构建,值为源仓库的仓库 slug如 group_slug/repo_name否则为空字符串",
/**
* @key CNB_PULL_REQUEST_ACTION
* @description:对于由 合并类事件 触发的构建可能的值有created(新建PR)、code_update(源分支push)、status_update(评审通过或CI状态变更),否则为空字符串
*/
pullRequestAction,
pullRequestActionLabel: "对于由 合并类事件 触发的构建可能的值有created(新建PR)、code_update(源分支push)、status_update(评审通过或CI状态变更),否则为空字符串",
/**
* @key CNB_PULL_REQUEST_ID
* @description:对于由 合并类事件 触发的构建,值为当前或者关联 PR 的全局唯一 id否则为空字符串
*/
pullRequestId,
pullRequestIdLabel: "对于由 合并类事件 触发的构建,值为当前或者关联 PR 的全局唯一 id否则为空字符串"
};
}

56
src/issue/npc/repo-env.ts Normal file
View File

@@ -0,0 +1,56 @@
import { useKey } from "@kevisual/context";
// CNB_REPO_SLUG kevision/dev-cnb 目标仓库路径,格式为 group_slug / repo_namegroup_slug / sub_gourp_slug /.../repo_name
// CNB_REPO_SLUG_LOWERCASE kevision/dev-cnb 目标仓库路径小写格式
// CNB_REPO_NAME dev-cnb 目标仓库名称
// CNB_REPO_NAME_LOWERCASE dev-cnb 目标仓库名称小写格式
// CNB_REPO_ID 2026263219584110592 目标仓库的 id
// CNB_REPO_URL_HTTPS 目标仓库 https 地址
export const useRepoInfoEnv = () => {
const repoSlug = useKey("CNB_REPO_SLUG");
const repoSlugLowercase = useKey("CNB_REPO_SLUG_LOWERCASE");
const repoName = useKey("CNB_REPO_NAME");
const repoNameLowercase = useKey("CNB_REPO_NAME_LOWERCASE");
const repoId = useKey("CNB_REPO_ID");
const repoUrlHttps = useKey("CNB_REPO_URL_HTTPS");
return {
/**
* @key CNB_REPO_SLUG
* @description:目标仓库路径,格式为 group_slug/repo_namegroup_slug/sub_group_slug/.../repo_name
*/
repoSlug,
repoSlugLabel: "目标仓库路径,格式为 group_slug/repo_namegroup_slug/sub_group_slug/.../repo_name",
/**
* @key CNB_REPO_SLUG_LOWERCASE
* @description:目标仓库路径小写格式
*/
repoSlugLowercase,
repoSlugLowercaseLabel: "目标仓库路径小写格式",
/**
* @key CNB_REPO_NAME
* @description:目标仓库名称
*/
repoName,
repoNameLabel: "目标仓库名称",
/**
* @key CNB_REPO_NAME_LOWERCASE
* @description:目标仓库名称小写格式
*/
repoNameLowercase,
repoNameLowercaseLabel: "目标仓库名称小写格式",
/**
* @key CNB_REPO_ID
* @description:目标仓库的 id
*/
repoId,
repoIdLabel: "目标仓库的 id",
/**
* @key CNB_REPO_URL_HTTPS
* @description:目标仓库 https 地址
*/
repoUrlHttps,
repoUrlHttpsLabel: "目标仓库 https 地址"
};
}