From ca6ed447e61e788455b74f325e0a8efbe51c57bb Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 6 Jun 2018 12:09:48 -0400 Subject: [PATCH 1/7] Got started writting a tool to automate ripme releases --- release.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 release.py diff --git a/release.py b/release.py new file mode 100644 index 00000000..f003cdc3 --- /dev/null +++ b/release.py @@ -0,0 +1,48 @@ +import re + +import os + +import sys +from github import Github +import json +from datetime import timezone +import datetime +import argparse + +parser = argparse.ArgumentParser(description="Make a new ripme release on github") +parser.add_argument("-f", "--file", help="Path to the version of ripme to release") +parser.add_argument("-t", "--token", help="Your github personal access token") +parser.add_argument("-d", "--debug", help="Run in debug mode", action="store_true") +args = parser.parse_args() + + +# Make sure the file the user selected is a jar +def isJar(filename): + if debug: + print("Checking if {} is a jar file".format(filename)) + return filename.endswith("jar") + + +def isValidCommitMessage(message): + if debug: + print("Checking if {} matchs pattern ^\d+\.\d+\.\d+:".format(message)) + pattern = re.compile("^\d+\.\d+\.\d+:") + return re.match(pattern, message) + + +fileToUpload = args.file +commitMessage = json.loads(open("ripme.json").read()).get("changeList")[0] +debug = args.debug + + +if not os.path.isfile(fileToUpload): + print("[!] Error: {} does not exist".format(fileToUpload)) + sys.exit(1) + +if not isJar(fileToUpload): + print("[!] Error: {} is not a jar file!".format(fileToUpload)) + sys.exit(1) + +if not isValidCommitMessage(commitMessage): + print("[!] Error: {} is not a valid commit message as it does not start with a version".format(fileToUpload)) + sys.exit(1) \ No newline at end of file From 8e4f91ada22ba016a25088bcd6474bc27f12f895 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 6 Jun 2018 12:33:53 -0400 Subject: [PATCH 2/7] release.py now checks to make sure file hash is correct; release.py now asks the user to review the filepath and release title are correct --- release.py | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/release.py b/release.py index f003cdc3..6174d81a 100644 --- a/release.py +++ b/release.py @@ -3,6 +3,7 @@ import re import os import sys +from hashlib import sha256 from github import Github import json from datetime import timezone @@ -13,6 +14,7 @@ parser = argparse.ArgumentParser(description="Make a new ripme release on github parser.add_argument("-f", "--file", help="Path to the version of ripme to release") parser.add_argument("-t", "--token", help="Your github personal access token") parser.add_argument("-d", "--debug", help="Run in debug mode", action="store_true") +parser.add_argument("-n", "--non-interactive", help="Do not ask for any input from the user", action="store_true") args = parser.parse_args() @@ -23,6 +25,8 @@ def isJar(filename): return filename.endswith("jar") +# Returns true if last entry to the "changeList" section of ripme.json is in the format of $number.$number.$number: and +# false if not def isValidCommitMessage(message): if debug: print("Checking if {} matchs pattern ^\d+\.\d+\.\d+:".format(message)) @@ -30,19 +34,41 @@ def isValidCommitMessage(message): return re.match(pattern, message) -fileToUpload = args.file -commitMessage = json.loads(open("ripme.json").read()).get("changeList")[0] +ripmeJson = json.loads(open("ripme.json").read()) +fileToUploadPath = args.file +InNoninteractiveMode = args.non_interactive +commitMessage = ripmeJson.get("changeList")[0] debug = args.debug - -if not os.path.isfile(fileToUpload): - print("[!] Error: {} does not exist".format(fileToUpload)) +if not os.path.isfile(fileToUploadPath): + print("[!] Error: {} does not exist".format(fileToUploadPath)) sys.exit(1) -if not isJar(fileToUpload): - print("[!] Error: {} is not a jar file!".format(fileToUpload)) +if not isJar(fileToUploadPath): + print("[!] Error: {} is not a jar file!".format(fileToUploadPath)) sys.exit(1) if not isValidCommitMessage(commitMessage): - print("[!] Error: {} is not a valid commit message as it does not start with a version".format(fileToUpload)) - sys.exit(1) \ No newline at end of file + print("[!] Error: {} is not a valid commit message as it does not start with a version".format(fileToUploadPath)) + sys.exit(1) + +ripmeUpdate = open(fileToUploadPath, mode='rb').read() + +# The hash that we expect the update to have +expectedHash = ripmeJson.get("currentHash") + +# The actual hash of the file on disk +actualHash = sha256(ripmeUpdate).hexdigest() + +# Make sure that the hash of the file we're uploading matches the hash in ripme.json. These hashes not matching will +# cause ripme to refuse to install the update for all users who haven't disabled update hash checking +if expectedHash != actualHash: + print("[!] Error: expected hash of file and actual hash differ") + print("[!] Expected hash is {}".format(expectedHash)) + print("[!] Actual hash is {}".format(actualHash)) + +# This only runs in we're in interactive mode +if not InNoninteractiveMode: + print("File path: {}\n".format(fileToUploadPath)) + print("Release title: {}".format(commitMessage)) + input("\nPlease review the information above and ensure it is correct and then press enter") \ No newline at end of file From 086e52cd65021faf8bb407fc1e0301a1c299527a Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 7 Jun 2018 04:48:43 -0400 Subject: [PATCH 3/7] More work on release.py --- release.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/release.py b/release.py index 6174d81a..00b95351 100644 --- a/release.py +++ b/release.py @@ -39,6 +39,7 @@ fileToUploadPath = args.file InNoninteractiveMode = args.non_interactive commitMessage = ripmeJson.get("changeList")[0] debug = args.debug +accessToken = args.token if not os.path.isfile(fileToUploadPath): print("[!] Error: {} does not exist".format(fileToUploadPath)) @@ -67,8 +68,12 @@ if expectedHash != actualHash: print("[!] Expected hash is {}".format(expectedHash)) print("[!] Actual hash is {}".format(actualHash)) +# Ask the user to review the information before we precede # This only runs in we're in interactive mode if not InNoninteractiveMode: print("File path: {}\n".format(fileToUploadPath)) print("Release title: {}".format(commitMessage)) - input("\nPlease review the information above and ensure it is correct and then press enter") \ No newline at end of file + input("\nPlease review the information above and ensure it is correct and then press enter") + +print("Accessing github using token") +g = Github(accessToken) \ No newline at end of file From 3084d048937032a92ef87e38ebafa6f997719ab6 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 7 Jun 2018 06:07:03 -0400 Subject: [PATCH 4/7] Can now publish new release automatically --- release.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/release.py b/release.py index 00b95351..31f61217 100644 --- a/release.py +++ b/release.py @@ -6,8 +6,6 @@ import sys from hashlib import sha256 from github import Github import json -from datetime import timezone -import datetime import argparse parser = argparse.ArgumentParser(description="Make a new ripme release on github") @@ -38,8 +36,11 @@ ripmeJson = json.loads(open("ripme.json").read()) fileToUploadPath = args.file InNoninteractiveMode = args.non_interactive commitMessage = ripmeJson.get("changeList")[0] +releaseVersion = ripmeJson.get("latestVersion") debug = args.debug accessToken = args.token +repoOwner = "ripmeapp" +repoName = "ripme" if not os.path.isfile(fileToUploadPath): print("[!] Error: {} does not exist".format(fileToUploadPath)) @@ -71,9 +72,17 @@ if expectedHash != actualHash: # Ask the user to review the information before we precede # This only runs in we're in interactive mode if not InNoninteractiveMode: - print("File path: {}\n".format(fileToUploadPath)) + print("File path: {}".format(fileToUploadPath)) print("Release title: {}".format(commitMessage)) + print("Repo: {}/{}".format(repoOwner, repoName)) input("\nPlease review the information above and ensure it is correct and then press enter") print("Accessing github using token") -g = Github(accessToken) \ No newline at end of file +g = Github(accessToken) + + +print("Creating release") +release = g.get_user(repoOwner).get_repo(repoName).create_git_release(releaseVersion, commitMessage, "") + +print("Uploading file") +release.upload_asset(fileToUploadPath, "ripme.jar") From 3eccf29596f9f68b54a69008a1eae77d2f7f0d9b Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 7 Jun 2018 06:15:14 -0400 Subject: [PATCH 5/7] Script now prints error and exits on hash missmatch --- release.py | 1 + 1 file changed, 1 insertion(+) diff --git a/release.py b/release.py index 31f61217..4217d94c 100644 --- a/release.py +++ b/release.py @@ -68,6 +68,7 @@ if expectedHash != actualHash: print("[!] Error: expected hash of file and actual hash differ") print("[!] Expected hash is {}".format(expectedHash)) print("[!] Actual hash is {}".format(actualHash)) + sys.exit(1) # Ask the user to review the information before we precede # This only runs in we're in interactive mode From 1b6c379e3619e1a29834ec995dc83f56bacc4b25 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 7 Jun 2018 06:16:27 -0400 Subject: [PATCH 6/7] Added shebang --- release.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release.py b/release.py index 4217d94c..16713122 100644 --- a/release.py +++ b/release.py @@ -1,3 +1,5 @@ +#!/usr/bin/python3 + import re import os From 09b8429c283ed6e34385777b98f655c38bac265a Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 7 Jun 2018 06:25:49 -0400 Subject: [PATCH 7/7] Now works both in python2 and python3 --- release.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release.py b/release.py index 16713122..3dcd3210 100644 --- a/release.py +++ b/release.py @@ -17,6 +17,11 @@ parser.add_argument("-d", "--debug", help="Run in debug mode", action="store_tru parser.add_argument("-n", "--non-interactive", help="Do not ask for any input from the user", action="store_true") args = parser.parse_args() +try: + input = raw_input +except NameError: + pass + # Make sure the file the user selected is a jar def isJar(filename):