Skip to content

Commit 6c45184

Browse files
author
Yuan Li
committed
Merge branch 'google:main' into feat/404-support
2 parents 9f6bcfe + c092c38 commit 6c45184

104 files changed

Lines changed: 33069 additions & 13451 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9.1.1

.github/workflows/build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ jobs:
110110
- name: Update Rust
111111
run: rustup update
112112

113+
- name: Setup Bazel cache
114+
uses: bazel-contrib/setup-bazel@0.19.0
115+
with:
116+
disk-cache: true
117+
113118
- name: Setup Rust cache
114119
uses: ./.github/workflows/setup-rust-cache
115120
with:
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Copyright 2026 Google LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
"""Ensure all deleted files have a redirect entry.
16+
17+
First, the code finds all deleted ".md" files under the "src/" directory between
18+
the current working copy and the specificed commit/branch.
19+
20+
Next, for each deleted ".md" file it searches for a corresponding entry in
21+
"book.toml" under the "[output.html.redirect]" section. The ".md" extension
22+
should be swapped with a ".html" extension and a "src/" prefix add to it.
23+
Any deleted ".md" file that is not found is printed to stdout.
24+
25+
If any deleted ".md" files are missing a redirect entry, the script exits with
26+
a value of 1. Otherwise, it exits with a value of 0.
27+
28+
Usage:
29+
check-redirects.py <root directory of the repository> <commit to compare (e.g. origin/main)>
30+
"""
31+
32+
import os
33+
import subprocess
34+
import sys
35+
36+
# NOTE: Update INVALID_FILE_EXTENSION_ERROR if ALLOWED_REDIRECT_EXTENSIONS is modified
37+
ALLOWED_REDIRECT_EXTENSIONS = [".html", ""]
38+
INVALID_FILE_EXTENSION_ERROR = f'Invalid file extension. Path must be a directory or a file ending in ".html".'
39+
40+
41+
class InvalidRedirectEntry:
42+
43+
def __init__(self, line, error):
44+
self.line = line
45+
self.error = error
46+
47+
def __str__(self):
48+
return f"{self.line} ({self.error})"
49+
50+
51+
def md_to_html_redirect_source(md_file):
52+
return md_file.replace("src/", "", 1).replace(".md", ".html")
53+
54+
55+
def html_redirect_target_to_md(redirect_source, redirect_target):
56+
redirect_source_directory = os.path.join("src",
57+
os.path.dirname(redirect_source))
58+
redirect_target_md_file = redirect_target.replace(".html", ".md")
59+
return os.path.normpath(
60+
os.path.join(redirect_source_directory, redirect_target_md_file))
61+
62+
63+
def main():
64+
if len(sys.argv) != 3:
65+
print(
66+
"Usage: check-redirects.py <root directory of the repository> <commit to compare (e.g. origin/main)>"
67+
)
68+
sys.exit(1)
69+
70+
repo_root = sys.argv[1]
71+
commit = sys.argv[2]
72+
73+
if not os.path.isdir(repo_root):
74+
print(f"Error: {repo_root} is not a directory")
75+
sys.exit(1)
76+
77+
# Change to repo root to run git commands and find book.toml
78+
os.chdir(repo_root)
79+
80+
# Get deleted .md files under src/
81+
try:
82+
diff_output = subprocess.check_output(
83+
["git", "diff", commit, "--diff-filter=D", "--name-only"],
84+
text=True)
85+
except subprocess.CalledProcessError as e:
86+
print(f"Error running git diff: {e}")
87+
sys.exit(1)
88+
89+
deleted_files = [
90+
f for f in diff_output.splitlines()
91+
if f.startswith("src/") and f.endswith(".md")
92+
]
93+
94+
# Read book.toml and extract redirects
95+
book_toml_path = "book.toml"
96+
if not os.path.exists(book_toml_path):
97+
print(f"Error: {book_toml_path} not found in {repo_root}")
98+
sys.exit(1)
99+
100+
with open(book_toml_path, "r") as f:
101+
lines = f.readlines()
102+
103+
invalid_redirect_entries = []
104+
redirects = {}
105+
in_redirect_section = False
106+
for line in lines:
107+
line = line.strip()
108+
if not line or line.startswith("#"):
109+
continue
110+
111+
if line.startswith("[") and line.endswith("]"):
112+
if line == "[output.html.redirect]":
113+
in_redirect_section = True
114+
else:
115+
in_redirect_section = False
116+
continue
117+
118+
if in_redirect_section:
119+
# Entry looks like "old.html" = "new.html" or "old.html" = "/new"
120+
parts = line.split("=")
121+
if len(parts) != 2:
122+
invalid_redirect_entries.append(
123+
InvalidRedirectEntry(line, 'Only one "=" expected'))
124+
continue
125+
126+
redirect_source = parts[0].strip().strip("\"'")
127+
redirect_target = parts[1].strip().strip("\"'")
128+
129+
_, redirect_source_extension = os.path.splitext(redirect_source)
130+
_, redirect_target_extension = os.path.splitext(redirect_target)
131+
132+
if (redirect_source_extension not in ALLOWED_REDIRECT_EXTENSIONS
133+
or redirect_target_extension
134+
not in ALLOWED_REDIRECT_EXTENSIONS):
135+
invalid_redirect_entries.append(
136+
InvalidRedirectEntry(
137+
line,
138+
INVALID_FILE_EXTENSION_ERROR,
139+
))
140+
continue
141+
142+
redirect_target_md = html_redirect_target_to_md(
143+
redirect_source, redirect_target)
144+
if not os.path.exists(redirect_target_md):
145+
invalid_redirect_entries.append(
146+
InvalidRedirectEntry(
147+
line,
148+
f"{redirect_source} -> {redirect_target}: could not find {redirect_target_md}"
149+
))
150+
continue
151+
152+
redirects[redirect_source] = redirect_target
153+
154+
missing_redirects = []
155+
for md_file in deleted_files:
156+
# Swap .md with .html and remove src/ prefix if it's relative to site root
157+
# Usually redirects in book.toml for mdbook are relative to the output root.
158+
# If the file is src/foo/bar.md, it becomes foo/bar.html in the output.
159+
html_file = md_file.replace("src/", "", 1).replace(".md", ".html")
160+
if html_file not in redirects:
161+
missing_redirects.append(md_file)
162+
163+
if invalid_redirect_entries:
164+
print("The following redirect entries in book.toml are invalid:")
165+
166+
for invalid_redirect_entry in invalid_redirect_entries:
167+
print(invalid_redirect_entry)
168+
169+
print()
170+
171+
if missing_redirects:
172+
print(
173+
"The following deleted files are missing a redirect entry in book.toml:"
174+
)
175+
for f in missing_redirects:
176+
print(f)
177+
178+
ret = 1 if invalid_redirect_entries or missing_redirects else 0
179+
sys.exit(ret)
180+
181+
182+
if __name__ == "__main__":
183+
main()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Check that redirects are valid
2+
permissions:
3+
contents: read
4+
5+
on:
6+
pull_request:
7+
8+
jobs:
9+
check-redirects:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v6
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Check redirects
18+
run: python3 .github/workflows/check-redirects.py . origin/main

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ jobs:
5252
uses: actions/checkout@v6
5353

5454
- name: Check for typos
55-
uses: crate-ci/typos@v1.44.0
55+
uses: crate-ci/typos@v1.47.0
5656
with:
5757
config: ./.github/typos.toml

.github/workflows/publish.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ jobs:
3838
- name: Update Rust
3939
run: rustup update
4040

41+
- name: Setup Bazel cache
42+
uses: bazel-contrib/setup-bazel@0.19.0
43+
with:
44+
disk-cache: true
45+
4146
- name: Setup Rust cache
4247
uses: ./.github/workflows/setup-rust-cache
4348

@@ -70,13 +75,13 @@ jobs:
7075
i18n-report report book/html/synced-translation-report.html synced-po/*.po
7176
7277
- name: Setup Pages
73-
uses: actions/configure-pages@v5
78+
uses: actions/configure-pages@v6
7479

7580
- name: Upload artifact
76-
uses: actions/upload-pages-artifact@v4
81+
uses: actions/upload-pages-artifact@v5
7782
with:
7883
path: book/html
7984

8085
- name: Deploy to GitHub Pages
8186
id: deployment
82-
uses: actions/deploy-pages@v4
87+
uses: actions/deploy-pages@v5

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
target/
44
*.bin
55

6+
# Bazel files
7+
/bazel-*
8+
69
# Translation artifacts
710
po/*.mo
811
po/*.po~

BUILD.bazel

Whitespace-only changes.

CONTRIBUTING.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ Install `dprint` using their
7171
[installation instructions](https://dprint.dev/install/) and install `rustfmt`
7272
via `rustup`.
7373

74+
Install Bazel via the
75+
[Bazelisk version manager](https://github.com/bazelbuild/bazelisk).
76+
7477
Install [pandoc 3.7.0.1](https://github.com/jgm/pandoc/releases/tag/3.7.0.1).
7578

7679
On Debian, you can install the other tools using:
@@ -84,7 +87,7 @@ sudo apt install yapf3 gettext texlive texlive-luatex texlive-lang-cjk texlive-l
8487
On MacOS with [Homebrew], you can install the necessary tools with:
8588

8689
```shell
87-
brew install dprint yapf gettext
90+
brew install dprint yapf gettext bazelisk
8891
```
8992

9093
### Windows
@@ -95,6 +98,9 @@ Install `dprint` using their
9598
[installation instructions](https://dprint.dev/install/) and install `rustfmt`
9699
via `rustup`.
97100

101+
Install Bazel via the
102+
[Bazelisk version manager](https://github.com/bazelbuild/bazelisk).
103+
98104
> _TODO: fill in how to install `yapf` on Windows._
99105
100106
[`dprint`]: https://dprint.dev/

0 commit comments

Comments
 (0)