安裝篇
1.打開(kāi)你的瀏覽器郁惜,輸入www.baidu.com
2.搜索jenkins點(diǎn)開(kāi)第一個(gè)骑晶,然后等待加載轉(zhuǎn)圈圈https://www.jenkins.io/zh/
3.下載左邊的蛾坯,穩(wěn)定版,不下每周更新版
4.MAC Linux Windows都下載自己的版本
5.安裝后打開(kāi),各種默認(rèn)化配置狂男,有下一步點(diǎn)擊下一步
6.等待插件下載完,部分下載失敗也沒(méi)事品腹,不用管岖食,能進(jìn)入主頁(yè)直接進(jìn)入主頁(yè)
7.看到這個(gè),恭喜舞吭,你安裝并且登錄成功了
使用篇 以u(píng)bantu為例
問(wèn)題1:jenkins配置局域網(wǎng)其他電腦可訪問(wèn)(自己百度找泡垃,就是把127.0.0.1改成0.0.0.0)
https://blog.csdn.net/weixin_33860147/article/details/89752482
問(wèn)題2:jenkins配置環(huán)境變量
Manage Jenkins ->Configure System->Environment variables 配置一些你的環(huán)境變量
系統(tǒng)默認(rèn)的path可用,可以輸出path以示例镣典。
問(wèn)題3:開(kāi)啟用戶認(rèn)證兔毙,或者說(shuō)多用戶體系
默認(rèn)只有單用戶唾琼,在Manage Jenkins ->Configure Global Security->勾選允許用戶注冊(cè)兄春,勾選項(xiàng)目矩陣授權(quán)策略,效果如下锡溯,給對(duì)應(yīng)的用戶赶舆,對(duì)應(yīng)的權(quán)限,允許用戶注冊(cè)祭饭,由管理員管理
問(wèn)題4芜茵,插件安裝
Manage Jenkins ->Manage Plugins->點(diǎn)擊可選插件->在搜索欄輸入對(duì)應(yīng)關(guān)鍵字,示例如下
已安裝倡蝙,或者已更新里面都可以找找九串,高級(jí)里面有安裝本地插件的選項(xiàng)。
問(wèn)題5.安裝gradle版本(你得先安裝gradle插件寺鸥,默認(rèn)推薦已經(jīng)安裝了)
Manage Jenkins ->Global Tool Configuration->找到gradle安裝->新增gradle->選個(gè)版本填個(gè)名字保存
準(zhǔn)備工作基本完畢猪钮,然后就是創(chuàng)建項(xiàng)目
1.回到j(luò)enkins首頁(yè),點(diǎn)擊新建item胆建。輸入個(gè)名字烤低,選擇freestyle project完成(其他類型的,有興趣自己搞笆载,我沒(méi)用到)
2.step1
3.step2
4.step3
這里就是一些鉤子扑馁,中文描述已經(jīng)很清楚,你不想點(diǎn)擊可以選擇其中一種凉驻,輪詢scm腻要,可以設(shè)置定時(shí)檢查,這個(gè)不用鉤子涝登,根據(jù)規(guī)則寫(xiě)一句話就好了
5.step4
構(gòu)建步驟雄家,與構(gòu)建后操作,只要你想要缀拭,自己添加咳短,構(gòu)建操作可以執(zhí)行python填帽,sh,windows command等咙好,習(xí)慣哪個(gè)用哪個(gè)篡腌。個(gè)人喜歡用sh調(diào)用本地python腳本,方便調(diào)試跟腳本管理勾效。也可以選擇這里上傳pgy等(要安裝個(gè)pgy插件嘹悼,按提示操作就好)
然后你就可以愉快的使用jenkins了。层宫。
目前我用的解決方案
1.使用jenkins進(jìn)行項(xiàng)目構(gòu)建杨伙,
2.構(gòu)建完成后,調(diào)用預(yù)寫(xiě)好的python腳本萌腿,做一系列操作
3.自己打包個(gè)qrcode.jar限匣。生成二維碼用
4.下載360加固的jiagu.jar。加固包使用
5.下載walle的jar包毁菱。打渠道包用
6.下載tomcat米死,起服務(wù)器用
7.python腳本具體流程實(shí)現(xiàn)為,保存mapping(解混淆使用)贮庞,執(zhí)行加固峦筒,加固完成后,移動(dòng)到備份的文件夾窗慎,執(zhí)行walle打渠道包物喷,打完后,將至復(fù)制到tomcat的webapp下遮斥,然后根據(jù)所在路徑生成二維碼峦失,然后從git中,取出一些信息伏伐,比如多少條提交日志宠进,所在分支,或者構(gòu)建參數(shù)等藐翎,組成推送文案材蹬,調(diào)用企業(yè)微信機(jī)器人的發(fā)消息方法通知到測(cè)試群,測(cè)試或者開(kāi)發(fā)同學(xué)自行掃碼下載即可
附其中部分python腳本方法吝镣。
import base64
import hashlib
import json
import os
import shutil
import socket
import time
import urllib.request
import urllib.error
import requests
# 新建任務(wù)需要執(zhí)行的腳本需要修改的地方
# 渠道名字堤器,復(fù)制粘貼的時(shí)候記得改
channel = "demo 名字自己設(shè)置"
# 這里對(duì)應(yīng)jenkins任務(wù)目錄,復(fù)制粘貼的時(shí)候記得改
rootPath = "/var/lib/jenkins/workspace/demo jenkins項(xiàng)目地址"
# 對(duì)應(yīng)渠道的keystore名字
key_store_name = "keystore.jks的名字"
# keystore的賬號(hào)密碼末贾,空格不可刪除
key_store_pass = ' 密碼 別名 別名密碼'
# 以下不需要改動(dòng)
# 加固寶的位置
jiaguPath = "/var/lib/jenkins/workspace/task/360jiagubao_linux_64/jiagu""#你放哪闸溃,就填哪里
# apk的位置
apkRootPath = rootPath + "/app/build/outputs"
# 歸檔文件夾的主目錄
copyfilePath = "/home/haha/NewDisk/歸檔"
# 歸檔文件夾的子目錄
outPutFolder = int(round(time.time() * 1000)).__str__()
# 管理員密碼
sudoPassword = "1"#ubantu 的管理員密碼,有些操作需要管理員權(quán)限
# tomecat服務(wù)器目錄
tomcatPath = "/home/haha/studio/tomcat/webapps/examples"
# 二維碼生成jar包的路徑
qrcodeJarPath = "/var/lib/jenkins/workspace/task/myqrcode.jar"
def getNewestMessage():
result2 = os.popen("git name-rev --name-only HEAD")
outPut = result2.buffer.read().decode('utf-8')
return outPut
def getCommitMsg():
outPut = os.popen("git log --pretty=format:\"%H\" | head -10")
idArray = outPut.buffer.read().decode('utf-8').split('\n')
for i in range(0, len(idArray)):
result2 = os.popen("git log --pretty=format:\"%s\" " + idArray[i] + " -1")
outPut = result2.buffer.read().decode('utf-8')
if "Merge branch" in outPut:
continue
else:
return outPut
return "無(wú)額外提交信息"
# 獲取apk路徑
def apkPath(file_dir):
list = []
for root, dirs, files in os.walk(file_dir):
if len(files) > 0:
for file in files:
if file.endswith(".apk"):
list.append(root + "/" + file + '')
return list
# 獲取apk版本號(hào)
def file_name():
for root, dirs, files in os.walk(apkRootPath):
if len(files) > 0:
for file in files:
if file.endswith(".apk"):
a = file.split("_")
return a[len(a) - 2]
# 創(chuàng)建文件夾
def create_folder(check_path):
if not os.path.exists(check_path):
os.makedirs(check_path)
# 拷貝目錄到子文件
def copyfile():
# 創(chuàng)建歸檔目錄
out_path = os.path.join(copyfilePath, channel, file_name(), outPutFolder)
create_folder(out_path)
# 獲取需要拷貝的apk列表
list = apkPath(apkRootPath)
if len(list) > 0:
for path in list:
shutil.copy(path, out_path)
def copyMapping():
# 創(chuàng)建歸檔目錄
os.chdir(copyfilePath)
# create_folder(os.path.join(file_name(), outPutFolder))
folder1 = os.path.join(apkRootPath, "mapping")
folder2 = os.path.join(copyfilePath, channel, file_name(), outPutFolder, "mapping")
shutil.copytree(folder1, folder2, ignore=shutil.ignore_patterns("output.json"))
def exec_360_jiagu(path):
output_path = os.path.join(copyfilePath, file_name(), outPutFolder)
if not os.path.exists(output_path):
os.mkdir(output_path)
jiagu_cmd = 'java -jar jiagu.jar -jiagu ' + path + ' ' + output_path + ' -autosign'
result = os.system('echo %s|sudo -S %s' % (sudoPassword, jiagu_cmd))
if not result:
print("========" + str(result) + " 加固成功")
else:
print("加固失敗")
def jiagu():
# 檢查輸出路徑是否存在
folder0 = os.path.join(copyfilePath, file_name(), outPutFolder)
create_folder(folder0)
# 登陸加固程序
os.chdir(jiaguPath)
command = 'java -jar jiagu.jar -login 18268065891 ff623893'
os.system('echo %s|sudo -S %s' % (sudoPassword, command))
folder1 = os.path.join(rootPath, "app", key_store_name)
command = 'java -jar jiagu.jar -importsign ' + folder1 + key_store_pass
os.system('echo %s|sudo -S %s' % (sudoPassword, command))
# 獲取需要加固的APK列表
list = apkPath(apkRootPath)
if len(list) > 0:
for path in list:
# 開(kāi)始加固
exec_360_jiagu(path)
def notifyQyWx(downloadPath):
url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=f38fa1f7-8193-4e28-bfff-d6fbd5680770'
os.chdir(rootPath)
con = {"msgtype": "text",
"text": {"content": "打包成功了:下載鏈接 \n" + downloadPath + "\n打包分支:" + getNewestMessage()}, }
jd = json.dumps(con).encode('utf-8')
req = urllib.request.Request(url, jd)
req.add_header('Content-Type', 'application/json')
response = urllib.request.urlopen(req)
def notifyQyWxText():
url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=aaaa'
os.chdir(rootPath)
result2 = os.popen("echo $message")
back_message = result2.buffer.read().decode('utf-8')
con = {"msgtype": "text",
"text": {"content": "打包成功了\n版本號(hào):" + file_name() + "\n提交日志:" + getCommitMsg()+"\n所在分支:" + getNewestMessage()+"\n備注信息:"+back_message}, }
jd = json.dumps(con).encode('utf-8')
req = urllib.request.Request(url, jd)
req.add_header('Content-Type', 'application/json')
response = urllib.request.urlopen(req)
def wx_image(image):
with open(image, 'rb') as file: # 轉(zhuǎn)換圖片成base64格式
data = file.read()
encodestr = base64.b64encode(data)
image_data = str(encodestr, 'utf-8')
with open(image, 'rb') as file: # 圖片的MD5值
md = hashlib.md5()
md.update(file.read())
image_md5 = md.hexdigest()
url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=aaaa" # 填上機(jī)器人Webhook地址
headers = {"Content-Type": "application/json"}
data = {
"msgtype": "image",
"image": {
"base64": image_data,
"md5": image_md5
}
}
result = requests.post(url, headers=headers, json=data)
return result
def generateQrcode():
# 加固的輸出目錄
input_path = os.path.join(copyfilePath, channel, file_name(), outPutFolder)
# list = apkPath(input_path)
# if len(list) > 0:
# for path in list:
# # 開(kāi)始加固
# exec_360_jiagu(path)
output_path = os.path.join(tomcatPath, "apk", channel, file_name())
if os.path.exists(output_path):
shutil.rmtree(output_path)
shutil.copytree(input_path, output_path, ignore=shutil.ignore_patterns("mapping"))
server_path = "http://" + get_host_ip() + ":8088"
list = apkPath(output_path)
downloadpaths = ""
if len(list) > 0:
notifyQyWxText()
for path in list:
qrcode_content = server_path + path.replace("/home/haha/studio/tomcat/webapps", "")
pic_path = tomcatPath + "/img/" + channel + "/" + file_name() + ".png"
command = "java -jar " + qrcodeJarPath + " src=" + qrcode_content + " path=" + pic_path
os.system('echo %s|sudo -S %s' % (sudoPassword, command))
wx_image(pic_path)
downloadpaths = downloadpaths \
.__add__(qrcode_content) \
.__add__("\n")
# 通知到企業(yè)微信(暫時(shí)不用)
# notifyQyWx(downloadpaths)
# 復(fù)制文件到tomcat
def get_host_ip():
"""
查詢本機(jī)ip地址
:return:
"""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
if __name__ == '__main__':
# 初始化存儲(chǔ)目錄
# copyMapping() 測(cè)試不需要拷貝mapping
# jiagu() 測(cè)試包不需要加固
copyfile()
generateQrcode()
附二維碼生成qrcode.jar
使用方法 java -jar myqrcode.jar src=aa path=D:/aaa.png //這里反斜桿不要輸入錯(cuò)
鏈接:https://pan.baidu.com/s/1sOOihVTCXGGzU62CzoXWpw
提取碼:8pzb