背景
- 有個(gè)私有倉(cāng)儲(chǔ),地址為
https://your.repo.com/pypi/
- 代碼存儲(chǔ)在gitlab, 地址為
https://gitlab.company.com/software.git
- CI為jenkins
常規(guī)解決手法
jenkins有一個(gè)特定的節(jié)點(diǎn),節(jié)點(diǎn)里面已經(jīng)配置好了%HOMEPATH%/.pypirc
[distutils]
index-servers =
deploy
[deploy]
repository=https://your.repo.com/pypi/
username=youraccmount
password=yourpwd
然后直接使用
python setup.py sdist upload -r deploy
問(wèn)題
權(quán)限控制
私有倉(cāng)儲(chǔ)存在一個(gè)權(quán)限, 只有高級(jí)別的賬號(hào)才能push. 而所有人都可以pull包. 那么就存在一個(gè)問(wèn)題. 絕對(duì)不能將leader的賬戶密碼直接記錄在jenkins節(jié)點(diǎn)的配置中.這樣很容易就暴露權(quán)限.
如果換了臺(tái)節(jié)點(diǎn)
常用方法需要在節(jié)點(diǎn)配置.pypirc
文件. 如果我想換臺(tái)節(jié)點(diǎn),還需要登陸到新節(jié)點(diǎn)進(jìn)行配置.這樣非常不方便.
需求
- 絕對(duì)不能暴露高級(jí)別的賬號(hào)密碼
- 對(duì)節(jié)點(diǎn)無(wú)特殊需求, CI任務(wù)換哪個(gè)節(jié)點(diǎn)都可以
- 希望能夠自定義包的版本. 而不是每次都是某個(gè)固定的版本
- 我提交代碼到gitlab. 然后就自動(dòng)發(fā)布到倉(cāng)儲(chǔ)
解決
我新打了一個(gè)tag0.1.1
, 然后我的私有倉(cāng)儲(chǔ)就有一個(gè)client0.1.1的包
- 通過(guò)jenkins password injection解決權(quán)限控制的問(wèn)題
- 通過(guò)expect解決需要交互式輸入用戶名密碼的問(wèn)題
- 通過(guò)gitlab push解決自動(dòng)發(fā)布的問(wèn)題
- 通過(guò)設(shè)置環(huán)境變量解決tag轉(zhuǎn)化為包版本的問(wèn)題
設(shè)置倉(cāng)儲(chǔ)名, 指定分支為refs/tags/*
. 這樣只會(huì)編譯tag分支
image.png
增加jenkins自動(dòng)觸發(fā)
image.png
gitlab 配置事件推送
image.png
注入密碼到環(huán)境變量
image.png
手動(dòng)添加憑據(jù)
image.png
shell腳本
這里有一個(gè)難題要解決, 首先jenkins shell執(zhí)行相當(dāng)于在目標(biāo)機(jī)器下發(fā)了一個(gè)文件. 如果要用expect
都是只能采用#!/usr/bin/expect
頭來(lái)執(zhí)行. 可是使用#!/usr/bin/expect
作為shell腳本執(zhí)行器,很多命令又沒(méi)辦法用. 所以采用#!/usr/bin/expect -c "command"
來(lái)執(zhí)行
#!/bin/bash
# 注入環(huán)境變量
set -e
# 將Tag版本傳到環(huán)境變量,Setup.py會(huì)讀取這個(gè)環(huán)境變量
version=`basename $GIT_BRANCH`
export VERSION=$version
here=`pwd`
# 安裝打包輔助庫(kù)twine到默認(rèn)python環(huán)境
pip install twine
# 打包
python setup.py sdist
# 使用expect進(jìn)行交互式用戶名,密碼輸入, 這里需要將yourpackagename改成python包名
/usr/bin/expect -c "spawn twine upload --repository-url https://your.repo.com/pypi/ "$here"/dist/yourpackage-"$version".tar.gz; expect "*username:" ; send ${ADMIN_USER}\r; expect "*password:"; send ${ADMIN_PWD}\r; expect eof"
而在setup.py
中,使用環(huán)境變量作為當(dāng)前版本
setuptools.setup(
...
version=os.getenv("VERSION", "0.1.0")
...
)