From 823eb7e252e5ab8d935282113ec3830c913eb3da Mon Sep 17 00:00:00 2001 From: Ruslan Farkhutdinov Date: Wed, 13 May 2026 14:43:13 +0300 Subject: [PATCH 1/5] Storybook Deployment: Add automatic workflows --- .github/workflows/pr-storybook-build.yml | 126 ++++++++++++++++++++++ .github/workflows/pr-storybook-deploy.yml | 83 ++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 .github/workflows/pr-storybook-build.yml create mode 100644 .github/workflows/pr-storybook-deploy.yml diff --git a/.github/workflows/pr-storybook-build.yml b/.github/workflows/pr-storybook-build.yml new file mode 100644 index 000000000000..6c9eb2618be7 --- /dev/null +++ b/.github/workflows/pr-storybook-build.yml @@ -0,0 +1,126 @@ +name: PR Storybook - Build + +on: + pull_request: + branches: + - 26_1 + types: + - opened + - reopened + - synchronize + - labeled + - unlabeled + - closed + +permissions: + contents: read + +concurrency: + group: preview-build-${{ github.event.pull_request.number }} + cancel-in-progress: true + +env: + SOURCE_DIR: ./apps/react-storybook/storybook-static + +jobs: + build: + name: Build preview artifacts + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Decide action (deploy/remove/none) + id: meta + shell: bash + run: | + set -euo pipefail + + PR_NUMBER="${{ github.event.pull_request.number }}" + EVENT_ACTION="${{ github.event.action }}" + CHANGED_LABEL="${{ github.event.label.name || '' }}" + HAS_LABEL="${{ contains(github.event.pull_request.labels.*.name, 'storybook') }}" + + ACTION="none" + + # Cleanup cases + if [[ "$EVENT_ACTION" == "closed" ]]; then + ACTION="remove" + elif [[ "$EVENT_ACTION" == "unlabeled" && "$CHANGED_LABEL" == "storybook" ]]; then + ACTION="remove" + # Deploy cases + elif [[ "$EVENT_ACTION" == "labeled" && "$CHANGED_LABEL" == "storybook" ]]; then + ACTION="deploy" + elif [[ "$EVENT_ACTION" == "opened" || "$EVENT_ACTION" == "reopened" || "$EVENT_ACTION" == "synchronize" ]]; then + if [[ "$HAS_LABEL" == "true" ]]; then + ACTION="deploy" + fi + fi + + mkdir -p preview_meta + cat > preview_meta/meta.json <> "$GITHUB_OUTPUT" + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + + - name: Checkout repository + if: steps.meta.outputs.action == 'deploy' + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 1 + + - name: Use Node.js + if: steps.meta.outputs.action == 'deploy' + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Setup pnpm + if: steps.meta.outputs.action == 'deploy' + uses: pnpm/action-setup@v4 + with: + run_install: false + + - name: Get pnpm store directory + if: steps.meta.outputs.action == 'deploy' + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm + nx cache + if: steps.meta.outputs.action == 'deploy' + uses: actions/cache@v4 + with: + path: | + ${{ env.STORE_PATH }} + .nx/cache + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store + + - name: Install dependencies + if: steps.meta.outputs.action == 'deploy' + run: pnpm install --frozen-lockfile + + - name: Build Storybook preview (static) + if: steps.meta.outputs.action == 'deploy' + run: | + pnpm nx build devextreme-react-storybook + + - name: Upload meta artifact (always) + if: always() + uses: actions/upload-artifact@v4 + with: + name: preview-meta + path: preview_meta/meta.json + retention-days: 1 + + - name: Upload static artifact (deploy only) + if: steps.meta.outputs.action == 'deploy' + uses: actions/upload-artifact@v4 + with: + name: preview-static + path: ${{ env.SOURCE_DIR }} + retention-days: 1 diff --git a/.github/workflows/pr-storybook-deploy.yml b/.github/workflows/pr-storybook-deploy.yml new file mode 100644 index 000000000000..329785f47768 --- /dev/null +++ b/.github/workflows/pr-storybook-deploy.yml @@ -0,0 +1,83 @@ +name: PR Storybook - Deploy + +on: + workflow_run: + workflows: + - PR Storybook - Build + types: + - completed + +permissions: + contents: write + pull-requests: write + +env: + SOURCE_DIR: dist/static + +jobs: + prepare: + name: Read build meta + if: github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + action: ${{ steps.meta.outputs.action }} + pr_number: ${{ steps.meta.outputs.pr_number }} + + steps: + - name: Download meta artifact + uses: dawidd6/action-download-artifact@v6 + with: + run_id: ${{ github.event.workflow_run.id }} + name: preview-meta + path: artifacts + + - name: Read meta + id: meta + shell: bash + run: | + set -euo pipefail + META="artifacts/meta.json" + echo "Meta:" + cat "$META" + + PR_NUMBER="$(jq -r '.pr_number' "$META")" + ACTION="$(jq -r '.action' "$META")" + + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "action=$ACTION" >> "$GITHUB_OUTPUT" + + deploy: + name: Deploy/remove preview + needs: prepare + if: needs.prepare.outputs.action != 'none' + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: preview + + concurrency: + group: preview-deploy-${{ needs.prepare.outputs.pr_number }} + cancel-in-progress: true + + steps: + - name: Download static artifact + if: needs.prepare.outputs.action == 'deploy' + uses: dawidd6/action-download-artifact@v6 + with: + run_id: ${{ github.event.workflow_run.id }} + name: preview-static + path: ${{ env.SOURCE_DIR }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Deploy/remove PR preview + uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 + with: + action: ${{ needs.prepare.outputs.action }} + pr-number: ${{ needs.prepare.outputs.pr_number }} + source-dir: ${{ env.SOURCE_DIR }} + preview-branch: gh-pages + umbrella-dir: storybook + comment: false + token: ${{ github.token }} From 8845b7607b2117f54fada9c7dc748393c0820cfb Mon Sep 17 00:00:00 2001 From: Ruslan Farkhutdinov Date: Wed, 13 May 2026 17:07:28 +0300 Subject: [PATCH 2/5] Storybook Deployment: Fix deploy job permissions & order issues --- .github/workflows/pr-storybook-deploy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-storybook-deploy.yml b/.github/workflows/pr-storybook-deploy.yml index 329785f47768..930442ae7039 100644 --- a/.github/workflows/pr-storybook-deploy.yml +++ b/.github/workflows/pr-storybook-deploy.yml @@ -9,7 +9,7 @@ on: permissions: contents: write - pull-requests: write + actions: read env: SOURCE_DIR: dist/static @@ -60,6 +60,9 @@ jobs: cancel-in-progress: true steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Download static artifact if: needs.prepare.outputs.action == 'deploy' uses: dawidd6/action-download-artifact@v6 @@ -68,9 +71,6 @@ jobs: name: preview-static path: ${{ env.SOURCE_DIR }} - - name: Checkout repository - uses: actions/checkout@v4 - - name: Deploy/remove PR preview uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1 with: @@ -78,6 +78,6 @@ jobs: pr-number: ${{ needs.prepare.outputs.pr_number }} source-dir: ${{ env.SOURCE_DIR }} preview-branch: gh-pages - umbrella-dir: storybook + umbrella-dir: preview comment: false token: ${{ github.token }} From 762e47809e327312c5e66bb702d6684592c204f1 Mon Sep 17 00:00:00 2001 From: Ruslan Farkhutdinov Date: Wed, 13 May 2026 17:29:09 +0300 Subject: [PATCH 3/5] Update environment name Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Ruslan Farkhutdinov --- .github/workflows/pr-storybook-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-storybook-deploy.yml b/.github/workflows/pr-storybook-deploy.yml index 930442ae7039..c62e23511bb6 100644 --- a/.github/workflows/pr-storybook-deploy.yml +++ b/.github/workflows/pr-storybook-deploy.yml @@ -53,7 +53,7 @@ jobs: if: needs.prepare.outputs.action != 'none' runs-on: ubuntu-latest timeout-minutes: 10 - environment: preview + environment: github-pages concurrency: group: preview-deploy-${{ needs.prepare.outputs.pr_number }} From 657bcbe87a5488c902efd323e8ed3de9f4dda5ae Mon Sep 17 00:00:00 2001 From: Ruslan Farkhutdinov Date: Wed, 13 May 2026 17:41:44 +0300 Subject: [PATCH 4/5] Storybook Deployment: Create meta file after checkout --- .github/workflows/pr-storybook-build.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-storybook-build.yml b/.github/workflows/pr-storybook-build.yml index 6c9eb2618be7..d419408e5a5e 100644 --- a/.github/workflows/pr-storybook-build.yml +++ b/.github/workflows/pr-storybook-build.yml @@ -56,11 +56,6 @@ jobs: fi fi - mkdir -p preview_meta - cat > preview_meta/meta.json <> "$GITHUB_OUTPUT" echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" @@ -71,6 +66,15 @@ jobs: submodules: true fetch-depth: 1 + - name: Write meta artifact + if: always() + shell: bash + run: | + mkdir -p preview_meta + printf '{ "pr_number": %s, "action": "%s" }\n' \ + '${{ steps.meta.outputs.pr_number }}' \ + '${{ steps.meta.outputs.action }}' > preview_meta/meta.json + - name: Use Node.js if: steps.meta.outputs.action == 'deploy' uses: actions/setup-node@v4 From dc2c8b353f3d7cb535c812d56dac5bc4dedad651 Mon Sep 17 00:00:00 2001 From: Ruslan Farkhutdinov Date: Wed, 13 May 2026 18:11:10 +0300 Subject: [PATCH 5/5] Storybook Deployment: Add wait-for-pages-deployment flag & add environment protection --- .github/workflows/pr-storybook-build.yml | 1 + .github/workflows/pr-storybook-deploy.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/pr-storybook-build.yml b/.github/workflows/pr-storybook-build.yml index d419408e5a5e..c9728095163c 100644 --- a/.github/workflows/pr-storybook-build.yml +++ b/.github/workflows/pr-storybook-build.yml @@ -27,6 +27,7 @@ jobs: name: Build preview artifacts runs-on: ubuntu-latest timeout-minutes: 20 + environment: github-pages steps: - name: Decide action (deploy/remove/none) diff --git a/.github/workflows/pr-storybook-deploy.yml b/.github/workflows/pr-storybook-deploy.yml index c62e23511bb6..00da7a1bf171 100644 --- a/.github/workflows/pr-storybook-deploy.yml +++ b/.github/workflows/pr-storybook-deploy.yml @@ -81,3 +81,4 @@ jobs: umbrella-dir: preview comment: false token: ${{ github.token }} + wait-for-pages-deployment: true