Skip to content

Commit 9427252

Browse files
committed
create deploy script
1 parent f1608a1 commit 9427252

File tree

4 files changed

+225
-0
lines changed

4 files changed

+225
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,7 @@ com_crashlytics_export_strings.xml
5656
crashlytics.properties
5757
crashlytics-build.properties
5858
fabric.properties
59+
60+
# Deply Script
61+
deploy/env
62+
deploy/credentials.json

deploy/askpass.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Short script for use with git credentials.
4+
# intended to be called by Git via GIT_ASKPASS.
5+
#
6+
import json
7+
import os
8+
from sys import argv
9+
10+
current_dir = os.path.dirname(os.path.abspath(__file__))
11+
with open(os.path.join(current_dir, 'credentials.json')) as file:
12+
json_str = file.read()
13+
credentials = json.loads(json_str)
14+
15+
if 'username' in argv[1].lower() and 'git_username' in credentials:
16+
print(credentials['git_username'])
17+
exit()
18+
19+
if 'password' in argv[1].lower() and 'git_pwd' in credentials:
20+
print(credentials['git_pwd'])
21+
exit()
22+
23+
exit(1)

deploy/deploy.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import re
2+
import os
3+
import glob
4+
import json
5+
import argparse
6+
import requests
7+
8+
from git import Repo
9+
from subprocess import call
10+
11+
12+
def read_credentials():
13+
try:
14+
with open("credentials.json") as credentials:
15+
json_str = credentials.read()
16+
data = json.loads(json_str)
17+
18+
if "github_access_token" not in data:
19+
return None
20+
if "git_username" not in data:
21+
return None
22+
if "git_pwd" not in data:
23+
return None
24+
25+
return data
26+
except:
27+
return None
28+
29+
30+
def cleanup_old_releases():
31+
current_releases = glob.glob("../build/libs/*")
32+
for release in current_releases:
33+
os.remove(release)
34+
35+
36+
def get_release_notes(repo, last_release_tag):
37+
commits = list(repo.iter_commits("{}..HEAD".format(last_release_tag)))
38+
changes = ["* {}".format(c.summary) for c in commits]
39+
return "\n".join(changes)
40+
41+
42+
def should_continue_release(release_notes, release_version):
43+
print(
44+
f"\n\n****Deploying release {release_version} with below changes****")
45+
print("------------------------------------------------------------")
46+
print(release_notes + "\n")
47+
48+
answer = ""
49+
while answer not in ["y", "n"]:
50+
answer = input("Proceed with deploy [Y/N]? ").lower()
51+
return answer == "y"
52+
53+
54+
def update_properties_file(new_release_version):
55+
with open("../app.properties", "r+") as file:
56+
text = file.read()
57+
text = re.sub(r"version=\d+\.?\d*",
58+
f"version={new_release_version}", text)
59+
file.seek(0)
60+
file.write(text)
61+
file.truncate()
62+
63+
64+
def commit_version_change(repo, release_version):
65+
repo.index.add(["src/main/resources/properties/app.properties"])
66+
repo.index.commit(f"Increment version for release {release_version}")
67+
68+
69+
def build_release(make_jar):
70+
target = "shadowJar" if make_jar else "build"
71+
status = call(f"./gradlew {target}", cwd="..", shell=True)
72+
return status == 0
73+
74+
75+
def test_release():
76+
status = call("./gradlew test", cwd="..", shell=True)
77+
return status == 0
78+
79+
80+
def push_changes(repo, tag_name):
81+
current_dir = os.path.dirname(os.path.abspath(__file__))
82+
askpass_script = os.path.join(current_dir, 'askpass.py')
83+
os.environ['GIT_ASKPASS'] = askpass_script
84+
85+
origin = repo.remote(name='origin')
86+
origin.push('HEAD')
87+
origin.push(tag_name)
88+
89+
90+
def create_github_release(access_token, tag_name, release_notes, release_path):
91+
release_binary_name = f"LogViewer_{tag_name}.jar"
92+
93+
url = "https://api.github.com/repos/tibagni/LogViewer/releases"
94+
headers = {
95+
"Authorization": f"token {access_token}"
96+
}
97+
release_content = {
98+
"tag_name": str(tag_name),
99+
"name": str(tag_name),
100+
"body": release_notes
101+
}
102+
103+
resp = requests.post(url, json=release_content, headers=headers)
104+
resp.raise_for_status()
105+
106+
upload_url = resp.json()["upload_url"]
107+
upload_url = re.sub(r"{.*}", f"?name={release_binary_name}", upload_url)
108+
files = {release_binary_name: open(release_path, 'rb')}
109+
110+
resp = requests.post(upload_url, files=files, headers=headers)
111+
resp.raise_for_status()
112+
113+
return resp.json()["url"]
114+
115+
116+
def main():
117+
parser = argparse.ArgumentParser()
118+
parser.add_argument('tag', type=str, help='new release TAG')
119+
option = parser.parse_args()
120+
121+
CREDENTIALS = read_credentials() or None
122+
repo = Repo("..")
123+
new_version = float(option.tag)
124+
last_version = float(str(repo.tags[-1]))
125+
126+
if CREDENTIALS is None:
127+
print("Missing credentials.json file")
128+
print("""
129+
Credentials file should be in the following format:
130+
{
131+
"github_access_token": "<github access token>",
132+
"git_username": "<git username>",
133+
"git_pwd": "<git password>"
134+
}
135+
""")
136+
exit(1)
137+
138+
if "nothing to commit" not in repo.git.status():
139+
print("There are uncommitted changes. Aborting...")
140+
exit(1)
141+
142+
if new_version <= last_version:
143+
print(f"New version ({new_version}) is not higher "
144+
f"than last version ({last_version}). Aborting...")
145+
exit(1)
146+
147+
if not test_release():
148+
print("This release is not passing the tests. Aborting...")
149+
exit(1)
150+
151+
if not build_release(make_jar=False):
152+
print("Releae build failed. Aborting...")
153+
exit(1)
154+
155+
print(f"Creating release {new_version}...")
156+
157+
release_notes = get_release_notes(repo, last_version)
158+
if not should_continue_release(release_notes, new_version):
159+
exit(0)
160+
161+
print("Cleaning up old releases...")
162+
cleanup_old_releases()
163+
164+
print(f"Updating version to {new_version}...")
165+
update_properties_file(new_version)
166+
167+
print("committing and pushing changes...")
168+
commit_version_change(repo, new_version)
169+
repo.create_tag(new_version)
170+
push_changes(repo, new_version)
171+
172+
build_release(make_jar=True)
173+
release_path = glob.glob("../build/libs/*")[0]
174+
175+
print("Creating new relese on github (this can take a while)...")
176+
try:
177+
release_url = create_github_release(
178+
CREDENTIALS["github_access_token"], new_version, release_notes, release_path)
179+
print(f"Release {new_version} successfully created: {release_url}")
180+
except Exception as e:
181+
print("Failed to create or upload github release. Try manually")
182+
print(e)
183+
exit(1)
184+
185+
186+
if __name__ == "__main__":
187+
main()

deploy/requirements.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
autopep8==1.5.3
2+
certifi==2020.4.5.2
3+
chardet==3.0.4
4+
gitdb==4.0.5
5+
GitPython==3.1.3
6+
idna==2.9
7+
pycodestyle==2.6.0
8+
requests==2.23.0
9+
smmap==3.0.4
10+
toml==0.10.1
11+
urllib3==1.25.9

0 commit comments

Comments
 (0)