diff --git a/gitlabreleaseuploader.py b/gitlabreleaseuploader.py index f01b059..aa268c3 100755 --- a/gitlabreleaseuploader.py +++ b/gitlabreleaseuploader.py @@ -16,7 +16,7 @@ parser.add_argument('--projectUrl', '-u', parser.add_argument('--file', '-f', help='File to be released, can appear multiple times', action='append', - required=True) + required=False) parser.add_argument('--releaseName', '-n', help='Name of the release', required=False, default='') @@ -102,121 +102,160 @@ if (releaseInfoFilename): if releaseName == '': raise Exception('No release name given') -if releaseTag == '': - raise Exception('No release tag given') +if (releaseTag == '') and createRelease: + raise Exception('No release tag given but creation of release requested') if (releaseTagTarget == '') and createReleaseTag: raise Exception('No release tag target given but creation of tag requested') -if releaseDescription == '': - raise Exception('No release description given') +if (releaseDescription == '') and createRelease: + raise Exception('No release description given but creation of release requested') if insecure: caBundle = (False) + +def checkAndShowResult(result, expectedCode, errorMessage): + global verbose + + if result.status_code != expectedCode: + print(result) + print(result.text) + raise Exception(errorMessage) + + if verbose: + print(result) + print(result.text) + + # --- upload the file -uploadUrl = "%s/api/v4/projects/%s/uploads" % (instanceUrl, projectId) -headers = {"PRIVATE-TOKEN": privateToken} +assets = [] # is required later, must be defined +if filesToUpload: + url = "%s/api/v4/projects/%s/uploads" % (instanceUrl, projectId) + headers = {"PRIVATE-TOKEN": privateToken} -assets = [] + for filename in filesToUpload: + with open(filename, 'rb') as filehandle: + files = {"file": filehandle} -for filename in filesToUpload: - with open(filename, 'rb') as filehandle: - files = {"file": filehandle} + if verbose: + print("POST to {}".format(url)) + result = requests.post(url, files=files, headers=headers, verify=caBundle) - uploadResult = requests.post(uploadUrl, files=files, headers=headers, verify=caBundle) + checkAndShowResult(result, 201, 'Unable to upload file to Gitlab') - if uploadResult.status_code != 201: - print(uploadResult) - print(uploadResult.text) - raise Exception('Unable to upload file to Gitlab') + assetUrl = projectUrl + json.loads(result.text)['url'] + assets.append({'name': filename, 'url': assetUrl, 'id': "new-link-{}".format(len(assets))}) - if verbose: - print(uploadResult) - print(uploadResult.text) - - url = projectUrl + json.loads(uploadResult.text)['url'] - assets.append({'name': filename, 'url': url, 'id': "new-link-{}".format(len(assets))}) - - print('File {} successfully uploaded, url is {}'.format(filename, url)) + print('File {} successfully uploaded, url is {}'.format(filename, assetUrl)) # --- create release tag if createReleaseTag: - createReleaseTagUrl = ("%s/api/v4//projects/%s/repository/tags" % - (instanceUrl, projectId)) - headers = {"PRIVATE-TOKEN": privateToken, - "Content-Type": "application/json"} + url = ("%s/api/v4//projects/%s/repository/tags" % (instanceUrl, projectId)) + headers = {"PRIVATE-TOKEN": privateToken, "Content-Type": "application/json"} - payloadCreateReleaseTag = { + payload = { "tag_name": releaseTag, "id": projectId, "ref": releaseTagTarget, "message": "Tag for release %s" % releaseName } - createReleaseTagResult = requests.post(createReleaseTagUrl, - headers=headers, - data=json.dumps(payloadCreateReleaseTag), - verify=caBundle) - - if createReleaseTagResult.status_code != 201: - print(createReleaseTagResult) - print(createReleaseTagResult.text) - raise Exception('Unable to create release tag') - if verbose: - print(createReleaseTagResult) - print(createReleaseTagResult.text) + print("POST to {}".format(url)) + result = requests.post(url, headers=headers, data=json.dumps(payload), verify=caBundle) + + checkAndShowResult(result, 201, 'Unable to create release tag') + print('Tag successfully created') # --- create release if createRelease: - createReleaseUrl = "%s/api/v4/projects/%s/releases" % (instanceUrl, projectId) + url = "%s/api/v4/projects/%s/releases" % (instanceUrl, projectId) headers = {"PRIVATE-TOKEN": privateToken, "Content-Type": "application/json"} - payloadCreateRelease = { + payload = { "name": releaseName, "tag_name": releaseTag, "description": releaseDescription } - createReleaseResult = requests.post(createReleaseUrl, headers=headers, - data=json.dumps(payloadCreateRelease), - verify=caBundle) - - if createReleaseResult.status_code != 201: - print(createReleaseResult) - print(createReleaseResult.text) - raise Exception('Unable to create release') - if verbose: - print(createReleaseResult) - print(createReleaseResult.text) + print("POST to {}".format(url)) + result = requests.post(url, headers=headers, data=json.dumps(payload), verify=caBundle) + + checkAndShowResult(result, 201, 'Unable to create release') + print('Release successfully created') +## --- update release in case of additional description +if not createRelease and releaseDescription: + # --- get release to fetch existing description + url = "%s/api/v4/projects/%s/releases/%s" % (instanceUrl, projectId, releaseName) + headers = {"PRIVATE-TOKEN": privateToken} -attachAssetsToReleaseUrl = "%s/api/v4/projects/%s/releases/%s" % (instanceUrl, projectId, releaseTag) -headers = {"PRIVATE-TOKEN": privateToken, "Content-Type": "application/json"} + if verbose: + print("GET to {}".format(url)) + result = requests.get(url, headers=headers, verify=caBundle) -payloadAttachAssetsToRelease = { - "name": releaseName, - "tag_name": releaseTag, - "assets": { - "links": assets - }, - "description": releaseDescription -} + checkAndShowResult(result, 200, 'Unable to get release') + existingDescription = json.loads(result.text)['description'] + print("Existing description is {}".format(existingDescription)) -attachAssetsToReleaseResult = requests.put(attachAssetsToReleaseUrl, headers=headers, - data=json.dumps(payloadAttachAssetsToRelease), - verify=caBundle) + releaseDescription += "\n\n---------------------------------------------\n\n" + releaseDescription += existingDescription -if attachAssetsToReleaseResult.status_code != 200: - print(attachAssetsToReleaseResult) - print(attachAssetsToReleaseResult.text) - raise Exception('Unable to assets to release') + # --- update release + url = "%s/api/v4/projects/%s/releases/%s" % (instanceUrl, projectId, releaseName) + headers = {"PRIVATE-TOKEN": privateToken, "Content-Type": "application/json"} + payload = { + "name": releaseName, + "tag_name": releaseTag, + "description": releaseDescription + } + + if verbose: + print("PUT to {}".format(url)) + result = requests.put(url, headers=headers, data=json.dumps(payload), verify=caBundle) + + checkAndShowResult(result, 200, 'Unable to update release') + + print('Release successfully update') + + +## --- add assets +# get existing assets +headers = {"PRIVATE-TOKEN": privateToken} +url = "%s/api/v4/projects/%s/releases/%s" % (instanceUrl, projectId, releaseName) if verbose: - print(attachAssetsToReleaseResult) - print(attachAssetsToReleaseResult.text) -print('Assets attached to release successfully') + print("GET to {}".format(url)) +result = requests.get(url, headers=headers, verify=caBundle) +checkAndShowResult(result, 200, 'Unable to get release information') + +# add existing assets to list of assets +links = json.loads(result.text)['assets']['links'] +assets.extend(links) + +# delete existing assets +headers = {"PRIVATE-TOKEN": privateToken} +for link in links: + assetId = link['id'] + url = "%s/api/v4/projects/%s/releases/%s/assets/links/%s" % (instanceUrl, projectId, releaseName, assetId) + if verbose: + print("DELETE to {}".format(url)) + result = requests.delete(url, headers=headers, verify=caBundle) + checkAndShowResult(result, 200, 'Unable to delete asset') + print("Asset {} successfully deleted".format(assetId)) + + +# create all assets ("existing" and new) +headers = {"PRIVATE-TOKEN": privateToken, "Content-Type": "application/json"} +url = "%s/api/v4/projects/%s/releases/%s/assets/links" % (instanceUrl, projectId, releaseName) +for asset in assets: + if verbose: + print("POST to {}".format(url)) + result = requests.post(url, headers=headers, data=json.dumps(asset), verify=caBundle) + checkAndShowResult(result, 201, "Unable to create asset") + print("Asset {} successfully created".format(asset)) +