Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # Copyright 2021 The Bazel Authors. All rights reserved. |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | |
| 17 | import collections |
| 18 | import os |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 19 | import shutil |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 20 | import subprocess |
| 21 | import sys |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 22 | import tempfile |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 23 | |
| 24 | import bazelci |
| 25 | |
Florian Weikert | fc42a1d | 2021-02-23 16:53:00 +0100 | [diff] [blame] | 26 | DEFAULT_FLAGS = ["--action_env=PATH=/usr/local/bin:/usr/bin:/bin", "--sandbox_tmpfs_path=/tmp"] |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 27 | |
Florian Weikert | af81683 | 2021-04-22 16:49:23 +0200 | [diff] [blame] | 28 | PLATFORM = "ubuntu1804" |
| 29 | |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 30 | Settings = collections.namedtuple( |
Florian Weikert | 8135ddd | 2021-05-12 18:14:07 +0200 | [diff] [blame] | 31 | "Settings", |
| 32 | ["target", "build_flags", "output_dir", "gcs_bucket", "gcs_subdir", "landing_page", "rewrite"], |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 33 | ) |
| 34 | |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 35 | BUILDKITE_BUILD_NUMBER = os.getenv("BUILDKITE_BUILD_NUMBER") |
| 36 | |
Florian Weikert | 8135ddd | 2021-05-12 18:14:07 +0200 | [diff] [blame] | 37 | |
Florian Weikert | 681da16 | 2022-02-22 12:19:54 +0100 | [diff] [blame] | 38 | def rewrite_staging_urls(content): |
| 39 | new_content = content.replace( |
| 40 | "docs.bazel.build", "docs-staging.bazel.build/{}".format(BUILDKITE_BUILD_NUMBER) |
| 41 | ) |
| 42 | # Hack to get search working |
| 43 | new_content = new_content.replace("009927877080525621790:2pxlpaexqpc", "12ee759976b5ec02f", 1) |
| 44 | return new_content.replace('"/', '"/{}/'.format(BUILDKITE_BUILD_NUMBER)) |
| 45 | |
| 46 | |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 47 | DOCGEN_SETTINGS = { |
| 48 | "bazel-trusted": { |
Florian Weikert | 681da16 | 2022-02-22 12:19:54 +0100 | [diff] [blame] | 49 | "https://github.com/bazelbuild/bazel.git": Settings( |
| 50 | target="//site", |
| 51 | build_flags=[], |
| 52 | output_dir="bazel-bin/site/site-build", |
| 53 | gcs_bucket="docs.bazel.build", |
| 54 | gcs_subdir="", |
| 55 | landing_page="versions/master/bazel-overview.html", |
| 56 | rewrite=None, |
| 57 | ), |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 58 | "https://github.com/bazelbuild/bazel-blog.git": Settings( |
| 59 | target="//:site", |
| 60 | build_flags=[], |
| 61 | output_dir="bazel-bin/site-build", |
| 62 | gcs_bucket="blog.bazel.build", |
| 63 | gcs_subdir="", |
| 64 | landing_page="index.html", |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 65 | rewrite=None, |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 66 | ), |
Florian Weikert | 681da16 | 2022-02-22 12:19:54 +0100 | [diff] [blame] | 67 | "https://github.com/bazelbuild/bazel-website.git": Settings( |
| 68 | target="//:site", |
| 69 | build_flags=[], |
| 70 | output_dir="bazel-bin/site-build", |
| 71 | gcs_bucket="www.bazel.build", |
| 72 | gcs_subdir="", |
| 73 | landing_page="index.html", |
| 74 | rewrite=None, |
| 75 | ), |
| 76 | }, |
| 77 | "bazel": { |
| 78 | "https://bazel.googlesource.com/bazel.git": Settings( |
| 79 | target="//site", |
| 80 | build_flags=bazelci.remote_caching_flags(PLATFORM), |
| 81 | output_dir="bazel-bin/site/site-build", |
| 82 | gcs_bucket="docs-staging.bazel.build", |
| 83 | gcs_subdir=BUILDKITE_BUILD_NUMBER, |
| 84 | landing_page="versions/master/bazel-overview.html", |
| 85 | rewrite=rewrite_staging_urls, |
| 86 | ), |
Florian Weikert | e6b25f5 | 2021-04-16 15:48:04 +0200 | [diff] [blame] | 87 | }, |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 91 | def rewrite_and_copy(src_root, dest_root, rewrite): |
| 92 | for src_dir, dirs, files in os.walk(src_root): |
| 93 | dest_dir = src_dir.replace(src_root, dest_root, 1) |
| 94 | os.mkdir(dest_dir) |
| 95 | |
Florian Weikert | 8135ddd | 2021-05-12 18:14:07 +0200 | [diff] [blame] | 96 | for filename in files: |
| 97 | src_file = os.path.join(src_dir, filename) |
| 98 | dest_file = os.path.join(dest_dir, filename) |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 99 | |
| 100 | if src_file.endswith(".html"): |
| 101 | with open(src_file, "r", encoding="utf-8") as src: |
| 102 | content = src.read() |
| 103 | |
| 104 | with open(dest_file, "w", encoding="utf-8") as dest: |
Florian Weikert | 032fc20 | 2021-05-12 19:07:39 +0200 | [diff] [blame] | 105 | dest.write(rewrite(content)) |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 106 | else: |
| 107 | shutil.copyfile(src_file, dest_file) |
| 108 | |
| 109 | |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 110 | def get_destination(bucket, subdir): |
| 111 | if not subdir: |
| 112 | return bucket |
| 113 | |
| 114 | return "{}/{}".format(bucket, subdir) |
| 115 | |
| 116 | |
Florian Weikert | 0ed195e | 2021-02-24 11:33:04 +0100 | [diff] [blame] | 117 | def get_url(settings): |
| 118 | return "https://{}/{}".format( |
| 119 | get_destination(settings.gcs_bucket, settings.gcs_subdir), settings.landing_page |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 120 | ) |
| 121 | |
| 122 | |
| 123 | def main(argv=None): |
| 124 | org = os.getenv("BUILDKITE_ORGANIZATION_SLUG") |
| 125 | repo = os.getenv("BUILDKITE_REPO") |
| 126 | settings = DOCGEN_SETTINGS.get(org, {}).get(repo) |
| 127 | if not settings: |
| 128 | bazelci.eprint("docgen is not enabled for '%s' org and repository %s", org, repo) |
| 129 | return 1 |
| 130 | |
| 131 | bazelci.print_expanded_group(":bazel: Building documentation from {}".format(repo)) |
| 132 | try: |
| 133 | bazelci.execute_command( |
| 134 | ["bazel", "build"] + DEFAULT_FLAGS + settings.build_flags + [settings.target] |
| 135 | ) |
| 136 | except subprocess.CalledProcessError as e: |
| 137 | bazelci.eprint("Bazel failed with exit code {}".format(e.returncode)) |
| 138 | return e.returncode |
| 139 | |
Florian Weikert | 164f806 | 2021-05-12 15:41:25 +0200 | [diff] [blame] | 140 | src_root = os.path.join(os.getcwd(), settings.output_dir) |
| 141 | if settings.rewrite: |
| 142 | bazelci.print_expanded_group(":bazel: Rewriting links in documentation files") |
| 143 | dest_root = os.path.join(tempfile.mkdtemp(), "site") |
| 144 | rewrite_and_copy(src_root, dest_root, settings.rewrite) |
| 145 | src_root = dest_root |
| 146 | |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 147 | bucket = "gs://{}".format(settings.gcs_bucket) |
| 148 | dest = get_destination(bucket, settings.gcs_subdir) |
| 149 | bazelci.print_expanded_group(":bazel: Uploading documentation to {}".format(dest)) |
| 150 | try: |
Florian Weikert | 8135ddd | 2021-05-12 18:14:07 +0200 | [diff] [blame] | 151 | bazelci.execute_command(["gsutil", "-m", "rsync", "-r", "-c", "-d", src_root, dest]) |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 152 | bazelci.execute_command( |
| 153 | ["gsutil", "web", "set", "-m", "index.html", "-e", "404.html", bucket] |
| 154 | ) |
| 155 | # TODO: does not work with 404 pages in sub directories |
| 156 | except subprocess.CalledProcessError as e: |
| 157 | bazelci.eprint("Upload to GCS failed with exit code {}".format(e.returncode)) |
| 158 | return e.returncode |
| 159 | |
| 160 | bazelci.print_collapsed_group(":bazel: Publishing documentation URL") |
Florian Weikert | 0ed195e | 2021-02-24 11:33:04 +0100 | [diff] [blame] | 161 | message = "You can find the documentation at {}".format(get_url(settings)) |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 162 | bazelci.execute_command( |
| 163 | ["buildkite-agent", "annotate", "--style=info", message, "--context", "doc_url"] |
| 164 | ) |
Florian Weikert | 8135ddd | 2021-05-12 18:14:07 +0200 | [diff] [blame] | 165 | bazelci.execute_command(["buildkite-agent", "meta-data", "set", "message", message]) |
Florian Weikert | 3ab3766 | 2021-02-22 17:46:31 +0100 | [diff] [blame] | 166 | |
| 167 | return 0 |
| 168 | |
| 169 | |
| 170 | if __name__ == "__main__": |
| 171 | sys.exit(main()) |