之前的京东自动签到、什么值得买自动签到都是放在阿里的云效,通过流水线部署,代码也是托管在云效上面。但是 8 月云效的小企业免费套餐就到期了,免费续期的条件是总人数达到 10 人,月活跃人数 3 人。孤家寡人有点难达到,就想着自己搭个 CI/CD。公司的项目用的都是 jenkins,插件多,社区活跃,非常合适。所以在 NAS 上安装了一个 docker 版的 Jenkins,目前已经把签到、博客部署等任务迁移了,工作稳定。

本篇主要讲一下构建中的参数化,出于开源考虑,有些项目在自己开发完 ok 以后希望可以提供给有需要的朋友一起使用,但是又有些敏感的数据,比如 token、cookies、id、key 等等,在代码中写标识或者引用环境变量,构建时传入敏感数据完成构建任务的做法是比较科学合理的。

目前接触较多的都是 node 相关的项目,自己写的小工具也都是基于 node,在 node 中可以直接使用 process.env.* 来引用环境变量,这时只要构建时环境变量中有对应的 key 和正确的 value 就能完成整个任务的执行。

那我们来看看怎么在 Jenkins job 中配置一个环境变量吧。(以下步骤 Jenkins 都为中文版,用英文版的小伙伴自己翻译一下~)

首先新建一个 job,可以选择模板或者自由风格。

选择“参数化构建过程” -> “添加参数” -> “字符参数”

添加两个字符参数,这两个参数将被作为环境变量,或者在配置中做变量替换。

下面看一下具体的使用例子:
在 node 中使用

首先创建了一个输出两个环境变量值的 js 文件,再通过 node 执行这个文件,输出结果如下:

那么如果一个变量是存在 json 或者 yml 中,在构建前需要替换文件中的环境变量标识应该怎么办呢?

目前我没有找到现成的方法,如果有的话请大佬在评论区留言告诉我。

自己用 node 写了一个小脚本 params_replace.js,用来替换文件中的环境变量,全量脚本在下面 ↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const fs = require('fs');
const path = require('path');

const { argv } = process;
const originInputFilePath = argv[argv.length - 1];

if (originInputFilePath === __filename) {
console.log('未输入需要替换变量的文件路径,相对于此脚本文件的路径');
return;
}

const inputFilePath = path.resolve(originInputFilePath);

const fileStatus = fs.lstatSync(inputFilePath, {
throwIfNoEntry: false,
});

// 判断文件是否存在
if (!fileStatus) {
console.log('查无此文件');
return;
}

// 判断是否是文件夹
if (fileStatus.isDirectory()) {
console.log('这是一个文件夹,不是文件');
return;
}

// 尝试关闭文件
try {
fs.closeSync(inputFilePath);
} catch (error) {
//
}

// 替换变量
let inputFileContent = fs.readFileSync(inputFilePath, 'utf-8').toString();
inputFileContent = inputFileContent.replace(
/\$\{([A-Z0-9_]*)\}/gm,
(matchFull, match) => {
return process.env[match] || '';
}
);

// 写入原路径
try {
fs.writeFileSync(inputFilePath, inputFileContent);
console.log(`变量替换成功,文件路径${inputFilePath}`);
} catch (error) {
console.log('变量替换失败');
}

这个脚本的使用方法:

1
node params_replace.js ./config.yml

唯一的参数是传入需要替换变量的文件路径,是相对于脚本执行路径的相对路径。
会判断文件是否存在,是否是文件夹。
当满足条件时会执行全文匹配,${*}且变量名为全大写或者下划线的变量会被找出,根据变量名取环境变量中对应的值。
替换后重写源文件。这样在执行构建时就能取到正确的参数值了。

完成了参数化配置后,就能放心大胆的把工具分享给朋友们了。