forked from rowanj/gitx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.py
executable file
·122 lines (93 loc) · 3.62 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python
import argh
import subprocess
import os
import package
import sign
app="GitX"
product="%s.app" % (app,)
label="dev"
base_version="0.15"
signing_key="Developer ID Application: Rowan James"
artifact_prefix= "%s-%s" % (app, label)
workspace="%s.xcodeproj/project.xcworkspace" % (app,)
debug_configuration="Debug"
release_configuration="Release"
agvtool="xcrun agvtool"
release_branch="master"
configuration=""
clean=""
pause=3
build_base_dir = os.path.join(os.getcwd(), "build")
class BuildError(RuntimeError):
pass
def clean():
clean_config(debug_configuration)
clean_config(release_configuration)
def release():
try:
assert_clean()
assert_branch(release_branch)
build_number = commit_count()
set_versions(base_version, build_number, "dev")
build_config(release_configuration)
build_dir = os.path.join(build_base_dir, release_configuration)
built_product = os.path.join(build_dir, product)
sign_app(built_product)
image_path = os.path.join(build_dir, "%s-%s.dmg" % (artifact_prefix, build_number))
image_name = "%s %s" % (app, build_number)
package_app(built_product, image_path, image_name)
except BuildError as e:
print("error: %s" % (str(e),))
def debug():
try:
build_config(debug_configuration)
except BuildError as e:
print("error: %s" % (str(e),))
@argh.arg("configuration", choices=['debug','release'])
def build(configuration):
if configuration == "debug":
debug()
if configuration == "release":
release()
def assert_clean():
status = check_string_output(["git", "status", "--porcelain"])
if len(status):
raise BuildError("Working copy must be clean")
def assert_branch(branch="master"):
ref = check_string_output(["git", "rev-parse", "--abbrev-ref", "HEAD"])
if ref != branch:
raise BuildError("HEAD must be %s, but is %s" % (branch, ref))
def build_config(config):
build_dir = os.path.join(build_base_dir, config)
xcodebuild(app, workspace, config, ["build"], build_dir)
def clean_config(config):
build_dir = os.path.join(build_base_dir, config)
xcodebuild(app, workspace, config, ["clean"], build_dir)
def commit_count():
count = check_string_output(["git", "rev-list", "HEAD", "--count"])
return count
def set_versions(base_version, build_number, label):
print("mvers: " + check_string_output(["agvtool", "mvers", "-terse1"]))
print("vers: " + check_string_output(["agvtool", "vers", "-terse"]))
marketing_version = "%s.%s %s" % (base_version, build_number, label)
build_version = "%s.%s" % (base_version, build_number)
subprocess.check_call(["agvtool", "new-marketing-version", marketing_version])
subprocess.check_call(["agvtool", "new-version", "-all", build_version])
def xcodebuild(scheme, workspace, configuration, commands, build_dir):
cmd = ["xcrun", "xcodebuild", "-scheme", scheme, "-workspace", workspace, "-configuration", configuration]
cmd = cmd + commands
cmd.append('CONFIGURATION_BUILD_DIR=%s' % (build_dir))
try:
output = check_string_output(cmd)
return output
except subprocess.CalledProcessError as e:
raise BuildError(str(e))
def check_string_output(command):
return subprocess.check_output(command).decode().strip()
def sign_app(app_path):
sign.sign_everything_in_app(app_path, key=signing_key)
def package_app(app_path, image_path, image_name):
package.package(app_path, image_path, image_name)
if __name__ == "__main__":
argh.dispatch_commands([clean, build])