Skip to content

Commit 4f950bb

Browse files
problameclaude
andauthored
docs: simplify build + zrepl.github.io publishing (#913)
This PR simplifies how we build and publish docs: - **Publish from `master` branch, retire `stable` branch.** The `stable` branch was a manual step in the release process and often out of date. Docs are now built and published directly from `master`. Release-specific docs are available in the `zrepl-noarch.tar` asset on each GitHub release. - **build dependencies**: use `uv` for dependency management - **zrepl.github.io: retire multi-version docs**: before this PR we used `sphinx-multiversion` to publish multiple docs versions to `zrepl.github.io`. This was never worth the pain, so, this PR removes it in order to simplify stuff. Old docs are available in the GitHub releases, and the docs now have a version dropdown that links there for a hand-curated set of versions. - **GitHub pages repo checkout**: use HTTPS because that's what I use these days for all things GitHub. Switch CircleCI to a fine-grained PAT. Refs - docs bug #895 - links to config examples should work again after this PR Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent e5704d5 commit 4f950bb

13 files changed

Lines changed: 460 additions & 232 deletions

‎.circleci/config.yml‎

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ orbs:
33
# NB: this is not the Go version, but the Orb version
44
# https://circleci.com/developer/orbs/orb/circleci/go#usage-go-modules-cache
55
go: circleci/[email protected]
6+
67
commands:
78
setup-home-local-bin:
89
steps:
@@ -25,11 +26,36 @@ commands:
2526
- run: sudo apt-get install -y git ca-certificates
2627

2728

29+
# NOTE: when updating uv version, update both the install URL and cache keys below
2830
install-docdep:
2931
steps:
3032
- apt-update-and-install-common-deps
31-
- run: sudo apt install python3 python3-pip libgirepository1.0-dev
32-
- run: pip3 install -r docs/requirements.txt
33+
# Python is managed by uv - it will automatically download the version
34+
# specified in docs/.python-version when needed
35+
- run:
36+
name: Install uv
37+
command: curl -LsSf https://astral.sh/uv/0.9.30/install.sh | sh
38+
- run:
39+
name: Add uv to PATH and set cache dir
40+
command: |
41+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> $BASH_ENV
42+
echo 'export UV_CACHE_DIR="$HOME/.cache/uv"' >> $BASH_ENV
43+
- restore_cache:
44+
name: Restore uv cache
45+
keys:
46+
- uv-cache-v1-0.9.30-{{ checksum "docs/uv.lock" }}
47+
- uv-cache-v1-0.9.30-
48+
49+
save-uv-cache:
50+
steps:
51+
- run:
52+
name: Prune uv cache for CI
53+
command: uv cache prune --ci
54+
- save_cache:
55+
name: Save uv cache
56+
key: uv-cache-v1-0.9.30-{{ checksum "docs/uv.lock" }}
57+
paths:
58+
- ~/.cache/uv
3359

3460
docs-publish-sh:
3561
parameters:
@@ -42,26 +68,19 @@ commands:
4268
git config --global user.email "[email protected]"
4369
git config --global user.name "zrepl-github-io-ci"
4470
45-
# if we're pushing, we need to add the deploy key
46-
# which is stored as "Additional SSH Keys" in the CircleCI project settings.
47-
# We can't use the CircleCI-manage deploy key because we're pushing
48-
# to a different repo than the one we're building.
71+
# Configure git to use the GitHub token for HTTPS authentication
72+
# The token is stored in the 'zrepl-github-io-deploy' context
4973
- when:
5074
condition: << parameters.push >>
5175
steps:
52-
# https://circleci.com/docs/2.0/add-ssh-key/#adding-multiple-keys-with-blank-hostnames
53-
- run: ssh-add -D
54-
# the default circleci ssh config only additional ssh keys for Host !github.com
5576
- run:
77+
name: Configure git credential helper for GitHub token
78+
# GITHUB_PAGES_TOKEN is from the 'zrepl-github-io-deploy' context.
79+
# CircleCI's secret masking automatically redacts context variables in logs.
5680
command: |
57-
cat > ~/.ssh/config \<<EOF
58-
Host *
59-
IdentityFile /home/circleci/.ssh/id_rsa_458e62c517f6c480e40452126ce47421
60-
EOF
61-
- add_ssh_keys:
62-
fingerprints:
63-
# deploy key for zrepl.github.io
64-
- "45:8e:62:c5:17:f6:c4:80:e4:04:52:12:6c:e4:74:21"
81+
git config --global credential.helper store
82+
echo "https://x-access-token:${GITHUB_PAGES_TOKEN}@github.com" > ~/.git-credentials
83+
chmod 600 ~/.git-credentials
6584
6685
# caller must install-docdep
6786
- when:
@@ -140,10 +159,12 @@ workflows:
140159
publish-zrepl.github.io:
141160
jobs:
142161
- publish-zrepl-github-io:
162+
context:
163+
- zrepl-github-io-deploy
143164
filters:
144165
branches:
145166
only:
146-
- stable
167+
- master
147168

148169
jobs:
149170
quickcheck-docs:
@@ -154,6 +175,7 @@ jobs:
154175
- install-docdep
155176
# do the current docs build
156177
- run: make docs
178+
- save-uv-cache
157179
# does the publish.sh script still work?
158180
- docs-publish-sh:
159181
push: false
@@ -297,3 +319,4 @@ jobs:
297319
- install-docdep
298320
- docs-publish-sh:
299321
push: true
322+
- save-uv-cache

‎Makefile‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,9 @@ $(ARTIFACTDIR)/go_env.txt:
380380

381381
docs: $(ARTIFACTDIR)/docs
382382
# https://www.sphinx-doc.org/en/master/man/sphinx-build.html
383-
$(MAKE) -C docs \
384-
html \
385-
BUILDDIR=../artifacts/docs \
386-
SPHINXOPTS="-W --keep-going -n"
383+
cd docs && uv sync --frozen
384+
cd docs && uv run sphinx-build -W --keep-going -n . ../artifacts/docs/html
387385

388386
docs-clean:
389-
$(MAKE) -C docs \
390-
clean \
391-
BUILDDIR=../artifacts/docs
387+
rm -rf artifacts/docs
388+
rm -rf docs/.venv

‎README.md‎

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ There is a CI check that ensures Git state is clean, i.e., code generation has b
5656

5757
#### Docs
5858

59-
Set up a Python environment that has `docs/requirements.txt` installed via `pip`.
60-
Use a [venv](https://docs.python.org/3/library/venv.html) to avoid global state.
59+
Install [uv](https://docs.astral.sh/uv/getting-started/installation/), then run `make docs`.
60+
uv automatically manages Python and dependencies.
6161

6262
### Testing
6363

@@ -90,17 +90,28 @@ There is a git tag for each zrepl release, usually `vMAJOR.MINOR.0`.
9090
We don't move git tags once the release has been published.
9191

9292
The procedure to issue a release is as follows:
93-
* Issue the source release:
94-
* Git tag the release on the `master` branch.
93+
94+
* Prepare the release (as a PR to `master`):
95+
* Finalize `docs/changelog.rst` for the release.
96+
* Merge the PR. Docs are auto-published to zrepl.github.io on merge.
97+
* Tag the release:
98+
* Git tag the release on the `master` branch (e.g., `vMAJOR.MINOR.0`).
9599
* Push the tag.
96-
* Run `./docs/publish.sh` to re-build & push zrepl.github.io.
97-
* Issue the official binary release:
98-
* Run the `release` pipeline (triggered via CircleCI API)
99-
* Download the artifacts to the release manager's machine.
100-
* Create a GitHub release, edit the changelog, upload all the release artifacts, including .rpm and .deb files.
101-
* Issue the GitHub release.
100+
* Build and publish:
101+
* Run the `release` pipeline (trigger via CircleCI UI).
102+
* Download artifacts: `make download-circleci-release BUILD_NUM=<circleci-build-number>`
103+
* Create GitHub release and upload artifacts:
104+
```bash
105+
gh release create vX.Y.Z --title "vX.Y.Z" --notes "See changelog" --draft
106+
gh release upload vX.Y.Z artifacts/release/*
107+
```
108+
* Review the draft release, edit the changelog, then publish.
102109
* Add the .rpm and .deb files to the official zrepl repos.
103110
* Code for management of these repos: https://github.com/zrepl/package-repo-ops (private repo at this time)
111+
* Update docs version list:
112+
* Update `docs/_templates/versions.html` with the new release.
113+
* Verify the link to `zrepl-noarch.tar` in the GitHub release works.
114+
* Merge to `master` (docs auto-publish).
104115

105116
#### Patch releases, Go toolchain updates, APT/RPM Package rebuilds
106117

@@ -161,6 +172,17 @@ Update the CI configuration `.circleci/config.yml`:
161172
- Update Go version references (we reference the minimum and max supported version)
162173
- Set `Makefile` `RELEASE_GOVERSION` to the new Go version
163174

175+
Update docs build tooling:
176+
- Update `uv` version in `.circleci/config.yml` (search for `astral.sh/uv/` and cache keys containing the version)
177+
- Check if there's now a CircleCI orb for uv that we could use
178+
- Update Python version in `docs/.python-version`
179+
180+
Update docs dependencies (Sphinx, sphinx-rtd-theme):
181+
- Check current versions in `docs/pyproject.toml`
182+
- Review upstream changelogs for breaking changes
183+
- Update version constraints in `pyproject.toml` and the `uv` lockfile (see [uv docs on dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/)):
184+
- Test locally with `make docs`
185+
164186
Kick a full CI pipeline run (`do_ci=true` and `do_release=true`).
165187

166188
Merge PR with merge commit.

‎docs/.python-version‎

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

‎docs/_templates/page.html‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1 @@
11
{% extends "!page.html" %}
2-
{% block body %}
3-
{% if current_version and latest_version and current_version != latest_version %}
4-
<p class="scv-banner scv-sphinx_rtd_theme">
5-
<strong>
6-
{% if current_version.is_released %}
7-
You're reading an old version of this documentation.
8-
If you want up-to-date information, please have a look at <a href="{{ vpathto(latest_version.name) }}">{{latest_version.name}}</a>.
9-
{% else %}
10-
You're reading the documentation for a development version.
11-
For the latest released version, please have a look at <a href="{{ vpathto(latest_version.name) }}">{{latest_version.name}}</a>.
12-
{% endif %}
13-
</strong>
14-
</p>
15-
{% endif %}
16-
{{ super() }}
17-
{% endblock %}%

‎docs/_templates/versions.html‎

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
{%- if current_version %}
21
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
32
<span class="rst-current-version" data-toggle="rst-current-version">
43
<span class="fa fa-book"> Other Versions</span>
5-
v: {{ current_version.name }}
4+
v: latest
65
<span class="fa fa-caret-down"></span>
76
</span>
87
<div class="rst-other-versions">
9-
{%- if versions.tags %}
108
<dl>
11-
<dt>Tags</dt>
12-
{%- for item in versions.tags %}
13-
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
14-
{%- endfor %}
9+
<dt>Releases</dt>
10+
<dd><a href="https://github.com/zrepl/zrepl/releases/tag/v0.6.1">v0.6.1</a></dd>
11+
<dd><a href="https://github.com/zrepl/zrepl/releases/tag/v0.5.0">v0.5.0</a></dd>
12+
<dd><a href="https://github.com/zrepl/zrepl/releases/tag/v0.4.0">v0.4.0</a></dd>
13+
<dd><a href="https://github.com/zrepl/zrepl/releases">All releases...</a></dd>
1514
</dl>
16-
{%- endif %}
17-
{%- if versions.branches %}
1815
<dl>
19-
<dt>Branches</dt>
20-
{%- for item in versions.branches %}
21-
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
22-
{%- endfor %}
16+
<dt>Note</dt>
17+
<dd style="white-space: normal;">
18+
Release-specific docs are in the
19+
<span style="font-family: monospace;">zrepl-noarch.tar</span>
20+
asset on each GitHub release.
21+
</dd>
2322
</dl>
24-
{%- endif %}
2523
</div>
2624
</div>
27-
{%- endif %}

‎docs/changelog.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ INCOMPLETE LIST OF CHANGES
4848
* |maint| Update to Go 1.25 toolchain with Go 1.24 language level.
4949
* |maint| Fix deprecations exposed by the toolchain update.
5050
* |maint| Long-overdue update of all our dependencies & address deprecations.
51+
* |maint| Publish docs from ``master`` branch, retire ``stable`` branch.
5152
* |maint| The `make release-docker` in CircleCI produces executables that are bit-identical to my personal machine.
5253

5354
0.6.1

‎docs/conf.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
# Add any Sphinx extension module names here, as strings. They can be
3232
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3333
# ones.
34-
extensions = ['sphinx.ext.todo',
34+
extensions = [
35+
'sphinx.ext.todo',
3536
'sphinx.ext.githubpages',
3637
'sphinx.ext.extlinks',
37-
"sphinx_multiversion",
3838
]
3939

4040
# suppress_warnings = ['image.nonlocal_uri']
@@ -53,17 +53,17 @@
5353

5454
# General information about the project.
5555
project = 'zrepl'
56-
copyright = '2017-2023, Christian Schwarz'
56+
copyright = '2017-2026, Christian Schwarz'
5757
author = 'Christian Schwarz'
5858

5959
# The version info for the project you're documenting, acts as replacement for
6060
# |version| and |release|, also used in various other places throughout the
6161
# built documents.
6262
#
6363
# The short X.Y version.
64-
#version = set by sphinxcontrib-versioning
64+
version = 'latest'
6565
# The full version, including alpha/beta/rc tags.
66-
#release = version
66+
release = 'latest'
6767

6868
# The language for content autogenerated by Sphinx. Refer to documentation
6969
# for a list of supported languages.
@@ -75,7 +75,7 @@
7575
# List of patterns, relative to source directory, that match files and
7676
# directories to ignore when looking for source files.
7777
# This patterns also effect to html_static_path and html_extra_path
78-
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
78+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.venv']
7979

8080
# The name of the Pygments (syntax highlighting) style to use.
8181
pygments_style = 'sphinx'

0 commit comments

Comments
 (0)