统一 Jenkins 本机 Git 源

将生产流水线 Git checkout 地址统一为 127.0.0.1:2222
数据库导入导出改由 Built-In Node 准备并传递脚本
新增 Git 源与目标节点边界的生产运维门禁
同步生产运维文档和项目共享记忆
This commit is contained in:
2026-07-14 22:03:32 +08:00
parent 34c6ed8756
commit c8dd6cbd33
11 changed files with 146 additions and 30 deletions
@@ -6827,6 +6827,32 @@ const nodeEnvFileCommandFiles = [
'scripts/deploy/pingora-direct-rollback.sh',
];
const jenkinsSourceCheckoutFiles = [
'jenkins/Jenkinsfile.production-api-build',
'jenkins/Jenkinsfile.production-web-build',
'jenkins/Jenkinsfile.production-stdb-module-build',
'jenkins/Jenkinsfile.production-full-build-and-deploy',
'jenkins/Jenkinsfile.production-database-export',
'jenkins/Jenkinsfile.production-database-import',
'jenkins/Jenkinsfile.production-server-provision',
];
const jenkinsLoopbackGitRemote =
"GIT_REMOTE_URL = 'ssh://git@127.0.0.1:2222/GenarrativeAI/Genarrative.git'";
const databaseTargetSourceStashes = [
{
file: 'jenkins/Jenkinsfile.production-database-export',
targetStage: "stage('Export Database')",
stashName: 'database-export-source',
},
{
file: 'jenkins/Jenkinsfile.production-database-import',
targetStage: "stage('Import Database')",
stashName: 'database-import-source',
},
];
let failed = false;
for (const check of checks) {
@@ -6845,6 +6871,72 @@ for (const check of checks) {
}
}
for (const file of jenkinsSourceCheckoutFiles) {
const content = readFileSync(file, 'utf8');
if (!content.includes(jenkinsLoopbackGitRemote)) {
failed = true;
console.error(
`[check:production-ops] ${file} 的 Git checkout 必须固定使用本机 127.0.0.1:2222。`,
);
}
if (
!content.includes(
"GIT_REMOTE_CREDENTIAL_ID = 'genarrative-local-gitea-ssh'",
)
) {
failed = true;
console.error(
`[check:production-ops] ${file} 必须继续显式使用 Jenkins Gitea SSH 凭据。`,
);
}
if (
content.includes('192.168.35.82') ||
content.includes('git.genarrative.world') ||
content.includes('genarrative-station/git')
) {
failed = true;
console.error(
`[check:production-ops] ${file} 不得保留局域网 IP、HTTP 内网别名或公网 Git 地址。`,
);
}
}
for (const { file, targetStage, stashName } of databaseTargetSourceStashes) {
const content = readFileSync(file, 'utf8');
const targetStageOffset = content.indexOf(targetStage);
const prepareStageContent =
targetStageOffset >= 0 ? content.slice(0, targetStageOffset) : '';
const targetStageContent =
targetStageOffset >= 0 ? content.slice(targetStageOffset) : '';
if (
!prepareStageContent.includes("label 'linux && genarrative-build'") ||
!prepareStageContent.includes("$class: 'GitSCM'")
) {
failed = true;
console.error(
`[check:production-ops] ${file} 必须只在 Jenkins Built-In Node 的 Prepare 阶段 checkout Git。`,
);
}
if (
!content.includes(`stash name: '${stashName}'`) ||
!targetStageContent.includes(`unstash '${stashName}'`)
) {
failed = true;
console.error(
`[check:production-ops] ${file} 必须由本机 build 节点 stash 源码脚本,再交给数据库目标阶段。`,
);
}
if (
targetStageContent.includes("$class: 'GitSCM'") ||
targetStageContent.includes('sshUserPrivateKey(')
) {
failed = true;
console.error(
`[check:production-ops] ${file} 的数据库目标阶段不得再次 checkout Git 或挂载 Git SSH 凭据。`,
);
}
}
const fullPipelineContent = readFileSync(
'jenkins/Jenkinsfile.production-full-build-and-deploy',
'utf8',