From 32792ab06f26035e3d027de39a8ef98a678169c7 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 06:01:10 -0500 Subject: [PATCH 01/58] docs(ci[deploy]): Publish to libtmux.org under this port's prefix why: The sync wrote the whole bucket root with --delete, which is the shape libtmux.org's per-port prefixes exist to prevent, and it left the Python docs outside the site: every /en/py// URL 403s because no port tree has been published. libtmux/docs is public as of today, so its reusable deploy workflow can be called from here. what: - Split the job: build uploads docs/_build/html, publish calls libtmux/docs reusable-deploy.yml and deploys only en/py/latest - Pass path-prefix unprefixed by locale; the workflow prepends it - Add the workflow-level concurrency group every caller must set - Drop LIBTMUX_DOCS_STANDALONE: the tree is nested now, so the shell's chrome and site-wide search are reachable and belong on - Pin the reusable workflow to a commit rather than a moving branch --- .github/workflows/docs.yml | 98 +++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1de59432d..5cc95b7f2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,13 +9,26 @@ permissions: contents: read id-token: write +# Required of every caller of reusable-deploy.yml, and not something that +# workflow can do for itself: concurrency groups do not cross repository +# boundaries, so each port serialises its own publishes here. `queue: max` +# runs the newest queued publish after the running one instead of cancelling +# it, and cannot be combined with cancel-in-progress. See libtmux/docs +# docs/ci.md. +concurrency: + group: docs-deploy-${{ github.repository }} + queue: max + jobs: build: runs-on: ubuntu-latest - environment: docs strategy: matrix: python-version: ['3.14'] + outputs: + # `publish` reaches the deploy job, which $GITHUB_ENV cannot: env vars + # written by a step are scoped to their own job. + publish: ${{ steps.should-publish.outputs.publish }} steps: - uses: actions/checkout@v7 @@ -36,8 +49,11 @@ jobs: - pyproject.toml - name: Should publish + id: should-publish if: steps.changes.outputs.docs == 'true' || steps.changes.outputs.root_docs == 'true' || steps.changes.outputs.python_files == 'true' - run: echo "PUBLISH=$(echo true)" >> $GITHUB_ENV + run: | + echo "PUBLISH=true" >> "$GITHUB_ENV" + echo "publish=true" >> "$GITHUB_OUTPUT" - name: Install uv if: env.PUBLISH == 'true' @@ -72,46 +88,52 @@ jobs: restore-keys: | sphinx-fonts- + # No LIBTMUX_DOCS_STANDALONE here: this tree now publishes under + # libtmux.org at en/py/latest/, where the shell's chrome and its + # site-wide search are reachable from the root-relative paths + # docs/conf.py emits. Setting it would publish nested and unskinned. - name: Build documentation if: env.PUBLISH == 'true' - env: - # This tree is published to the bucket root, not nested under - # libtmux.org's shell, so the shell's chrome and site-wide search - # are not reachable from here. Keep Furo's own search page and load - # no chrome. See the note in docs/conf.py. - # - # Delete this when the sync below moves under libtmux.org, to a - # per-port prefix. Left behind, the build publishes nested and - # still unskinned — no chrome, and Furo's search where the site's - # own belongs — which reads as the shell having failed rather than - # as a stale flag. tests/test_docs_conf.py covers both shapes. - LIBTMUX_DOCS_STANDALONE: '1' run: | cd docs && just html - - name: Configure AWS Credentials + - name: Upload the built site if: env.PUBLISH == 'true' - uses: aws-actions/configure-aws-credentials@v6 + uses: actions/upload-artifact@v7 with: - role-to-assume: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }} - aws-region: us-east-1 - - - name: Push documentation to S3 - if: env.PUBLISH == 'true' - run: | - aws s3 sync docs/_build/html "s3://${{ secrets.LIBTMUX_DOCS_BUCKET }}" \ - --delete --follow-symlinks - - - name: Invalidate CloudFront - if: env.PUBLISH == 'true' - run: | - aws cloudfront create-invalidation \ - --distribution-id "${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }}" \ - --paths "/index.html" "/objects.inv" "/searchindex.js" - - - name: Purge cache on Cloudflare - if: env.PUBLISH == 'true' - uses: jakejarvis/cloudflare-purge-action@v0.3.0 - env: - CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} - CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + name: docs-html + path: docs/_build/html + retention-days: 1 + + # path-prefix is unprefixed by locale: reusable-deploy prepends `/` + # itself whenever `port` is set, so this publishes to en/py/latest/. Passing + # en/py/latest here would produce en/en/py/latest. + # + # `environment` is an input rather than `environment:` on this job, which + # `uses:` does not accept — and reusable-deploy's own job is the one whose + # OIDC subject has to carry `environment:docs` to match the role's trust + # policy. The three secrets are passed explicitly, never `secrets: inherit`. + publish: + needs: build + if: needs.build.outputs.publish == 'true' + permissions: + contents: read + id-token: write + # Pinned to a commit, as reusable-deploy.yml's own header asks of + # callers. It says `@v1`; libtmux/docs carries no tags yet, and a + # floating `@main` would let another repository change what runs here + # with `id-token: write` and a role that can write the bucket. Move this + # to the tag once one exists. + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@dfe5b6c8f718992a3baec4ed0a03b840d8bdb623 + with: + path-prefix: py/latest + artifact: docs-html + version-kind: trunk + port: py + version: latest + is-default: true + environment: docs + secrets: + role-arn: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }} + bucket: ${{ secrets.LIBTMUX_DOCS_BUCKET }} + distribution: ${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }} From ad2d4fe3474ebb42953f4419b22058c4b0cc05dc Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 06:08:08 -0500 Subject: [PATCH 02/58] docs(ci[deploy]) Pin the deploy workflow to v1 why: The SHA pin stood in for a tag that did not exist when this was written; libtmux/docs has since tagged v1, which is the ref its own header asks callers to use and bump on review. what: - Point the publish job at @v1, whose reusable-deploy.yml is byte-identical to the commit it replaces --- .github/workflows/docs.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5cc95b7f2..1a04c8f06 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -119,12 +119,11 @@ jobs: permissions: contents: read id-token: write - # Pinned to a commit, as reusable-deploy.yml's own header asks of - # callers. It says `@v1`; libtmux/docs carries no tags yet, and a - # floating `@main` would let another repository change what runs here - # with `id-token: write` and a role that can write the bucket. Move this - # to the tag once one exists. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@dfe5b6c8f718992a3baec4ed0a03b840d8bdb623 + # Pinned to the tag reusable-deploy.yml's own header asks callers to + # use, and bumped on review like any other dependency. Not `@main`: + # this hands another repository execution inside ours, with + # `id-token: write` and a role that can write the bucket. + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@v1 with: path-prefix: py/latest artifact: docs-html From de5437c20ddb6fc55bcffdf47f30a7a4376352bf Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 06:17:51 -0500 Subject: [PATCH 03/58] docs(ci[deploy]): Publish to libtmux.org alongside git-pull.com why: The previous shape moved the publish, which would have stopped libtmux.git-pull.com updating the moment it merged. Serving both costs one more build and leaves a failure on the new side with no effect on the old one. what: - Build twice: the two sites need different bytes, not one artifact published to both. git-pull.com is served at a root and is built standalone; libtmux.org nests at en/py/latest and carries the shell - Publish git-pull.com from inside its own build, exactly as before, rather than behind an artifact that would not keep its symlinks - Give libtmux.org its own LIBTMUX_ORG_* secrets, leaving LIBTMUX_DOCS_* meaning what it means today - Move the paths-filter gate into its own job, so one output feeds both and no step repeats the condition - Pin the shared workflow to v2 --- .github/workflows/docs.yml | 138 ++++++++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 42 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1a04c8f06..9d0941a10 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,21 +20,19 @@ concurrency: queue: max jobs: - build: + # Its own job because the answer has to reach the deploy job, and a step's + # $GITHUB_ENV does not leave the job that wrote it. Every job below is + # gated on this one output rather than repeating the condition per step. + changes: runs-on: ubuntu-latest - strategy: - matrix: - python-version: ['3.14'] outputs: - # `publish` reaches the deploy job, which $GITHUB_ENV cannot: env vars - # written by a step are scoped to their own job. - publish: ${{ steps.should-publish.outputs.publish }} + publish: ${{ steps.gate.outputs.publish }} steps: - uses: actions/checkout@v7 - name: Filter changed file paths to outputs uses: dorny/paths-filter@v4 - id: changes + id: filter with: filters: | root_docs: @@ -49,38 +47,57 @@ jobs: - pyproject.toml - name: Should publish - id: should-publish - if: steps.changes.outputs.docs == 'true' || steps.changes.outputs.root_docs == 'true' || steps.changes.outputs.python_files == 'true' - run: | - echo "PUBLISH=true" >> "$GITHUB_ENV" - echo "publish=true" >> "$GITHUB_OUTPUT" + id: gate + env: + MATCHED: ${{ steps.filter.outputs.docs == 'true' || steps.filter.outputs.root_docs == 'true' || steps.filter.outputs.python_files == 'true' }} + run: echo "publish=$MATCHED" >> "$GITHUB_OUTPUT" + + # The two sites need different bytes, not the same tree published twice. + # libtmux.git-pull.com serves this build at a root, where /_shell/ is + # nothing and /search/ is the build's own search page — so it is built + # standalone, keeping Furo's search and loading no chrome. libtmux.org + # nests it at en/py/latest/, where both are reachable and belong on. + # Publishing one artifact to both gives an unskinned nested site or a + # root site whose search redirects to itself, depending which way the + # flag is set. tests/test_docs_conf.py pins both shapes. + build: + needs: changes + if: needs.changes.outputs.publish == 'true' + runs-on: ubuntu-latest + environment: docs + strategy: + # Neither destination should lose its publish because the other + # failed to build. + fail-fast: false + matrix: + include: + - site: git-pull-com + standalone: '1' + - site: libtmux-org + standalone: '' + steps: + - uses: actions/checkout@v7 - name: Install uv - if: env.PUBLISH == 'true' uses: astral-sh/setup-uv@v10.2.0 with: enable-cache: true - - name: Set up Python ${{ matrix.python-version }} - if: env.PUBLISH == 'true' - run: uv python install ${{ matrix.python-version }} + - name: Set up Python + run: uv python install 3.14 - name: Install dependencies [w/ docs] - if: env.PUBLISH == 'true' run: uv sync --all-extras --dev - name: Install just - if: env.PUBLISH == 'true' uses: extractions/setup-just@v4 - name: Print python versions - if: env.PUBLISH == 'true' run: | python -V uv run python -V - name: Cache sphinx fonts - if: env.PUBLISH == 'true' uses: actions/cache@v6 with: path: ~/.cache/sphinx-fonts @@ -88,42 +105,79 @@ jobs: restore-keys: | sphinx-fonts- - # No LIBTMUX_DOCS_STANDALONE here: this tree now publishes under - # libtmux.org at en/py/latest/, where the shell's chrome and its - # site-wide search are reachable from the root-relative paths - # docs/conf.py emits. Setting it would publish nested and unskinned. - name: Build documentation - if: env.PUBLISH == 'true' + env: + LIBTMUX_DOCS_STANDALONE: ${{ matrix.standalone }} run: | cd docs && just html - - name: Upload the built site - if: env.PUBLISH == 'true' + # libtmux.git-pull.com publishes from inside this job, as it always + # has. Kept in place rather than moved behind an artifact: this is a + # live site, and an artifact round trip does not preserve the symlinks + # the sync below is told to follow. + - name: Configure AWS credentials for libtmux.git-pull.com + if: matrix.site == 'git-pull-com' + uses: aws-actions/configure-aws-credentials@v6 + with: + role-to-assume: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }} + aws-region: us-east-1 + + - name: Push documentation to S3 + if: matrix.site == 'git-pull-com' + run: | + aws s3 sync docs/_build/html "s3://${{ secrets.LIBTMUX_DOCS_BUCKET }}" \ + --delete --follow-symlinks + + - name: Invalidate CloudFront + if: matrix.site == 'git-pull-com' + run: | + aws cloudfront create-invalidation \ + --distribution-id "${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }}" \ + --paths "/index.html" "/objects.inv" "/searchindex.js" + + - name: Purge cache on Cloudflare + if: matrix.site == 'git-pull-com' + uses: jakejarvis/cloudflare-purge-action@v0.3.0 + env: + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + + # libtmux.org publishes through the shared workflow instead, which + # only ever writes one port's own prefix. It downloads to dist/ and + # syncs dist/, so the tree has to sit at the artifact root. + - name: Upload the built site for libtmux.org + if: matrix.site == 'libtmux-org' uses: actions/upload-artifact@v7 with: name: docs-html path: docs/_build/html retention-days: 1 - # path-prefix is unprefixed by locale: reusable-deploy prepends `/` - # itself whenever `port` is set, so this publishes to en/py/latest/. Passing - # en/py/latest here would produce en/en/py/latest. + # Additive: a failure here leaves libtmux.git-pull.com serving exactly what + # it serves today, because that publish already happened in the job above. + # + # path-prefix is unprefixed by locale — reusable-deploy prepends `/` + # itself whenever `port` is set, so this publishes to en/py/latest/, and + # passing en/py/latest here would produce en/en/py/latest. # # `environment` is an input rather than `environment:` on this job, which # `uses:` does not accept — and reusable-deploy's own job is the one whose # OIDC subject has to carry `environment:docs` to match the role's trust # policy. The three secrets are passed explicitly, never `secrets: inherit`. - publish: - needs: build - if: needs.build.outputs.publish == 'true' + # + # LIBTMUX_ORG_* is a separate set from LIBTMUX_DOCS_*, which keeps its + # current meaning: the libtmux.git-pull.com bucket, unchanged. + publish-libtmux-org: + needs: [changes, build] + if: needs.changes.outputs.publish == 'true' permissions: contents: read id-token: write - # Pinned to the tag reusable-deploy.yml's own header asks callers to - # use, and bumped on review like any other dependency. Not `@main`: - # this hands another repository execution inside ours, with - # `id-token: write` and a role that can write the bucket. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@v1 + # Pinned to the tag reusable-deploy.yml's own header asks callers to use, + # and bumped on review like any other dependency. Not `@main`: this hands + # another repository execution inside ours, with `id-token: write` and a + # role that can write the bucket. + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@v2 with: path-prefix: py/latest artifact: docs-html @@ -133,6 +187,6 @@ jobs: is-default: true environment: docs secrets: - role-arn: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }} - bucket: ${{ secrets.LIBTMUX_DOCS_BUCKET }} - distribution: ${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }} + role-arn: ${{ secrets.LIBTMUX_ORG_ROLE_ARN }} + bucket: ${{ secrets.LIBTMUX_ORG_BUCKET }} + distribution: ${{ secrets.LIBTMUX_ORG_DISTRIBUTION }} From 77a30666083b0e615e4652483207ea3f9c63e5df Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 06:22:49 -0500 Subject: [PATCH 04/58] docs(ci[deploy]): Pin the deploy workflow to a commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit why: libtmux/docs deleted v1 and v2, so the `@v2` here resolved to nothing and this workflow could not have started. Its replacement is a 0.x prerelease series documented as moving, and a ref that can be repointed changes what executes in this repository — with `id-token: write` and a role that can write the bucket — without a diff here or a review. what: - Pin the commit the deleted tag pointed at, whose reusable-deploy.yml is byte-identical to both deleted tags - Name the release it belongs to in a trailing comment, which is the form Dependabot reads to offer a bump --- .github/workflows/docs.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9d0941a10..837a37be2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -173,11 +173,17 @@ jobs: permissions: contents: read id-token: write - # Pinned to the tag reusable-deploy.yml's own header asks callers to use, - # and bumped on review like any other dependency. Not `@main`: this hands - # another repository execution inside ours, with `id-token: write` and a - # role that can write the bucket. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@v2 + # Pinned to a commit, with the release it belongs to named beside it. + # + # Not a tag: libtmux/docs's 0.x series is documented as moving, and this + # `uses:` runs another repository's workflow inside ours with + # `id-token: write` and a role that can write the bucket. A ref that can + # be repointed makes what executes here change with no diff in this + # repository and no review. A commit cannot be repointed, and Dependabot + # reads the trailing comment to offer the bump. + # + # Bump it on review, like any other dependency. + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@0cd5a3f10c70bf55130ab6a02d5177f6318beaca # v0.1.0-alpha.1 with: path-prefix: py/latest artifact: docs-html From 4935a3d50f995a96712e275b75bfe085289b2675 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 06:34:51 -0500 Subject: [PATCH 05/58] docs(ci[deploy]) Move the deploy pin to v0.1.0-alpha.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit why: libtmux/docs has settled its convention — callers pin a full-length commit and name the release beside it — and the commit carrying that is the one to depend on. Its reusable-deploy.yml differs from the pinned one in comments only; the parsed workflow is identical. what: - Pin e30bcba4, which tag v0.1.0-alpha.1 names - Correct this comment: it claimed Dependabot would offer the bump, and nothing here will, since the repository has no dependabot.yml --- .github/workflows/docs.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 837a37be2..c46762876 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -175,15 +175,16 @@ jobs: id-token: write # Pinned to a commit, with the release it belongs to named beside it. # - # Not a tag: libtmux/docs's 0.x series is documented as moving, and this - # `uses:` runs another repository's workflow inside ours with - # `id-token: write` and a role that can write the bucket. A ref that can - # be repointed makes what executes here change with no diff in this - # repository and no review. A commit cannot be repointed, and Dependabot - # reads the trailing comment to offer the bump. + # Not a tag: this `uses:` runs another repository's workflow inside ours + # with `id-token: write` and a role that can write the bucket, and a tag + # can be repointed — so pinning one lets what executes here change with + # no diff in this repository and no review. A commit cannot be + # repointed. libtmux/docs asks callers for the same thing. # - # Bump it on review, like any other dependency. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@0cd5a3f10c70bf55130ab6a02d5177f6318beaca # v0.1.0-alpha.1 + # Bumping is manual. Dependabot reads a trailing version comment, but + # only where the `github-actions` ecosystem is enabled, and this + # repository has no dependabot.yml at all. + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@e30bcba4ca470e49ba798255ca4e3d36d58f95bf # v0.1.0-alpha.1 with: path-prefix: py/latest artifact: docs-html From 164a5bc1ed19b6dc3ef44b1b11c30dc00fb780c8 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 07:30:13 -0500 Subject: [PATCH 06/58] DO NOT MERGE: publish from docs-site-deploy, and repin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /en/py/latest/ 403s on libtmux.org — nothing has published under a port version prefix. This lets the branch publish without merging, which also sidesteps the base-branch problem: this PR targets docs-site, so merging it would trigger nothing. Repinned to ce9d7ed, which fixes the manifest upsert: jq precedence made it add an array to an object, so every publish failed after syncing. Found on the first real run, from libtmux-rs. libtmux.git-pull.com is unaffected — its leg publishes in the job before. Drop docs-site-deploy from the trigger when merging to master. --- .github/workflows/docs.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c46762876..d6877c320 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,6 +4,9 @@ on: push: branches: - master + # DO NOT MERGE: publishes /en/py/latest/ before anything merges — that + # tree 403s on libtmux.org today. Drop this line when merging to master. + - docs-site-deploy permissions: contents: read @@ -184,7 +187,7 @@ jobs: # Bumping is manual. Dependabot reads a trailing version comment, but # only where the `github-actions` ecosystem is enabled, and this # repository has no dependabot.yml at all. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@e30bcba4ca470e49ba798255ca4e3d36d58f95bf # v0.1.0-alpha.1 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@ce9d7edd63f6a543801d9b93366ecad5e158c0ec # v0.1.0-alpha.2 with: path-prefix: py/latest artifact: docs-html From a767b6fb2a0ad894970a7c0ff4f734ddc2eda334 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 08:09:05 -0500 Subject: [PATCH 07/58] fix(ci) Publish the shell tree to libtmux.org, not the Sphinx site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /en/py/latest/ was serving Furo, and /en/py/latest/concepts/ 403'd — so the port switcher was broken for Python from every shared page. The libtmux.org leg uploaded docs/_build/html, on the assumption that the Sphinx site is this port's tree. It is not: en/py/latest/ is the shared shell rendered with Python's code fences, and the gp-sphinx output belongs at en/py/latest/api/ inside it. Publishing Sphinx to the prefix replaced the whole tree, api and all. That leg now runs libtmux/docs's build-site.sh, which renders the shell and runs sphinx itself from this checkout, and uploads the assembled en/py/latest. Without --skip-refs, because Python's api/ is the real render rather than the redirect stub every other port gets — it is what check-style-parity.mjs measures against. libtmux.git-pull.com is untouched: its leg still builds standalone and publishes in-job, before this one runs. --- .github/workflows/docs.yml | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d6877c320..a89e4c84e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -109,11 +109,49 @@ jobs: sphinx-fonts- - name: Build documentation + if: matrix.site == 'git-pull-com' env: LIBTMUX_DOCS_STANDALONE: ${{ matrix.standalone }} run: | cd docs && just html + # libtmux.org's tree is not this Sphinx build. en/py/latest/ is the + # shared shell rendered with Python's code fences, with this port's + # gp-sphinx output nested at api/ — build-site.sh produces both, running + # sphinx itself from this checkout. Publishing the Sphinx site directly + # replaced the whole tree with it: /en/py/latest/ served Furo and + # /en/py/latest/concepts/ 403'd. + - uses: actions/checkout@v7 + if: matrix.site == 'libtmux-org' + with: + repository: libtmux/docs + ref: ce9d7edd63f6a543801d9b93366ecad5e158c0ec # v0.1.0-alpha.2 + path: libtmux-docs + + - uses: pnpm/action-setup@v6 + if: matrix.site == 'libtmux-org' + with: + package_json_file: libtmux-docs/package.json + - uses: actions/setup-node@v7 + if: matrix.site == 'libtmux-org' + with: + node-version: '26' + cache: pnpm + cache-dependency-path: libtmux-docs/pnpm-lock.yaml + - run: pnpm install --frozen-lockfile + if: matrix.site == 'libtmux-org' + working-directory: libtmux-docs + + # No --skip-refs: for every other port api/ is a redirect to + # /reference//, but Python's is the real gp-sphinx render that + # check-style-parity.mjs measures against, so it has to be built. + - name: Build the libtmux.org tree + if: matrix.site == 'libtmux-org' + working-directory: libtmux-docs + env: + LIBTMUX_DOCS_CHECKOUT_PY: ${{ github.workspace }} + run: ./scripts/build-site.sh --ports py --skip-pagefind + # libtmux.git-pull.com publishes from inside this job, as it always # has. Kept in place rather than moved behind an artifact: this is a # live site, and an artifact round trip does not preserve the symlinks @@ -153,7 +191,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: docs-html - path: docs/_build/html + path: libtmux-docs/_site/en/py/latest retention-days: 1 # Additive: a failure here leaves libtmux.git-pull.com serving exactly what From 523251dd5e8c434374a260198d26c5923f50e814 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 09:50:36 -0500 Subject: [PATCH 08/58] docs(CHANGES) A second docs publish, to libtmux.org --- CHANGES | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index b86ab0743..4408fd13a 100644 --- a/CHANGES +++ b/CHANGES @@ -66,6 +66,14 @@ it. ### Development +#### Docs publish to libtmux.org (#756) + +The docs build publishes to `libtmux.org` under `en/py/latest/` through the +shared deploy workflow every libtmux port calls, and keeps publishing to +libtmux.git-pull.com unchanged. Each destination takes its own build: +libtmux.org gets the site's shared shell with this port's reference nested +at `api/`, libtmux.git-pull.com the Sphinx site at a root. + #### Ruff 0.17.3 for development (#755) Minimum `ruff>=0.17.3` (was `>=0.17.1`) for development and CI lint checks. From 1c4d7f14b61c3fef55b3a021df792b802fa069bd Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 15:29:07 -0500 Subject: [PATCH 09/58] docs(query_list): Document the two exceptions QueryList raises Both reached the API reference as a name and a base class with no sentence. One says a primary key was never set; the other that a filter named a lookup that does not exist, which is what a mistyped keyword arrives as. --- src/libtmux/_internal/query_list.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libtmux/_internal/query_list.py b/src/libtmux/_internal/query_list.py index 20aeb407f..5cc0ccb8f 100644 --- a/src/libtmux/_internal/query_list.py +++ b/src/libtmux/_internal/query_list.py @@ -315,11 +315,24 @@ def lookup_iregex( class PKRequiredException(Exception): + """Raised when :meth:`QueryList.items` is called without a primary key. + + ``items()`` pairs each entry with a key, and the list has no opinion about + which field that should be. Set ``pk_key`` on the list before calling it. + """ + def __init__(self, *args: object) -> None: super().__init__("items() require a pk_key exists") class OpNotFound(ValueError): + """Raised when a filter names a lookup that does not exist. + + The lookup is the part after the last ``__`` in a keyword, so a mistyped + one — or a field name that happens to end in ``__`` — reaches here rather + than silently matching nothing. + """ + def __init__(self, op: str, *args: object) -> None: super().__init__(f"{op} not in LOOKUP_NAME_MAP") From 9031d2f13009a1892172cac29631e9b68e231586 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 6 Sep 2026 15:44:22 -0500 Subject: [PATCH 10/58] docs(constants): Say what the default-scope sentinel means It is the default value of every `scope` parameter and appeared in the API reference as a name with a `...` body. The distinction worth stating is that it is not the same as passing no scope: tmux resolves the option itself. --- src/libtmux/constants.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libtmux/constants.py b/src/libtmux/constants.py index 43ad3f519..904558b17 100644 --- a/src/libtmux/constants.py +++ b/src/libtmux/constants.py @@ -54,8 +54,13 @@ class PaneDirection(enum.Enum): class _DefaultOptionScope: - # Sentinel value for default scope - ... + """Sentinel meaning "whichever scope tmux would use". + + Distinct from passing no scope at all: this is the default value of the + ``scope`` parameter, and a call carrying it sends no scope flag. tmux then + resolves the option itself, which for a pane option means falling back to + the window's and then to the global window options. + """ DEFAULT_OPTION_SCOPE: _DefaultOptionScope = _DefaultOptionScope() From 5c55192327c8f6871513414863e425019e05aaf0 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 20 Sep 2026 06:57:46 -0500 Subject: [PATCH 11/58] Docs(ci[deploy]): Pin the current docs shell --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a89e4c84e..fd9084ded 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -125,7 +125,7 @@ jobs: if: matrix.site == 'libtmux-org' with: repository: libtmux/docs - ref: ce9d7edd63f6a543801d9b93366ecad5e158c0ec # v0.1.0-alpha.2 + ref: 7ca49769e9e738d5e4b2e7bfea721ab055d0291b path: libtmux-docs - uses: pnpm/action-setup@v6 @@ -225,7 +225,7 @@ jobs: # Bumping is manual. Dependabot reads a trailing version comment, but # only where the `github-actions` ecosystem is enabled, and this # repository has no dependabot.yml at all. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@ce9d7edd63f6a543801d9b93366ecad5e158c0ec # v0.1.0-alpha.2 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@7ca49769e9e738d5e4b2e7bfea721ab055d0291b with: path-prefix: py/latest artifact: docs-html From 0526d6537f815b8a9c4fb41daeb943006c753822 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 20 Sep 2026 07:55:06 -0500 Subject: [PATCH 12/58] Docs(ci[deploy]): Pin the refreshed docs shell why: Port builds still use the previous docs shell. what: - Pin the docs checkout and deploy workflow to the published refresh. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index fd9084ded..6da2128b9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -125,7 +125,7 @@ jobs: if: matrix.site == 'libtmux-org' with: repository: libtmux/docs - ref: 7ca49769e9e738d5e4b2e7bfea721ab055d0291b + ref: b1e3bb25b1b5aaad9381365f4566019586cd00ff path: libtmux-docs - uses: pnpm/action-setup@v6 @@ -225,7 +225,7 @@ jobs: # Bumping is manual. Dependabot reads a trailing version comment, but # only where the `github-actions` ecosystem is enabled, and this # repository has no dependabot.yml at all. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@7ca49769e9e738d5e4b2e7bfea721ab055d0291b + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@b1e3bb25b1b5aaad9381365f4566019586cd00ff with: path-prefix: py/latest artifact: docs-html From 612b7c51173e28e0bf2cade1ea3f49b9978af3b5 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 27 Sep 2026 18:05:17 -0500 Subject: [PATCH 13/58] Docs(ci): Publish selected source revisions why: The branch needs a reviewed, explicit publication path without merging, while pull requests must remain build-only. what: - Call shared source-bound builds with the native Sphinx reference - Add dispatch inputs and include workflow edits in the path filter - Keep standalone publication on default-branch pushes - Group weekly GitHub Actions updates for both shared workflow pins --- .github/dependabot.yml | 9 ++ .github/workflows/docs.yml | 267 +++++++++++++------------------------ 2 files changed, 104 insertions(+), 172 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..315914c05 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + actions: + patterns: ['*'] diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6da2128b9..bd4268ada 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,83 +1,108 @@ name: docs on: + pull_request: + paths: &docs-paths + - CHANGES + - README.* + - 'docs/**' + - 'examples/**' + - 'src/libtmux/**' + - uv.lock + - pyproject.toml + - '.github/workflows/docs.yml' push: - branches: - - master - # DO NOT MERGE: publishes /en/py/latest/ before anything merges — that - # tree 403s on libtmux.org today. Drop this line when merging to master. - - docs-site-deploy + branches: [master] + tags: ['v*'] + paths: *docs-paths + workflow_dispatch: + inputs: + source-ref: + description: Exact source ref to build + required: true + default: master + version: + description: URL version slug + required: true + default: latest + version-kind: + description: Version policy + required: true + type: choice + options: [trunk, tag, alias] + default: trunk + is-default: + description: Make this version canonical + required: true + type: boolean + default: false + resolves-to: + description: Immutable target for an alias + required: false + default: '' + publish: + description: Publish the selected revision to libtmux.org + required: true + type: boolean + default: false permissions: contents: read - id-token: write - -# Required of every caller of reusable-deploy.yml, and not something that -# workflow can do for itself: concurrency groups do not cross repository -# boundaries, so each port serialises its own publishes here. `queue: max` -# runs the newest queued publish after the running one instead of cancelling -# it, and cannot be combined with cancel-in-progress. See libtmux/docs -# docs/ci.md. -concurrency: - group: docs-deploy-${{ github.repository }} - queue: max jobs: - # Its own job because the answer has to reach the deploy job, and a step's - # $GITHUB_ENV does not leave the job that wrote it. Every job below is - # gated on this one output rather than repeating the condition per step. - changes: - runs-on: ubuntu-latest - outputs: - publish: ${{ steps.gate.outputs.publish }} - steps: - - uses: actions/checkout@v7 + build-libtmux-org: + uses: libtmux/docs/.github/workflows/port-docs.yml@6dec8f7cf780f9f3f4709b75f8a22e170c8a73f8 + with: + port: py + source-ref: ${{ inputs.source-ref }} + version: ${{ inputs.version }} + version-kind: ${{ inputs.version-kind }} + is-default: ${{ inputs.is-default == true }} + resolves-to: ${{ inputs.resolves-to }} + publish: ${{ inputs.publish == true }} + + # Both reusable workflows must move together to the same reviewed commit. + # Pull requests build only; dispatch publication is an explicit input. + publish-libtmux-org: + needs: build-libtmux-org + if: needs.build-libtmux-org.outputs.should-publish == 'true' + concurrency: + group: docs-deploy-${{ github.repository }}-py + queue: max + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-libtmux-org.outputs.matrix) }} + permissions: + contents: read + id-token: write + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@6dec8f7cf780f9f3f4709b75f8a22e170c8a73f8 + with: + path-prefix: py/${{ matrix.version }} + artifact: docs-py-${{ matrix.version }} + version-kind: ${{ matrix.kind }} + port: py + version: ${{ matrix.version }} + label: ${{ matrix.version }} + is-default: ${{ matrix.isDefault }} + resolves-to: ${{ matrix.resolvesTo }} + environment: docs + secrets: + role-arn: ${{ secrets.LIBTMUX_ORG_ROLE_ARN }} + bucket: ${{ secrets.LIBTMUX_ORG_BUCKET }} + distribution: ${{ secrets.LIBTMUX_ORG_DISTRIBUTION }} - - name: Filter changed file paths to outputs - uses: dorny/paths-filter@v4 - id: filter - with: - filters: | - root_docs: - - CHANGES - - README.* - docs: - - 'docs/**' - - 'examples/**' - python_files: - - 'src/libtmux/**' - - uv.lock - - pyproject.toml - - - name: Should publish - id: gate - env: - MATCHED: ${{ steps.filter.outputs.docs == 'true' || steps.filter.outputs.root_docs == 'true' || steps.filter.outputs.python_files == 'true' }} - run: echo "publish=$MATCHED" >> "$GITHUB_OUTPUT" - - # The two sites need different bytes, not the same tree published twice. - # libtmux.git-pull.com serves this build at a root, where /_shell/ is - # nothing and /search/ is the build's own search page — so it is built - # standalone, keeping Furo's search and loading no chrome. libtmux.org - # nests it at en/py/latest/, where both are reachable and belong on. - # Publishing one artifact to both gives an unskinned nested site or a - # root site whose search redirects to itself, depending which way the - # flag is set. tests/test_docs_conf.py pins both shapes. - build: - needs: changes - if: needs.changes.outputs.publish == 'true' + # The standalone site keeps its root Sphinx build and follows local symlinks. + # Only a default-branch push publishes it; branch dispatches target libtmux.org. + publish-git-pull-com: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest environment: docs - strategy: - # Neither destination should lose its publish because the other - # failed to build. - fail-fast: false - matrix: - include: - - site: git-pull-com - standalone: '1' - - site: libtmux-org - standalone: '' + permissions: + contents: read + id-token: write + concurrency: + group: docs-git-pull-com-${{ github.repository }} + queue: max steps: - uses: actions/checkout@v7 @@ -90,7 +115,7 @@ jobs: run: uv python install 3.14 - name: Install dependencies [w/ docs] - run: uv sync --all-extras --dev + run: uv sync --locked --all-extras --dev - name: Install just uses: extractions/setup-just@v4 @@ -109,132 +134,30 @@ jobs: sphinx-fonts- - name: Build documentation - if: matrix.site == 'git-pull-com' env: - LIBTMUX_DOCS_STANDALONE: ${{ matrix.standalone }} + LIBTMUX_DOCS_STANDALONE: '1' run: | cd docs && just html - # libtmux.org's tree is not this Sphinx build. en/py/latest/ is the - # shared shell rendered with Python's code fences, with this port's - # gp-sphinx output nested at api/ — build-site.sh produces both, running - # sphinx itself from this checkout. Publishing the Sphinx site directly - # replaced the whole tree with it: /en/py/latest/ served Furo and - # /en/py/latest/concepts/ 403'd. - - uses: actions/checkout@v7 - if: matrix.site == 'libtmux-org' - with: - repository: libtmux/docs - ref: b1e3bb25b1b5aaad9381365f4566019586cd00ff - path: libtmux-docs - - - uses: pnpm/action-setup@v6 - if: matrix.site == 'libtmux-org' - with: - package_json_file: libtmux-docs/package.json - - uses: actions/setup-node@v7 - if: matrix.site == 'libtmux-org' - with: - node-version: '26' - cache: pnpm - cache-dependency-path: libtmux-docs/pnpm-lock.yaml - - run: pnpm install --frozen-lockfile - if: matrix.site == 'libtmux-org' - working-directory: libtmux-docs - - # No --skip-refs: for every other port api/ is a redirect to - # /reference//, but Python's is the real gp-sphinx render that - # check-style-parity.mjs measures against, so it has to be built. - - name: Build the libtmux.org tree - if: matrix.site == 'libtmux-org' - working-directory: libtmux-docs - env: - LIBTMUX_DOCS_CHECKOUT_PY: ${{ github.workspace }} - run: ./scripts/build-site.sh --ports py --skip-pagefind - - # libtmux.git-pull.com publishes from inside this job, as it always - # has. Kept in place rather than moved behind an artifact: this is a - # live site, and an artifact round trip does not preserve the symlinks - # the sync below is told to follow. - name: Configure AWS credentials for libtmux.git-pull.com - if: matrix.site == 'git-pull-com' uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }} aws-region: us-east-1 - name: Push documentation to S3 - if: matrix.site == 'git-pull-com' run: | aws s3 sync docs/_build/html "s3://${{ secrets.LIBTMUX_DOCS_BUCKET }}" \ --delete --follow-symlinks - name: Invalidate CloudFront - if: matrix.site == 'git-pull-com' run: | aws cloudfront create-invalidation \ --distribution-id "${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }}" \ --paths "/index.html" "/objects.inv" "/searchindex.js" - name: Purge cache on Cloudflare - if: matrix.site == 'git-pull-com' uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} - - # libtmux.org publishes through the shared workflow instead, which - # only ever writes one port's own prefix. It downloads to dist/ and - # syncs dist/, so the tree has to sit at the artifact root. - - name: Upload the built site for libtmux.org - if: matrix.site == 'libtmux-org' - uses: actions/upload-artifact@v7 - with: - name: docs-html - path: libtmux-docs/_site/en/py/latest - retention-days: 1 - - # Additive: a failure here leaves libtmux.git-pull.com serving exactly what - # it serves today, because that publish already happened in the job above. - # - # path-prefix is unprefixed by locale — reusable-deploy prepends `/` - # itself whenever `port` is set, so this publishes to en/py/latest/, and - # passing en/py/latest here would produce en/en/py/latest. - # - # `environment` is an input rather than `environment:` on this job, which - # `uses:` does not accept — and reusable-deploy's own job is the one whose - # OIDC subject has to carry `environment:docs` to match the role's trust - # policy. The three secrets are passed explicitly, never `secrets: inherit`. - # - # LIBTMUX_ORG_* is a separate set from LIBTMUX_DOCS_*, which keeps its - # current meaning: the libtmux.git-pull.com bucket, unchanged. - publish-libtmux-org: - needs: [changes, build] - if: needs.changes.outputs.publish == 'true' - permissions: - contents: read - id-token: write - # Pinned to a commit, with the release it belongs to named beside it. - # - # Not a tag: this `uses:` runs another repository's workflow inside ours - # with `id-token: write` and a role that can write the bucket, and a tag - # can be repointed — so pinning one lets what executes here change with - # no diff in this repository and no review. A commit cannot be - # repointed. libtmux/docs asks callers for the same thing. - # - # Bumping is manual. Dependabot reads a trailing version comment, but - # only where the `github-actions` ecosystem is enabled, and this - # repository has no dependabot.yml at all. - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@b1e3bb25b1b5aaad9381365f4566019586cd00ff - with: - path-prefix: py/latest - artifact: docs-html - version-kind: trunk - port: py - version: latest - is-default: true - environment: docs - secrets: - role-arn: ${{ secrets.LIBTMUX_ORG_ROLE_ARN }} - bucket: ${{ secrets.LIBTMUX_ORG_BUCKET }} - distribution: ${{ secrets.LIBTMUX_ORG_DISTRIBUTION }} From 2816683a9b8fd5bf9250601c6bdbe7f6ae9c43af Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 27 Sep 2026 18:17:07 -0500 Subject: [PATCH 14/58] Docs(ci): Preserve the selected dependency lock why: A source revision can carry a lock resolved with a contributor's package cooldown. A clean runner must reproduce that lock. what: - Pin the shared native build and publisher to the same reviewed commit - Keep standalone Sphinx commands on the committed lock --- .github/workflows/docs.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bd4268ada..623620c65 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@6dec8f7cf780f9f3f4709b75f8a22e170c8a73f8 + uses: libtmux/docs/.github/workflows/port-docs.yml@551550c963f9a5d73166aa25b054c9ac57553248 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@6dec8f7cf780f9f3f4709b75f8a22e170c8a73f8 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@551550c963f9a5d73166aa25b054c9ac57553248 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} @@ -97,6 +97,8 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest environment: docs + env: + UV_FROZEN: 'true' permissions: contents: read id-token: write @@ -115,7 +117,7 @@ jobs: run: uv python install 3.14 - name: Install dependencies [w/ docs] - run: uv sync --locked --all-extras --dev + run: uv sync --frozen --all-extras --dev - name: Install just uses: extractions/setup-just@v4 From e5e018281664f18b20ee33300349433402b0fbf8 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 27 Sep 2026 20:59:36 -0500 Subject: [PATCH 15/58] Docs(ci): Pin the merged documentation layout why: Published port trees need the compact app layout and neutral reading colors from the merged documentation changes. what: - Pin the build and publisher to the same reviewed docs revision - Include the centered README parser and empty-sidebar layout fixes --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 623620c65..d8a8af5de 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@551550c963f9a5d73166aa25b054c9ac57553248 + uses: libtmux/docs/.github/workflows/port-docs.yml@8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@551550c963f9a5d73166aa25b054c9ac57553248 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From e3902fe898804005142edc2576d9e34484bfda7f Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Tue, 29 Sep 2026 18:17:11 -0500 Subject: [PATCH 16/58] docs(ci[publish]): Verify publication provenance why: Publication must reject altered build bytes and dirty source records before obtaining AWS credentials. what: - Pin the builder and publisher together at reviewed revision 843278f5. - Preserve the standalone site and ordinary dispatch behavior. - Verify real publication, three pre-AWS rejections, immutable reruns, and ordinary public delivery in hosted run 36642578777. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d8a8af5de..ad01edbe4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4 + uses: libtmux/docs/.github/workflows/port-docs.yml@843278f595d8a4495c18c9d9dbe8ab0b2bd50289 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@8fda4b89071621b9ed2c4722a68d61f6ecf9c1c4 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@843278f595d8a4495c18c9d9dbe8ab0b2bd50289 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 68fbf05f6529d4536e115c157db93845779e7ed6 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Tue, 29 Sep 2026 19:19:46 -0500 Subject: [PATCH 17/58] Docs(ci): Build from source MCP catalogs why: Use the selected source and toolchain for the MCP catalog. what: - Pin the shared builder and publisher to one reviewed revision Shared workflow: https://github.com/libtmux/docs/commit/42dd5b7 --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ad01edbe4..ac1ad3261 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@843278f595d8a4495c18c9d9dbe8ab0b2bd50289 + uses: libtmux/docs/.github/workflows/port-docs.yml@42dd5b71e6eefd785b9bf8ce11d34e8f1a058a22 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@843278f595d8a4495c18c9d9dbe8ab0b2bd50289 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@42dd5b71e6eefd785b9bf8ce11d34e8f1a058a22 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 0c40137e649cc3c3d2d014c18e753c23886ad069 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 4 Oct 2026 20:49:05 -0500 Subject: [PATCH 18/58] Docs(ci): Publish the current documentation UI why: The Python documentation caller needs the same reviewed renderer and publisher revision used by the other libtmux.org ports. what: - Update both reusable workflow pins together. - Preserve the isolated docs caller and source selection. validation: Paired-pin and diff checks pass. Workflow syntax passes with the existing queue-keyword compatibility exclusion. Library files are unchanged. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ac1ad3261..d4f2a12cb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@42dd5b71e6eefd785b9bf8ce11d34e8f1a058a22 + uses: libtmux/docs/.github/workflows/port-docs.yml@953ddc14add30e12aa0640df66f3dfb2b8f3b554 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@42dd5b71e6eefd785b9bf8ce11d34e8f1a058a22 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@953ddc14add30e12aa0640df66f3dfb2b8f3b554 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From a2cc07ffe9a62ba61ee45dbf55d8ed5d7fc03050 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 4 Oct 2026 22:42:02 -0500 Subject: [PATCH 19/58] Docs(fix[ci]): use the repaired site publisher why: Python's selected MCP revision groups tool pages in subdirectories, so publication needs the recursive source validation. The publisher also accepts the current AWS CLI missing-manifest diagnostic. what: - Pin both libtmux.org reusable workflows to the same reviewed revision. - Keep the standalone Sphinx publisher and library source unchanged. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d4f2a12cb..b3755efec 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@953ddc14add30e12aa0640df66f3dfb2b8f3b554 + uses: libtmux/docs/.github/workflows/port-docs.yml@ac24b27152e2139617fb63039b9a2d09b25a31ae with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@953ddc14add30e12aa0640df66f3dfb2b8f3b554 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@ac24b27152e2139617fb63039b9a2d09b25a31ae with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From ec7fd64b32a296f2bae07b5210056a1bff823728 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Wed, 7 Oct 2026 20:03:51 -0500 Subject: [PATCH 20/58] Docs(ci): Use shared header publication why: Keep port-owned documentation on the shared header revision so navigation stays consistent with the root site. what: - Pin documentation construction and publication to the same producer --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2cc6fc80b..5bbb7e386 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@a73151575047f571d03a3179f6647c402c6d7e6f + uses: libtmux/docs/.github/workflows/port-docs.yml@631515e50afbbc2d4f4d75cdee825ab748e7eb89 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@a73151575047f571d03a3179f6647c402c6d7e6f + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@631515e50afbbc2d4f4d75cdee825ab748e7eb89 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 13f310a37bfd7ae758b41352c4aa285c13ad31ec Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Mon, 5 Oct 2026 00:14:35 -0500 Subject: [PATCH 21/58] Docs(fix): Initialize navigation before analytics why: Delayed analytics must not keep documentation menus inert. what: - Adopt the reviewed shared navigation script ordering. - Keep build and publication on the same approved revision. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b3755efec..f21bbd409 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@ac24b27152e2139617fb63039b9a2d09b25a31ae + uses: libtmux/docs/.github/workflows/port-docs.yml@5a92e7cbc14ef1dcd67ef2894ba3bf84891b93ad with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@ac24b27152e2139617fb63039b9a2d09b25a31ae + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@5a92e7cbc14ef1dcd67ef2894ba3bf84891b93ad with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 0eb528e168c4a975e5ec8b45a9b30b178552898d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Wed, 7 Oct 2026 20:25:23 -0500 Subject: [PATCH 22/58] Docs(ci): Pin verified shared navigation why: Include the native font preload correction and current publication checks in the shared-header rollout. what: - Keep construction and publication on the same final producer --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5bbb7e386..0aabe5d75 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@631515e50afbbc2d4f4d75cdee825ab748e7eb89 + uses: libtmux/docs/.github/workflows/port-docs.yml@d4d232dcede5979c50079be06bc1f314d79954b0 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@631515e50afbbc2d4f4d75cdee825ab748e7eb89 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@d4d232dcede5979c50079be06bc1f314d79954b0 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From e099110509c2a3f430fcc8614b19242262a9e1d5 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Mon, 5 Oct 2026 22:23:23 -0500 Subject: [PATCH 23/58] Docs(ci): Refresh shared navigation why: Port-owned documentation needs the shared navigation refinements and Workspace Manager CLI manuals. what: - Pin documentation build and publication to one reviewed revision. - Publish compact selectors, Overview links and inline copy feedback. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f21bbd409..2cc6fc80b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@5a92e7cbc14ef1dcd67ef2894ba3bf84891b93ad + uses: libtmux/docs/.github/workflows/port-docs.yml@a73151575047f571d03a3179f6647c402c6d7e6f with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@5a92e7cbc14ef1dcd67ef2894ba3bf84891b93ad + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@a73151575047f571d03a3179f6647c402c6d7e6f with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 6669fd1f8c9d028bed2f554bd13df430db991afe Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Thu, 8 Oct 2026 05:16:26 -0500 Subject: [PATCH 24/58] ci(docs) Handle legacy Python documentation assets what: - Pin the documentation builder and publisher to the reviewed compatibility fix for older native reference assets. why: - Publish stable documentation from its tagged source without retaining a reference to the tabs script that its theme deliberately removes. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0aabe5d75..57ae6ba72 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@d4d232dcede5979c50079be06bc1f314d79954b0 + uses: libtmux/docs/.github/workflows/port-docs.yml@d84a7f7ed80ccd67f40b2d2ce406720c8f34b14a with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@d4d232dcede5979c50079be06bc1f314d79954b0 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@d84a7f7ed80ccd67f40b2d2ce406720c8f34b14a with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 37b931b8434e1f7f4f287b10c08fba487aabba23 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Thu, 8 Oct 2026 20:08:57 -0500 Subject: [PATCH 25/58] Docs(ci): Publish reviewed navigation fixes why: Port-owned pages need the same navigation and layout fixes as the root site, including working terminal artwork credits. what: - Pin documentation building and publishing to one reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 57ae6ba72..a643a90ee 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@d84a7f7ed80ccd67f40b2d2ce406720c8f34b14a + uses: libtmux/docs/.github/workflows/port-docs.yml@b60c547e5c4f16e1915c560e6cc1deccd0c9b64d with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@d84a7f7ed80ccd67f40b2d2ce406720c8f34b14a + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@b60c547e5c4f16e1915c560e6cc1deccd0c9b64d with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From ced0b2c2edb3d71b8c1812b4e5bbfd37f6bc4886 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Thu, 8 Oct 2026 22:07:23 -0500 Subject: [PATCH 26/58] Docs(ci): Publish native Contents layout why: Python reference drawers need readable, consistent text and spacing below the viewport edge. what: - Pin the docs build and publisher to the reviewed Contents fix --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a643a90ee..a6be47f39 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@b60c547e5c4f16e1915c560e6cc1deccd0c9b64d + uses: libtmux/docs/.github/workflows/port-docs.yml@c2a05230da162377fd339048d4122c47e41243da with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@b60c547e5c4f16e1915c560e6cc1deccd0c9b64d + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@c2a05230da162377fd339048d4122c47e41243da with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 2314ca90fb55e9ba83ff2397ff1feabe0a1663a9 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Fri, 9 Oct 2026 02:05:06 -0500 Subject: [PATCH 27/58] Docs(ci): Publish query and transport docs why: Publish the reviewed Rust guides and correct the shared transport explanation in the affected port-owned trees. what: - Pin documentation building and publishing to one reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a6be47f39..c7821f5da 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@c2a05230da162377fd339048d4122c47e41243da + uses: libtmux/docs/.github/workflows/port-docs.yml@863d4420b75561ea5e0f5aa5da1412e75b4817d4 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@c2a05230da162377fd339048d4122c47e41243da + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@863d4420b75561ea5e0f5aa5da1412e75b4817d4 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From d65dbdc507b0f853f07ded838b14d68e228263a6 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Fri, 9 Oct 2026 16:56:33 -0500 Subject: [PATCH 28/58] Docs(ci): Publish MCP guides and Copy fix why: Publish the reviewed Ruby MCP guides and preserve copied console commands throughout the port-owned documentation. what: - Pin documentation building and publishing to one reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c7821f5da..123f2a85c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@863d4420b75561ea5e0f5aa5da1412e75b4817d4 + uses: libtmux/docs/.github/workflows/port-docs.yml@81066606e5aeb6b5f82ae9d7aa79d7afa4e35167 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@863d4420b75561ea5e0f5aa5da1412e75b4817d4 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@81066606e5aeb6b5f82ae9d7aa79d7afa4e35167 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 502bcf633f83fde84bdd52ddabb3b87f0b04b1e6 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Fri, 9 Oct 2026 20:54:33 -0500 Subject: [PATCH 29/58] Docs(ci): Publish Copy readiness and port prose why: Publish the reviewed Copy loading fix and port-specific prose throughout the documentation owned by this repository. what: - Pin documentation building and publishing to one reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 123f2a85c..2eb21e985 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@81066606e5aeb6b5f82ae9d7aa79d7afa4e35167 + uses: libtmux/docs/.github/workflows/port-docs.yml@f9ed37e8cc4c1ef9f86a446e1443f21da644ce1e with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@81066606e5aeb6b5f82ae9d7aa79d7afa4e35167 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@f9ed37e8cc4c1ef9f86a446e1443f21da644ce1e with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 6e7ab151544f8b7605eb35ff11119a3fc4a3fb32 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 10 Oct 2026 09:59:34 -0500 Subject: [PATCH 30/58] Docs(ci): Publish shared navigation fixes why: Keep breadcrumb labels intact and publish the reviewed prefetch and Japanese fallback-link corrections. what: - Pin documentation building and publishing to one reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2eb21e985..28f1613bd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@f9ed37e8cc4c1ef9f86a446e1443f21da644ce1e + uses: libtmux/docs/.github/workflows/port-docs.yml@133013c4817fb8c654ca1e049d7ce2591e640c05 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@f9ed37e8cc4c1ef9f86a446e1443f21da644ce1e + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@133013c4817fb8c654ca1e049d7ce2591e640c05 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 55625207d30c2b7e885aa8c034254a95f43a2963 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Mon, 12 Oct 2026 02:37:32 -0500 Subject: [PATCH 31/58] Docs(ci): Pin reviewed reference UI publisher why: Publish the reviewed reference UI through the owning repository with an immutable shared builder and publisher revision. what: - Bind the docs builder and publisher to the reviewed revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 28f1613bd..574af62d9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@133013c4817fb8c654ca1e049d7ce2591e640c05 + uses: libtmux/docs/.github/workflows/port-docs.yml@98c203127ac29f9021fc066a4dd4aa7a07fc3a28 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@133013c4817fb8c654ca1e049d7ce2591e640c05 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@98c203127ac29f9021fc066a4dd4aa7a07fc3a28 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 88a2abc430702d67aef5d90b915e81ebe4fd4206 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Fri, 16 Oct 2026 17:27:21 -0500 Subject: [PATCH 32/58] Docs(chore): Use the updated reference renderer why: Deliver the shared API reference fixes through the owning documentation publisher. what: - Bind the documentation builder and publisher to one revision --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 574af62d9..ac9931d10 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@98c203127ac29f9021fc066a4dd4aa7a07fc3a28 + uses: libtmux/docs/.github/workflows/port-docs.yml@893daa12d86f3dec0ae4a82a8a1c05b7c63d37dd with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@98c203127ac29f9021fc066a4dd4aa7a07fc3a28 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@893daa12d86f3dec0ae4a82a8a1c05b7c63d37dd with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 1b1c55e07f43d13050f6499d902a6041d819de54 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 17 Oct 2026 00:33:59 -0500 Subject: [PATCH 33/58] Docs(ci): Add glossary contents and tab shortcuts (#781) what: - Change only the two shared workflow pins to 32de9876ff51cdb206acbb05785f946cc08f517a. why: - Publish with the reviewed shared documentation checkpoint. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ac9931d10..e420a3f19 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@893daa12d86f3dec0ae4a82a8a1c05b7c63d37dd + uses: libtmux/docs/.github/workflows/port-docs.yml@32de9876ff51cdb206acbb05785f946cc08f517a with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@893daa12d86f3dec0ae4a82a8a1c05b7c63d37dd + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@32de9876ff51cdb206acbb05785f946cc08f517a with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From e55eedfe7b2be161b5a7d75f40638d1d6f738034 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 17 Oct 2026 03:08:30 -0500 Subject: [PATCH 34/58] Docs(ci): Fix reference spacing and drawer focus (#782) what: - Change only the two shared workflow pins to 8f304904465a15b929e139345d9b9e4672ecb7b3. why: - Publish with the reviewed shared documentation checkpoint. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e420a3f19..0b4f4df2b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@32de9876ff51cdb206acbb05785f946cc08f517a + uses: libtmux/docs/.github/workflows/port-docs.yml@8f304904465a15b929e139345d9b9e4672ecb7b3 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@32de9876ff51cdb206acbb05785f946cc08f517a + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@8f304904465a15b929e139345d9b9e4672ecb7b3 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From cc8551321829df21279ed63d398ce6042ed37f6c Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 17 Oct 2026 13:39:41 -0500 Subject: [PATCH 35/58] ci(docs) Update shared publisher (#784) what: - Change only the two shared workflow pins to 9f5cef954e3c52e7eb239a3da56a34f92b69f161. why: - Publish with the reviewed shared documentation checkpoint. --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0b4f4df2b..6c7f70572 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -51,7 +51,7 @@ permissions: jobs: build-libtmux-org: - uses: libtmux/docs/.github/workflows/port-docs.yml@8f304904465a15b929e139345d9b9e4672ecb7b3 + uses: libtmux/docs/.github/workflows/port-docs.yml@9f5cef954e3c52e7eb239a3da56a34f92b69f161 with: port: py source-ref: ${{ inputs.source-ref }} @@ -75,7 +75,7 @@ jobs: permissions: contents: read id-token: write - uses: libtmux/docs/.github/workflows/reusable-deploy.yml@8f304904465a15b929e139345d9b9e4672ecb7b3 + uses: libtmux/docs/.github/workflows/reusable-deploy.yml@9f5cef954e3c52e7eb239a3da56a34f92b69f161 with: path-prefix: py/${{ matrix.version }} artifact: docs-py-${{ matrix.version }} From 28338357898751ba6c49d29d296296c1fce5e8ba Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 18 Oct 2026 03:12:43 -0500 Subject: [PATCH 36/58] ci(docs) Adopt header menus and reference fixes (#786) what: - Add GitHub, package and external documentation menus to the site header, each row showing its destination's icon - Show a parameter's type and optional marker against its name, print an overload note as "for