diff --git a/.github/scripts/build-preview-urls-comment.js b/.github/scripts/build-preview-urls-comment.js new file mode 100644 index 00000000000..cb6450663c1 --- /dev/null +++ b/.github/scripts/build-preview-urls-comment.js @@ -0,0 +1,24 @@ +#!/usr/bin/env node + +/*! + * Copyright 2025 Adobe. All rights reserved. + * + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const buildPreviewURLComment = (prNumber) => { + const prHash = `pr-${prNumber}`; + const baseUrl = 'https://spectrumcss.z13.web.core.windows.net'; + + return `## 📚 Branch preview + +PR #${prNumber} has been deployed to Azure Blob Storage: [${baseUrl}/${prHash}/index.html](${baseUrl}/${prHash}/index.html).`; + +}; diff --git a/.github/scripts/comment-or-update.js b/.github/scripts/comment-or-update.js new file mode 100644 index 00000000000..46429505f97 --- /dev/null +++ b/.github/scripts/comment-or-update.js @@ -0,0 +1,41 @@ +/*! + * Copyright 2025 Adobe. All rights reserved. + * + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +export const commentOrUpdate = (github, context, title, body) => { + github.rest.issues + .listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }) + .then(({ data }) => { + const priorComment = data.find((comment) => + comment.body.startsWith(title) + ); + if (priorComment) { + github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: priorComment.id, + body, + }); + } else { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } + }); +}; diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 002991ed342..bb7aafa83de 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -203,8 +203,8 @@ jobs: secrets: inherit # ------------------------------------------------------------- - # PUBLISH TO NETLIFY --- # - # Publish to netlify by leveraging the previous build and then building the site as well + # PUBLISH TO AZURE --- # + # Publish to azure by leveraging the previous build and then building the site as well # ------------------------------------------------------------- publish_site: name: Publish diff --git a/.github/workflows/publish-site.yml b/.github/workflows/publish-site.yml index bd7bd9fe603..ca1b363fab1 100644 --- a/.github/workflows/publish-site.yml +++ b/.github/workflows/publish-site.yml @@ -1,91 +1,137 @@ name: Publish documentation # -# This workflow publishes the documentation to Netlify +# This workflow publishes the documentation to Azure blob storage # on: - workflow_dispatch: - inputs: - deploy-message: - required: false - type: string - alias: - required: false - type: string - workflow_call: - inputs: - deploy-message: - required: false - type: string - alias: - required: false - type: string + pull_request: + types: + - closed + workflow_dispatch: + inputs: + deploy-message: + required: false + type: string + alias: + required: false + type: string + workflow_call: + inputs: + deploy-message: + required: false + type: string + alias: + required: false + type: string permissions: - contents: read - pull-requests: write + contents: read + pull-requests: write jobs: - # --- PUBLISH TO NETLIFY --- # - # Publish to netlify by leveraging the previous build and then building the site as well - # --- # - publish_site: - name: Publish - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - ## --- SETUP --- ## - - name: Check out code - uses: actions/checkout@v4 - with: - fetch-depth: 0 + build_and_deploy_job: + if: github.event_name == 'pull_request' && github.event.action != 'closed' + runs-on: ubuntu-latest + name: Publish + steps: + ## --- SETUP --- ## + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node LTS version + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Enable Corepack + run: corepack enable - - name: Use Node LTS version - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: yarn + - name: Generate PR hash + id: pr_hash + run: | + pr_hash="pr-${{ github.event.pull_request.number }}" + echo "hash=${pr_hash}" >> $GITHUB_OUTPUT + echo "Generated PR hash: ${pr_hash}" - - name: Enable Corepack - run: corepack enable + ## --- YARN CACHE --- ## + - name: Check for cached dependencies + continue-on-error: true + id: cache-dependencies + uses: actions/cache@v4 + with: + path: | + .cache/yarn + node_modules + key: ubuntu-latest-node20-${{ hashFiles('yarn.lock') }} - ## --- YARN CACHE --- ## - - name: Check for cached dependencies - continue-on-error: true - id: cache-dependencies - uses: actions/cache@v4 - with: - path: | - .cache/yarn - node_modules - key: ubuntu-latest-node20-${{ hashFiles('yarn.lock') }} + ## --- INSTALL --- ## + - name: Install dependencies + shell: bash + run: yarn install --immutable - ## --- INSTALL --- ## - # note: if cache-hit isn't needed b/c yarn will leverage the cache if it exists - - name: Install dependencies - shell: bash - run: yarn install --immutable + ## --- BUILD --- ## + - name: Build storybook + shell: bash + run: BASE_PATH="/${{ steps.pr_hash.outputs.hash }}" yarn build:docs - ## --- BUILD --- ## - - name: Build storybook - shell: bash - run: yarn build:docs + ## --- DEPLOY TO AZURE BLOB STORAGE --- ## + - name: Install AzCopy + run: | + wget -O azcopy.tar.gz https://aka.ms/downloadazcopy-v10-linux + tar -xf azcopy.tar.gz --strip-components=1 + sudo mv azcopy /usr/local/bin/ + azcopy --version + + - name: Deploy to Azure Blob Storage + id: deploy + env: + AZURE_STORAGE_SAS_TOKEN: ${{ secrets.AZURE_STORAGE_SAS_TOKEN }} + PR_HASH: ${{ steps.pr_hash.outputs.hash }} + run: | + CLEAN_SAS_TOKEN=$(echo "${AZURE_STORAGE_SAS_TOKEN}" | tr -d '\n\r\t ') + echo "Uploading Storybook to ${PR_HASH}" + azcopy copy "/home/runner/work/spectrum-css/spectrum-css/dist/*" --log-level=INFO \ + "https://spectrumcss.blob.core.windows.net/\$web/${PR_HASH}/?${CLEAN_SAS_TOKEN}" \ + --recursive \ + --from-to LocalBlob + docs_url="https://spectrumcss.z13.web.core.windows.net/${PR_HASH}" + echo "docs_url=${docs_url}" >> $GITHUB_OUTPUT + echo "Deployed to: ${docs_url}" + - name: Post Previews Comment + uses: actions/github-script@v7 + with: + script: | + const { buildPreviewURLComment } = await import('${{ github.workspace }}/.github/scripts/build-preview-urls-comment.js'); + const { commentOrUpdate } = await import('${{ github.workspace }}/.github/scripts/comment-or-update.js'); + const prNumber = context.payload.pull_request.number; + const body = buildPreviewURLComment(prNumber); + commentOrUpdate(github, context, '## 📚 Branch preview', body); + timeout-minutes: 10 - ## --- DEPLOY WEBSITE TO NETLIFY --- ## - - name: Deploy - uses: nwtgck/actions-netlify@v3 - with: - publish-dir: dist - production-branch: main - production-deploy: false - netlify-config-path: ./netlify.toml - github-token: ${{ secrets.GITHUB_TOKEN }} - deploy-message: ${{ inputs.deploy-message }} - enable-pull-request-comment: true - enable-commit-comment: false - overwrites-pull-request-comment: true - alias: ${{ inputs.alias }} - env: - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN_GH_ACTIONS_DEPLOY }} - NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} - timeout-minutes: 10 + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Clean up PR deployment + steps: + - name: Generate PR hash + id: pr_hash + run: | + pr_hash="pr-${{ github.event.pull_request.number }}" + echo "hash=${pr_hash}" >> $GITHUB_OUTPUT + - name: Install AzCopy + run: | + wget -O azcopy.tar.gz https://aka.ms/downloadazcopy-v10-linux + tar -xf azcopy.tar.gz --strip-components=1 + sudo mv azcopy /usr/local/bin/ + - name: Clean up PR deployment + env: + AZURE_STORAGE_SAS_TOKEN: ${{ secrets.AZURE_STORAGE_SAS_TOKEN }} + PR_HASH: ${{ steps.pr_hash.outputs.hash }} + run: | + echo "Cleaning up deployment: ${PR_HASH}/" + azcopy remove "https://spectrumcss.z13.web.core.windows.net/\$web/${PR_HASH}/?${AZURE_STORAGE_SAS_TOKEN}" \ + --recursive || echo "Cleanup completed (some files may not exist)" + echo "Cleanup completed for PR deployment: ${PR_HASH}/" diff --git a/.storybook/main.js b/.storybook/main.js index 1ef01068d65..5914dd5b083 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -90,6 +90,7 @@ export default { const { mergeConfig } = await import("vite"); return mergeConfig(config, { + base: process.env.BASE_PATH || config.base, publicDir: "./assets", // Add dependencies to pre-optimization optimizeDeps: {