Skip to content

Instantly share code, notes, and snippets.

@jimmylin212
Last active April 8, 2019 10:19
Show Gist options
  • Save jimmylin212/7f9196914b40fe43f68f4129102b1de7 to your computer and use it in GitHub Desktop.
Save jimmylin212/7f9196914b40fe43f68f4129102b1de7 to your computer and use it in GitHub Desktop.
The python version that create commit by GitHub API
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