-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[+]增加 [持续交付之.NET项目版本管理及技术落地(Python版)] 资料
- Loading branch information
zuozewei
committed
Oct 21, 2019
1 parent
ec4a655
commit 157ae53
Showing
7 changed files
with
397 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* 全局程序集信息 | ||
* GlobalAssemblyInfo.cs | ||
* | ||
* 请把此文件引用到其他的项目中 | ||
*/ | ||
using System.Reflection; | ||
using V3C.Client.Properties; | ||
|
||
[assembly: AssemblyProduct("xxxx")] | ||
[assembly: AssemblyCompany("xxxx科技股份有限公司")] | ||
[assembly: AssemblyCopyright("Copyright(C) e-xxxx 2000-2020")] | ||
[assembly: AssemblyVersion(RevisionClass.FullVersion)] | ||
//产品版本号:统一使用2.0.0 | ||
[assembly: AssemblyInformationalVersionAttribute("2.0.1001")] | ||
//程序中使用统一改为文件版本号 | ||
[assembly: AssemblyFileVersion(RevisionClass.FullVersion + | ||
//只有Master、Release分支编译的版本才是正式版本,其他都是开发版。 | ||
#if !MASTER | ||
"-开发版" | ||
#else | ||
"" | ||
#endif | ||
)] | ||
|
||
namespace V3C.Client.Properties | ||
{ | ||
internal static class RevisionClass | ||
{ | ||
public const string Major = "2"; | ||
public const string Minor = "0"; | ||
public const string Build = "1005"; | ||
public const string Revision = "9151"; | ||
public const string MainVersion = Major + "." + Minor; | ||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# coding=utf-8 | ||
|
||
import os,re,configparser | ||
from git import getcommits | ||
|
||
# 接收jenkins当前JOB_NAME参数 | ||
workSpace = os.getenv("WORKSPACE") | ||
JENKINS_HOME = os.getenv("JENKINS_HOME") | ||
# 分支提交总次数 | ||
Revision = str(getcommits()) | ||
Major = '' | ||
Minor = '' | ||
Build = '' | ||
path = workSpace+"\GlobalAssemblyInfo.cs" | ||
versionPath = JENKINS_HOME+"\workspace\Version.ini" | ||
|
||
config = configparser.ConfigParser() | ||
|
||
with open(path,'r', encoding='UTF-8') as f: | ||
lines = list(f) | ||
new_lines = list() | ||
changed = False | ||
|
||
for line in lines: | ||
if "Revision = " in line: | ||
line = ' public const string Revision = "'+ Revision +'";\n' | ||
changed = True | ||
elif "Major = " in line: | ||
Major = re.sub("\D", "", line) | ||
elif "Minor = " in line: | ||
Minor = re.sub("\D", "", line) | ||
elif "Build = " in line: | ||
Build = re.sub("\D", "", line) | ||
else: | ||
pass | ||
|
||
new_lines.append(line) | ||
if not changed: | ||
continue | ||
|
||
with open(path, 'w',encoding='UTF-8') as f: | ||
f.write("".join(new_lines)) | ||
|
||
FullVersion = Major + "." + Minor + "." + Build + "." + Revision | ||
print("【版本号】:"+FullVersion) | ||
|
||
config['xxx'] = { | ||
'xxx_Major': Major, | ||
'xxx_Minor': Minor, | ||
'xxx_Build': Build, | ||
'xxx_Revision': Revision | ||
} | ||
|
||
with open(versionPath, 'w', encoding='UTF-8') as configfile: | ||
config.write(configfile) | ||
|
||
configfile.close() | ||
f.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
# coding=utf-8 | ||
|
||
import os, os.path, configparser, zipfile, shutil, nexuscli, ftplib, socket | ||
|
||
# 获取Jenkins变量 | ||
WORKSPACE = os.getenv("WORKSPACE") | ||
JENKINS_HOME = os.getenv("JENKINS_HOME") | ||
BUILD_VERSION = str(os.getenv("BUILD_VERSION")) | ||
JOB_NAME = str(os.getenv("JOB_NAME")) | ||
|
||
# 版本号信息 | ||
versionPath = JENKINS_HOME + "\workspace\Version.ini" | ||
packageName = "" | ||
xxx_Major = '' | ||
xxx_Minor = '' | ||
xxx_Build = '' | ||
xxx_Revision = '' | ||
|
||
# 打包目录 | ||
targetFilePath = WORKSPACE + '\\' | ||
# bulid目录 | ||
bulidFilePath = WORKSPACE | ||
Version = '' | ||
zipName = '' | ||
|
||
packagePath = WORKSPACE + "\\package.ini" | ||
|
||
|
||
# 获取版本号信息 | ||
def readVersion(): | ||
config = configparser.ConfigParser() | ||
config.read(versionPath) | ||
xxx_Major = config.get("xxx", "xxx_Major") | ||
xxx_Minor = config.get("xxx", "xxx_Minor") | ||
xxx_Build = config.get("xxx", "xxx_Build") | ||
xxx_Revision = config.get("xxx", "xxx_Revision") | ||
Version = BUILD_VERSION + '-' + xxx_Major + '.' + xxx_Minor + '.' + xxx_Build + '.' + xxx_Revision | ||
print("【Build】version:" + Version) | ||
zipName = Version + '.zip' | ||
return zipName | ||
|
||
|
||
# 包名写入配置文件 | ||
def packageConifg(name, remotepath): | ||
config = configparser.ConfigParser() | ||
config['package'] = { | ||
'name': name, | ||
'remotedir': remotepath | ||
} | ||
with open(packagePath, 'w', encoding='UTF-8') as configfile: | ||
config.write(configfile) | ||
|
||
configfile.close() | ||
print("【Build】packageConifg is done!") | ||
|
||
|
||
# 使用zipfile做目录压缩 | ||
def zip_dir(dirname, zipfilename): | ||
filelist = [] | ||
if os.path.isfile(dirname): | ||
filelist.append(dirname) | ||
else: | ||
for root, dirs, files in os.walk(dirname): | ||
for name in files: | ||
filelist.append(os.path.join(root, name)) | ||
|
||
zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED) | ||
for tar in filelist: | ||
arcname = tar[len(dirname):] | ||
# print arcname | ||
zf.write(tar, arcname) | ||
print("【Build】zip is done!") | ||
|
||
|
||
# 清空文件夹及ZIP文件 | ||
def cleanFile(bulidFilePath, zipPath): | ||
# 判断文件夹是否存在 | ||
if os.path.exists(bulidFilePath): | ||
shutil.rmtree(bulidFilePath) | ||
print("【Build】cleanFile is done!") | ||
# 判断zip文件是否存在 | ||
if os.path.exists(zipPath): | ||
os.remove(zipPath) | ||
print("【Build】cleanZIP is done!") | ||
|
||
|
||
# 复制目录 | ||
def copytree(src, dst, symlinks=False, ignore=None): | ||
for item in os.listdir(src): | ||
s = os.path.join(src, item) | ||
d = os.path.join(dst, item) | ||
if os.path.isdir(s): | ||
shutil.copytree(s, d, symlinks, ignore) | ||
else: | ||
shutil.copy2(s, d) | ||
|
||
|
||
# 上传指定文件到 ftp 服务器 | ||
def uploadFile(dir_ftp, filename_ftp, filepath_local, host, port, username, password): | ||
""" | ||
参数说明: | ||
* dir_ftp: 在 ftp 服务器上存储文件的路径; | ||
* filename_ftp: 存储到 ftp 服务器上的文件名; | ||
* filepath_local: 需要上传的本地源文件路径; | ||
* host: ftp 服务器地址(ip/域名); | ||
* port: ftp 服务器端口号,一般是 21; | ||
* username、password: 登陆 ftp 服务器时的用户名和密码。 | ||
""" | ||
if not os.path.exists(filepath_local): | ||
print('【Build】找不到指定的源文件,请检查路径配置。') | ||
return False | ||
# connect | ||
try: | ||
f = ftplib.FTP() | ||
f.connect(host=host, port=port) | ||
except (socket.error, socket.gaierror) as e: | ||
print('【Build】----ERROR:cannot reach ' + host) | ||
print(e) | ||
return False | ||
# login | ||
try: | ||
f.login(user=username, passwd=password) | ||
except ftplib.error_perm as e: | ||
print('【Build】----ERROR:cannot login to server ' + host) | ||
print(e) | ||
f.quit() | ||
return False | ||
print('【Build】****Logged in as ' + username + ' to server ' + host) | ||
# change folder | ||
try: | ||
f.cwd(dir_ftp) | ||
except ftplib.error_perm as e: | ||
print('【Build】----ERROR:cannot CD to %s on %s' % (dir_ftp, host)) | ||
print(e) | ||
f.quit() | ||
return False | ||
print('【Build】**** changed to %s folder on %s' % (dir_ftp, host)) | ||
# upload file | ||
try: | ||
f.storbinary('STOR ' + filename_ftp, open(filepath_local, 'rb')) | ||
except ftplib.error_perm as e: | ||
print('【Build】----ERROR:cannot write %s on %s' % (filename_ftp, host)) | ||
print(e) | ||
return False | ||
else: | ||
print('【Build】****Uploaded ' + filepath_local + ' to ' + host + ' as ' \ | ||
+ os.path.join(dir_ftp, filename_ftp)) | ||
f.quit() | ||
return True | ||
|
||
|
||
# FTP上传路径 | ||
def remotedir(): | ||
if JOB_NAME == 'xxx-Client-Release': | ||
remotepath = 'xxx-release-info/client/' | ||
print("【消息内容】:" + remotepath) | ||
return remotepath | ||
|
||
|
||
# 编译后的文件夹 | ||
def bulidFile(): | ||
if JOB_NAME == 'xxx-Client-Release': | ||
bulidFilePath = 'D:\\Jenkins-workspace\\Jenkins\\workspace\\bin\\Client\\' | ||
print("【消息内容】:" + bulidFilePath) | ||
return bulidFilePath | ||
|
||
|
||
def unloadNexus(loaclfile, repository): | ||
nexus_client = nexuscli.nexus_client.NexusClient('http://xxx.xx.xxx.xxx:8081', 'jenkins', 'xxxx') | ||
upload_count = nexus_client.upload(loaclfile, repository) | ||
print("【上传数量】:" + str(upload_count)) | ||
|
||
def packageHistory(zipname): | ||
Path = WORKSPACE+"\\package_history.txt" | ||
f = open(Path,'a',encoding='utf-8') | ||
f.write(zipname) | ||
f.write("\n") | ||
f.close() | ||
|
||
|
||
if __name__ == '__main__': | ||
# 压缩包路径 | ||
localpath = targetFilePath + readVersion() | ||
|
||
# FTP上传路径 | ||
remotepath = remotedir() | ||
|
||
# 判断是否包含字符串 | ||
if JOB_NAME.find("Client") >= 0: | ||
# 压缩编译文件 | ||
zip_dir(bulidFile(), localpath) | ||
# 上传 | ||
# uploadFile(remotepath, readVersion(), localpath, host,21, username, password) | ||
unloadNexus(localpath, remotepath) | ||
# 包名写入配置文件 | ||
packageConifg(readVersion(), remotepath) | ||
# 清理 | ||
cleanFile(bulidFile(), localpath) | ||
print('【Build】(JOB_NAME.find("Client") >= 0) done') | ||
else: | ||
pass | ||
|
||
print('【Build】****done') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# coding=utf-8 | ||
import gitlab | ||
|
||
# gitlab地址 | ||
url = 'http://x.x.x.x:82' | ||
token = '' | ||
# 登录 | ||
gl = gitlab.Gitlab(url, token) | ||
|
||
# 获取仓库提交次数 | ||
def getcommits(): | ||
# 获取指定项目 | ||
project = gl.projects.get(197) | ||
sum = 0 | ||
list = ['dev','hotfixes','log','master','release'] | ||
for li in list: | ||
commits = project.commits.list(all=True,query_parameters={'ref_name': li}) | ||
print(li +":" + str(len(commits))) | ||
sum += len(commits) | ||
|
||
branches = project.branches.list() | ||
return sum | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# coding=utf-8 | ||
|
||
''' | ||
@author: zuozewei | ||
@file: notification.py | ||
@time: 2019/4/25 18:00 | ||
@description:dingTalk通知类 | ||
''' | ||
import os, jenkins, configparser, requests, json, time | ||
from dingtalkchatbot.chatbot import DingtalkChatbot | ||
from jsonpath import jsonpath | ||
|
||
JOB_NAME = str(os.getenv("JOB_NAME")) | ||
print("【JOB_NAME】:" + JOB_NAME) | ||
BUILD_URL = str(os.getenv("BUILD_URL")) + "console" | ||
BUILD_VERSION = str(os.getenv("BUILD_VERSION")) | ||
JENKINS_HOME = os.getenv("JENKINS_HOME") | ||
BUILD_NUMBER = str(os.getenv("BUILD_NUMBER")) | ||
WORKSPACE = os.getenv("WORKSPACE") | ||
|
||
versionPath = JENKINS_HOME + "\workspace\Version.ini" | ||
|
||
config = configparser.ConfigParser() | ||
config.read(versionPath) | ||
xxx_Major = config.get("xxx", "xxx_Major") | ||
xxx_Minor = config.get("xxx", "xxx_Minor") | ||
xxx_Build = config.get("xxx", "xxx_Build") | ||
xxx_Revision = config.get("xxx", "xxx_Revision") | ||
VERSION = xxx_Major + "." + xxx_Minor + "." + xxx_Build + "." +xxx_Revision | ||
print("【当前版本】:" + VERSION) | ||
|
||
packagePath = WORKSPACE + "\\package.ini" | ||
|
||
def packagNotification(): | ||
title = 'xxxx打包通知' | ||
|
||
# 获取打包信息 | ||
packagconfig = configparser.ConfigParser() | ||
packagconfig.read(packagePath) | ||
packagName = packagconfig.get("package", "name") | ||
packagRemotedir = packagconfig.get("package", "remotedir") | ||
|
||
downloadlink = 'http://xxx.xx.xxx.xxx:8081/repository/' + packagRemotedir + packagName | ||
print("【Build】downloadlink:" + downloadlink) | ||
|
||
text = '#### ' + JOB_NAME + ' - Package # ' + BUILD_NUMBER + ' \n' + \ | ||
'##### **版本类型**: ' + '开发版' + '\n' + \ | ||
'##### **当前版本**: ' + VERSION + '\n' + \ | ||
'##### **仓库类型**: ' + 'Nexus 3 OSS' + '\n' + \ | ||
'##### **文件格式**: ' + 'raw' + '\n' + \ | ||
'##### **文件名称**: ' + packagName + '\n' + \ | ||
'##### **文件地址**: [点击下载](' + downloadlink + ') \n' + \ | ||
'> ###### xxx技术团队 \n ' | ||
|
||
sendding(title, text) | ||
|
||
|
||
def sendding(title, content): | ||
at_mobiles = ['186xxxx2487'] | ||
Dingtalk_access_token = 'https://oapi.dingtalk.com/robot/send?access_token=xxxx' | ||
# 初始化机器人小丁 | ||
xiaoding = DingtalkChatbot(Dingtalk_access_token) | ||
# Markdown消息@指定用户 | ||
xiaoding.send_markdown(title=title, text=content, at_mobiles=at_mobiles) | ||
|
||
if __name__ == "__main__": | ||
packagNotification() |
Oops, something went wrong.