[infra] Add chrome_release_branch script
Bug: skia:8932
Change-Id: I258fd8f5262e5f87800b85f9bcbd0c4982ef1e3d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/208503
Commit-Queue: Eric Boren <borenet@google.com>
Reviewed-by: Ben Wagner aka dogben <benjaminwagner@google.com>
diff --git a/tools/chrome_release_branch b/tools/chrome_release_branch
new file mode 100755
index 0000000..8a6cffc
--- /dev/null
+++ b/tools/chrome_release_branch
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+#
+# Copyright 2019 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+base_dir=$(dirname "$0")
+
+PYTHONDONTWRITEBYTECODE=1 exec python -u "$base_dir/chrome_release_branch.py" "$@"
diff --git a/tools/chrome_release_branch.bat b/tools/chrome_release_branch.bat
new file mode 100644
index 0000000..1f61fe2
--- /dev/null
+++ b/tools/chrome_release_branch.bat
@@ -0,0 +1,7 @@
+@echo off
+:: Copyright 2019 Google Inc.
+::
+:: Use of this source code is governed by a BSD-style license that can be
+:: found in the LICENSE file.
+setlocal
+python -u "%~dp0\chrome_release_branch.py" %*
diff --git a/tools/chrome_release_branch.py b/tools/chrome_release_branch.py
new file mode 100644
index 0000000..7fba18b
--- /dev/null
+++ b/tools/chrome_release_branch.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2019 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+import subprocess
+import sys
+
+from infra import git
+from infra import go
+
+
+REFS_HEADS_PREFIX = 'refs/heads/'
+CHROME_REF_PREFIX = REFS_HEADS_PREFIX + 'chrome/m'
+SUPPORTED_CHROME_BRANCHES = 2 # Per infra policy; see skbug.com/8940
+
+
+def get_chrome_branches():
+ '''Return all Chrome milestone branches as tuples of (milestone, ref).'''
+ refs = git.git('ls-remote', 'origin', 'refs/heads/*')
+ chrome_branches = []
+ for line in refs.splitlines():
+ ref = line.split()[1]
+ if ref.startswith(CHROME_REF_PREFIX):
+ m = int(ref[len(CHROME_REF_PREFIX):])
+ chrome_branches.append((m, ref))
+ chrome_branches.sort(reverse=True)
+ return chrome_branches
+
+
+def main():
+ owner = git.git('config', 'user.email').rstrip()
+ if not owner:
+ print >> sys.stderr, 'No configured git user; please run "git config user.email <your email>".'
+ sys.exit(1)
+ branches = get_chrome_branches()
+ new_branch = branches[0][1][len(REFS_HEADS_PREFIX):]
+ old_branch = branches[SUPPORTED_CHROME_BRANCHES][1][len(REFS_HEADS_PREFIX):]
+ go.get(go.INFRA_GO+'/go/supported_branches/cmd/new-branch')
+ subprocess.check_call(['new-branch',
+ '--branch', new_branch,
+ '--delete', old_branch,
+ '--owner', owner])
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/infra/__init__.py b/tools/infra/__init__.py
new file mode 100644
index 0000000..d5cf199
--- /dev/null
+++ b/tools/infra/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2019 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
diff --git a/tools/infra/git.py b/tools/infra/git.py
new file mode 100644
index 0000000..cc51d42
--- /dev/null
+++ b/tools/infra/git.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# Copyright 2019 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+import subprocess
+import sys
+
+
+GIT = 'git.bat' if sys.platform == 'win32' else 'git'
+
+
+def git(*args):
+ '''Run the given Git command, return the output.'''
+ return subprocess.check_output([GIT]+list(args))
diff --git a/tools/infra/go.py b/tools/infra/go.py
new file mode 100644
index 0000000..e30540e
--- /dev/null
+++ b/tools/infra/go.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2019 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+import os
+import subprocess
+import sys
+
+
+INFRA_GO = 'go.skia.org/infra'
+WHICH = 'where' if sys.platform == 'win32' else 'which'
+
+
+def check():
+ '''Verify that golang is properly installed. If not, exit with an error.'''
+ def _fail(msg):
+ print >> sys.stderr, msg
+ sys.exit(1)
+
+ try:
+ go_exe = subprocess.check_output([WHICH, 'go'])
+ except (subprocess.CalledProcessError, OSError):
+ pass
+ if not go_exe:
+ _fail('Unable to find Golang installation; see '
+ 'https://golang.org/doc/install')
+ if not os.environ.get('GOPATH'):
+ _fail('GOPATH environment variable is not set; is Golang properly '
+ 'installed?')
+ go_bin = os.path.join(os.environ['GOPATH'], 'bin')
+ for entry in os.environ.get('PATH', '').split(os.pathsep):
+ if entry == go_bin:
+ break
+ else:
+ _fail('%s not in PATH; is Golang properly installed?' % go_bin)
+
+
+def get(url):
+ '''Clone or update the given repo URL via "go get".'''
+ check()
+ subprocess.check_call(['go', 'get', '-u', url])
+
+
+def update_infra():
+ '''Update the local checkout of the Skia infra codebase.'''
+ get(INFRA_GO + '/...')