Skip to content

chore(settings): Update to React 19 #5761

chore(settings): Update to React 19

chore(settings): Update to React 19 #5761

name: Deploy Storybooks to GitHub Pages
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: write
pull-requests: write
statuses: write
pages: write
id-token: write
jobs:
build:
name: Build Storybooks
runs-on: ubuntu-latest
outputs:
has_storybooks: ${{ steps.check-affected.outputs.has_storybooks || 'true' }}
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
filter: tree:0
persist-credentials: false
- name: Set NX_BASE and NX_HEAD for affected detection
if: github.event_name == 'pull_request'
run: |
git fetch origin ${GITHUB_BASE_REF}
MERGE_BASE=$(git merge-base HEAD origin/${GITHUB_BASE_REF})
echo "NX_BASE=$MERGE_BASE" >> $GITHUB_ENV
echo "NX_HEAD=HEAD" >> $GITHUB_ENV
echo "Comparing against merge-base: $MERGE_BASE"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install
- name: Clone l10n repository
run: _scripts/l10n/clone.sh
- name: Check if any projects with storybook are affected (PR)
id: check-affected
if: github.event_name == 'pull_request'
run: |
AFFECTED=$(npx nx show projects --affected -t build-storybook)
if [ -z "$AFFECTED" ]; then
echo "has_storybooks=false" >> $GITHUB_OUTPUT
echo "No storybook projects affected"
else
echo "has_storybooks=true" >> $GITHUB_OUTPUT
echo "Affected storybook projects:"
echo "$AFFECTED"
fi
- name: Build Storybooks for affected packages (PR)
if: github.event_name == 'pull_request' && steps.check-affected.outputs.has_storybooks == 'true'
run: npx nx affected -t build-storybook --output-style=stream
- name: Build all Storybooks (main branch)
if: github.event_name == 'push'
run: npx nx run-many -t build-storybook --output-style=stream
- name: Organize Storybooks for deployment
if: github.event_name == 'push' || steps.check-affected.outputs.has_storybooks == 'true'
run: node _scripts/organize-storybooks.js
env:
DEPLOY_DIR: deploy/
- name: Upload storybooks artifact
if: github.event_name == 'push' || steps.check-affected.outputs.has_storybooks == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: storybooks-${{ github.event_name == 'pull_request' && github.event.pull_request.number || 'main' }}
path: deploy/
retention-days: 1
prepare:
name: Prepare Storybooks for Deployment
runs-on: ubuntu-latest
needs: build
if: needs.build.outputs.has_storybooks == 'true'
outputs:
deploy_dir: ${{ steps.deploy-dir.outputs.path }}
# Per-PR (or per-ref) concurrency: different PRs no longer share one global
# lock, so they stop cancelling each other. The non-destructive push below
# makes concurrent updates to gh-pages safe without a global serialization group.
concurrency:
group: gh-pages-deploy-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Checkout repository for scripts
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
path: repo
persist-credentials: false
- name: Checkout gh-pages branch
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
with:
ref: gh-pages
path: gh-pages
fetch-depth: 1
- name: Set deployment directory
id: deploy-dir
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
DEPLOY_DIR="storybooks/pr-${{ github.event.pull_request.number }}"
else
DEPLOY_DIR="storybooks/main"
fi
echo "path=$DEPLOY_DIR" >> $GITHUB_OUTPUT
echo "DEPLOY_DIR=$DEPLOY_DIR" >> $GITHUB_ENV
- name: Download storybooks artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: storybooks-${{ github.event_name == 'pull_request' && github.event.pull_request.number || 'main' }}
# Stage outside the gh-pages checkout so the reset --hard below can't wipe it
path: ${{ runner.temp }}/storybooks-artifact
- name: Update gh-pages branch for artifact storage
env:
DEPLOY_DIR: ${{ steps.deploy-dir.outputs.path }}
ARTIFACT_DIR: ${{ runner.temp }}/storybooks-artifact
STORYBOOKS_DIR: gh-pages/storybooks
REPO_NAME: ${{ github.event.repository.name }}
REPO_OWNER: ${{ github.repository_owner }}
run: |
git -C gh-pages config user.name "github-actions[bot]"
git -C gh-pages config user.email "github-actions[bot]@users.noreply.github.com"
if [ "${{ github.event_name }}" == "pull_request" ]; then
COMMIT_MSG="Store storybooks for PR ${{ github.event.pull_request.number }}"
else
COMMIT_MSG="Store storybooks from main branch"
fi
# Optimistic-concurrency update: re-apply our storybooks onto the latest
# gh-pages and push, retrying if another PR landed first. Replaces the old
# orphan force-push, which required a single global concurrency lock and made
# concurrent PRs cancel each other ("higher priority waiting request").
for attempt in 1 2 3 4 5; do
git -C gh-pages fetch --depth 1 origin gh-pages
git -C gh-pages reset --hard origin/gh-pages
rm -rf "gh-pages/${DEPLOY_DIR}"
mkdir -p "gh-pages/${DEPLOY_DIR}"
cp -R "${ARTIFACT_DIR}/." "gh-pages/${DEPLOY_DIR}/"
node repo/_scripts/generate-storybook-index.js
git -C gh-pages add -A
git -C gh-pages commit -m "$COMMIT_MSG" || { echo "Nothing to update"; break; }
if git -C gh-pages push origin HEAD:gh-pages; then
echo "Pushed storybooks to gh-pages (attempt ${attempt})"
break
fi
if [ "${attempt}" -eq 5 ]; then
echo "Failed to update gh-pages after ${attempt} attempts" >&2
exit 1
fi
echo "gh-pages advanced during run; retrying (attempt ${attempt})"
done
- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: gh-pages/
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: [build, prepare]
if: needs.build.outputs.has_storybooks == 'true'
continue-on-error: true
# GitHub Pages allows only one in-progress deployment per environment, so
# serialize deploy jobs to stop concurrent runs colliding with an HTTP 400.
concurrency:
group: gh-pages-publish
cancel-in-progress: false
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
- name: Create GitHub status check
if: github.event_name == 'pull_request'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const deployDir = "${{ needs.prepare.outputs.deploy_dir }}";
const deployUrl = `https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${deployDir}/`;
const sha = context.payload.pull_request.head.sha;
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: sha,
state: 'success',
context: 'Link to Storybooks',
description: 'Storybooks deployed',
target_url: deployUrl
});
console.log(`Created status check for ${sha} with URL: ${deployUrl}`);