From 0d8f184023a286e6d4d86a6c4354da09c4516dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Andrei?= Date: Wed, 20 May 2026 17:27:43 +0200 Subject: [PATCH 1/4] Add deploy_mode, upload_artifact and outputs to frontend-storybook workflow (#373) --- .github/workflows/frontend-storybook.yml | 56 +++++++++++++++++++++++- news/373.feature.md | 1 + 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 news/373.feature.md diff --git a/.github/workflows/frontend-storybook.yml b/.github/workflows/frontend-storybook.yml index 344c489f..72da3abf 100644 --- a/.github/workflows/frontend-storybook.yml +++ b/.github/workflows/frontend-storybook.yml @@ -12,11 +12,31 @@ on: deploy: type: boolean default: false + deploy_mode: + type: string + required: false + default: 'branch' + upload_artifact: + type: boolean + default: false + outputs: + artifact_name: + description: "Name of the uploaded artifact — empty when upload_artifact=false or the step was skipped" + value: ${{ jobs.storybook.outputs.artifact_name }} + artifact_id: + description: "GitHub Actions artifact ID — pass to actions/download-artifact" + value: ${{ jobs.storybook.outputs.artifact_id }} + jobs: storybook: name: Storybook runs-on: ubuntu-latest + permissions: + contents: write + outputs: + artifact_name: ${{ steps.upload-artifact.outcome == 'success' && format('storybook-{0}', github.run_id) || '' }} + artifact_id: ${{ steps.upload-artifact.outputs.artifact-id }} defaults: run: working-directory: ${{ inputs.working-directory }} @@ -41,9 +61,41 @@ jobs: run: | make storybook-build - - name: Deploy to GitHub pages - if: ${{ github.ref == 'refs/heads/main' && inputs.deploy }} + - name: Upload artifact + uses: actions/upload-artifact@v4 + id: upload-artifact + if: ${{ inputs.upload_artifact }} + with: + name: storybook-${{ github.run_id }} + path: ${{ inputs.working-directory }}/.storybook-build + + - name: Deploy branch to GitHub pages uses: JamesIves/github-pages-deploy-action@v4 + if: ${{ github.ref == 'refs/heads/main' && inputs.deploy && inputs.deploy_mode == 'branch' }} with: branch: gh-pages folder: ${{ inputs.working-directory }}/.storybook-build + + - name: Upload Storybook pages artifact + uses: actions/upload-pages-artifact@v5 + if: ${{ github.ref == 'refs/heads/main' && inputs.deploy && inputs.deploy_mode == 'action' }} + with: + path: ${{ inputs.working-directory }}/.storybook-build + + deploy-action: + needs: storybook + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' && inputs.deploy && inputs.deploy_mode == 'action' }} + permissions: + pages: write + id-token: write + concurrency: + group: pages + cancel-in-progress: false + environment: + name: github-pages + url: "${{ steps.deployment.outputs.page_url }}" + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/news/373.feature.md b/news/373.feature.md new file mode 100644 index 00000000..44401a01 --- /dev/null +++ b/news/373.feature.md @@ -0,0 +1 @@ +Added `deploy_mode` and `upload_artifact` inputs and `artifact_name`/`artifact_id` outputs to the `frontend-storybook` reusable workflow, with `actions/deploy-pages@v5` as an alternative to the `gh-pages` branch deploy. @ericof From 771cef9165726b819acb98f06ea6c9e09477cfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Andrei?= Date: Wed, 20 May 2026 17:27:48 +0200 Subject: [PATCH 2/4] Add upload_artifact, build-path and outputs to docs-build workflow --- .github/workflows/docs-build.yml | 25 +++++++++++++++++++++++++ news/+7a0f9a59.feature.md | 1 + 2 files changed, 26 insertions(+) create mode 100644 news/+7a0f9a59.feature.md diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index ecbd0220..15d9f3c0 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -11,17 +11,34 @@ on: type: string required: false default: '.' + build-path: + type: string + required: false + default: '_build/html' check-links: default: true type: boolean check-vale: default: true type: boolean + upload_artifact: + type: boolean + default: false + outputs: + artifact_name: + description: "Name of the uploaded artifact — empty when upload_artifact=false or the step was skipped" + value: ${{ jobs.docs.outputs.artifact_name }} + artifact_id: + description: "GitHub Actions artifact ID — pass to actions/download-artifact" + value: ${{ jobs.docs.outputs.artifact_id }} jobs: docs: name: Documentation runs-on: ubuntu-latest + outputs: + artifact_name: ${{ steps.upload-artifact.outcome == 'success' && format('docs-{0}', github.run_id) || '' }} + artifact_id: ${{ steps.upload-artifact.outputs.artifact-id }} defaults: run: working-directory: ${{ inputs.working-directory }} @@ -54,3 +71,11 @@ jobs: shell: bash run: | make vale VALEOPTS="--minAlertLevel='warning'" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + id: upload-artifact + if: ${{ inputs.upload_artifact }} + with: + name: docs-${{ github.run_id }} + path: ${{ inputs.working-directory }}/${{ inputs.build-path }} diff --git a/news/+7a0f9a59.feature.md b/news/+7a0f9a59.feature.md new file mode 100644 index 00000000..e4704786 --- /dev/null +++ b/news/+7a0f9a59.feature.md @@ -0,0 +1 @@ +Added `upload_artifact` and `build-path` inputs and `artifact_name`/`artifact_id` outputs to the `docs-build` reusable workflow, enabling callers to merge documentation with other artifacts before deploying to GitHub Pages. @ericof From 3d15c9cab937901e66a88bd135e58ad3dbbc75ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Andrei?= Date: Wed, 20 May 2026 17:27:54 +0200 Subject: [PATCH 3/4] Document new inputs, outputs and deploy modes for docs-build and frontend-storybook --- docs/sources/reference/shared-workflows.md | 103 ++++++++++++++++++++- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/docs/sources/reference/shared-workflows.md b/docs/sources/reference/shared-workflows.md index b4913bae..e3ec9bad 100644 --- a/docs/sources/reference/shared-workflows.md +++ b/docs/sources/reference/shared-workflows.md @@ -118,7 +118,25 @@ jobs: ### docs-build -Builds project documentation. +Builds project documentation, optionally uploading the build output as a GitHub Actions artifact for later consumption (e.g. merging with other artifacts before deploying to GitHub Pages). + +**Inputs:** + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `python-version` | Python version to install | No | `"3.12"` | +| `working-directory` | Directory the workflow operates in | No | `"."` | +| `build-path` | Build output directory, relative to `working-directory` | No | `"_build/html"` | +| `check-links` | Run `make linkcheckbroken` | No | `true` | +| `check-vale` | Run `make vale` style checks | No | `true` | +| `upload_artifact` | Upload the build output as a GitHub Actions artifact | No | `false` | + +**Outputs:** + +| Output | Description | +|--------|-------------| +| `artifact_name` | Name of the uploaded artifact (`docs-`). Empty when `upload_artifact=false` or the upload step is skipped. | +| `artifact_id` | GitHub Actions artifact ID. Pass to `actions/download-artifact` via the `artifact-ids` input. | **Example usage:** @@ -126,6 +144,9 @@ Builds project documentation. jobs: docs-build: uses: plone/meta/.github/workflows/docs-build.yml@2.x + with: + python-version: "3.13" + upload_artifact: true ``` ## Frontend Workflows @@ -168,14 +189,90 @@ jobs: ### frontend-storybook -Builds and validates Storybook stories. +Builds Storybook stories and, optionally, deploys them to GitHub Pages or uploads them as a regular artifact for downstream consumption. -**Example usage:** +**Inputs:** + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `node-version` | Node.js version to install | Yes | — | +| `working-directory` | Directory the workflow operates in | No | `"."` | +| `deploy` | Deploy the build (only fires on `refs/heads/main`) | No | `false` | +| `deploy_mode` | Deploy mechanism: `branch` (push to `gh-pages` via `JamesIves/github-pages-deploy-action`) or `action` (publish via `actions/deploy-pages`) | No | `"branch"` | +| `upload_artifact` | Upload the build output as a GitHub Actions artifact (independent of `deploy`) | No | `false` | + +**Outputs:** + +| Output | Description | +|--------|-------------| +| `artifact_name` | Name of the uploaded artifact (`storybook-`). Empty when `upload_artifact=false` or the upload step is skipped. | +| `artifact_id` | GitHub Actions artifact ID. Pass to `actions/download-artifact` via the `artifact-ids` input. | + +**Permissions required from the caller:** + +| `deploy_mode` | Permissions | +|---------------|-------------| +| `branch` | Workflow needs `contents: write` (granted by this workflow at the job level) | +| `action` | Caller workflow must grant `pages: write` and `id-token: write` | + +**Example — build and deploy via `actions/deploy-pages`:** ```yaml +permissions: + pages: write + id-token: write + jobs: frontend-storybook: uses: plone/meta/.github/workflows/frontend-storybook.yml@2.x + with: + node-version: "22.x" + deploy: true + deploy_mode: "action" +``` + +**Example — combine docs and Storybook into a single Pages deploy:** + +```yaml +permissions: + pages: write + id-token: write + +jobs: + storybook: + uses: plone/meta/.github/workflows/frontend-storybook.yml@2.x + with: + node-version: "22.x" + upload_artifact: true + + docs: + uses: plone/meta/.github/workflows/docs-build.yml@2.x + with: + upload_artifact: true + + deploy-pages: + needs: [storybook, docs] + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/download-artifact@v4 + with: + name: ${{ needs.docs.outputs.artifact_name }} + path: ./site + + - uses: actions/download-artifact@v4 + with: + name: ${{ needs.storybook.outputs.artifact_name }} + path: ./site/storybook + + - uses: actions/upload-pages-artifact@v5 + with: + path: ./site + + - id: deployment + uses: actions/deploy-pages@v5 ``` ### frontend-unit From a3783e17eed51d9e275f6495c7c9ffd8be8cf4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Andrei?= Date: Wed, 20 May 2026 17:51:58 +0200 Subject: [PATCH 4/4] Move permissions out of frontend-storybook reusable workflow; document caller responsibility --- .github/workflows/frontend-storybook.yml | 5 ----- docs/sources/reference/shared-workflows.md | 12 ++++++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/frontend-storybook.yml b/.github/workflows/frontend-storybook.yml index 72da3abf..2b285a3a 100644 --- a/.github/workflows/frontend-storybook.yml +++ b/.github/workflows/frontend-storybook.yml @@ -32,8 +32,6 @@ jobs: storybook: name: Storybook runs-on: ubuntu-latest - permissions: - contents: write outputs: artifact_name: ${{ steps.upload-artifact.outcome == 'success' && format('storybook-{0}', github.run_id) || '' }} artifact_id: ${{ steps.upload-artifact.outputs.artifact-id }} @@ -86,9 +84,6 @@ jobs: needs: storybook runs-on: ubuntu-latest if: ${{ github.ref == 'refs/heads/main' && inputs.deploy && inputs.deploy_mode == 'action' }} - permissions: - pages: write - id-token: write concurrency: group: pages cancel-in-progress: false diff --git a/docs/sources/reference/shared-workflows.md b/docs/sources/reference/shared-workflows.md index e3ec9bad..383855be 100644 --- a/docs/sources/reference/shared-workflows.md +++ b/docs/sources/reference/shared-workflows.md @@ -210,10 +210,14 @@ Builds Storybook stories and, optionally, deploys them to GitHub Pages or upload **Permissions required from the caller:** -| `deploy_mode` | Permissions | -|---------------|-------------| -| `branch` | Workflow needs `contents: write` (granted by this workflow at the job level) | -| `action` | Caller workflow must grant `pages: write` and `id-token: write` | +This reusable workflow does **not** declare any `permissions:` of its own — a reusable workflow cannot grant the caller more access than the caller has already enabled. The caller workflow must declare the required permissions at the workflow level (or on the calling job): + +| `deploy_mode` | Permissions the caller must grant | +|---------------|-----------------------------------| +| `branch` | `contents: write` (so `JamesIves/github-pages-deploy-action` can push to the `gh-pages` branch) | +| `action` | `pages: write` and `id-token: write` (required by `actions/deploy-pages@v5`) | + +If `deploy: false`, no extra permissions are required beyond the workflow defaults. **Example — build and deploy via `actions/deploy-pages`:**