pipeline { agent { label 'kt-node-agent' } options { buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '30')) disableConcurrentBuilds() skipDefaultCheckout(true) timestamps() timeout(time: 60, unit: 'MINUTES') } parameters { string(name: 'NAPCAT_FORK_REF', defaultValue: 'main', description: 'Reviewed NapCatQQ fork branch, tag, or commit.') string(name: 'UPSTREAM_RELEASE_TAG', defaultValue: '', description: 'Reviewed upstream release tag, when applicable.') string(name: 'UPSTREAM_RELEASE_COMMIT', defaultValue: '5c18a62530d87dbadf53d267002894faa6ca7e90', description: 'Reviewed upstream release commit used for runtime marker metadata.') string(name: 'NAPCAT_BASE_IMAGE_DIGEST', defaultValue: 'mlikiowa/napcat-docker@sha256:9254ec12af101576c5eeb4910847abd1d219297bc6d9a35c52511e12500f0f45', description: 'Immutable NapCat base image digest used by the runtime image build.') string(name: 'QQBOT_NAPCAT_IMAGE_OVERRIDE', defaultValue: '', description: 'Explicit runtime image tag to build or promote, for example kt-napcat-desktop-cn:desktop-cn-v9.') string(name: 'QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE', defaultValue: '', description: 'Explicit API desktop profile version override.') booleanParam(name: 'BUILD_RUNTIME_IMAGE', defaultValue: false, description: 'When true, trigger the reviewed Jenkins runtime image build/publish job.') choice(name: 'RUNTIME_BUILD_JOB', choices: ['KT-NapCatQQ/Runtime-Image-Build'], description: 'Whitelisted Jenkins job that performs the reviewed runtime image build and publish.') booleanParam(name: 'PROMOTE_API_RUNTIME', defaultValue: false, description: 'When true, trigger API promotion with explicit image/profile overrides.') choice(name: 'API_PROMOTION_JOB', choices: ['KT-Template/KT-Template-API/main'], description: 'Whitelisted API Jenkins job that accepts NapCat runtime override parameters.') string(name: 'CONFIRM_API_PROMOTION_TARGET', defaultValue: '', description: 'Type PROMOTE_KT_TEMPLATE_API_MAIN before triggering the production API promotion job.') } environment { KT_WORKSPACE_ROOT = '/vol1/docker/kt-codex/workspace/KT' KT_WORKFLOW_DIR = '/vol1/docker/kt-codex/workspace/KT/mcp/ktWorkflow' KT_ARTIFACT_ROOT = '/vol1/docker/kt-codex/artifacts' KT_WORKFLOW_RUNNER_IMAGE = 'kt-jenkins-node-agent:current' } stages { stage('ktWorkflow readiness') { steps { sh ''' 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 UPSTREAM_RELEASE_COMMIT="$UPSTREAM_RELEASE_COMMIT" \ -e NAPCAT_BASE_IMAGE_DIGEST="$NAPCAT_BASE_IMAGE_DIGEST" \ -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 -- \ --artifact-root "$KT_ARTIFACT_ROOT/napcat-runtime-release" \ --fork-branch "$NAPCAT_FORK_REF" \ --upstream-release-tag "$UPSTREAM_RELEASE_TAG" \ --napcat-image-tag "$QQBOT_NAPCAT_IMAGE_OVERRIDE" \ --profile "$QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE" ' ''' } } stage('Runtime image build and publish') { when { expression { return params.BUILD_RUNTIME_IMAGE } } steps { script { requireRuntimeOverrides( params.QQBOT_NAPCAT_IMAGE_OVERRIDE, params.QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE ) build job: params.RUNTIME_BUILD_JOB, wait: true, parameters: [ string(name: 'NAPCAT_FORK_REF', value: params.NAPCAT_FORK_REF), string(name: 'UPSTREAM_RELEASE_TAG', value: params.UPSTREAM_RELEASE_TAG), string(name: 'UPSTREAM_RELEASE_COMMIT', value: params.UPSTREAM_RELEASE_COMMIT), string(name: 'NAPCAT_BASE_IMAGE_DIGEST', value: params.NAPCAT_BASE_IMAGE_DIGEST), string(name: 'QQBOT_NAPCAT_IMAGE_OVERRIDE', value: params.QQBOT_NAPCAT_IMAGE_OVERRIDE), string(name: 'QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE', value: params.QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE), string(name: 'KT_ARTIFACT_ROOT', value: "${env.KT_ARTIFACT_ROOT}/napcat-runtime-release") ] } } } stage('API promotion') { when { expression { return params.PROMOTE_API_RUNTIME } } steps { script { if (params.CONFIRM_API_PROMOTION_TARGET != 'PROMOTE_KT_TEMPLATE_API_MAIN') { error('CONFIRM_API_PROMOTION_TARGET must equal PROMOTE_KT_TEMPLATE_API_MAIN before API promotion runs.') } requireRuntimeOverrides( params.QQBOT_NAPCAT_IMAGE_OVERRIDE, params.QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE ) build job: params.API_PROMOTION_JOB, wait: true, parameters: [ string(name: 'QQBOT_NAPCAT_IMAGE_OVERRIDE', value: params.QQBOT_NAPCAT_IMAGE_OVERRIDE), string(name: 'QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE', value: params.QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE) ] } } } } post { always { 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 rm -rf "$WORKSPACE/artifacts" mkdir -p "$WORKSPACE/artifacts/napcat-runtime-release" 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 } } } /** * Stops runtime build or promotion unless both release override values are explicit. * @param imageTag Reviewed NapCat runtime image tag supplied by the operator. * @param profile Reviewed desktop profile version supplied by the operator. * @return Nothing; aborts this pipeline through `error` when a required value is missing. */ void requireRuntimeOverrides(String imageTag, String profile) { if (!imageTag?.trim()) { error('QQBOT_NAPCAT_IMAGE_OVERRIDE is required before build or promotion.') } if (!profile?.trim()) { error('QQBOT_NAPCAT_DESKTOP_PROFILE_VERSION_OVERRIDE is required before build or promotion.') } }