From d79ef6bc560cc2413c1c05fc0c159f7e8a132de2 Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:08:23 +0200 Subject: [PATCH 1/6] [CI] add mkdocs and doc portal PR previews Build and publish a mkdocs pr-preview plus a doc-portal preview on pull requests, and clean them up when the PR closes. --- .github/workflows/preview.yml | 150 ++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 0000000..f264e0b --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,150 @@ +name: Deploy PR previews + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - closed + +permissions: {} + +concurrency: + group: preview-${{ github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + build: + name: Build docs + if: github.event.action != 'closed' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Install graphviz + run: sudo apt-get install -y graphviz + + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.10" + + - name: Install Hatch + run: pip install hatch + + - name: Build documentation + run: hatch -v run docs:build + + - name: Upload built site + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: pr-preview-site + path: ./site/ + retention-days: 1 + + deploy: + name: Deploy preview + needs: [build] + if: | + always() && + github.event.pull_request.head.repo.full_name == github.repository && + (github.event.action == 'closed' || needs.build.result == 'success') + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout the base commit, never the PR head + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.base.sha }} + + - name: Download built site + if: github.event.action != 'closed' + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: pr-preview-site + path: ./site/ + + - name: Deploy preview + uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 + with: + source-dir: ./site/ + preview-branch: gh-pages + qr-code: false + + portal-preview: + name: Deploy doc-portal preview + needs: [deploy] + if: | + always() && + github.event.pull_request.head.repo.full_name == github.repository && + (github.event.action == 'closed' || needs.deploy.result == 'success') + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + env: + PORTAL_PREVIEW_PATH: portal-preview/pr-${{ github.event.pull_request.number }} + DOC_PORTAL_IMAGE: europe-west9-docker.pkg.dev/pasqal-artifact/frontend/doc-portal:source-runtime + steps: + - name: Checkout the base commit, never the PR head + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.base.sha }} + persist-credentials: false + + - name: Login to Artifact Registry + if: github.event.action != 'closed' + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: europe-west9-docker.pkg.dev + username: _json_key + password: ${{ secrets.GCP_ARTIFACT_REGISTRY_SA }} + + - name: Pull the doc portal image + if: github.event.action != 'closed' + run: docker pull "$DOC_PORTAL_IMAGE" + + - name: Build the portal preview + if: github.event.action != 'closed' + run: | + mkdir -p portal-dist + docker run --rm \ + --volume "$PWD/portal-dist:/out" \ + --env BUILD_CONFIG='{"qek":"https://pasqal-io.github.io/quantum-evolution-kernel/pr-preview/pr-${{ github.event.pull_request.number }}/"}' \ + --env ASTRO_BASE="/quantum-evolution-kernel/${PORTAL_PREVIEW_PATH}/" \ + --entrypoint sh \ + "$DOC_PORTAL_IMAGE" \ + -c 'sh /app/docker/doc-portal-rebuild-source.sh qek && cp -r /app/packages/doc-portal/dist/. /out/' + + - name: Deploy portal preview + uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 + with: + source-dir: ./portal-dist/ + preview-branch: gh-pages + umbrella-dir: portal-preview + qr-code: false + comment: false + + - name: Comment the preview link on the PR + if: github.event.action != 'closed' + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 + with: + header: doc-portal-preview + message: | + Doc portal preview: https://pasqal-io.github.io/quantum-evolution-kernel/${{ env.PORTAL_PREVIEW_PATH }}/applicationsolvingtools/qek/ + + Built from ${{ github.event.pull_request.head.sha }}. + + - name: Remove the preview comment + if: github.event.action == 'closed' + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 + with: + header: doc-portal-preview + delete: true From a1446795756c59f724e68030eeddb1c731a67945 Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:25:26 +0200 Subject: [PATCH 2/6] Update preview.yml --- .github/workflows/preview.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index f264e0b..24380cd 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -38,6 +38,8 @@ jobs: run: pip install hatch - name: Build documentation + env: + PYTHONWARNINGS: ignore run: hatch -v run docs:build - name: Upload built site From ee5cf0ff95915fa8cafbb1374aea21c2170b4a8f Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:31:01 +0200 Subject: [PATCH 3/6] [FEAT] added comments like pasqal cloud --- .github/workflows/preview.yml | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 24380cd..167fb80 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,3 +1,4 @@ +# .github/workflows/preview.yml name: Deploy PR previews on: @@ -8,19 +9,27 @@ on: - synchronize - closed +# `pull_request` (never `pull_request_target`) is deliberate: the build below +# executes code from the pull request, so it must not run in a context that has +# access to repository secrets or a writable token. permissions: {} concurrency: group: preview-${{ github.event.pull_request.number }} + # Deploys push to gh-pages; cancelling one midway can leave it inconsistent. cancel-in-progress: false jobs: + # UNTRUSTED. Builds the pull request's own code: `hatch run docs:build` runs + # packaging/docs tooling, and mkdocs.yml enables `markdown_exec`, which + # executes Python from the docs at build time. This job therefore holds no + # permissions and no credentials -- it only produces an artifact. build: name: Build docs if: github.event.action != 'closed' runs-on: ubuntu-latest permissions: - contents: read + contents: read # checkout only; deliberately nothing else steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -49,17 +58,22 @@ jobs: path: ./site/ retention-days: 1 + # TRUSTED. Holds the write token but never runs code from the pull request: + # it checks out the base commit and only unpacks the artifact built above. deploy: name: Deploy preview needs: [build] + # Forks get a read-only token no matter what `permissions` says, so a + # deploy from one cannot succeed. Skip it rather than fail the PR; the + # build job above still validates that a fork's docs compile. if: | always() && github.event.pull_request.head.repo.full_name == github.repository && (github.event.action == 'closed' || needs.build.result == 'success') runs-on: ubuntu-latest permissions: - contents: write - pull-requests: write + contents: write # push the preview to the gh-pages branch + pull-requests: write # leave/update the sticky preview comment steps: - name: Checkout the base commit, never the PR head uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -83,14 +97,16 @@ jobs: portal-preview: name: Deploy doc-portal preview needs: [deploy] + # Same-repo only (secrets + write token). Runs after deploy so mkdocs and + # portal never push to gh-pages in parallel — including on PR close. if: | always() && github.event.pull_request.head.repo.full_name == github.repository && (github.event.action == 'closed' || needs.deploy.result == 'success') runs-on: ubuntu-latest permissions: - contents: write - pull-requests: write + contents: write # publish under portal-preview/pr-/ on gh-pages + pull-requests: write # sticky comment env: PORTAL_PREVIEW_PATH: portal-preview/pr-${{ github.event.pull_request.number }} DOC_PORTAL_IMAGE: europe-west9-docker.pkg.dev/pasqal-artifact/frontend/doc-portal:source-runtime From cc61c0f5dcd2c3d9330d1302e06a93b3b6a1a1f0 Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Wed, 16 Sep 2026 16:17:34 +0200 Subject: [PATCH 4/6] Update preview.yml --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 167fb80..00c4946 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -139,7 +139,7 @@ jobs: --env ASTRO_BASE="/quantum-evolution-kernel/${PORTAL_PREVIEW_PATH}/" \ --entrypoint sh \ "$DOC_PORTAL_IMAGE" \ - -c 'sh /app/docker/doc-portal-rebuild-source.sh qek && cp -r /app/packages/doc-portal/dist/. /out/' + -c 'cd /app && pnpm --filter @pasqal/doc-portal run build:selected && cp -r /app/packages/doc-portal/dist/. /out/' - name: Deploy portal preview uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 From 73abae5e2a05e1791bf5dc5b791be92b5c5fabff Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Wed, 16 Sep 2026 17:37:26 +0200 Subject: [PATCH 5/6] Update preview.yml --- .github/workflows/preview.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 00c4946..235c3a8 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -134,6 +134,7 @@ jobs: run: | mkdir -p portal-dist docker run --rm \ + --user 0:0 \ --volume "$PWD/portal-dist:/out" \ --env BUILD_CONFIG='{"qek":"https://pasqal-io.github.io/quantum-evolution-kernel/pr-preview/pr-${{ github.event.pull_request.number }}/"}' \ --env ASTRO_BASE="/quantum-evolution-kernel/${PORTAL_PREVIEW_PATH}/" \ From aa0070633f9bf49d24ba68aba90fb01fd391a095 Mon Sep 17 00:00:00 2001 From: Thomas Baronnet <109949762+thomasbaronnet@users.noreply.github.com> Date: Mon, 21 Sep 2026 10:18:13 +0200 Subject: [PATCH 6/6] [FIX] added wait-for-pages-deployment: true --- .github/workflows/preview.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 235c3a8..c243e75 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -74,6 +74,7 @@ jobs: permissions: contents: write # push the preview to the gh-pages branch pull-requests: write # leave/update the sticky preview comment + deployments: read # wait-for-pages-deployment polls the Deployments API steps: - name: Checkout the base commit, never the PR head uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -93,6 +94,7 @@ jobs: source-dir: ./site/ preview-branch: gh-pages qr-code: false + wait-for-pages-deployment: true portal-preview: name: Deploy doc-portal preview