3.2.1.9 : La génération des releases

Voici le createReleaseCurl.py : Commençons par définir l'interpeteur de notre script :
1
2
#!/usr/bin/env python
# coding: utf-8


Quelques import car nous allons utiliser curl pour intéragir avec l'API de Gitlab afin de créer notre release :
1
2
3
4
5
6
import sys
import os
import subprocess
import json
import glob
import argparse


Petite description du server Gitlab du CC :
1
2
server="gitlab.in2p3.fr"
apiProject="/api/v4/projects/"


Fonction qui récupère tous les paquets d'un projet donné (avec un glob) :
1
2
3
4
5
6
7
8
9
10
11
12
def getListArchiveFile(inputDirectory, projectName):
	'''
	Get the list of the archives file for a given project name
	Parameters:
		inputDirectory : directory (for one OS) where all the binary packages are created
		projectName : name of the project
	Return:
		list of corresponding binary packages
	'''
	listPackage = glob.glob(inputDirectory + "/*/" + projectName + "-*" )
	print(listPackage)
	return listPackage


Fonction qui permet d'uploader des fichiers avec curl :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/projects/5/uploads"
def uploadFileCommand(projectIdOwn, fileName, token):
	'''
	Upload a file in the given gitlab project
	Parameters:
		projectIdOwn : id of the project
		fileName : name of the file to be uploaded
		token : token to be used to create the release
	Return:
		url of the uploaded file
	'''
	print("Upload file",fileName)
	URL = '"https://'+server+apiProject+str(projectIdOwn)+'/uploads"'
	privateToken='--header "PRIVATE-TOKEN: '+token+'" '
	fileCmd = '--form "file=@'+fileName+'" '
	command = "curl --insecure --request POST " + privateToken + fileCmd + URL
	#print("Updload file command :", command)
	output = subprocess.getoutput(command)
	print("Upload file output :",output)
	outputDico = json.loads('{' + output.split("{")[1])
	outputFile = outputDico["full_path"]
	outputUrl = outputDico["full_path"]
	print("Upload file output file ",outputFile, ", url :",outputUrl)
	return outputFile, outputUrl


Fonction qui renvoie la liste des fichiers uploadés dans la release :
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
# { "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64", "link_type":"other" }
def getListArchiveLinks(projectIdOwn, listPackage, useComma, token):
	'''
	Create the list of link to the archive uploaded binary packages
	Parameters:
		projectIdOwn : id of the project to be used
		listPackage : list of the binary packages to be uploaded and linked
		useComma : True to add a comma in the first place, false otherwise
		token : token to be used to create the release
	Return:
		string of the list of archive links corresponding to the given list of packages
	'''
	linksData = ""
	for packageName in listPackage:
		if useComma:
			linksData += ", "
		baseName = os.path.basename(packageName)
		packageOsName = packageName.split('/')[-2]
		nameData = "name": " + packageOsName + " " + baseName+"""
		
		uploadedFullPath, outputUrl = uploadFileCommand(projectIdOwn, packageName, token)
		print("outputUrl =",outputUrl)
		fullPathToFile = 'https://'+server+"/"+uploadedFullPath
		#filePathData = '"filepath": "'+fullPathToFile+'"' 
		linkType = '"link_type": "other" '
		urlData = '"url": "'+fullPathToFile+'"'
		
		addDataLink = '{ '+nameData + ", " + urlData + ", " + linkType +'}'
		print("addDataLink =",addDataLink)
		linksData += addDataLink
		useComma = True
	
	return linksData


Fonction qui créé la release proprement dite :
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
def createReleaseCurlCommand(projectIdOwn, projectName, projectTagName, basePackageDir, token):
	'''
	Create a release of the given project
	Parameters:
		projectIdOwn : id of the project on gitlab
		projectName : name of the project
		projectTagName : tag name of the project
		basePackageDir : base directory wher eto find binary packages
		token : token to be used to create the release
	'''
	postURL="--request POST https://"+server+apiProject+str(projectIdOwn)+"/releases"
	header="--header 'Content-Type: application/json' "
	privateToken='--header "PRIVATE-TOKEN: '+token+'" '
	versionName="version " + projectTagName
	dataStr = "--data '{ name": Release "+versionName+""," + "tag_name": "+projectTagName+"","
	dataStr += "description": Automatic release, "+versionName+"""
	
	useComma = False
	linksData = ", assets": { links": ["
	listArchiveFile = getListArchiveFile(basePackageDir + "/", projectName)
	linksData += getListArchiveLinks(projectIdOwn, listArchiveFile, useComma, token)
	linksData += "] } "
	dataStr += linksData
	dataStr += "}' "
	command = "curl --insecure " + header + privateToken + dataStr + postURL
	print("Create Release command :",command)
	output = subprocess.getoutput(command)
	print("Release Output :",output)


Petit parsing d'argument passés au programme :
1
2
3
4
5
6
7
8
9
10
if __name__ == "__main__":
	parser = argparse.ArgumentParser(description="Program which creates release with given tag")
	parser.add_argument('-n', '--projectname', help="Name of the current projet", required=True, type=str)
	parser.add_argument('-i', '--projectid', help="Id of the current projet", required=True, type=int)
	parser.add_argument('-t', '--tag', help="Tag to be used to create the current release", required=True, type=str)
	parser.add_argument('-p', '--token', help="Token to be used to create the release", required=True, type=str)
	parser.add_argument('-d', '--packagedirectory', help="Directory where to find packages", required=False, type=str, default="./")
	args = parser.parse_args()
	
	createReleaseCurlCommand(args.projectid, args.projectname, args.tag, args.packagedirectory, args.token)


Pour conlure, on peu dire que curl est ultra-puissant mais est délicas à prendre en main. Le fichier createReleaseCurl.py complet :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python
# coding: utf-8

import sys
import os
import subprocess
import json
import glob
import argparse

server="gitlab.in2p3.fr"
apiProject="/api/v4/projects/"

def getListArchiveFile(inputDirectory, projectName):
	'''
	Get the list of the archives file for a given project name
	Parameters:
		inputDirectory : directory (for one OS) where all the binary packages are created
		projectName : name of the project
	Return:
		list of corresponding binary packages
	'''
	listPackage = glob.glob(inputDirectory + "/*/" + projectName + "-*" )
	print(listPackage)
	return listPackage


#curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/projects/5/uploads"
def uploadFileCommand(projectIdOwn, fileName, token):
	'''
	Upload a file in the given gitlab project
	Parameters:
		projectIdOwn : id of the project
		fileName : name of the file to be uploaded
		token : token to be used to create the release
	Return:
		url of the uploaded file
	'''
	print("Upload file",fileName)
	URL = '"https://'+server+apiProject+str(projectIdOwn)+'/uploads"'
	privateToken='--header "PRIVATE-TOKEN: '+token+'" '
	fileCmd = '--form "file=@'+fileName+'" '
	command = "curl --insecure --request POST " + privateToken + fileCmd + URL
	#print("Updload file command :", command)
	output = subprocess.getoutput(command)
	print("Upload file output :",output)
	outputDico = json.loads('{' + output.split("{")[1])
	outputFile = outputDico["full_path"]
	outputUrl = outputDico["full_path"]
	print("Upload file output file ",outputFile, ", url :",outputUrl)
	return outputFile, outputUrl


# { "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64", "link_type":"other" }
def getListArchiveLinks(projectIdOwn, listPackage, useComma, token):
	'''
	Create the list of link to the archive uploaded binary packages
	Parameters:
		projectIdOwn : id of the project to be used
		listPackage : list of the binary packages to be uploaded and linked
		useComma : True to add a comma in the first place, false otherwise
		token : token to be used to create the release
	Return:
		string of the list of archive links corresponding to the given list of packages
	'''
	linksData = ""
	for packageName in listPackage:
		if useComma:
			linksData += ", "
		baseName = os.path.basename(packageName)
		packageOsName = packageName.split('/')[-2]
		nameData = "name": " + packageOsName + " " + baseName+"""
		
		uploadedFullPath, outputUrl = uploadFileCommand(projectIdOwn, packageName, token)
		print("outputUrl =",outputUrl)
		fullPathToFile = 'https://'+server+"/"+uploadedFullPath
		#filePathData = '"filepath": "'+fullPathToFile+'"' 
		linkType = '"link_type": "other" '
		urlData = '"url": "'+fullPathToFile+'"'
		
		addDataLink = '{ '+nameData + ", " + urlData + ", " + linkType +'}'
		print("addDataLink =",addDataLink)
		linksData += addDataLink
		useComma = True
	
	return linksData


def createReleaseCurlCommand(projectIdOwn, projectName, projectTagName, basePackageDir, token):
	'''
	Create a release of the given project
	Parameters:
		projectIdOwn : id of the project on gitlab
		projectName : name of the project
		projectTagName : tag name of the project
		basePackageDir : base directory wher eto find binary packages
		token : token to be used to create the release
	'''
	postURL="--request POST https://"+server+apiProject+str(projectIdOwn)+"/releases"
	header="--header 'Content-Type: application/json' "
	privateToken='--header "PRIVATE-TOKEN: '+token+'" '
	versionName="version " + projectTagName
	dataStr = "--data '{ name": Release "+versionName+""," + "tag_name": "+projectTagName+"","
	dataStr += "description": Automatic release, "+versionName+"""
	
	useComma = False
	linksData = ", assets": { links": ["
	listArchiveFile = getListArchiveFile(basePackageDir + "/", projectName)
	linksData += getListArchiveLinks(projectIdOwn, listArchiveFile, useComma, token)
	linksData += "] } "
	dataStr += linksData
	dataStr += "}' "
	command = "curl --insecure " + header + privateToken + dataStr + postURL
	print("Create Release command :",command)
	output = subprocess.getoutput(command)
	print("Release Output :",output)


if __name__ == "__main__":
	parser = argparse.ArgumentParser(description="Program which creates release with given tag")
	parser.add_argument('-n', '--projectname', help="Name of the current projet", required=True, type=str)
	parser.add_argument('-i', '--projectid', help="Id of the current projet", required=True, type=int)
	parser.add_argument('-t', '--tag', help="Tag to be used to create the current release", required=True, type=str)
	parser.add_argument('-p', '--token', help="Token to be used to create the release", required=True, type=str)
	parser.add_argument('-d', '--packagedirectory', help="Directory where to find packages", required=False, type=str, default="./")
	args = parser.parse_args()
	
	createReleaseCurlCommand(args.projectid, args.projectname, args.tag, args.packagedirectory, args.token)
Lien de téléchargement ici.