Skip to content

Commit 063d1e9

Browse files
authored
Automate release version updating (#1414)
1 parent 7b1ed98 commit 063d1e9

File tree

5 files changed

+256
-102
lines changed

5 files changed

+256
-102
lines changed

Releases/Manifests/5.3.0.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"FirebaseCore":"5.0.4",
3+
"FirebaseFirestore":"0.12.4"
4+
}

Releases/Manifests/README

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Each file in this directory corresponds with a Firebase release. The file
2+
includes a list of the podspecs and versions from this repo that updated in the
3+
Firebase release version indicated by the filename.

Releases/update-versions.py

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
#!/usr/bin/python
2+
3+
# Copyright 2018 Google
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""update-versions.py creates a release branch and commit with version updates.
18+
19+
With the required --version parameter, this script will update all files in
20+
the repo based on the versions in Releases/Manifests/{version}.json.
21+
22+
It will create a release branch, push and tag the updates, and push the
23+
updated podspecs to cpdc-internal.
24+
"""
25+
26+
import argparse
27+
import json
28+
import os
29+
import subprocess
30+
import sys
31+
import tempfile
32+
33+
test_mode = False # Flag to disable external repo updates
34+
35+
36+
def SetupArguments():
37+
"""SetupArguments sets up the set of command-line arguments.
38+
39+
Returns:
40+
Args: The set of command line arguments
41+
"""
42+
parser = argparse.ArgumentParser(description='Update Pod Versions')
43+
44+
parser.add_argument('--version', required=True, help='Firebase version')
45+
46+
parser.add_argument(
47+
'--test_mode',
48+
dest='test_mode',
49+
action='store_true',
50+
help='Log commands instead of updating public repo')
51+
52+
parser.add_argument(
53+
'--tag_update',
54+
dest='tag_update',
55+
action='store_true',
56+
help='Update the tags only')
57+
58+
args = parser.parse_args()
59+
return args
60+
61+
62+
def LogOrRun(command):
63+
"""Log or run a command depending on test_mode value.
64+
65+
Args:
66+
command: command to log or run.
67+
"""
68+
if test_mode:
69+
print 'Log only: {}'.format(command)
70+
else:
71+
os.system(command)
72+
73+
74+
def GetVersionData(git_root, version):
75+
"""Update version specifier in FIROptions.m.
76+
77+
Args:
78+
git_root: root of git checkout.
79+
version: the next version to release.
80+
Returns:
81+
Dictionary with pod keys and version values.
82+
"""
83+
json_file = os.path.join(git_root, 'Releases', 'Manifests',
84+
'{}.json'.format(version))
85+
if os.path.isfile(json_file):
86+
return json.load(open(json_file))
87+
else:
88+
sys.exit('Missing version file:{}'.format(json_file))
89+
90+
91+
def CreateReleaseBranch(release_branch):
92+
"""Create and push the release branch.
93+
94+
Args:
95+
release_branch: the name of the git release branch.
96+
"""
97+
os.system('git checkout master')
98+
os.system('git pull')
99+
os.system('git checkout -b {}'.format(release_branch))
100+
LogOrRun('git push origin {}'.format(release_branch))
101+
LogOrRun('git branch --set-upstream-to=origin/{} {}'.format(release_branch,
102+
release_branch))
103+
104+
105+
def UpdateFIROptions(git_root, version_data):
106+
"""Update version specifier in FIROptions.m.
107+
108+
Args:
109+
git_root: root of git checkout.
110+
version_data: dictionary of versions to be updated.
111+
"""
112+
core_version = version_data['FirebaseCore']
113+
major, minor, patch = core_version.split('.')
114+
path = os.path.join(git_root, 'Firebase', 'Core', 'FIROptions.m')
115+
os.system("sed -E -i.bak 's/[[:digit:]]+\"[[:space:]]*\\/\\/ Major/"
116+
"{}\" \\/\\/ Major/' {}".format(major, path))
117+
os.system("sed -E -i.bak 's/[[:digit:]]+\"[[:space:]]*\\/\\/ Minor/"
118+
"{}\" \\/\\/ Minor/' {}".format(minor.zfill(2), path))
119+
os.system("sed -E -i.bak 's/[[:digit:]]+\"[[:space:]]*\\/\\/ Build/"
120+
"{}\" \\/\\/ Build/' {}".format(patch.zfill(2), path))
121+
122+
123+
def UpdatePodSpecs(git_root, version_data, firebase_version):
124+
"""Update the podspecs with the right version.
125+
126+
Args:
127+
git_root: root of git checkout.
128+
version_data: dictionary of versions to be updated.
129+
firebase_version: the Firebase version.
130+
"""
131+
core_podspec = os.path.join(git_root, 'FirebaseCore.podspec')
132+
os.system("sed -i.bak -e \"s/\\(Firebase_VERSION=\\).*'/\\1{}'/\" {}".format(
133+
firebase_version, core_podspec))
134+
for pod, version in version_data.items():
135+
podspec = os.path.join(git_root, '{}.podspec'.format(pod))
136+
os.system("sed -i.bak -e \"s/\\(\\.version.*=[[:space:]]*'\\).*'/\\1{}'/\" "
137+
'{}'.format(version, podspec))
138+
139+
140+
def UpdatePodfiles(git_root, version):
141+
"""Update Podfile's to reference the latest Firebase pod.
142+
143+
Args:
144+
git_root: root of git checkout.
145+
version: the next Firebase version to release.
146+
"""
147+
firebase_podfile = os.path.join(git_root, 'Example', 'Podfile')
148+
firestore_podfile = os.path.join(git_root, 'Firestore', 'Example', 'Podfile')
149+
150+
sed_command = ("sed -i.bak -e \"s#\\(pod "
151+
"'Firebase/Core',[[:space:]]*'\\).*'#\\1{}'#\" {}")
152+
os.system(sed_command.format(version, firebase_podfile))
153+
os.system(sed_command.format(version, firestore_podfile))
154+
155+
156+
def UpdateTags(version_data, firebase_version, first=False):
157+
"""Update tags.
158+
159+
Args:
160+
version_data: dictionary of versions to be updated.
161+
firebase_version: the Firebase version.
162+
first: set to true the first time the versions are set.
163+
"""
164+
if not first:
165+
LogOrRun("git push --delete origin '{}'".format(firebase_version))
166+
LogOrRun("git tag --delete '{}'".format(firebase_version))
167+
LogOrRun("git tag '{}'".format(firebase_version))
168+
for pod, version in version_data.items():
169+
name = pod[len('Firebase'):]
170+
tag = '{}-{}'.format(name, version)
171+
if not first:
172+
LogOrRun("git push --delete origin '{}'".format(tag))
173+
LogOrRun("git tag --delete '{}'".format(tag))
174+
LogOrRun("git tag '{}'".format(tag))
175+
LogOrRun('git push origin --tags')
176+
177+
178+
def GetCpdcInternal():
179+
"""Find the cpdc-internal repo.
180+
181+
"""
182+
tmp_file = tempfile.mktemp()
183+
os.system('pod repo list | grep -B2 sso://cpdc-internal | head -1 > {}'
184+
.format(tmp_file))
185+
with open(tmp_file,'r') as o:
186+
output_var = ''.join(o.readlines()).strip()
187+
os.system('rm -rf {}'.format(tmp_file))
188+
return output_var
189+
190+
191+
def PushPodspecs(version_data):
192+
"""Push podspecs to cpdc-internal.
193+
194+
Args:
195+
version_data: dictionary of versions to be updated.
196+
"""
197+
pods = version_data.keys()
198+
pods.insert(0, pods.pop(pods.index('FirebaseCore'))) # Core should be first
199+
tmp_dir = tempfile.mkdtemp()
200+
for pod in pods:
201+
LogOrRun('pod cache clean {} --all'.format(pod))
202+
if pod == 'FirebaseFirestore':
203+
warnings_ok = ' --allow-warnings'
204+
else:
205+
warnings_ok = ''
206+
207+
podspec = '{}.podspec'.format(pod)
208+
json = os.path.join(tmp_dir, '{}.json'.format(podspec))
209+
os.system('pod ipc spec {} > {}'.format(podspec, json))
210+
LogOrRun('pod repo push {} {}{}'.format(GetCpdcInternal(), json,
211+
warnings_ok))
212+
os.system('rm -rf {}'.format(tmp_dir))
213+
214+
215+
def UpdateVersions():
216+
"""UpdateVersions is the main body to create the branch and change versions.
217+
"""
218+
global test_mode
219+
args = SetupArguments()
220+
test_mode = args.test_mode
221+
# Validate version is proper format
222+
major, minor, patch = args.version.split('.')
223+
if (not major.isdigit()) or (not minor.isdigit()) or (not patch.isdigit()):
224+
sys.exit('Invalid version parameter')
225+
226+
git_root = subprocess.Popen(
227+
['git', 'rev-parse', '--show-toplevel'],
228+
stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')
229+
230+
version_data = GetVersionData(git_root, args.version)
231+
if args.tag_update:
232+
UpdateTags(version_data, args.version)
233+
return
234+
235+
release_branch = 'release-{}'.format(args.version)
236+
CreateReleaseBranch(release_branch)
237+
UpdateFIROptions(git_root, version_data)
238+
UpdatePodSpecs(git_root, version_data, args.version)
239+
UpdatePodfiles(git_root, args.version)
240+
241+
LogOrRun('git commit -am "Update versions for Release {}"'
242+
.format(args.version))
243+
LogOrRun('git push origin {}'.format(release_branch))
244+
UpdateTags(version_data, args.version, True)
245+
PushPodspecs(version_data)
246+
247+
248+
if __name__ == '__main__':
249+
UpdateVersions()

scripts/push-pods.sh

Lines changed: 0 additions & 41 deletions
This file was deleted.

scripts/update-tags.sh

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)