blob: 6d5a7084762267ab30929444d7a6dd5601bb92e2 [file] [log] [blame]
Florian Weikert3ab37662021-02-22 17:46:31 +01001#!/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
17import collections
18import os
Florian Weikert164f8062021-05-12 15:41:25 +020019import shutil
Florian Weikert3ab37662021-02-22 17:46:31 +010020import subprocess
21import sys
Florian Weikert164f8062021-05-12 15:41:25 +020022import tempfile
Florian Weikert3ab37662021-02-22 17:46:31 +010023
24import bazelci
25
Florian Weikertfc42a1d2021-02-23 16:53:00 +010026DEFAULT_FLAGS = ["--action_env=PATH=/usr/local/bin:/usr/bin:/bin", "--sandbox_tmpfs_path=/tmp"]
Florian Weikert3ab37662021-02-22 17:46:31 +010027
Florian Weikertaf816832021-04-22 16:49:23 +020028PLATFORM = "ubuntu1804"
29
Florian Weikert3ab37662021-02-22 17:46:31 +010030Settings = collections.namedtuple(
Florian Weikert8135ddd2021-05-12 18:14:07 +020031 "Settings",
32 ["target", "build_flags", "output_dir", "gcs_bucket", "gcs_subdir", "landing_page", "rewrite"],
Florian Weikert3ab37662021-02-22 17:46:31 +010033)
34
Florian Weikert164f8062021-05-12 15:41:25 +020035BUILDKITE_BUILD_NUMBER = os.getenv("BUILDKITE_BUILD_NUMBER")
36
Florian Weikert8135ddd2021-05-12 18:14:07 +020037
Florian Weikert681da162022-02-22 12:19:54 +010038def 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 Weikert3ab37662021-02-22 17:46:31 +010047DOCGEN_SETTINGS = {
48 "bazel-trusted": {
Florian Weikert681da162022-02-22 12:19:54 +010049 "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 Weikert3ab37662021-02-22 17:46:31 +010058 "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 Weikert164f8062021-05-12 15:41:25 +020065 rewrite=None,
Florian Weikert3ab37662021-02-22 17:46:31 +010066 ),
Florian Weikert681da162022-02-22 12:19:54 +010067 "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 Weikerte6b25f52021-04-16 15:48:04 +020087 },
Florian Weikert3ab37662021-02-22 17:46:31 +010088}
89
90
Florian Weikert164f8062021-05-12 15:41:25 +020091def 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 Weikert8135ddd2021-05-12 18:14:07 +020096 for filename in files:
97 src_file = os.path.join(src_dir, filename)
98 dest_file = os.path.join(dest_dir, filename)
Florian Weikert164f8062021-05-12 15:41:25 +020099
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 Weikert032fc202021-05-12 19:07:39 +0200105 dest.write(rewrite(content))
Florian Weikert164f8062021-05-12 15:41:25 +0200106 else:
107 shutil.copyfile(src_file, dest_file)
108
109
Florian Weikert3ab37662021-02-22 17:46:31 +0100110def get_destination(bucket, subdir):
111 if not subdir:
112 return bucket
113
114 return "{}/{}".format(bucket, subdir)
115
116
Florian Weikert0ed195e2021-02-24 11:33:04 +0100117def get_url(settings):
118 return "https://{}/{}".format(
119 get_destination(settings.gcs_bucket, settings.gcs_subdir), settings.landing_page
Florian Weikert3ab37662021-02-22 17:46:31 +0100120 )
121
122
123def 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 Weikert164f8062021-05-12 15:41:25 +0200140 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 Weikert3ab37662021-02-22 17:46:31 +0100147 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 Weikert8135ddd2021-05-12 18:14:07 +0200151 bazelci.execute_command(["gsutil", "-m", "rsync", "-r", "-c", "-d", src_root, dest])
Florian Weikert3ab37662021-02-22 17:46:31 +0100152 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 Weikert0ed195e2021-02-24 11:33:04 +0100161 message = "You can find the documentation at {}".format(get_url(settings))
Florian Weikert3ab37662021-02-22 17:46:31 +0100162 bazelci.execute_command(
163 ["buildkite-agent", "annotate", "--style=info", message, "--context", "doc_url"]
164 )
Florian Weikert8135ddd2021-05-12 18:14:07 +0200165 bazelci.execute_command(["buildkite-agent", "meta-data", "set", "message", message])
Florian Weikert3ab37662021-02-22 17:46:31 +0100166
167 return 0
168
169
170if __name__ == "__main__":
171 sys.exit(main())