Introduce cloud build trigger release process script

Sample release-versions.yaml config:
```
- container_name: "toolbox"
  build_commit: "4910d0158ba497795fdfd4172e2315e83d169f40"
  release_tags:
    - "latest"
    - "va.b.c"
- container_name: "cos-customizer"
  build_commit: "4910d0158ba497795fdfd4172e2315e83d169f40"
  release_tags:
    - "latest"
    - "vx.y.z"
```

BUG=b/184579125

Change-Id: I485964635f391c120bf2cc35bc3bfcfb7d240720
Reviewed-on: https://cos-review.googlesource.com/c/cos/tools/+/17890
Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Cloud-Build: GCB Service account <228075978874@cloudbuild.gserviceaccount.com>
Tested-by: Arnav Kansal <rnv@google.com>
diff --git a/release/BUILD b/release/BUILD
new file mode 100644
index 0000000..1f3a7f3
--- /dev/null
+++ b/release/BUILD
@@ -0,0 +1,14 @@
+py_library(
+    name = "release_lib",
+    srcs = ["release.py"],
+    data = ["release-versions.yaml"],
+    srcs_version = "PY3",
+)
+
+py_binary(
+    name = "release",
+    srcs = ["release.py"],
+    data = ["release-versions.yaml"],
+    python_version = "PY3",
+    deps = [":release_lib"],
+)
diff --git a/release/cloudbuild.yaml b/release/cloudbuild.yaml
new file mode 100644
index 0000000..503a7a6
--- /dev/null
+++ b/release/cloudbuild.yaml
@@ -0,0 +1,4 @@
+steps:
+- name: 'gcr.io/cloud-marketplace-containers/google/bazel'
+  entrypoint: 'bazel'
+  args: ['run', ':release', $_BUILD_GCR, $_RELEASE_GCR]
diff --git a/release/release-versions.yaml b/release/release-versions.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/release/release-versions.yaml
diff --git a/release/release.py b/release/release.py
new file mode 100644
index 0000000..4882e47
--- /dev/null
+++ b/release/release.py
@@ -0,0 +1,55 @@
+"""
+Release script invoked from git trigger upon submission of changes to release-versions.yaml config file to the cos/tools GoB repo
+
+Parses contents of release-versions.yaml file and copies release candidates to gcr.io/cos-tools
+"""
+
+import sys
+import yaml
+import subprocess
+import os
+
+def validate_config(release_config):
+  for release_container in release_config:
+    for key in ["container_name", "build_commit", "release_tags"]:
+      assert key in release_container, "missing {} in entry {}".format(key, release_container)
+
+def validate_gcr_path(path):
+  return len(path) > len("gcr.io/") and path[:len("gcr.io/")] == "gcr.io/"
+
+def copy_container_image(src_bucket, dst_bucket, container_name, build_tag, release_tags):
+  assert validate_gcr_path(src_bucket), "cannot use address {}, only gcr.io/ addresses are supported".format(src_bucket)
+  assert validate_gcr_path(dst_bucket), "cannot use address {}, only gcr.io/ addresses are supported".format(dst_bucket)
+
+  src_path = os.path.join(src_bucket, container_name)
+  dst_path = os.path.join(dst_bucket, container_name)
+
+  for release_tag in release_tags:
+    subprocess.run(["gcloud", "container", "images", "add-tag", src_path + ":" + build_tag, dst_path + ":" + release_tag])
+
+def release(src_bucket, dst_bucket):
+  with open('release/release-versions.yaml', 'r') as file:
+    try:
+      release_config = yaml.safe_load(file)
+      validate_config(release_config)
+
+      for release_container in release_config:
+        container_name = release_container["container_name"]
+        build_tag = release_container["build_commit"]
+        release_tags = release_container["release_tags"]
+        copy_container_image(src_bucket, dst_bucket, container_name, build_tag, release_tags)
+
+    except yaml.YAMLError as ex:
+      raise Exception("Invalid YAML config: %s" % str(ex))
+
+def main():
+  if len(sys.argv) != 3:
+    sys.Exit("sample use: ./release_script <source_gcr_path> <destination_gcr_path>")
+
+  src_bucket = sys.argv[1]
+  dst_bucket = sys.argv[2]
+
+  release(src_bucket, dst_bucket)
+
+if __name__ == '__main__':
+  main()