From bb5172ea563588e9649d80c82f51cc7749c7a2e0 Mon Sep 17 00:00:00 2001 From: Andre Manoel Date: Mon, 13 Apr 2026 14:12:02 +0000 Subject: [PATCH 1/4] ci: add workflow to publish devnotes independently of releases Adds a GitHub Actions workflow that rebuilds the `latest` docs alias when devnotes change on main, so blog posts go live without cutting a package release. --- .github/workflows/publish-devnotes.yml | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/publish-devnotes.yml diff --git a/.github/workflows/publish-devnotes.yml b/.github/workflows/publish-devnotes.yml new file mode 100644 index 000000000..6d6824013 --- /dev/null +++ b/.github/workflows/publish-devnotes.yml @@ -0,0 +1,56 @@ +name: Publish devnotes + +on: + push: + branches: [main] + paths: + - "docs/devnotes/**" + workflow_dispatch: + +jobs: + build-notebooks: + uses: ./.github/workflows/build-notebooks.yml + with: + use_cache: true + secrets: inherit + + deploy: + needs: build-notebooks + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "0.9.5" + - name: Set up Python + run: uv python install 3.11 + - name: Install dependencies for docs + run: uv sync --all-packages --group docs + - name: Download notebooks + uses: actions/download-artifact@v7 + with: + name: notebooks + path: docs/notebooks + - name: Get latest release version + run: | + LATEST_TAG=$(gh release view --json tagName -q .tagName 2>/dev/null) + if [ -z "$LATEST_TAG" ]; then + echo "::error::No published release found. Publish a release first." + exit 1 + fi + VERSION=$(echo "$LATEST_TAG" | sed 's/^v//' | sed 's/ .*$//') + echo "::notice::Rebuilding docs for version $VERSION (latest)" + echo "VERSION=$VERSION" >> $GITHUB_ENV + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Setup doc deploy + run: | + git fetch origin gh-pages --depth=1 + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + - name: Rebuild latest docs + run: uv run mike deploy --push --update-aliases ${{ env.VERSION }} latest From 6cfec5a5733ca4be667709a003feb8f631c4c80c Mon Sep 17 00:00:00 2001 From: Andre Manoel Date: Mon, 13 Apr 2026 14:26:08 +0000 Subject: [PATCH 2/4] ci: pin actions to commit SHAs and restrict default permissions Address Greptile review findings: - Pin checkout, setup-uv, and download-artifact to commit SHAs matching the pattern from #517 - Add top-level permissions: {} to restrict default token scope --- .github/workflows/publish-devnotes.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-devnotes.yml b/.github/workflows/publish-devnotes.yml index 6d6824013..831cc9630 100644 --- a/.github/workflows/publish-devnotes.yml +++ b/.github/workflows/publish-devnotes.yml @@ -7,6 +7,8 @@ on: - "docs/devnotes/**" workflow_dispatch: +permissions: {} + jobs: build-notebooks: uses: ./.github/workflows/build-notebooks.yml @@ -21,9 +23,9 @@ jobs: contents: write steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install uv - uses: astral-sh/setup-uv@v7 + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 with: version: "0.9.5" - name: Set up Python @@ -31,7 +33,7 @@ jobs: - name: Install dependencies for docs run: uv sync --all-packages --group docs - name: Download notebooks - uses: actions/download-artifact@v7 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 with: name: notebooks path: docs/notebooks From 0cd7ca7d248c14fd37fe313669865df038b30213 Mon Sep 17 00:00:00 2001 From: Andre Manoel Date: Mon, 13 Apr 2026 14:49:11 +0000 Subject: [PATCH 3/4] ci: build devnotes from last deployed state, not main Instead of building the full site from main (which could include unreleased docs), checkout the commit that latest was last built from (tracked in gh-pages commit messages) and overlay only docs/devnotes/ from main. Download notebooks from the last successful build-docs run instead of rebuilding them. --- .github/workflows/publish-devnotes.yml | 52 +++++++++++++++----------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/.github/workflows/publish-devnotes.yml b/.github/workflows/publish-devnotes.yml index 831cc9630..b0542d2c9 100644 --- a/.github/workflows/publish-devnotes.yml +++ b/.github/workflows/publish-devnotes.yml @@ -10,20 +10,34 @@ on: permissions: {} jobs: - build-notebooks: - uses: ./.github/workflows/build-notebooks.yml - with: - use_cache: true - secrets: inherit - deploy: - needs: build-notebooks runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + - name: Get last deployed docs state + run: | + git fetch origin gh-pages --depth=1 + DEPLOY_MSG=$(git log FETCH_HEAD -1 --format="%s") + SOURCE_SHA=$(echo "$DEPLOY_MSG" | sed -n 's/^Deployed \([0-9a-f]*\) to .*/\1/p') + VERSION=$(echo "$DEPLOY_MSG" | sed -n 's/^Deployed [0-9a-f]* to \([^ ]*\) .*/\1/p') + + if [ -z "$SOURCE_SHA" ] || [ -z "$VERSION" ]; then + echo "::error::Could not parse deploy info from gh-pages. Expected: 'Deployed to ...'" + exit 1 + fi + + echo "::notice::Last deploy: commit $SOURCE_SHA for version $VERSION" + echo "SOURCE_SHA=$SOURCE_SHA" >> $GITHUB_ENV + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Checkout docs source and overlay devnotes + run: | + git checkout ${{ env.SOURCE_SHA }} + git checkout ${{ github.sha }} -- docs/devnotes/ - name: Install uv uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 with: @@ -32,26 +46,20 @@ jobs: run: uv python install 3.11 - name: Install dependencies for docs run: uv sync --all-packages --group docs - - name: Download notebooks - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - name: notebooks - path: docs/notebooks - - name: Get latest release version + - name: Download notebooks from last docs build + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - LATEST_TAG=$(gh release view --json tagName -q .tagName 2>/dev/null) - if [ -z "$LATEST_TAG" ]; then - echo "::error::No published release found. Publish a release first." + mkdir -p docs/notebooks + LAST_RUN_ID=$(gh run list --workflow build-docs.yml --status success --limit 1 --json databaseId -q '.[0].databaseId') + if [ -z "$LAST_RUN_ID" ]; then + echo "::error::No successful build-docs run found. Cannot build without notebooks." exit 1 fi - VERSION=$(echo "$LATEST_TAG" | sed 's/^v//' | sed 's/ .*$//') - echo "::notice::Rebuilding docs for version $VERSION (latest)" - echo "VERSION=$VERSION" >> $GITHUB_ENV - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + gh run download "$LAST_RUN_ID" --name notebooks --dir docs/notebooks + echo "::notice::Downloaded notebooks from build-docs run $LAST_RUN_ID" - name: Setup doc deploy run: | - git fetch origin gh-pages --depth=1 git config --global user.name "github-actions[bot]" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Rebuild latest docs From 4edd163c76024ca19f13f0bb257ff690978f8d0b Mon Sep 17 00:00:00 2001 From: Andre Manoel Date: Mon, 13 Apr 2026 15:20:04 +0000 Subject: [PATCH 4/4] ci: add actions:read permission for notebook download The gh run list/download calls need actions:read on GITHUB_TOKEN, which is denied by the top-level permissions: {} block. --- .github/workflows/publish-devnotes.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-devnotes.yml b/.github/workflows/publish-devnotes.yml index b0542d2c9..474a2bf5d 100644 --- a/.github/workflows/publish-devnotes.yml +++ b/.github/workflows/publish-devnotes.yml @@ -13,6 +13,7 @@ jobs: deploy: runs-on: ubuntu-latest permissions: + actions: read contents: write steps: - name: Checkout repository