fix: 修复NapCat自动流水线闭环
This commit is contained in:
parent
9eae9cc9a0
commit
65807e8ef3
@ -1,5 +1,5 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent { label 'kt-node-agent' }
|
||||||
|
|
||||||
options {
|
options {
|
||||||
buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '30'))
|
buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '30'))
|
||||||
@ -25,6 +25,7 @@ pipeline {
|
|||||||
KT_WORKSPACE_ROOT = '/vol1/docker/kt-codex/workspace/KT'
|
KT_WORKSPACE_ROOT = '/vol1/docker/kt-codex/workspace/KT'
|
||||||
KT_WORKFLOW_DIR = '/vol1/docker/kt-codex/workspace/KT/mcp/ktWorkflow'
|
KT_WORKFLOW_DIR = '/vol1/docker/kt-codex/workspace/KT/mcp/ktWorkflow'
|
||||||
KT_ARTIFACT_ROOT = '/vol1/docker/kt-codex/artifacts'
|
KT_ARTIFACT_ROOT = '/vol1/docker/kt-codex/artifacts'
|
||||||
|
KT_WORKFLOW_RUNNER_IMAGE = 'kt-jenkins-node-agent:current'
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@ -32,12 +33,26 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
set -e
|
set -e
|
||||||
|
docker run --rm \
|
||||||
|
-e KT_WORKFLOW_DIR="$KT_WORKFLOW_DIR" \
|
||||||
|
-e KT_ARTIFACT_ROOT="$KT_ARTIFACT_ROOT" \
|
||||||
|
-e NAPCAT_FORK_REF="$NAPCAT_FORK_REF" \
|
||||||
|
-e UPSTREAM_RELEASE_TAG="$UPSTREAM_RELEASE_TAG" \
|
||||||
|
-e QQBOT_NAPCAT_IMAGE_OVERRIDE="$QQBOT_NAPCAT_IMAGE_OVERRIDE" \
|
||||||
|
-e QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE="$QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE" \
|
||||||
|
-e COREPACK_HOME=/vol1/docker/kt-codex/runtime/corepack \
|
||||||
|
-v /vol1/docker/kt-codex:/vol1/docker/kt-codex \
|
||||||
|
--entrypoint bash "$KT_WORKFLOW_RUNNER_IMAGE" -lc '
|
||||||
|
set -e
|
||||||
|
source /vol1/docker/kt-codex/runtime/nvm/nvm.sh
|
||||||
|
corepack prepare pnpm@10.28.2 --activate
|
||||||
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-runtime-release-readiness -- \
|
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-runtime-release-readiness -- \
|
||||||
--artifact-root "$KT_ARTIFACT_ROOT/napcat-runtime-release" \
|
--artifact-root "$KT_ARTIFACT_ROOT/napcat-runtime-release" \
|
||||||
--fork-branch "$NAPCAT_FORK_REF" \
|
--fork-branch "$NAPCAT_FORK_REF" \
|
||||||
--upstream-release-tag "$UPSTREAM_RELEASE_TAG" \
|
--upstream-release-tag "$UPSTREAM_RELEASE_TAG" \
|
||||||
--napcat-image-tag "$QQBOT_NAPCAT_IMAGE_OVERRIDE" \
|
--napcat-image-tag "$QQBOT_NAPCAT_IMAGE_OVERRIDE" \
|
||||||
--profile "$QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE"
|
--profile "$QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE"
|
||||||
|
'
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,12 +107,20 @@ pipeline {
|
|||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
sh '''
|
sh '''
|
||||||
|
set +e
|
||||||
|
docker run --rm \
|
||||||
|
-e KT_ARTIFACT_ROOT="$KT_ARTIFACT_ROOT" \
|
||||||
|
-e WORKSPACE="$WORKSPACE" \
|
||||||
|
-v /vol1/docker/kt-codex:/vol1/docker/kt-codex \
|
||||||
|
-v kt-node-agent-workdir:/home/jenkins/agent \
|
||||||
|
--entrypoint bash "$KT_WORKFLOW_RUNNER_IMAGE" -lc '
|
||||||
set +e
|
set +e
|
||||||
rm -rf "$WORKSPACE/artifacts"
|
rm -rf "$WORKSPACE/artifacts"
|
||||||
mkdir -p "$WORKSPACE/artifacts/napcat-runtime-release"
|
mkdir -p "$WORKSPACE/artifacts/napcat-runtime-release"
|
||||||
cp -a "$KT_ARTIFACT_ROOT/napcat-runtime-release/." "$WORKSPACE/artifacts/napcat-runtime-release/" 2>/dev/null || true
|
cp -a "$KT_ARTIFACT_ROOT/napcat-runtime-release/." "$WORKSPACE/artifacts/napcat-runtime-release/" 2>/dev/null || true
|
||||||
|
'
|
||||||
'''
|
'''
|
||||||
archiveArtifacts artifacts: 'artifacts/napcat-runtime-release/**/*', allowEmptyArchive: true, fingerprint: false
|
archiveArtifacts artifacts: 'artifacts/napcat-runtime-release/**', allowEmptyArchive: true, fingerprint: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent { label 'kt-node-agent' }
|
||||||
|
|
||||||
options {
|
options {
|
||||||
buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '30'))
|
buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '30'))
|
||||||
@ -17,6 +17,7 @@ pipeline {
|
|||||||
environment {
|
environment {
|
||||||
KT_WORKFLOW_DIR = '/vol1/docker/kt-codex/workspace/KT/mcp/ktWorkflow'
|
KT_WORKFLOW_DIR = '/vol1/docker/kt-codex/workspace/KT/mcp/ktWorkflow'
|
||||||
KT_ARTIFACT_ROOT = '/vol1/docker/kt-codex/artifacts'
|
KT_ARTIFACT_ROOT = '/vol1/docker/kt-codex/artifacts'
|
||||||
|
KT_WORKFLOW_RUNNER_IMAGE = 'kt-jenkins-node-agent:current'
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@ -24,8 +25,19 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
set -e
|
set -e
|
||||||
|
docker run --rm \
|
||||||
|
-e KT_WORKFLOW_DIR="$KT_WORKFLOW_DIR" \
|
||||||
|
-e KT_ARTIFACT_ROOT="$KT_ARTIFACT_ROOT" \
|
||||||
|
-e CODEX_HOME=/vol1/docker/kt-codex/home/.codex \
|
||||||
|
-e COREPACK_HOME=/vol1/docker/kt-codex/runtime/corepack \
|
||||||
|
-v /vol1/docker/kt-codex:/vol1/docker/kt-codex \
|
||||||
|
--entrypoint bash "$KT_WORKFLOW_RUNNER_IMAGE" -lc '
|
||||||
|
set -e
|
||||||
|
source /vol1/docker/kt-codex/runtime/nvm/nvm.sh
|
||||||
|
corepack prepare pnpm@10.28.2 --activate
|
||||||
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-upstream-audit -- \
|
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-upstream-audit -- \
|
||||||
--artifact-root "$KT_ARTIFACT_ROOT/napcat-upstream-sync/dry-run"
|
--artifact-root "$KT_ARTIFACT_ROOT/napcat-upstream-sync/dry-run"
|
||||||
|
'
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,10 +54,21 @@ pipeline {
|
|||||||
}
|
}
|
||||||
sh '''
|
sh '''
|
||||||
set -e
|
set -e
|
||||||
|
docker run --rm \
|
||||||
|
-e KT_WORKFLOW_DIR="$KT_WORKFLOW_DIR" \
|
||||||
|
-e KT_ARTIFACT_ROOT="$KT_ARTIFACT_ROOT" \
|
||||||
|
-e CODEX_HOME=/vol1/docker/kt-codex/home/.codex \
|
||||||
|
-e COREPACK_HOME=/vol1/docker/kt-codex/runtime/corepack \
|
||||||
|
-v /vol1/docker/kt-codex:/vol1/docker/kt-codex \
|
||||||
|
--entrypoint bash "$KT_WORKFLOW_RUNNER_IMAGE" -lc '
|
||||||
|
set -e
|
||||||
|
source /vol1/docker/kt-codex/runtime/nvm/nvm.sh
|
||||||
|
corepack prepare pnpm@10.28.2 --activate
|
||||||
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-upstream-audit -- \
|
pnpm --dir "$KT_WORKFLOW_DIR" run napcat-upstream-audit -- \
|
||||||
--execute \
|
--execute \
|
||||||
--use-codex \
|
--use-codex \
|
||||||
--artifact-root "$KT_ARTIFACT_ROOT/napcat-upstream-sync/codex"
|
--artifact-root "$KT_ARTIFACT_ROOT/napcat-upstream-sync/codex"
|
||||||
|
'
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,12 +77,20 @@ pipeline {
|
|||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
sh '''
|
sh '''
|
||||||
|
set +e
|
||||||
|
docker run --rm \
|
||||||
|
-e KT_ARTIFACT_ROOT="$KT_ARTIFACT_ROOT" \
|
||||||
|
-e WORKSPACE="$WORKSPACE" \
|
||||||
|
-v /vol1/docker/kt-codex:/vol1/docker/kt-codex \
|
||||||
|
-v kt-node-agent-workdir:/home/jenkins/agent \
|
||||||
|
--entrypoint bash "$KT_WORKFLOW_RUNNER_IMAGE" -lc '
|
||||||
set +e
|
set +e
|
||||||
rm -rf "$WORKSPACE/artifacts"
|
rm -rf "$WORKSPACE/artifacts"
|
||||||
mkdir -p "$WORKSPACE/artifacts/napcat-upstream-sync"
|
mkdir -p "$WORKSPACE/artifacts/napcat-upstream-sync"
|
||||||
cp -a "$KT_ARTIFACT_ROOT/napcat-upstream-sync/." "$WORKSPACE/artifacts/napcat-upstream-sync/" 2>/dev/null || true
|
cp -a "$KT_ARTIFACT_ROOT/napcat-upstream-sync/." "$WORKSPACE/artifacts/napcat-upstream-sync/" 2>/dev/null || true
|
||||||
|
'
|
||||||
'''
|
'''
|
||||||
archiveArtifacts artifacts: 'artifacts/napcat-upstream-sync/**/*', allowEmptyArchive: true, fingerprint: false
|
archiveArtifacts artifacts: 'artifacts/napcat-upstream-sync/**', allowEmptyArchive: true, fingerprint: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,7 @@ import {
|
|||||||
buildNasCodexBootstrapPlan,
|
buildNasCodexBootstrapPlan,
|
||||||
classifyNapcatUpstreamAudit,
|
classifyNapcatUpstreamAudit,
|
||||||
napcatAutomationDefaults,
|
napcatAutomationDefaults,
|
||||||
|
shouldFailNapcatAutomationCli,
|
||||||
} from "./tools/napcatAutomation.js";
|
} from "./tools/napcatAutomation.js";
|
||||||
import { registerTools } from "./registerTools.js";
|
import { registerTools } from "./registerTools.js";
|
||||||
import {
|
import {
|
||||||
@ -119,6 +120,22 @@ export async function runSelfTest(): Promise<void> {
|
|||||||
if (!napcatCli.execute || !napcatCli.useCodex) {
|
if (!napcatCli.execute || !napcatCli.useCodex) {
|
||||||
throw new Error("NapCat upstream audit CLI parser self-check failed");
|
throw new Error("NapCat upstream audit CLI parser self-check failed");
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
!shouldFailNapcatAutomationCli({
|
||||||
|
classification: "blocked",
|
||||||
|
recommendedAction: "block",
|
||||||
|
}) ||
|
||||||
|
shouldFailNapcatAutomationCli({
|
||||||
|
classification: "manual-review",
|
||||||
|
recommendedAction: "request-human-review",
|
||||||
|
}) ||
|
||||||
|
shouldFailNapcatAutomationCli({
|
||||||
|
classification: "safe-candidate",
|
||||||
|
recommendedAction: "create-candidate-branch",
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
throw new Error("NapCat automation CLI blocked gate self-check failed");
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
napcatCli.artifactRoot !==
|
napcatCli.artifactRoot !==
|
||||||
"/vol1/docker/kt-codex/artifacts/napcat-upstream-sync"
|
"/vol1/docker/kt-codex/artifacts/napcat-upstream-sync"
|
||||||
@ -154,9 +171,17 @@ export async function runSelfTest(): Promise<void> {
|
|||||||
throw new Error("NapCat auxiliary CLI dry-run default self-check failed");
|
throw new Error("NapCat auxiliary CLI dry-run default self-check failed");
|
||||||
}
|
}
|
||||||
const napcatCandidateDefaults = buildNapcatSyncCandidateReview({}).context;
|
const napcatCandidateDefaults = buildNapcatSyncCandidateReview({}).context;
|
||||||
const napcatRuntimeDefaults = buildNapcatRuntimeReleaseReadiness({}).context;
|
const napcatRuntimeReadinessDefaults = buildNapcatRuntimeReleaseReadiness({});
|
||||||
|
const napcatRuntimeDefaults = napcatRuntimeReadinessDefaults.context;
|
||||||
const napcatRemoteDefaults = buildNapcatRemoteDevHandoff({}).context;
|
const napcatRemoteDefaults = buildNapcatRemoteDevHandoff({}).context;
|
||||||
const nasBootstrapDefaults = buildNasCodexBootstrapPlan({}).context;
|
const nasBootstrapDefaults = buildNasCodexBootstrapPlan({}).context;
|
||||||
|
for (const artifact of napcatRuntimeReadinessDefaults.artifacts) {
|
||||||
|
if (!existsSync(artifact.path)) {
|
||||||
|
throw new Error(
|
||||||
|
`NapCat runtime readiness artifact write self-check failed: ${artifact.path}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
napcatCandidateDefaults.candidateBranch !==
|
napcatCandidateDefaults.candidateBranch !==
|
||||||
napcatAutomationDefaults.candidateBranch ||
|
napcatAutomationDefaults.candidateBranch ||
|
||||||
@ -477,7 +502,7 @@ export async function runSelfTest(): Promise<void> {
|
|||||||
"RUN_CODEX_WORKSPACE_WRITE_AUDIT",
|
"RUN_CODEX_WORKSPACE_WRITE_AUDIT",
|
||||||
"buildDiscarder(logRotator",
|
"buildDiscarder(logRotator",
|
||||||
"disableConcurrentBuilds()",
|
"disableConcurrentBuilds()",
|
||||||
"archiveArtifacts artifacts: 'artifacts/napcat-upstream-sync/**/*'",
|
"archiveArtifacts artifacts: 'artifacts/napcat-upstream-sync/**'",
|
||||||
]) {
|
]) {
|
||||||
if (!upstreamSyncJenkinsTemplate.includes(expected)) {
|
if (!upstreamSyncJenkinsTemplate.includes(expected)) {
|
||||||
throw new Error(`NapCat upstream Jenkins template missing: ${expected}`);
|
throw new Error(`NapCat upstream Jenkins template missing: ${expected}`);
|
||||||
@ -549,6 +574,62 @@ export async function runSelfTest(): Promise<void> {
|
|||||||
"NapCat upstream Jenkins template unsafe default audit self-check failed",
|
"NapCat upstream Jenkins template unsafe default audit self-check failed",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Verifies that a NapCat Jenkins template targets the NAS Jenkins node that can run shell work.
|
||||||
|
* @param template - Full Jenkinsfile text that Jenkins will execute.
|
||||||
|
* @param name - Human-readable template name for the self-test failure.
|
||||||
|
* @returns Nothing; throws when the template can stay queued on the exclusive agent topology.
|
||||||
|
*/
|
||||||
|
const assertNapCatJenkinsUsesNasAgent = (
|
||||||
|
template: string,
|
||||||
|
name: string,
|
||||||
|
): void => {
|
||||||
|
if (!template.includes("agent { label 'kt-node-agent' }")) {
|
||||||
|
throw new Error(
|
||||||
|
`${name} Jenkins template must target kt-node-agent instead of agent any`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assertNapCatJenkinsUsesNasAgent(
|
||||||
|
upstreamSyncJenkinsTemplate,
|
||||||
|
"NapCat upstream",
|
||||||
|
);
|
||||||
|
assertNapCatJenkinsUsesNasAgent(
|
||||||
|
runtimeReleaseJenkinsTemplate,
|
||||||
|
"NapCat runtime",
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Verifies that a NapCat Jenkins template runs ktWorkflow inside a helper container with NAS mounts.
|
||||||
|
* @param template - Full Jenkinsfile text that Jenkins will execute.
|
||||||
|
* @param name - Human-readable template name for the self-test failure.
|
||||||
|
* @returns Nothing; throws when the template assumes `/vol1` exists inside `kt-node-agent`.
|
||||||
|
*/
|
||||||
|
const assertNapCatJenkinsUsesWorkflowRunner = (
|
||||||
|
template: string,
|
||||||
|
name: string,
|
||||||
|
): void => {
|
||||||
|
for (const expected of [
|
||||||
|
"KT_WORKFLOW_RUNNER_IMAGE",
|
||||||
|
"docker run --rm",
|
||||||
|
"/vol1/docker/kt-codex:/vol1/docker/kt-codex",
|
||||||
|
"COREPACK_HOME=/vol1/docker/kt-codex/runtime/corepack",
|
||||||
|
"corepack prepare pnpm@10.28.2 --activate",
|
||||||
|
]) {
|
||||||
|
if (!template.includes(expected)) {
|
||||||
|
throw new Error(
|
||||||
|
`${name} Jenkins template must run ktWorkflow through the NAS helper container: ${expected}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assertNapCatJenkinsUsesWorkflowRunner(
|
||||||
|
upstreamSyncJenkinsTemplate,
|
||||||
|
"NapCat upstream",
|
||||||
|
);
|
||||||
|
assertNapCatJenkinsUsesWorkflowRunner(
|
||||||
|
runtimeReleaseJenkinsTemplate,
|
||||||
|
"NapCat runtime",
|
||||||
|
);
|
||||||
for (const forbidden of ["git merge", "git push", "docker build", "kubectl"]) {
|
for (const forbidden of ["git merge", "git push", "docker build", "kubectl"]) {
|
||||||
if (upstreamSyncJenkinsTemplate.includes(forbidden)) {
|
if (upstreamSyncJenkinsTemplate.includes(forbidden)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -563,7 +644,7 @@ export async function runSelfTest(): Promise<void> {
|
|||||||
"PROMOTE_KT_TEMPLATE_API_MAIN",
|
"PROMOTE_KT_TEMPLATE_API_MAIN",
|
||||||
"buildDiscarder(logRotator",
|
"buildDiscarder(logRotator",
|
||||||
"disableConcurrentBuilds()",
|
"disableConcurrentBuilds()",
|
||||||
"archiveArtifacts artifacts: 'artifacts/napcat-runtime-release/**/*'",
|
"archiveArtifacts artifacts: 'artifacts/napcat-runtime-release/**'",
|
||||||
]) {
|
]) {
|
||||||
if (!runtimeReleaseJenkinsTemplate.includes(expected)) {
|
if (!runtimeReleaseJenkinsTemplate.includes(expected)) {
|
||||||
throw new Error(`NapCat runtime Jenkins template missing: ${expected}`);
|
throw new Error(`NapCat runtime Jenkins template missing: ${expected}`);
|
||||||
|
|||||||
@ -29,8 +29,24 @@ import {
|
|||||||
buildNapcatSyncCandidateReview,
|
buildNapcatSyncCandidateReview,
|
||||||
buildNapcatUpstreamAudit,
|
buildNapcatUpstreamAudit,
|
||||||
buildNasCodexBootstrapPlan,
|
buildNasCodexBootstrapPlan,
|
||||||
|
shouldFailNapcatAutomationCli,
|
||||||
} from './tools/napcatAutomation.js';
|
} from './tools/napcatAutomation.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a NapCat automation result and turns blocked classifications into a failing CLI exit code.
|
||||||
|
* @param result - Structured NapCat automation result that must remain visible on stdout for Jenkins artifacts and manual diagnostics.
|
||||||
|
* @returns Nothing; writes JSON evidence and mutates `process.exitCode` when the result blocks safe continuation.
|
||||||
|
*/
|
||||||
|
function printNapcatAutomationCliResult(result: {
|
||||||
|
classification?: unknown;
|
||||||
|
recommendedAction?: unknown;
|
||||||
|
}): void {
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
if (shouldFailNapcatAutomationCli(result)) {
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (process.argv.includes('--cleanup-history')) {
|
if (process.argv.includes('--cleanup-history')) {
|
||||||
console.log(JSON.stringify(cleanupHistoryArtifacts(parseCliCleanupArgs(process.argv)), null, 2));
|
console.log(JSON.stringify(cleanupHistoryArtifacts(parseCliCleanupArgs(process.argv)), null, 2));
|
||||||
} else if (process.argv.includes('--global-review')) {
|
} else if (process.argv.includes('--global-review')) {
|
||||||
@ -56,8 +72,8 @@ if (process.argv.includes('--cleanup-history')) {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (process.argv.includes('--napcat-upstream-audit')) {
|
} else if (process.argv.includes('--napcat-upstream-audit')) {
|
||||||
console.log(
|
printNapcatAutomationCliResult(
|
||||||
JSON.stringify(buildNapcatUpstreamAudit(parseNapcatUpstreamAuditCliArgs(process.argv)), null, 2),
|
buildNapcatUpstreamAudit(parseNapcatUpstreamAuditCliArgs(process.argv)),
|
||||||
);
|
);
|
||||||
} else if (process.argv.includes('--napcat-sync-candidate-review')) {
|
} else if (process.argv.includes('--napcat-sync-candidate-review')) {
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@ -117,6 +117,18 @@ export const napcatAutomationDefaults = {
|
|||||||
workspaceRoot: '/vol1/docker/kt-codex/workspace/KT',
|
workspaceRoot: '/vol1/docker/kt-codex/workspace/KT',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides whether a NapCat automation CLI invocation must fail the hosting pipeline after printing JSON evidence.
|
||||||
|
* @param result - Structured ktWorkflow result from a NapCat automation command; only terminal block states represent infrastructure or safety failures.
|
||||||
|
* @returns True when Jenkins or another CLI caller must stop the pipeline instead of showing a green build with blocked evidence.
|
||||||
|
*/
|
||||||
|
export function shouldFailNapcatAutomationCli(result: {
|
||||||
|
classification?: unknown;
|
||||||
|
recommendedAction?: unknown;
|
||||||
|
}): boolean {
|
||||||
|
return result.classification === 'blocked' || result.recommendedAction === 'block';
|
||||||
|
}
|
||||||
|
|
||||||
interface NapcatPromptSkeletonConfig {
|
interface NapcatPromptSkeletonConfig {
|
||||||
artifactSlug: string;
|
artifactSlug: string;
|
||||||
commands: NapcatAuditCommand[];
|
commands: NapcatAuditCommand[];
|
||||||
@ -144,9 +156,9 @@ function resolveNapcatSkeletonArtifactRoot(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a deterministic dry-run prompt skeleton for Task 5 NapCat automation tools that are not allowed to mutate state yet.
|
* Builds a deterministic dry-run prompt skeleton for Task 5 NapCat automation tools that are not allowed to mutate release state yet.
|
||||||
* @param config - Prompt name, context payload, read-only command hints, and caller execution intent.
|
* @param config - Prompt name, context payload, read-only command hints, and caller execution intent.
|
||||||
* @returns A structured prompt/context/command package that never runs Codex or mutating release commands.
|
* @returns A structured prompt/context/command package; writes prompt and context artifacts for Jenkins archiving but never runs Codex or release mutation commands.
|
||||||
*/
|
*/
|
||||||
function buildNapcatPromptSkeleton(config: NapcatPromptSkeletonConfig) {
|
function buildNapcatPromptSkeleton(config: NapcatPromptSkeletonConfig) {
|
||||||
const artifactRoot = resolveNapcatSkeletonArtifactRoot(
|
const artifactRoot = resolveNapcatSkeletonArtifactRoot(
|
||||||
@ -154,21 +166,32 @@ function buildNapcatPromptSkeleton(config: NapcatPromptSkeletonConfig) {
|
|||||||
config.artifactSlug,
|
config.artifactSlug,
|
||||||
);
|
);
|
||||||
const requestedExecute = config.input.execute === true;
|
const requestedExecute = config.input.execute === true;
|
||||||
|
const promptText = loadNapcatAutomationPrompt(config.promptName).trim();
|
||||||
|
const promptPath = joinNapcatArtifactPath(
|
||||||
|
artifactRoot,
|
||||||
|
`${config.artifactSlug}-prompt.md`,
|
||||||
|
);
|
||||||
|
const contextPath = joinNapcatArtifactPath(
|
||||||
|
artifactRoot,
|
||||||
|
`${config.artifactSlug}-context.json`,
|
||||||
|
);
|
||||||
|
|
||||||
|
mkdirSync(artifactRoot, { recursive: true });
|
||||||
|
writeFileSync(promptPath, promptText, 'utf8');
|
||||||
|
writeFileSync(
|
||||||
|
contextPath,
|
||||||
|
JSON.stringify(config.context, null, 2),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
artifacts: [
|
artifacts: [
|
||||||
{
|
{
|
||||||
path: joinNapcatArtifactPath(
|
path: promptPath,
|
||||||
artifactRoot,
|
|
||||||
`${config.artifactSlug}-prompt.md`,
|
|
||||||
),
|
|
||||||
type: 'markdown',
|
type: 'markdown',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: joinNapcatArtifactPath(
|
path: contextPath,
|
||||||
artifactRoot,
|
|
||||||
`${config.artifactSlug}-context.json`,
|
|
||||||
),
|
|
||||||
type: 'json',
|
type: 'json',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -184,7 +207,7 @@ function buildNapcatPromptSkeleton(config: NapcatPromptSkeletonConfig) {
|
|||||||
],
|
],
|
||||||
prompt: {
|
prompt: {
|
||||||
name: config.promptName,
|
name: config.promptName,
|
||||||
text: loadNapcatAutomationPrompt(config.promptName).trim(),
|
text: promptText,
|
||||||
},
|
},
|
||||||
requestedExecute,
|
requestedExecute,
|
||||||
summary: `${config.title} dry-run prompt skeleton generated.`,
|
summary: `${config.title} dry-run prompt skeleton generated.`,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user