@agile-team/wl-skills-gate 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/docs/01-quick-start.md +1 -1
- package/docs/07-jenkins.md +2 -2
- package/docs/README.md +1 -1
- package/lib/jenkins-cluster.js +3 -2
- package/lib/jenkins-installation.js +5 -4
- package/npm-shrinkwrap.json +7 -7
- package/package.json +1 -1
- package/scripts/lib-tests/jenkins-native.test.mjs +3 -0
- package/templates/ci/check-project.config.json +1 -1
- package/templates/ci/jenkins-bootstrap.py +1 -1
- package/templates/ci/jenkins-loader.groovy +2 -0
- package/templates/ci/jenkins-native.groovy +2 -0
- package/templates/onboarding/backend/quality-tools.package.json +1 -1
- package/templates/quality/rules.lock.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## [0.13.1] — 2026-10-22
|
|
4
|
+
|
|
5
|
+
- Jenkins安装自动记录实际Node目录;服务器命令别名使用固定Node绝对路径,公共入口及各角色任务自动设置Node/npm的PATH。各节点可用受控WL_NODE_BIN_DIR覆盖本机差异。
|
|
6
|
+
- 接入交付启动器支持WL_NODE_BIN_DIR与现场Node路径,所有安装子进程共用同一套Node/npm;启动前核验执行器原件,脚本被编辑或函数被删除时给出明确恢复提示。
|
|
7
|
+
- 增加精简PATH、自定义Node路径、原件恢复与跨节点环境回归,保留完整性校验及严格构建准入。
|
|
8
|
+
|
|
3
9
|
## [0.13.0] — 2026-10-22
|
|
4
10
|
|
|
5
11
|
- Jenkins服务器公共入口随Gate安装,按实际Job识别检查、构建、中央、签发和维护角色;一个fleet任务批量配置,预览确认、回读、续跑及回退均留记录。
|
package/README.md
CHANGED
package/docs/01-quick-start.md
CHANGED
|
@@ -27,7 +27,7 @@ wl-quality init
|
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
npm exec --yes --ignore-scripts --registry=https://registry.npmjs.org/ \
|
|
30
|
-
--package=@agile-team/wl-skills-gate@0.13.
|
|
30
|
+
--package=@agile-team/wl-skills-gate@0.13.1 -- wl-quality init
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
向导展示差异与实际安装计划,确认后执行;检查异常不能当成零问题。接入后日常由Hook自动检查;正式Review、远端强制检查、群消息与报告权限仍按现场清单验收。
|
package/docs/07-jenkins.md
CHANGED
|
@@ -18,7 +18,7 @@ node('wl-quality-router') { load('/opt/wl-quality/gate-validation/jenkins/entry.
|
|
|
18
18
|
|
|
19
19
|
## 节点自检与失败通知
|
|
20
20
|
|
|
21
|
-
正常接入先运行编号脚本,再由自动创建的`wl-quality-doctor`验环境与机器人。若要在安装Gate前先验证失败通知,使用交付包`验收/环境与飞书验证.Jenkinsfile`:首次默认环境检查;后续在参数化构建中勾选`TEST_NOTIFICATION`可只测消息。自检使用 Python3 标准库;即使 Node 或 Gate
|
|
21
|
+
正常接入先运行编号脚本,再由自动创建的`wl-quality-doctor`验环境与机器人。若要在安装Gate前先验证失败通知,使用交付包`验收/环境与飞书验证.Jenkinsfile`:首次默认环境检查;后续在参数化构建中勾选`TEST_NOTIFICATION`可只测消息。自检使用 Python3 标准库;即使 Node 或 Gate 缺失,也能记录失败并尝试签名通知。安装自动记录实际Node目录,服务器公共入口、命令别名及任务子进程统一使用该目录;其他节点路径不同时,在该节点设置受控`WL_NODE_BIN_DIR`。无需修改受控脚本,不能在自检与构建中各选一套运行时。
|
|
22
22
|
|
|
23
23
|
生成的业务入口与辅助任务均先自检,再执行业务操作。异常处理使用流水线机器人凭据 `wl-feishu-ci-webhook`、`wl-feishu-ci-signing-secret`;凭据只在通知阶段绑定。缺凭据、缺 Python3、网络失败不会把原失败变成成功,也不假报送达。普通代码质量阻断由中央质量卡片通知,避免再发一张环境异常卡片;报告发布失败仍单独报执行异常。
|
|
24
24
|
|
|
@@ -63,7 +63,7 @@ node('wl-quality-router') { load('/opt/wl-quality/gate-validation/jenkins/entry.
|
|
|
63
63
|
|
|
64
64
|
## 当前交付边界
|
|
65
65
|
|
|
66
|
-
本轮以0.13.
|
|
66
|
+
本轮以0.13.1固定正式版本交付。包发布和隔离测试不代表两业务仓库或远端已接通。正式Review后的自动续建、验证构建结果/制品采集、紧凑检查卡片可靠投递已通过隔离贯通测试;真实项目配置、中央服务、TEST任务和飞书身份仍需现场交接/验收。
|
|
67
67
|
|
|
68
68
|
团队操作以交付包根目录的完整或运维接入操作说明为准,本文供维护者排查底层契约。
|
|
69
69
|
|
package/docs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# wl-skills-gate 技术手册索引
|
|
2
2
|
|
|
3
|
-
当前正式版本0.13.
|
|
3
|
+
当前正式版本0.13.1。团队操作以交付包根目录主说明为准,见[16 项目与运维入口](16-project-ci-integration.md);本索引提供工具契约与参数参考。
|
|
4
4
|
|
|
5
5
|
授权声明见 [LICENSE](../LICENSE);公开获取不授予使用、复制、修改或再分发授权,申请入口为 [仓库 Issues](https://github.com/ChenyCHENYU/wl-skills-gate/issues)。
|
|
6
6
|
|
package/lib/jenkins-cluster.js
CHANGED
|
@@ -9,7 +9,8 @@ export const MAINTENANCE_JOBS={node:'wl-quality-doctor',verify:'wl-quality-verif
|
|
|
9
9
|
export const defaultClusterFile=env=>env.WL_QUALITY_CLUSTER_CONFIG||'/srv/wl-quality/config/jenkins-cluster.json';
|
|
10
10
|
export function loadJenkinsCluster(file){
|
|
11
11
|
file=controlledPath(path.resolve(file));const c=readControlledJson(file),base=path.dirname(file);
|
|
12
|
-
assert(c.schemaVersion===1&&c.kind==='wl-quality-jenkins-cluster'&&Object.keys(c).every(k=>['schemaVersion','kind','jenkinsOrigin','registryFiles','configDir','agents','nativeEntry'].includes(k)),'需要有效的集群接入配置');
|
|
12
|
+
assert(c.schemaVersion===1&&c.kind==='wl-quality-jenkins-cluster'&&Object.keys(c).every(k=>['schemaVersion','kind','jenkinsOrigin','registryFiles','configDir','nodeBinDir','agents','nativeEntry'].includes(k)),'需要有效的集群接入配置');
|
|
13
|
+
if(c.nodeBinDir!==undefined){assert(typeof c.nodeBinDir==='string'&&path.isAbsolute(c.nodeBinDir)&&!/[\u0000-\u001f'"`$\\]/.test(c.nodeBinDir),'Node目录须为受控绝对路径');c.nodeBinDir=controlledPath(c.nodeBinDir);}
|
|
13
14
|
const u=new URL(c.jenkinsOrigin);assert(u.protocol==='https:'&&!u.username&&!u.password&&u.pathname==='/'&&!u.search&&!u.hash,'集群入口须为批准HTTPS origin');c.jenkinsOrigin=u.origin+'/';validateNativeEntry(c.nativeEntry);
|
|
14
15
|
assert(Array.isArray(c.registryFiles)&&c.registryFiles.length>0&&c.registryFiles.length<=1000&&new Set(c.registryFiles).size===c.registryFiles.length,'需要无重复的批准登记路径');c.registryFiles=c.registryFiles.map(v=>{assert(typeof v==='string'&&v,'登记路径无效');return controlledPath(path.resolve(base,v));});
|
|
15
16
|
assert(typeof c.configDir==='string'&&c.configDir,'缺少中央配置目录');c.configDir=controlledPath(path.resolve(base,c.configDir));
|
|
@@ -26,5 +27,5 @@ export async function resolveJenkinsContext({role='auto',configFile=defaultClust
|
|
|
26
27
|
assert(entryPointHash(selected.r.nativeEntry)===entryPointHash(c.nativeEntry),'登记与集群公共入口不一致,先更新批准登记');assert(selected.r.bindings.find(b=>Object.values(b.jobs).includes(env.JOB_NAME)).runtimeHash===gateRuntimeHash(),'跨节点包字节不一致,不能路由到另一套规则');
|
|
27
28
|
}
|
|
28
29
|
if(verifyEntry){assert(c.nativeEntry.runtimeHash===gateRuntimeHash(),'Gate运行时与批准公共入口不一致');assert(digest(readFileSync(controlledPath(c.nativeEntry.loaderFile)))===c.nativeEntry.loaderHash,'服务器公共入口被修改,停止执行');}
|
|
29
|
-
return {schemaVersion:1,kind:'wl-quality-jenkins-context',role,agentLabel,gateRoot,registry:registryFile,configDir:c.configDir,clusterFile:c.file,jenkinsOrigin:c.jenkinsOrigin,nativeEntry:c.nativeEntry,entryVerified:verifyEntry,gateVersion:GATE_VERSION,runtimeHash:gateRuntimeHash(),clusterHash:c.configHash,qualityPassed:false,buildAuthorized:false};
|
|
30
|
+
return {schemaVersion:1,kind:'wl-quality-jenkins-context',role,agentLabel,gateRoot,nodeBinDir:c.nodeBinDir||path.dirname(process.execPath),registry:registryFile,configDir:c.configDir,clusterFile:c.file,jenkinsOrigin:c.jenkinsOrigin,nativeEntry:c.nativeEntry,entryVerified:verifyEntry,gateVersion:GATE_VERSION,runtimeHash:gateRuntimeHash(),clusterHash:c.configHash,qualityPassed:false,buildAuthorized:false};
|
|
30
31
|
}
|
|
@@ -15,11 +15,12 @@ export function planJenkinsInstallation(options={}){
|
|
|
15
15
|
const u=new URL(jenkinsOrigin);assert(u.protocol==='https:'&&u.pathname==='/'&&!u.username&&!u.password&&!u.search&&!u.hash,'安装需要批准Jenkins HTTPS origin');assert([centralAgentLabel,reviewSignerAgentLabel].every(v=>/^[A-Za-z0-9_.-]{1,100}$/.test(v||'')),'需要现场实际中央及独立签发节点标签');
|
|
16
16
|
registryFiles||=[path.join(configDir,'jenkins-bindings.json')];assert(Array.isArray(registryFiles)&®istryFiles.length>0&®istryFiles.every(v=>path.isAbsolute(v)),'批准登记路径须明确');
|
|
17
17
|
const clusterFile=path.join(configDir,'jenkins-cluster.json'),loaderFile=path.join(prefix,'jenkins/entry.groovy'),aliasFile=path.join(prefix,'bin/wl-quality');
|
|
18
|
-
const
|
|
18
|
+
const nodeBinDir=controlledPath(path.dirname(process.execPath));assert(!/[\u0000-\u001f'"`$\\]/.test(nodeBinDir),'Node安装路径含不支持的字符');
|
|
19
|
+
const loader=jenkinsBootstrapHelper()+readFileSync(path.join(GATE_ROOT,'templates/ci/jenkins-loader.groovy'),'utf8').replaceAll('__WL_GATE_ROOT__',GATE_ROOT).replaceAll('__WL_CLUSTER_FILE__',clusterFile).replaceAll('__WL_RUNTIME_HASH__',gateRuntimeHash()).replaceAll('__WL_NODE_BIN_DIR__',nodeBinDir);
|
|
19
20
|
const nativeEntry={loaderFile,loaderHash:digest(loader),runtimeHash:gateRuntimeHash()};
|
|
20
|
-
const c={schemaVersion:1,kind:'wl-quality-jenkins-cluster',jenkinsOrigin:u.origin+'/',registryFiles,configDir,agents:{central:centralAgentLabel,review:reviewSignerAgentLabel},nativeEntry};
|
|
21
|
-
const files=[{file:loaderFile,text:loader,mode:0o644},{file:aliasFile,text:'#!/bin/sh\nset -eu\nexec
|
|
22
|
-
const plan={kind:'wl-quality-installation-plan',prefix,configDir,runtimeHash:gateRuntimeHash(),files,nativeEntry,pipelineScript:nativePipelineEntry(nativeEntry),nodeEnvironment:{'PATH+WLQUALITY':path.join(prefix,'bin'),WL_QUALITY_CLUSTER_CONFIG:clusterFile},routerLabel:'wl-quality-router'};return {...plan,planHash:digest(stableStringify(plan)),status:'preview'};
|
|
21
|
+
const c={schemaVersion:1,kind:'wl-quality-jenkins-cluster',jenkinsOrigin:u.origin+'/',registryFiles,configDir,nodeBinDir,agents:{central:centralAgentLabel,review:reviewSignerAgentLabel},nativeEntry};
|
|
22
|
+
const files=[{file:loaderFile,text:loader,mode:0o644},{file:aliasFile,text:'#!/bin/sh\nset -eu\nPATH='+quote(nodeBinDir)+':"$PATH"\nexport PATH\nexec '+quote(process.execPath)+' '+quote(path.join(GATE_ROOT,'bin/wl-quality.js'))+' "$@"\n',mode:0o755},{file:clusterFile,text:JSON.stringify(c,null,2)+'\n',mode:0o600}].map(f=>{controlledPath(f.file);const before=existsSync(f.file)?readFileSync(f.file,'utf8'):null;return {...f,before,action:before===f.text&&(lstatSync(f.file).mode&0o777)===f.mode?'unchanged':before===null?'create':'update'};});
|
|
23
|
+
const plan={kind:'wl-quality-installation-plan',prefix,configDir,runtimeHash:gateRuntimeHash(),files,nativeEntry,pipelineScript:nativePipelineEntry(nativeEntry),nodeEnvironment:{'PATH+WLQUALITY':path.join(prefix,'bin'),WL_NODE_BIN_DIR:nodeBinDir,WL_QUALITY_CLUSTER_CONFIG:clusterFile},routerLabel:'wl-quality-router'};return {...plan,planHash:digest(stableStringify(plan)),status:'preview'};
|
|
23
24
|
}
|
|
24
25
|
export function applyJenkinsInstallation(options={}){
|
|
25
26
|
const plan=planJenkinsInstallation(options);assert(options.confirm===true&&options.planHash===plan.planHash,'准备执行须绑定当前路径、包版本和差异计划');
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agile-team/wl-skills-gate",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@agile-team/wl-skills-gate",
|
|
9
|
-
"version": "0.13.
|
|
9
|
+
"version": "0.13.1",
|
|
10
10
|
"license": "UNLICENSED",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@secretlint/node": "13.0.7",
|
|
@@ -1194,7 +1194,7 @@
|
|
|
1194
1194
|
"tapable": "^2.3.3"
|
|
1195
1195
|
},
|
|
1196
1196
|
"engines": {
|
|
1197
|
-
"node": ">=10.13.
|
|
1197
|
+
"node": ">=10.13.1"
|
|
1198
1198
|
}
|
|
1199
1199
|
},
|
|
1200
1200
|
"node_modules/entities": {
|
|
@@ -1613,7 +1613,7 @@
|
|
|
1613
1613
|
"is-glob": "^4.0.3"
|
|
1614
1614
|
},
|
|
1615
1615
|
"engines": {
|
|
1616
|
-
"node": ">=10.13.
|
|
1616
|
+
"node": ">=10.13.1"
|
|
1617
1617
|
}
|
|
1618
1618
|
},
|
|
1619
1619
|
"node_modules/global-directory": {
|
|
@@ -1728,7 +1728,7 @@
|
|
|
1728
1728
|
"integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
|
|
1729
1729
|
"license": "MIT",
|
|
1730
1730
|
"engines": {
|
|
1731
|
-
"node": ">=10.13.
|
|
1731
|
+
"node": ">=10.13.1"
|
|
1732
1732
|
}
|
|
1733
1733
|
},
|
|
1734
1734
|
"node_modules/is-core-module": {
|
|
@@ -2433,7 +2433,7 @@
|
|
|
2433
2433
|
"resolve": "^1.20.0"
|
|
2434
2434
|
},
|
|
2435
2435
|
"engines": {
|
|
2436
|
-
"node": ">= 10.13.
|
|
2436
|
+
"node": ">= 10.13.1"
|
|
2437
2437
|
}
|
|
2438
2438
|
},
|
|
2439
2439
|
"node_modules/regexp-tree": {
|
|
@@ -2910,7 +2910,7 @@
|
|
|
2910
2910
|
"tsconfig-paths": "^4.1.2"
|
|
2911
2911
|
},
|
|
2912
2912
|
"engines": {
|
|
2913
|
-
"node": ">=10.13.
|
|
2913
|
+
"node": ">=10.13.1"
|
|
2914
2914
|
}
|
|
2915
2915
|
},
|
|
2916
2916
|
"node_modules/type-check": {
|
package/package.json
CHANGED
|
@@ -16,9 +16,12 @@ const environment=(job='wl-quality-fleet')=>({JENKINS_URL:'https://jenkins.examp
|
|
|
16
16
|
test('服务器公共入口随Gate安装,零新仓库;重复安装无差异且修改须重新预览',t=>{
|
|
17
17
|
const f=fixture(t),v=installed(f);assert.match(v.result.pipelineScript,/node\('wl-quality-router'\).*load\(.*entry.groovy.*\) \}\.call\(\)/);assert(!v.result.remoteModified);assert(existsSync(v.result.nativeEntry.loaderFile));assert(planJenkinsInstallation(v.input).files.every(e=>e.action==='unchanged'));assert.throws(()=>applyJenkinsInstallation({...v.input,confirm:true,planHash:v.p.planHash}),/差异计划/);assert.throws(()=>planJenkinsInstallation({...v.input,libraryManifestFile:'unused'}),/未知/);
|
|
18
18
|
const alias=spawnSync(v.result.command,['--version'],{encoding:'utf8'});assert.equal(alias.status,0,alias.stderr);assert.equal(alias.stdout.split(' ')[1],GATE_VERSION);
|
|
19
|
+
const minimal=spawnSync(v.result.command,['--version'],{encoding:'utf8',env:{...process.env,PATH:'/usr/bin:/bin'}});assert.equal(minimal.status,0,minimal.stderr);assert.equal(minimal.stdout.split(' ')[1],GATE_VERSION);
|
|
20
|
+
assert.equal(v.result.nodeEnvironment.WL_NODE_BIN_DIR,path.dirname(process.execPath));const cluster=JSON.parse(readFileSync(v.result.clusterFile));assert.equal(cluster.nodeBinDir,path.dirname(process.execPath));assert(!readFileSync(v.result.nativeEntry.loaderFile,'utf8').includes('__WL_NODE_BIN_DIR__'));assert(readFileSync(v.result.nativeEntry.loaderFile,'utf8').includes(path.dirname(process.execPath)));
|
|
19
21
|
});
|
|
20
22
|
test('路由按真实Job识别维护角色,拒绝冒充签发者和入口漂移',async t=>{
|
|
21
23
|
const f=fixture(t),v=installed(f),args={configFile:v.result.clusterFile,env:environment(),verifyEntry:true};const c=await resolveJenkinsContext(args);assert.equal(c.role,'fleet');assert.equal(c.agentLabel,'central');assert(c.entryVerified);await assert.rejects(resolveJenkinsContext({...args,role:'review'}),/不能借/);writeFileSync(v.result.nativeEntry.loaderFile,'changed');await assert.rejects(resolveJenkinsContext(args),/入口被修改/);
|
|
24
|
+
assert.equal(c.nodeBinDir,path.dirname(process.execPath));
|
|
22
25
|
});
|
|
23
26
|
test('业务Job按登记路由,公共入口和当前包字节都须一致',async t=>{
|
|
24
27
|
const f=fixture(t);await bind(f);const v=installed(f),r=JSON.parse(readFileSync(f.registryFile));r.nativeEntry=v.result.nativeEntry;put(f.base,'bindings.json',r);const c=await resolveJenkinsContext({configFile:v.result.clusterFile,env:f.environment('CHECK'),verifyEntry:true});assert.equal(c.role,'job');assert.equal(c.registry,f.registryFile);assert.equal(renderJenkinsEntry(r,f.registryFile),v.result.pipelineScript);await assert.rejects(resolveJenkinsContext({role:'review',configFile:v.result.clusterFile,env:f.environment('CHECK')}),/不能借/);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"kind": "wl-quality-ci-check",
|
|
4
4
|
"project": "REPLACE_WITH_ACTUAL_PROJECT",
|
|
5
|
-
"gateVersion": "0.13.
|
|
5
|
+
"gateVersion": "0.13.1",
|
|
6
6
|
"workspaceHash": "REPLACE_WITH_APPROVED_WORKSPACE_SHA256",
|
|
7
7
|
"lockHash": "REPLACE_WITH_APPROVED_LOCK_SHA256",
|
|
8
8
|
"policyHash": "REPLACE_WITH_APPROVED_POLICY_SHA256",
|
|
@@ -55,7 +55,7 @@ def preflight(env):
|
|
|
55
55
|
valid_root = root.is_absolute() and root.is_dir()
|
|
56
56
|
check("gate-root", valid_root, "固定 Gate 目录可读取" if valid_root else "固定 Gate 目录不存在或不可读取",
|
|
57
57
|
"在该Jenkins节点运行本包的接入Jenkins脚本;使用安装回执中的 gateHome。包内入口为 bin/wl-skills-gate.js。")
|
|
58
|
-
expected = env.get("WL_BOOTSTRAP_GATE_VERSION", "0.13.
|
|
58
|
+
expected = env.get("WL_BOOTSTRAP_GATE_VERSION", "0.13.1")
|
|
59
59
|
try:
|
|
60
60
|
package = json.loads((root / "package.json").read_text())
|
|
61
61
|
correct = package.get("name") == "@agile-team/wl-skills-gate" and package.get("version") == expected
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Installed by Gate outside every project workspace. No shared Git repository.
|
|
3
3
|
def adapter = null
|
|
4
4
|
def target = null
|
|
5
|
+
withEnv(["WL_NODE_BIN_DIR=${env.WL_NODE_BIN_DIR ?: '__WL_NODE_BIN_DIR__'}", "PATH+WLNODE=${env.WL_NODE_BIN_DIR ?: '__WL_NODE_BIN_DIR__'}"]) {
|
|
5
6
|
try {
|
|
6
7
|
wlGatePreflight(mode: 'node', gateRoot: '__WL_GATE_ROOT__', runtimeHash: '__WL_RUNTIME_HASH__')
|
|
7
8
|
def routeDir = "wl-quality-route-${java.util.UUID.randomUUID().toString()}"
|
|
@@ -17,6 +18,7 @@ try {
|
|
|
17
18
|
wlGateFailureNotice()
|
|
18
19
|
throw failure
|
|
19
20
|
}
|
|
21
|
+
}
|
|
20
22
|
def bootstrap = this
|
|
21
23
|
// Return first: the caller releases the router executor before allocating a
|
|
22
24
|
// business/signing Agent. This also works with a single executor on a node.
|
|
@@ -53,6 +53,7 @@ def wlPrepareJobs(Map cfg) {
|
|
|
53
53
|
}
|
|
54
54
|
def call(Map cfg, def bootstrap) {
|
|
55
55
|
node(cfg.agentLabel) {
|
|
56
|
+
withEnv(["WL_NODE_BIN_DIR=${env.WL_NODE_BIN_DIR ?: cfg.nodeBinDir ?: '/usr/bin'}", "PATH+WLNODE=${env.WL_NODE_BIN_DIR ?: cfg.nodeBinDir ?: '/usr/bin'}"]) {
|
|
56
57
|
timeout(time: cfg.role == 'fleet' ? 120 : 30, unit: 'MINUTES') {
|
|
57
58
|
try {
|
|
58
59
|
if (cfg.role != 'job') {
|
|
@@ -140,6 +141,7 @@ node "$WL_APPROVED_GATE_CLI" automation --config "$WL_CENTRAL_CONFIG/automation-
|
|
|
140
141
|
archiveArtifacts artifacts: '.wl-gate-bootstrap/**,wl-fleet-public/*,wl-bootstrap-public/*.json,review-delivery/**', allowEmptyArchive: true
|
|
141
142
|
}
|
|
142
143
|
}
|
|
144
|
+
}
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
return this
|