From 27a3a802c52b805770688ab5b1c64133e312f16b Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Sat, 18 Apr 2026 09:38:53 +0200 Subject: [PATCH 1/3] ci: Fix docs release failing on detached HEAD The post-publish doc release job invokes manual_release_docs.yaml with a commit SHA, so actions/checkout leaves the repo in detached HEAD and the hand-rolled git push fails. Switch to EndBug/add-and-commit with new_branch set to the default branch, and apply the same fix to manual_version_docs.yaml where the same latent bug existed. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/manual_release_docs.yaml | 14 +++++++------- .github/workflows/manual_version_docs.yaml | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/manual_release_docs.yaml b/.github/workflows/manual_release_docs.yaml index 491bea03..6f933578 100644 --- a/.github/workflows/manual_release_docs.yaml +++ b/.github/workflows/manual_release_docs.yaml @@ -71,13 +71,13 @@ jobs: run: uv run poe update-docs-theme - name: Commit the updated package.json and lockfile - run: | - git config user.name 'GitHub Actions' - git config user.email 'github-actions[bot]@users.noreply.github.com' - git add website/package.json - git add website/yarn.lock - git diff-index --quiet HEAD || git commit -m 'chore: Automatic docs theme update [skip ci]' || true - git push + uses: EndBug/add-and-commit@v10 + with: + add: website/package.json website/yarn.lock + message: "chore: Automatic docs theme update [skip ci]" + default_author: github_actions + # Required: checkout may leave a detached HEAD when invoked with a SHA ref. + new_branch: ${{ github.event.repository.default_branch }} - name: Build docs run: uv run poe build-docs diff --git a/.github/workflows/manual_version_docs.yaml b/.github/workflows/manual_version_docs.yaml index b9f99886..c8946fa4 100644 --- a/.github/workflows/manual_version_docs.yaml +++ b/.github/workflows/manual_version_docs.yaml @@ -123,6 +123,8 @@ jobs: add: website/versioned_docs website/versioned_sidebars website/versions.json message: "docs: Version docs for v${{ steps.snapshot.outputs.version }} [skip ci]" default_author: github_actions + # Required: checkout may leave a detached HEAD when invoked with a SHA ref. + new_branch: ${{ github.event.repository.default_branch }} - name: Resolve output commitish id: resolve_commitish From 6a414fc7761fed436818df64e7740f2d8c5039cd Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Mon, 20 Apr 2026 11:57:27 +0200 Subject: [PATCH 2/3] ci: Drop ref input from docs workflow_dispatch Manual dispatches always use the default branch, since these workflows push commits back to it and an off-master ref would non-fast-forward. The ref input stays on workflow_call for pinning release commits. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/manual_release_docs.yaml | 20 ++++++++++---------- .github/workflows/manual_version_docs.yaml | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/manual_release_docs.yaml b/.github/workflows/manual_release_docs.yaml index 6f933578..b3102139 100644 --- a/.github/workflows/manual_release_docs.yaml +++ b/.github/workflows/manual_release_docs.yaml @@ -1,20 +1,17 @@ name: Release docs on: - # Runs when manually triggered from the GitHub UI. + # Runs when manually triggered from the GitHub UI. Always checks out the default branch — + # this workflow pushes a theme-update commit back to the default branch, so the checked-out + # ref must be its current tip to avoid non-fast-forward pushes. workflow_dispatch: - inputs: - ref: - description: Git ref to checkout (branch, tag, or SHA). Defaults to the default branch. - required: false - type: string - default: "" - # Runs when invoked by another workflow. + # Runs when invoked by another workflow. The caller is responsible for passing a ref that's + # on the default branch tip (e.g. a freshly pushed commit protected by `concurrency: release`). workflow_call: inputs: ref: - description: Git ref to checkout (branch, tag, or SHA) + description: Git ref to checkout (must resolve to the default branch tip). required: true type: string @@ -76,7 +73,10 @@ jobs: add: website/package.json website/yarn.lock message: "chore: Automatic docs theme update [skip ci]" default_author: github_actions - # Required: checkout may leave a detached HEAD when invoked with a SHA ref. + # Required: `actions/checkout` leaves a detached HEAD when invoked with a SHA ref. + # Creating a local default-branch pointer at HEAD lets EndBug push it back. The caller + # contract (see trigger definitions above) guarantees HEAD is the default branch tip, + # so this push is always a fast-forward. new_branch: ${{ github.event.repository.default_branch }} - name: Build docs diff --git a/.github/workflows/manual_version_docs.yaml b/.github/workflows/manual_version_docs.yaml index c8946fa4..cebc2f5a 100644 --- a/.github/workflows/manual_version_docs.yaml +++ b/.github/workflows/manual_version_docs.yaml @@ -1,20 +1,17 @@ name: Version docs on: - # Runs when manually triggered from the GitHub UI. + # Runs when manually triggered from the GitHub UI. Always checks out the default branch — + # this workflow pushes the version snapshot commit back to the default branch, so the + # checked-out ref must be its current tip to avoid non-fast-forward pushes. workflow_dispatch: - inputs: - ref: - description: Git ref to checkout (branch, tag, or SHA). Defaults to the default branch. - required: false - type: string - default: "" - # Runs when invoked by another workflow. + # Runs when invoked by another workflow. The caller is responsible for passing a ref that's + # on the default branch tip (e.g. a freshly pushed commit protected by `concurrency: release`). workflow_call: inputs: ref: - description: Git ref to checkout (branch, tag, or SHA) + description: Git ref to checkout (must resolve to the default branch tip). required: true type: string outputs: @@ -123,7 +120,10 @@ jobs: add: website/versioned_docs website/versioned_sidebars website/versions.json message: "docs: Version docs for v${{ steps.snapshot.outputs.version }} [skip ci]" default_author: github_actions - # Required: checkout may leave a detached HEAD when invoked with a SHA ref. + # Required: `actions/checkout` leaves a detached HEAD when invoked with a SHA ref. + # Creating a local default-branch pointer at HEAD lets EndBug push it back. The caller + # contract (see trigger definitions above) guarantees HEAD is the default branch tip, + # so this push is always a fast-forward. new_branch: ${{ github.event.repository.default_branch }} - name: Resolve output commitish From 06d41275e26e78d103f0cc990fccd4edfdb563c3 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Mon, 20 Apr 2026 12:12:30 +0200 Subject: [PATCH 3/3] Final polishment --- .github/workflows/manual_release_docs.yaml | 25 ++++-------------- .github/workflows/manual_release_stable.yaml | 5 ++-- .github/workflows/manual_version_docs.yaml | 27 +++++--------------- 3 files changed, 14 insertions(+), 43 deletions(-) diff --git a/.github/workflows/manual_release_docs.yaml b/.github/workflows/manual_release_docs.yaml index b3102139..68608f16 100644 --- a/.github/workflows/manual_release_docs.yaml +++ b/.github/workflows/manual_release_docs.yaml @@ -1,17 +1,14 @@ name: Release docs on: - # Runs when manually triggered from the GitHub UI. Always checks out the default branch — - # this workflow pushes a theme-update commit back to the default branch, so the checked-out - # ref must be its current tip to avoid non-fast-forward pushes. + # Runs when manually triggered from the GitHub UI. workflow_dispatch: - # Runs when invoked by another workflow. The caller is responsible for passing a ref that's - # on the default branch tip (e.g. a freshly pushed commit protected by `concurrency: release`). + # Runs when invoked by another workflow. workflow_call: inputs: ref: - description: Git ref to checkout (must resolve to the default branch tip). + description: Git ref to checkout. required: true type: string @@ -31,20 +28,11 @@ jobs: runs-on: ubuntu-latest steps: - - name: Determine checkout ref - id: resolve_ref - env: - INPUT_REF: ${{ inputs.ref }} - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - run: | - REF="${INPUT_REF:-$DEFAULT_BRANCH}" - echo "ref=$REF" >> "$GITHUB_OUTPUT" - - name: Checkout repository uses: actions/checkout@v6 with: token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} - ref: ${{ steps.resolve_ref.outputs.ref }} + ref: ${{ inputs.ref || github.event.repository.default_branch }} - name: Set up Node uses: actions/setup-node@v6 @@ -73,10 +61,7 @@ jobs: add: website/package.json website/yarn.lock message: "chore: Automatic docs theme update [skip ci]" default_author: github_actions - # Required: `actions/checkout` leaves a detached HEAD when invoked with a SHA ref. - # Creating a local default-branch pointer at HEAD lets EndBug push it back. The caller - # contract (see trigger definitions above) guarantees HEAD is the default branch tip, - # so this push is always a fast-forward. + # `actions/checkout` detaches HEAD on SHA refs; EndBug needs a branch to push. new_branch: ${{ github.event.repository.default_branch }} - name: Build docs diff --git a/.github/workflows/manual_release_stable.yaml b/.github/workflows/manual_release_stable.yaml index 70dcb5bd..9460e63e 100644 --- a/.github/workflows/manual_release_stable.yaml +++ b/.github/workflows/manual_release_stable.yaml @@ -98,7 +98,7 @@ jobs: version_number: ${{ needs.release_prepare.outputs.version_number }} ref: ${{ needs.changelog_update.outputs.changelog_commitish }} - # Publishes the package to PyPI using PyPA official GitHub action with OIDC authentication. + # Publish the package to PyPI using PyPA official GitHub action with OIDC authentication. - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 @@ -109,6 +109,7 @@ jobs: contents: write uses: ./.github/workflows/manual_version_docs.yaml with: + # Commit the version docs changes on top of the changelog commit. ref: ${{ needs.changelog_update.outputs.changelog_commitish }} secrets: inherit @@ -121,6 +122,6 @@ jobs: id-token: write uses: ./.github/workflows/manual_release_docs.yaml with: - # Use the version_docs commit to include both changelog and versioned docs. + # Commit the docs release changes on top of the version docs commit. ref: ${{ needs.version_docs.outputs.version_docs_commitish }} secrets: inherit diff --git a/.github/workflows/manual_version_docs.yaml b/.github/workflows/manual_version_docs.yaml index cebc2f5a..d2fe9d88 100644 --- a/.github/workflows/manual_version_docs.yaml +++ b/.github/workflows/manual_version_docs.yaml @@ -1,22 +1,19 @@ name: Version docs on: - # Runs when manually triggered from the GitHub UI. Always checks out the default branch — - # this workflow pushes the version snapshot commit back to the default branch, so the - # checked-out ref must be its current tip to avoid non-fast-forward pushes. + # Runs when manually triggered from the GitHub UI. workflow_dispatch: - # Runs when invoked by another workflow. The caller is responsible for passing a ref that's - # on the default branch tip (e.g. a freshly pushed commit protected by `concurrency: release`). + # Runs when invoked by another workflow. workflow_call: inputs: ref: - description: Git ref to checkout (must resolve to the default branch tip). + description: Git ref to checkout. required: true type: string outputs: version_docs_commitish: - description: The commit SHA of the versioned docs commit + description: The commit SHA of the versioned docs commit. value: ${{ jobs.version_docs.outputs.version_docs_commitish }} concurrency: @@ -40,20 +37,11 @@ jobs: contents: write steps: - - name: Determine checkout ref - id: resolve_ref - env: - INPUT_REF: ${{ inputs.ref }} - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - run: | - REF="${INPUT_REF:-$DEFAULT_BRANCH}" - echo "ref=$REF" >> "$GITHUB_OUTPUT" - - name: Checkout repository uses: actions/checkout@v6 with: token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} - ref: ${{ steps.resolve_ref.outputs.ref }} + ref: ${{ inputs.ref || github.event.repository.default_branch }} - name: Set up Node uses: actions/setup-node@v6 @@ -120,10 +108,7 @@ jobs: add: website/versioned_docs website/versioned_sidebars website/versions.json message: "docs: Version docs for v${{ steps.snapshot.outputs.version }} [skip ci]" default_author: github_actions - # Required: `actions/checkout` leaves a detached HEAD when invoked with a SHA ref. - # Creating a local default-branch pointer at HEAD lets EndBug push it back. The caller - # contract (see trigger definitions above) guarantees HEAD is the default branch tip, - # so this push is always a fast-forward. + # `actions/checkout` detaches HEAD on SHA refs; EndBug needs a branch to push. new_branch: ${{ github.event.repository.default_branch }} - name: Resolve output commitish