From def750490cc1975d59bc80d160228c210ef0c119 Mon Sep 17 00:00:00 2001 From: Andrei Aristarkhov Date: Wed, 14 Oct 2026 17:26:05 -0700 Subject: [PATCH] ci(docs): publish main's web client to its versioned release slot Main now deploys the web client to both client/main/ and client/release-/, so consumers of the latest release line keep getting current builds without mirroring main into the release branch. The release slot belongs to main until release/ has commits main lacks. A release push that main already covers (e.g. the sync fast-forward) skips the web client build, and a main push whose VERSION names a diverged release branch fails CI until VERSION is bumped. VERSION changes now trigger a client rebuild. Signed-off-by: Andrei Aristarkhov --- .github/workflows/docs.yaml | 49 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 080117f8bd..2de41b88e3 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -67,6 +67,7 @@ jobs: outputs: docs: ${{ steps.filter.outputs.docs }} webapp: ${{ steps.filter.outputs.webapp }} + client-targets: ${{ steps.filter.outputs.client_targets }} steps: - name: Checkout (with history) uses: actions/checkout@v6 @@ -79,6 +80,31 @@ jobs: BASE_REF: ${{ github.base_ref }} run: | set -euo pipefail + # client// directories this push publishes. Main also fills client/release-/ + # until release/ has commits main lacks; a release push (e.g. a sync + # fast-forward) that has none publishes nothing. + diverged() { ! git merge-base --is-ancestor "$1" refs/remotes/origin/main; } + client_targets="" + if [[ "$GITHUB_REF_TYPE" == 'tag' ]]; then + client_targets="$GITHUB_REF_NAME" + elif [[ "$GITHUB_REF" == 'refs/heads/main' ]]; then + version="$(tr -d '[:space:]' < VERSION)" + release="refs/remotes/origin/release/$version" + if git rev-parse -q --verify "$release" >/dev/null && diverged "$release"; then + echo "::error file=VERSION::release/$version has commits main lacks; bump VERSION on main." + exit 1 + fi + client_targets="main release-$version" + elif [[ "$EVENT" == 'push' ]]; then + slug="${GITHUB_REF_NAME//\//-}" + if [[ "$(git show refs/remotes/origin/main:VERSION | tr -d '[:space:]')" == "${GITHUB_REF_NAME#release/}" ]] \ + && ! diverged HEAD; then + echo "::notice::main publishes client/$slug/; skipping the web client." + else + client_targets="$slug" + fi + fi + if [ "$EVENT" = 'pull_request' ]; then git fetch --no-tags --depth=1 origin "$BASE_REF" base="$(git merge-base FETCH_HEAD HEAD || true)" @@ -94,10 +120,12 @@ jobs: docs/*|.github/workflows/docs.yaml) docs=true ;; esac case "$f" in - deps/cloudxr/webxr_client/*|deps/cloudxr/.env.default|.github/actions/build-cloudxr-web-client/*|.github/workflows/docs.yaml) + deps/cloudxr/webxr_client/*|deps/cloudxr/.env.default|.github/actions/build-cloudxr-web-client/*|.github/workflows/docs.yaml|VERSION) webapp=true ;; esac done <<< "$files" + if [[ "$EVENT" == 'push' && -z "$client_targets" ]]; then webapp=false; fi + echo "client_targets=$client_targets" >> "$GITHUB_OUTPUT" echo "docs=$docs" >> "$GITHUB_OUTPUT" echo "webapp=$webapp" >> "$GITHUB_OUTPUT" echo "::notice::changes: docs=$docs webapp=$webapp (base=${base:-})" @@ -212,11 +240,15 @@ jobs: name: webapp path: ./webapp - # Web client lands at client//: tag → v1.2.3, main → main, release branch → release-1.3.x. + # Web client lands at each of `changes`' client-targets: tag → v1.2.3, main → main plus + # release-, release branch → release-1.3.x. Identical copies share git objects, + # so main's duplicate costs no gh-pages repo storage. # Tag pushes also (re)point client/stable/ at the highest v* tag. # The root client/ redirect is owned by the main branch deploy and points at ./stable/. - name: Place web app under versioned subpath if: needs.build-app.result == 'success' + env: + CLIENT_TARGETS: ${{ needs.changes.outputs.client-targets }} run: | set -euo pipefail CLIENT_BASE=./docs/build/client @@ -227,14 +259,11 @@ jobs: exit 0 fi - if [ "$GITHUB_REF_TYPE" = 'tag' ]; then - target="$GITHUB_REF_NAME" - else - target="${GITHUB_REF_NAME//\//-}" - fi - mkdir -p "$CLIENT_BASE/$target" - cp -r ./webapp/. "$CLIENT_BASE/$target/" - echo "Deployed web client to /client/$target/" + for target in $CLIENT_TARGETS; do + mkdir -p "$CLIENT_BASE/$target" + cp -r ./webapp/. "$CLIENT_BASE/$target/" + echo "Deployed web client to /client/$target/" + done if [ "$GITHUB_REF" = 'refs/heads/main' ]; then cat > "$CLIENT_BASE/index.html" <<'HTML'