Last active
April 8, 2019 10:19
-
-
Save jimmylin212/7f9196914b40fe43f68f4129102b1de7 to your computer and use it in GitHub Desktop.
The python version that create commit by GitHub API
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
import os | |
import json | |
import base64 | |
import shutil | |
import urllib | |
import httplib | |
import urllib2 | |
import hashlib | |
import subprocess | |
from urlparse import urlparse | |
from argparse import ArgumentParser | |
BASE_URL = 'https://github.hpe.com/api/v3/repos' | |
OWNER = 'OWNER-NAME' | |
REPO = 'REPO-NAME' | |
BRANCH = 'BRANCH-NAME' | |
ACCESSTOKEN = '' | |
HEADERS = { | |
"Authorization": "token %s" % ACCESSTOKEN | |
} | |
COMMIT_FILES = [ | |
'path-to-file-to-be-commit' | |
] | |
TARGET_TREE_FILES = { | |
'file-in-the-tree': '' | |
} | |
COMMIT_MSG = 'COMMIT-MESSAGE' | |
def get_content_sha1(file_path): | |
query_url = '%s/%s/%s/contents/%s?ref=%s' % (BASE_URL, OWNER, REPO, file_path, BRANCH) | |
print('Get content from %s' % query_url) | |
request = urllib2.Request(query_url, headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error getting content') | |
readable_res = json.loads(response.read()) | |
content_sha1 = readable_res['sha'] | |
return content_sha1, readable_res['content'].replace('\n', '') | |
def create_blob(content_path): | |
query_url = '%s/%s/%s/git/blobs' % (BASE_URL, OWNER, REPO) | |
print('Create blob of %s from %s' % (content_path, query_url)) | |
with open(content_path, 'rb') as f: | |
content = f.read() | |
query_data = { | |
"content": content | |
} | |
request = urllib2.Request(query_url, data=json.dumps(query_data), headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error create commit') | |
readable_res = json.loads(response.read()) | |
commit_sha1 = readable_res["sha"] | |
return commit_sha1 | |
def get_refs_sha1(): | |
query_url = '%s/%s/%s/git/refs/heads/%s' % (BASE_URL, OWNER, REPO, BRANCH) | |
print('--------------------\nGet refs from %s' % query_url) | |
request = urllib2.Request(query_url, headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error getting refs') | |
readable_res = json.loads(response.read()) | |
parent_sha1 = readable_res['object']['sha'] | |
return parent_sha1 | |
def get_trees_sha1(sha1): | |
query_url = '%s/%s/%s/commits/%s' % (BASE_URL, OWNER, REPO, sha1) | |
print('--------------------\nGet trees from %s' % query_url) | |
request = urllib2.Request(query_url, headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error getting trees') | |
readable_res = json.loads(response.read()) | |
tree_sha1 = readable_res['commit']['tree']['sha'] | |
lastest_commit_msg = readable_res['commit']['message'] | |
if lastest_commit_msg == COMMIT_MSG: | |
return tree_sha1, False | |
else: | |
return tree_sha1, True | |
def create_new_tree(tree_sha1): | |
need_commit = False | |
cwd = os.getcwd() | |
query_url = '%s/%s/%s/git/trees' % (BASE_URL, OWNER, REPO) | |
print ('--------------------\nCreate new tree from %s with %s' % (query_url, tree_sha1)) | |
query_data = { | |
"base_tree": tree_sha1, | |
"tree": [] | |
} | |
for commit_file in COMMIT_FILES: | |
basic_content = { | |
"mode": "100644", | |
"type": "blob", | |
} | |
file_path = os.path.join(cwd, commit_file) | |
file_name = os.path.basename(file_path) | |
file_dir = os.path.dirname(file_path) | |
updated_file_path = os.path.join(cwd, file_dir, 'base_%s' % file_name) | |
content_path = os.path.relpath(updated_file_path) | |
content_sha, original_content_b64 = get_content_sha1(content_path) | |
with open(file_path, 'rb') as f: | |
updated_content_b64 = base64.b64encode(f.read()) | |
if original_content_b64 == updated_content_b64: | |
print('File %s is not changed, skip' % file_name) | |
else: | |
need_commit = True | |
updated_content_sha1 = create_blob(content_path) | |
basic_content['path'] = content_path | |
basic_content['sha'] = updated_content_sha1 | |
shutil.copy(file_path, updated_file_path) | |
query_data["tree"].append(basic_content) | |
print('Copy %s -> %s (%s)' % (file_name, os.path.basename(updated_file_path), basic_content['sha'])) | |
if need_commit: | |
request = urllib2.Request(query_url, data=json.dumps(query_data), headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error create tree') | |
readable_res = json.loads(response.read()) | |
new_tree_sha1 = readable_res["sha"] | |
return new_tree_sha1, need_commit | |
else: | |
return None, need_commit | |
def create_commit(parent_sha1, tree_sha1): | |
query_url = '%s/%s/%s/git/commits' % (BASE_URL, OWNER, REPO) | |
print('--------------------\nCreate commit to %s with \nparents: [%s], tree: %s' % (query_url, parent_sha1, tree_sha1)) | |
query_data = { | |
"message": "%s" % COMMIT_MSG, | |
"tree": tree_sha1, | |
"parents": [ parent_sha1 ], | |
} | |
request = urllib2.Request(query_url, data=json.dumps(query_data), headers=HEADERS) | |
try: | |
response = urllib2.urlopen(request) | |
except urllib2.HTTPError as e: | |
print('Error with code: %s' % e.code) | |
print('Error content: %s' % e.read()) | |
raise ValueError('Error create commit') | |
readable_res = json.loads(response.read()) | |
commit_sha1 = readable_res["sha"] | |
return commit_sha1 | |
def patch_refs(commit_sha1): | |
parsed_url = urlparse(BASE_URL) | |
query_data = { | |
'sha': commit_sha1, | |
'force': True | |
} | |
connect = httplib.HTTPSConnection(parsed_url.netloc) | |
query_url = "%s/%s/%s/git/refs/heads/%s" % (parsed_url.path, OWNER, REPO, BRANCH) | |
print('--------------------\nPatch commit %s to %s' % (commit_sha1, query_url)) | |
connect.request("PATCH", query_url, json.dumps(query_data), HEADERS) | |
response = connect.getresponse() | |
if response.status != 200: | |
print('Error with code: %s, reason: %s' % (response.code, response.reason)) | |
raise ValueError('Error patch commit') | |
response = json.loads(response.read()) | |
print('\nFinish!!!!\nPlease check the new commit at %s' % (response["object"]["url"])) | |
connect.close() | |
def main(): | |
try: | |
parent_sha1 = get_refs_sha1() | |
tree_sha1, new_commit = get_trees_sha1(parent_sha1) | |
if new_commit: | |
new_tree_sha1, need_commit = create_new_tree(tree_sha1) | |
if need_commit: | |
commit_sha1 = create_commit(parent_sha1, new_tree_sha1) | |
patch_refs(commit_sha1) | |
else: | |
print('Skip!!! There is no file to be commit') | |
else: | |
print('Skip!!! There is no new commit') | |
except ValueError as e: | |
print(e.message) | |
raise | |
if __name__ == '__main__': | |
parser = ArgumentParser() | |
parser.add_argument("access_token", help="access token to contact with GitHub") | |
args = parser.parse_args() | |
ACCESSTOKEN = args.access_token | |
if ACCESSTOKEN != '': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment