bug 1292393 - Support symbolic revisions in decision task draft
authorAnthony Miyaguchi <amiyaguchi@mozilla.com>
Tue, 09 Aug 2016 13:14:05 -0700
changeset 398826 e647d5c745120c1f73e43c8ec9209fa00f0a6739
parent 398813 d7750d91b9179fab6fe27f912552101d2515c5b9
child 527759 212419d940217a90704e302ec2a68ab6ca698d1e
push id25642
push useramiyaguchi@mozilla.com
push dateTue, 09 Aug 2016 20:14:39 +0000
bugs1292393
milestone51.0a1
bug 1292393 - Support symbolic revisions in decision task The decision task now uses robustcheckout to get the latest mercurial state. However, robustcheckout also enforces that the revision it's passed is actually a revision hash, and not a symbolic name. This will use the --branch option of robustcheckout if GECKO_HEAD_REF is defined and will use `hg log` to fill in GECKO_HEAD_REF. MozReview-Commit-ID: LJikceW4YVg
testing/docker/recipes/run-task
--- a/testing/docker/recipes/run-task
+++ b/testing/docker/recipes/run-task
@@ -16,16 +16,17 @@ current time to improve log usefulness.
 from __future__ import absolute_import, print_function, unicode_literals
 
 import argparse
 import datetime
 import errno
 import grp
 import os
 import pwd
+import re
 import subprocess
 import sys
 
 
 def print_line(prefix, m):
     now = datetime.datetime.utcnow()
     print('[%s %sZ] %s' % (prefix, now.isoformat(), m), end='')
 
@@ -69,28 +70,51 @@ def vcs_checkout(args):
     base_repo = os.environ.get('GECKO_BASE_REPOSITORY')
 
     # We set the base repository to mozilla-central so tc-vcs doesn't get
     # confused. Switch to mozilla-unified because robustcheckout works best
     # with it.
     if base_repo == 'https://hg.mozilla.org/mozilla-central':
         base_repo = b'https://hg.mozilla.org/mozilla-unified'
 
+    # Specify method to checkout a revision. This defaults to revisions as
+    # SHA-1 strings, but also supports symbolic revisions like `tip` via the
+    # branch flag.
+    if os.environ.get('GECKO_HEAD_REV'):
+        revision_flag = b'--revision'
+        revision = os.environ['GECKO_HEAD_REV']
+    elif os.environ.get('GECKO_HEAD_REF'):
+        revision_flag = b'--branch'
+        revision = os.environ['GECKO_HEAD_REF']
+    else:
+        print('revision is not specified for checkout')
+        sys.exit(1)
+
     res = run_and_prefix_output(b'vcs', [
         b'/usr/bin/hg', b'robustcheckout',
         b'--sharebase', b'/home/worker/hg-shared',
         b'--purge',
         b'--upstream', base_repo,
-        b'--revision', os.environ['GECKO_HEAD_REV'],
+        revision_flag, revision,
         os.environ['GECKO_HEAD_REPOSITORY'], args.vcs_checkout
     ])
 
     if res:
         sys.exit(res)
 
+    # Update the current revision hash and ensure that it is well formed.
+    revision = subprocess.check_output(
+        [b'/usr/bin/hg', b'log',
+         b'--rev', b'.',
+         b'--template', b'{node}'],
+        cwd=args.vcs_checkout)
+
+    assert re.match('^[a-f0-9]{40}$', revision)
+    os.environ['GECKO_HEAD_REV'] = revision
+
 
 def main(args):
     print_line('setup', 'run-task started\n')
 
     if os.getuid() != 0:
         print('assertion failed: not running as root')
         return 1
 
@@ -149,18 +173,26 @@ def main(args):
     # container. We do not bother calling setrlimit() because containers have
     # their own limits.
     print_line('setup', 'running as %s:%s\n' % (args.user, args.group))
     os.setgroups(gids)
     os.umask(022)
     os.setresgid(gid, gid, gid)
     os.setresuid(uid, uid, uid)
 
+    # Checkout the repository, setting the GECKO_HEAD_REV to the current
+    # revision hash. Revision hashes have priority over symbolic revisions. We
+    # disallow running tasks with symbolic revisions unless they have been
+    # resolved by a checkout.
     if checkout:
         vcs_checkout(args)
+    elif not os.environ.get('GECKO_HEAD_REV') and \
+            os.environ.get('GECKO_HEAD_REF'):
+        print('task should be defined in terms of non-symbolic revision')
+        return 1
 
     return run_and_prefix_output('task', task_args)
 
 
 if __name__ == '__main__':
     # Unbuffer stdio.
     sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
     sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)