automation: add a command to submit to a Try server
The CI code for running the Try Server requires more thorough review.
Let's add just the client-side bits for submitting to Try so others
can start using it.
Differential Revision: https://phab.mercurial-scm.org/D6983
--- a/contrib/automation/README.rst Sat Oct 05 11:58:17 2019 -0400
+++ b/contrib/automation/README.rst Sat Oct 05 11:21:39 2019 -0400
@@ -33,6 +33,46 @@
into a remote machine, we create a temporary directory for the SSH
config so the user's known hosts file isn't updated.
+Try Server
+==========
+
+There exists a *Try Server* which allows automation to run against
+an arbitrary Mercurial changeset and displays results via the web.
+
+.. note::
+
+ The *Try Server* is still experimental infrastructure.
+
+To use the *Try Server*::
+
+ $ ./automation.py try
+
+With a custom AWS profile::
+
+ $ AWS_PROFILE=hg contrib/automation/automation.py try
+
+By default, the ``.`` revision is submitted. **Any uncommitted changes
+are not submitted.**
+
+To switch which revision is used::
+
+ $ ./automation.py try -r abcdef
+
+Access to the *Try Server* requires access to a special AWS account.
+This account is currently run by Gregory Szorc. Here is the procedure
+for accessing the *Try Server*:
+
+1. Email Gregory Szorc at gregory.szorc@gmail.com and request a
+ username. This username will be stored in the public domain.
+2. Wait for an email reply containing your temporary AWS credentials.
+3. Log in at https://gregoryszorc-hg.signin.aws.amazon.com/console
+ and set a new, secure password.
+4. Go to https://console.aws.amazon.com/iam/home?region=us-west-2#/security_credentials
+5. Under ``Access keys for CLI, SDK, & API access``, click the
+ ``Create access key`` button.
+6. See the ``AWS Integration`` section for instructions on
+ configuring your local client to use the generated credentials.
+
AWS Integration
===============
--- a/contrib/automation/hgautomation/cli.py Sat Oct 05 11:58:17 2019 -0400
+++ b/contrib/automation/hgautomation/cli.py Sat Oct 05 11:21:39 2019 -0400
@@ -17,6 +17,7 @@
aws,
HGAutomation,
linux,
+ try_server,
windows,
)
@@ -193,6 +194,11 @@
ssh_username=ssh_username)
+def run_try(hga: HGAutomation, aws_region: str, rev: str):
+ c = hga.aws_connection(aws_region, ensure_ec2_state=False)
+ try_server.trigger_try(c, rev=rev)
+
+
def get_parser():
parser = argparse.ArgumentParser()
@@ -439,6 +445,15 @@
)
sp.set_defaults(func=publish_windows_artifacts)
+ sp = subparsers.add_parser(
+ 'try',
+ help='Run CI automation against a custom changeset'
+ )
+ sp.add_argument('-r', '--rev',
+ default='.',
+ help='Revision to run CI on')
+ sp.set_defaults(func=run_try)
+
return parser
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/automation/hgautomation/try_server.py Sat Oct 05 11:21:39 2019 -0400
@@ -0,0 +1,99 @@
+# try_server.py - Interact with Try server
+#
+# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+# no-check-code because Python 3 native.
+
+import base64
+import json
+import os
+import subprocess
+import tempfile
+
+from .aws import AWSConnection
+
+LAMBDA_FUNCTION = "ci-try-server-upload"
+
+
+def trigger_try(c: AWSConnection, rev="."):
+ """Trigger a new Try run."""
+ lambda_client = c.session.client("lambda")
+
+ cset, bundle = generate_bundle(rev=rev)
+
+ payload = {
+ "bundle": base64.b64encode(bundle).decode("utf-8"),
+ "node": cset["node"],
+ "branch": cset["branch"],
+ "user": cset["user"],
+ "message": cset["desc"],
+ }
+
+ print("resolved revision:")
+ print("node: %s" % cset["node"])
+ print("branch: %s" % cset["branch"])
+ print("user: %s" % cset["user"])
+ print("desc: %s" % cset["desc"].splitlines()[0])
+ print()
+
+ print("sending to Try...")
+ res = lambda_client.invoke(
+ FunctionName=LAMBDA_FUNCTION,
+ InvocationType="RequestResponse",
+ Payload=json.dumps(payload).encode("utf-8"),
+ )
+
+ body = json.load(res["Payload"])
+ for message in body:
+ print("remote: %s" % message)
+
+
+def generate_bundle(rev="."):
+ """Generate a bundle suitable for use by the Try service.
+
+ Returns a tuple of revision metadata and raw Mercurial bundle data.
+ """
+ # `hg bundle` doesn't support streaming to stdout. So we use a temporary
+ # file.
+ path = None
+ try:
+ fd, path = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
+ os.close(fd)
+
+ args = [
+ "hg",
+ "bundle",
+ "--type",
+ "gzip-v2",
+ "--base",
+ "public()",
+ "--rev",
+ rev,
+ path,
+ ]
+
+ print("generating bundle...")
+ subprocess.run(args, check=True)
+
+ with open(path, "rb") as fh:
+ bundle_data = fh.read()
+
+ finally:
+ if path:
+ os.unlink(path)
+
+ args = [
+ "hg",
+ "log",
+ "-r",
+ rev,
+ # We have to upload as JSON, so it won't matter if we emit binary
+ # since we need to normalize to UTF-8.
+ "-T",
+ "json",
+ ]
+ res = subprocess.run(args, check=True, capture_output=True)
+ return json.loads(res.stdout)[0], bundle_data
--- a/tests/test-check-code.t Sat Oct 05 11:58:17 2019 -0400
+++ b/tests/test-check-code.t Sat Oct 05 11:21:39 2019 -0400
@@ -18,6 +18,7 @@
Skipping contrib/automation/hgautomation/linux.py it has no-che?k-code (glob)
Skipping contrib/automation/hgautomation/pypi.py it has no-che?k-code (glob)
Skipping contrib/automation/hgautomation/ssh.py it has no-che?k-code (glob)
+ Skipping contrib/automation/hgautomation/try_server.py it has no-che?k-code (glob)
Skipping contrib/automation/hgautomation/windows.py it has no-che?k-code (glob)
Skipping contrib/automation/hgautomation/winrm.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/downloads.py it has no-che?k-code (glob)