move everything into one file
diff --git a/buildkite/pipelines/bazelci.py b/buildkite/pipelines/bazelci.py
new file mode 100644
index 0000000..53bf481
--- /dev/null
+++ b/buildkite/pipelines/bazelci.py
@@ -0,0 +1,190 @@
+import argparse
+import codecs
+import json
+import os.path
+import shutil
+import subprocess
+import sys
+import urllib.request
+from shutil import copyfile
+from urllib.parse import urlparse
+
+OUTPUT_DIRECTORY = ".bazelci_outputs/"
+BEP_OUTPUT_FILENAME = OUTPUT_DIRECTORY + "test.json"
+
+def supported_platforms():
+    return {
+        "ubuntu1404" : "Ubuntu 14.04", 
+        "ubuntu1604" : "Ubuntu 16.04",
+        "macos" : "macOS"
+    }
+
+def fetch_configs(http_config):
+    if http_config is None:
+        with open(".bazelci/config.json", "r") as fd:
+            return json.load(fd)
+    with urllib.request.urlopen(http_config) as resp:
+        reader = codecs.getreader("utf-8")
+        return json.load(reader(resp))
+
+def run(config, platform, bazel_binary, git_repository):
+    try:
+        if git_repository:
+            clone_repository(git_repository)
+            cleanup(bazel_binary)
+        else:
+            cleanup(bazel_binary)
+        os.mkdir(OUTPUT_DIRECTORY)
+        shell_commands(config.get("shell_commands", None))
+        bazel_run(bazel_binary, config.get("run_targets", None))
+        bazel_build(bazel_binary, config.get("build_flags", []), config.get("build_targets", None))
+        exit_code = bazel_test(bazel_binary, config.get("test_flags", []), config.get("test_targets", None))
+        upload_failed_test_logs(BEP_OUTPUT_FILENAME)
+        if git_repository:
+            delete_repository(git_repository)
+        exit(exit_code)
+    finally:
+        cleanup(bazel_binary)
+
+def clone_repository(git_repository):
+    run_command(["git", "clone", git_repository, "downstream-repo"])
+    os.chdir("downstream-repo")
+
+def delete_repository(git_repository):
+    os.chdir("..")
+    shutil.rmtree("downstream-repo")
+
+def shell_commands(commands):
+    if not commands:
+        return
+    print("--- Shell Commands")
+    shell_command = "\n".join(commands)
+    run_command(shell_command, shell=True)
+
+def bazel_run(bazel_binary, targets):
+    if not targets:
+        return
+    print("--- Run Targets")
+    for target in targets:
+        run_command([bazel_binary, "run", target])
+
+def bazel_build(bazel_binary, flags, targets):
+    if not targets:
+        return
+    print("+++ Build")
+    run_command([bazel_binary, "build", "--color=yes"] + flags + targets)
+
+def bazel_test(bazel_binary, flags, targets):
+    if not targets:
+        return
+    print("+++ Test")
+    res = subprocess.run([bazel_binary, "test", "--color=yes", "--build_event_json_file=" + BEP_OUTPUT_FILENAME] + flags + targets)
+    return res.returncode
+
+def upload_failed_test_logs(bep_path):
+    for logfile in failed_test_logs(bep_path):
+        run_command(["buildkite-agent", "artifact", "upload", logfile])
+
+def failed_test_logs(bep_path):
+    test_logs = []
+    raw_data = ""
+    with open(bep_path) as f:
+        raw_data = f.read()
+    decoder = json.JSONDecoder()
+
+    pos = 0
+    while pos < len(raw_data):
+        json_dict, size = decoder.raw_decode(raw_data[pos:])
+        if "testResult" in json_dict:
+            test_result = json_dict["testResult"]
+            if test_result["status"] != "PASSED":
+                outputs = test_result["testActionOutput"]
+                for output in outputs:
+                    if output["name"] == "test.log":
+                        new_path = label_to_path(json_dict["id"]["testResult"]["label"])
+                        os.makedirs(os.path.dirname(new_path), exist_ok=True)
+                        copyfile(urlparse(output["uri"]).path, new_path)
+                        test_logs.append(new_path)
+        pos += size + 1
+    return test_logs
+
+def label_to_path(label):
+  # remove leading //
+  path = label[2:]
+  path = path.replace(":", "/")
+  return OUTPUT_DIRECTORY + path + ".log"
+
+def cleanup(bazel_binary):
+    print("--- Cleanup")
+    if os.path.exists("WORKSPACE"):
+        run_command([bazel_binary, "clean", "--expunge"])
+    if os.path.exists(OUTPUT_DIRECTORY):
+        shutil.rmtree(OUTPUT_DIRECTORY)
+    if os.path.exists("downstream-repo"):
+        shutil.rmtree("downstream-repo")
+
+def run_command(args, shell=False):
+    print(" ".join(args))
+    res = subprocess.run(args, shell)
+    if res.returncode != 0:
+        exit(res.returncode)
+
+def generate_pipeline(configs, http_config):
+    if not configs:
+        print("The CI config is empty.")
+        exit(1)
+    pipeline_steps = []
+    for platform, config in configs.items():
+        if platform not in supported_platforms():
+            print("'{0}' is not a supported platform on Bazel CI".format(platform))
+            exit(1)
+        pipeline_steps.append(command_step(supported_platforms()[platform], platform, http_config))
+    if not pipeline_steps:
+        print("The CI config is empty.")
+        exit(1)
+    write_pipeline_file(pipeline_steps)
+
+def write_pipeline_file(steps):
+    print("steps:")
+    for step in steps:
+        print(step)
+
+def command_step(label, platform, http_config):
+  return """
+ - label: \"{0}\"
+   command: \"curl -s https://raw.githubusercontent.com/bazelbuild/continuous-integration/master/buildkite/pipelines/bazelci.py > bazelci.py\\n{1}\"
+   agents:
+     - \"os={2}\"""".format(label, "{0} --platform={1} {2} ".format(runner_command(platform), platform, http_config_flag(http_config)), platform)
+
+def runner_command(platform):
+    return "python3 bazelci.py --runner"
+
+def http_config_flag(http_config):
+    if http_config is not None:
+        return "--http_config=" + http_config
+    return ""
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Bazel Continous Integration Runner')
+    parser.add_argument("--generate_pipeline", type=bool)
+    parser.add_argument("--runner", type=bool)
+    parser.add_argument("--platform", type=str, help="The platform the script is running on. Required.")
+    parser.add_argument("--bazel_binary", type=str, help="The path to the Bazel binary. Optional.")
+    parser.add_argument("--http_config", type=str, help="The URL of the config file. Optional.")
+    args = parser.parse_args()
+
+    if args.generate_pipeline:
+        configs = fetch_configs(args.http_config)
+        generate_pipeline(configs.get("platforms", None), args.http_config)
+    elif args.runner:
+        configs = fetch_configs(args.http_config)
+        bazel_binary = "bazel"
+        if args.bazel_binary is not None:
+            bazel_binary = args.bazel_binary
+        git_repository = configs.get("git_repository", None)
+        if args.platform not in configs["platforms"]:
+            print("No configuration exists for '{0}'".format(args.platform))
+        run(configs["platforms"][args.platform], args.platform, bazel_binary, git_repository)
+    else:
+        print("Need to specify either --runner or --generate_pipeline")
+        exit(1)
diff --git a/buildkite/pipelines/common.py b/buildkite/pipelines/common.py
deleted file mode 100644
index e04c75a..0000000
--- a/buildkite/pipelines/common.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import codecs
-import json
-import urllib.request
-
-OUTPUT_DIRECTORY = ".bazelci_outputs/"
-BEP_OUTPUT_FILENAME = OUTPUT_DIRECTORY + "test.json"
-
-def supported_platforms():
-    return {
-        "ubuntu1404" : "Ubuntu 14.04", 
-        "ubuntu1604" : "Ubuntu 16.04",
-        "macos" : "macOS"
-    }
-
-def fetch_configs(http_config):
-    if http_config is None:
-        with open(".bazelci/config.json", "r") as fd:
-            return json.load(fd)
-    with urllib.request.urlopen(http_config) as resp:
-        reader = codecs.getreader("utf-8")
-        return json.load(reader(resp))
diff --git a/buildkite/pipelines/generate_pipeline.py b/buildkite/pipelines/generate_pipeline.py
deleted file mode 100644
index bfa91c8..0000000
--- a/buildkite/pipelines/generate_pipeline.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import argparse
-from common import supported_platforms
-from common import fetch_configs
-
-def generate_pipeline(configs, http_config):
-    if not configs:
-        print("The CI config is empty.")
-        exit(1)
-    pipeline_steps = []
-    for platform, config in configs.items():
-        if platform not in supported_platforms():
-            print("'{0}' is not a supported platform on Bazel CI".format(platform))
-            exit(1)
-        pipeline_steps.append(command_step(supported_platforms()[platform], platform, http_config))
-    if not pipeline_steps:
-        print("The CI config is empty.")
-        exit(1)
-    write_pipeline_file(pipeline_steps)
-
-def write_pipeline_file(steps):     
-    print("steps:")
-    for step in steps:
-        print(step)
-
-def command_step(label, platform, http_config):
-  return """
- - label: \"{0}\"
-   command: \"{1}\"
-   agents:
-     - \"os={2}\"""".format(label, "{0} --platform={1} {2} ".format(runner_command(platform), platform, http_config_flag(http_config)), platform)
-
-def runner_command(platform):
-    return "python3 runner.py"
-
-def http_config_flag(http_config):
-    if http_config is not None:
-        return "--http_config=" + http_config
-    return ""
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='Bazel Continous Integration Pipeline Generator')
-    parser.add_argument("--http_config", type=str, help="The URL of the config file. Optional.")
-    args = parser.parse_args()
-
-    configs = fetch_configs(args.http_config)
-    generate_pipeline(configs.get("platforms", None), args.http_config)
diff --git a/buildkite/pipelines/runner.py b/buildkite/pipelines/runner.py
deleted file mode 100644
index 9017753..0000000
--- a/buildkite/pipelines/runner.py
+++ /dev/null
@@ -1,129 +0,0 @@
-import argparse
-import json
-import os.path
-import shutil
-import subprocess
-import sys
-from common import fetch_configs
-from common import OUTPUT_DIRECTORY
-from common import BEP_OUTPUT_FILENAME
-from shutil import copyfile
-from urllib.parse import urlparse
-
-def run(config, platform, bazel_binary, git_repository):
-    try:
-        if git_repository:
-            clone_repository(git_repository)
-            cleanup(bazel_binary)
-        else:
-            cleanup(bazel_binary)
-        os.mkdir(OUTPUT_DIRECTORY)
-        shell_commands(config.get("shell_commands", None))
-        bazel_run(bazel_binary, config.get("run_targets", None))
-        bazel_build(bazel_binary, config.get("build_flags", []), config.get("build_targets", None))
-        exit_code = bazel_test(bazel_binary, config.get("test_flags", []), config.get("test_targets", None))
-        upload_failed_test_logs(BEP_OUTPUT_FILENAME)
-        if git_repository:
-            delete_repository(git_repository)
-        exit(exit_code)
-    finally:
-        cleanup(bazel_binary)
-
-def clone_repository(git_repository):
-    run_command(["git", "clone", git_repository, "downstream-repo"])
-    os.chdir("downstream-repo")
-
-def delete_repository(git_repository):
-    os.chdir("..")
-    shutil.rmtree("downstream-repo")
-
-def shell_commands(commands):
-    if not commands:
-        return
-    print("--- Shell Commands")
-    shell_command = "\n".join(commands)
-    run_command(shell_command, shell=True)
-
-def bazel_run(bazel_binary, targets):
-    if not targets:
-        return
-    print("--- Run Targets")
-    for target in targets:
-        run_command([bazel_binary, "run", target])
-
-def bazel_build(bazel_binary, flags, targets):
-    if not targets:
-        return
-    print("+++ Build")
-    run_command([bazel_binary, "build", "--color=yes"] + flags + targets)
-
-def bazel_test(bazel_binary, flags, targets):
-    if not targets:
-        return
-    print("+++ Test")
-    res = subprocess.run([bazel_binary, "test", "--color=yes", "--build_event_json_file=" + BEP_OUTPUT_FILENAME] + flags + targets)
-    return res.returncode
-
-def upload_failed_test_logs(bep_path):
-    for logfile in failed_test_logs(bep_path):
-        run_command(["buildkite-agent", "artifact", "upload", logfile])
-
-def failed_test_logs(bep_path):
-    test_logs = []
-    raw_data = ""
-    with open(bep_path) as f:
-        raw_data = f.read()
-    decoder = json.JSONDecoder()
-
-    pos = 0
-    while pos < len(raw_data):
-        json_dict, size = decoder.raw_decode(raw_data[pos:])
-        if "testResult" in json_dict:
-            test_result = json_dict["testResult"]
-            if test_result["status"] != "PASSED":
-                outputs = test_result["testActionOutput"]
-                for output in outputs:
-                    if output["name"] == "test.log":
-                        new_path = label_to_path(json_dict["id"]["testResult"]["label"])
-                        os.makedirs(os.path.dirname(new_path), exist_ok=True)
-                        copyfile(urlparse(output["uri"]).path, new_path)
-                        test_logs.append(new_path)
-        pos += size + 1
-    return test_logs
-
-def label_to_path(label):
-  # remove leading //
-  path = label[2:]
-  path = path.replace(":", "/")
-  return OUTPUT_DIRECTORY + path + ".log"
-
-def cleanup(bazel_binary):
-    print("--- Cleanup")
-    if os.path.exists("WORKSPACE"):
-        run_command([bazel_binary, "clean", "--expunge"])
-    if os.path.exists(OUTPUT_DIRECTORY):
-        shutil.rmtree(OUTPUT_DIRECTORY)
-    if os.path.exists("downstream-repo"):
-        shutil.rmtree("downstream-repo")
-
-def run_command(args, shell=False):
-    print(" ".join(args))
-    res = subprocess.run(args, shell)
-    if res.returncode != 0:
-        exit(res.returncode)
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='Bazel Continous Integration Runner')
-    parser.add_argument("--platform", type=str, required=True, help="The platform the script is running on. Required.")
-    parser.add_argument("--bazel_binary", type=str, help="The path to the Bazel binary. Optional.")
-    parser.add_argument("--http_config", type=str, help="The URL of the config file. Optional.")
-    args = parser.parse_args()
-
-    configs = fetch_configs(args.http_config)
-    bazel_binary = "bazel"
-    if args.bazel_binary is not None:
-        bazel_binary = args.bazel_binary
-    git_repository = configs.get("git_repository", None)
-    if args.platform not in configs["platforms"]:
-        print("No configuration exists for '{0}'".format(args.platform))
-    run(configs["platforms"][args.platform], args.platform, bazel_binary, git_repository)