diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06325bca60c0d..4bb30e23b1ffb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,21 +145,13 @@ jobs: cp -r /tmp/paimon-rust-site/* docs/rust/ - name: Clone Paimon CPP repo - run: git clone --depth 1 https://github.com/apache/paimon-cpp.git /tmp/paimon-cpp + run: git clone https://github.com/apache/paimon-cpp.git /tmp/paimon-cpp - name: Build Paimon CPP docs run: | sudo apt-get update sudo apt-get install -y doxygen - pip install -r /tmp/paimon-cpp/docs/requirements.txt - cd /tmp/paimon-cpp/apidoc - doxygen - cd /tmp/paimon-cpp/docs - make html - cd $GITHUB_WORKSPACE - rm -rf docs/cpp - mkdir -p docs/cpp - cp -r /tmp/paimon-cpp/docs/_build/html/* docs/cpp/ + bash .github/workflows/cpp-docs.sh /tmp/paimon-cpp "$PWD/docs/cpp" - name: Clone Paimon Mosaic repo run: git clone --depth 1 https://github.com/apache/paimon-mosaic.git /tmp/paimon-mosaic diff --git a/.github/workflows/cpp-docs.sh b/.github/workflows/cpp-docs.sh new file mode 100644 index 0000000000000..e0f0fc96b4b66 --- /dev/null +++ b/.github/workflows/cpp-docs.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +source_dir=$(realpath "$1") +destination=$(realpath -m "$2") +staging=$(mktemp -d) +trap 'rm -rf "$staging"' EXIT + +cd "$source_dir" +git checkout --quiet main +cp docs/source/_static/versions.json "$staging/versions.json" + +# Use full release labels to find release-X.Y branches. The stable switcher +# identifier is empty; archived identifiers contain only the major.minor series. +# Write the plan separately so malformed metadata fails before any build starts. +python3 - "$staging/versions.json" > "$staging/plan" <<'PY' +import json +import re +import sys + +with open(sys.argv[1]) as stream: + versions = json.load(stream) +base_url = "https://paimon.apache.org/docs/cpp/" +assert len(versions) >= 2, "Expected main and stable documentation entries" +main, stable, *archives = versions +assert main["version"] == "main" and main["url"] == base_url + "main/" +match = re.fullmatch(r"(\d+\.\d+)\.\d+ \(stable\)", stable["name"]) +assert match and stable["version"] == "" and stable.get("preferred") is True +assert stable["url"] == base_url +stable_series = match.group(1) +# Build stable first because it occupies the root of the staged tree. +print(f"stable\trelease-{stable_series}\t.") +print("main\tmain\tmain") +seen = {stable_series} +for entry in archives: + match = re.fullmatch(r"(\d+\.\d+)\.\d+", entry["name"]) + assert match, f"Invalid archived release label: {entry!r}" + series = match.group(1) + assert series not in seen, f"Duplicate release series: {series}" + assert entry["version"] == series and entry["url"] == base_url + series + "/" + seen.add(series) + print(f"{series}\trelease-{series}\t{series}") +PY + +# Check every required branch before starting. Publishing a partial tree would +# leave the shared version dropdown pointing at missing documentation. +while IFS=$'\t' read -r channel branch path; do + git rev-parse --verify "refs/remotes/origin/$branch" >/dev/null +done < "$staging/plan" + +while IFS=$'\t' read -r channel branch path; do + git checkout --quiet "$branch" + python3 -m pip install -r docs/requirements.txt + rm -rf apidoc/xml docs/_build + (cd apidoc && doxygen) + (cd docs && PAIMON_DOCS_VERSION="$channel" make html) + mkdir -p "$staging/html/$path" + cp -a docs/_build/html/. "$staging/html/$path/" + # Keep each built copy consistent with the shared list from main, even if + # an older release branch still contains legacy version metadata. + cp "$staging/versions.json" "$staging/html/$path/_static/versions.json" + git reset --hard HEAD + git clean -fdx +done < "$staging/plan" + +# Replace only after all versions succeed. This also removes obsolete versions +# without deleting Sphinx's _static, _sources or generated page directories. +mkdir -p "$(dirname "$destination")" +rm -rf "$destination" +mv "$staging/html" "$destination"