diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index ecbd022..15d9f3c 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/.github/workflows/frontend-storybook.yml b/.github/workflows/frontend-storybook.yml index 344c489..2b285a3 100644 --- a/.github/workflows/frontend-storybook.yml +++ b/.github/workflows/frontend-storybook.yml @@ -12,11 +12,29 @@ 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 + 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 +59,38 @@ 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' }} + 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/docs/sources/reference/shared-workflows.md b/docs/sources/reference/shared-workflows.md index b4913ba..383855b 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,94 @@ 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:** + +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`:** ```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 diff --git a/news/+7a0f9a59.feature.md b/news/+7a0f9a59.feature.md new file mode 100644 index 0000000..e470478 --- /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 diff --git a/news/373.feature.md b/news/373.feature.md new file mode 100644 index 0000000..44401a0 --- /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