diff --git a/.eslintrc.js b/.eslintrc.js index 2dee39964..48626dcc1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,9 +15,9 @@ module.exports = { "plugin:jsx-a11y/recommended", "airbnb-typescript", "plugin:sonarjs/recommended", - "plugin:jest-playwright/recommended", "plugin:storybook/recommended", "plugin:prettier/recommended", + "plugin:react-hooks/recommended", ], // this is to disable // no-unused-var, no-extraneous-dependencies and prettier diff --git a/.github/ISSUE_TEMPLATE/amend-existing-component.md b/.github/ISSUE_TEMPLATE/amend-existing-component.md deleted file mode 100644 index 1415fcb4a..000000000 --- a/.github/ISSUE_TEMPLATE/amend-existing-component.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Amend existing component -about: Request amends to existing components -title: 'Amend existing component: [component name]' -labels: '' -assignees: '' - ---- - -## Component to amend - -Add component name(s) here - -## Exists or New - -Does this component already exist in one of our products or is it new? - -## Visual - -Provide a screenshot or link to a prototype of your component changes. - -## Context - -In what context does your amendment solve a problem? diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..22ca100d4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Security Issues + url: mailto:security@chanzuckerberg.com + about: Please responsibly disclose security issues by emailing us at security@chanzuckerberg.com. diff --git a/.github/ISSUE_TEMPLATE/functional-tests-for-a-component.md b/.github/ISSUE_TEMPLATE/functional-tests-for-a-component.md new file mode 100644 index 000000000..bd932a920 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/functional-tests-for-a-component.md @@ -0,0 +1,24 @@ +--- +name: Functional tests for a component +about: Use this template to create issues for writing functional tests for c... +title: Functional tests for [Component] +labels: "" +assignees: "" +--- + +- [ ] Align with design, product, other engineers, if necessary, on what functionality to test +- As a starting point, you can find the component in this doc: [Functional tests: Ideas for what to test per component](https://docs.google.com/document/d/1qKFFBWMBq0QMhRrk5-mgrZYI2QqiL-c9YLKi28w94Gg/edit#heading=h.aixehdk039ik) +- [ ] Write the tests in the index.test.tsx for the component. + +### Tips for writing functional tests: + +- Consider the various types of [queries within the React Testing Library and when to use which](https://testing-library.com/docs/queries/about/#types-of-queries) +- [React Testing Library Cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet/) +- [Guiding principles](https://testing-library.com/docs/guiding-principles/) from React Testing Library +- Consider when to group test cases into a single test, for example “if search bar included, it appears in menu” can be combined with “if search bar included, entered text filters to exclude non-matches” in the same test + +### Tips for running the tests: + +- Make sure the test will fail when it should, too (or even make these test cases themselves to keep as permanent tests). For example, write a test such that if there should be an icon but there’s not, it will fail, in addition to writing a test for if there is an icon it will pass +- To save time when running the tests, in Terminal, use the command `lerna run test -- [INSERT LOCAL PATH TO TEST FILE]` to limit the tests that are run to those within a given component’s test file only (e.g. `lerna run test -- /Users/quigley/sci-components/packages/components/src/core/Button/button.test.tsx` for running tests for the Button component only) +- To save even more time and to help isolate an individual test when troubleshooting, you can limit to a single test to run within the component’s suite by adding `.only` directly after `it` for the particular test as such: `it.only(“...` diff --git a/.github/ISSUE_TEMPLATE/propose-new-component.md b/.github/ISSUE_TEMPLATE/propose-new-component.md deleted file mode 100644 index d076a06fc..000000000 --- a/.github/ISSUE_TEMPLATE/propose-new-component.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Propose new Component -about: Propose a new component to the Science Design System -title: 'Propose new component: [component name]' -labels: '' -assignees: '' - ---- - -A component in Science Design System needs to be flexible enough that it can be used across a wide range of scenarios and shouldn't be constrained to a specific number of products. - -## Visual - -Provide a screenshot or link to a prototype of your component proposal. - -## Context - -Where and when might this proposed component be used? - -## Owner - -Is this something you and your product has time to do or is this a request of the Science Design System team? - -## State - -Does this component have states? If so, what are the different states (e.g. accordion with closed/open states)? - -## Progressive enhancement - -A component should be designed small screen first. How does this component scale up? -How will this component degrade on less competent browsers? diff --git a/.github/ISSUE_TEMPLATE/request-new-component.yml b/.github/ISSUE_TEMPLATE/request-new-component.yml new file mode 100644 index 000000000..99b548726 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/request-new-component.yml @@ -0,0 +1,50 @@ +name: Request new SDS component +description: Request a component be added to SDS +body: + - type: markdown + attributes: + value: | + Thanks for requesting a new component in the SDS! Please fill out the following information about the requested component. + - type: input + id: component-name + attributes: + label: Component Name + description: A name for the desired component. + validations: + required: true + - type: textarea + id: component-requirements + attributes: + label: Component Requirements + description: A list of requirements for the component. + validations: + required: true + - type: input + id: mui-base-component + attributes: + label: MUI Base Component (if applicable) + description: If the component is based on a Material-UI component, please specify. + placeholder: e.g., MUI Button + validations: + required: false + - type: input + id: teams-requesting + attributes: + label: Team(s) Requesting + description: The team(s) that need this component. + validations: + required: true + - type: input + id: component-needed-by + attributes: + label: Component Needed By + description: The date by which the component is needed. + validations: + required: true + - type: input + id: component-screenshot + attributes: + label: Component Screenshot / Prototype + description: A link to a screenshot or prototype of the component. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/request-support.yml b/.github/ISSUE_TEMPLATE/request-support.yml new file mode 100644 index 000000000..4156cba17 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/request-support.yml @@ -0,0 +1,21 @@ +name: Request support +description: Request support for a SDS component +body: + - type: markdown + attributes: + value: | + Please fill out the form below to request help with a SDS component. + - type: input + id: component-name + attributes: + label: Component Name + description: Component that help request is for. + validations: + required: true + - type: textarea + id: issue-description + attributes: + label: Issue description + description: Details about the issue with the component. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/visual-tests-for-a-component.md b/.github/ISSUE_TEMPLATE/visual-tests-for-a-component.md new file mode 100644 index 000000000..b15e2720c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/visual-tests-for-a-component.md @@ -0,0 +1,18 @@ +--- +name: Visual tests for a component +about: + Use this template to create issues for writing visual (Chromatic) tests for + components +title: Visual tests for [Component] +labels: Test Cases Epic +assignees: "" +--- + +- [ ] Align with design, product, and other engineers, if necessary, on what visual traits to include as permutation dimensions for the Chromatic test +- As a starting point, you can find the component in this doc: [Chromatic tests: Which component dimensions to consider looping through](https://docs.google.com/document/d/1i40YV1rX61dNzGsqbhqJAD8PL1puCecX7rnHgD_FawE/edit#heading=h.s63zmnx3lqv1) +- Permutation dimensions may include the component’s props, but it may not always be necessary to include every prop +- If the component can be interacted with, or if part of it can (e.g. an “x” button or similar within it), it may need pseudo state as a permutation dimension. (The SDS codebase already has a [pseudo state addon for Storybook integrated](https://storybook.js.org/addons/storybook-addon-pseudo-states), but each relevant state will need to be looped through, see next bullet for an example.) + +- [ ] Write the tests in the index.stories.tsx for the component. See the [index.stories.tsx file for the Button component](https://github.com/chanzuckerberg/sci-components/blob/main/packages/components/src/core/Button/index.stories.tsx) for an example of how to structure the loops within the test, to ensure all relevant permutations are iterated through. +- Name the test `ScreenshotTest`; this will result in a new page called “Screenshot Test” generated in Storybook for the component () +- `ScreenshotTest` should come after `Default` and `LivePreview` but before `Test` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9a1df641b..73208929b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,7 @@ **Structural Element (Base, Gene, DNA, Chromosome or Cell)** Github issue: [#XXXX](link) -Copy isuue descirption here +Copy issue description here ## Checklist diff --git a/.github/workflows/slack-breaking-changes.yml b/.github/config/slack.yml similarity index 100% rename from .github/workflows/slack-breaking-changes.yml rename to .github/config/slack.yml diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index f6f631449..3d590cf5d 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -1,6 +1,6 @@ -name: "Chromatic" +name: "Chromatic Deployment" -# Event for the workflow +# Triggers on Push event on all branches, excluding the 'prod' branch on: push: branches-ignore: @@ -8,24 +8,29 @@ on: jobs: chromatic-deployment: - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment steps: - # 👇 Version 2 of the action + # Step 1: Checkout the repository code - name: Checkout repository uses: actions/checkout@v3 with: - fetch-depth: 0 # 👈 Required to retrieve git history - - uses: actions/setup-node@v3 + fetch-depth: 0 + + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 with: - node-version-file: ".node-version" + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + + # Step 3: Install project dependencies using Yarn - name: Install dependencies run: yarn - # 👇 Adds Chromatic as a step in the workflow + + # Step 4: Publish the project to Chromatic - name: Publish to Chromatic uses: chromaui/action@v1 - # Options required to the GitHub Chromatic Action with: - token: ${{ secrets.GITHUB_TOKEN }} - # 👇 Chromatic projectToken, refer to the manage page to obtain it. - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} # Authenticate using the GitHub token + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} # Provide the Chromatic project token for authentication diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index d55729cba..f389bdddc 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,5 +1,6 @@ name: Lint PR commit +# Triggers on pull requests with specific types on: pull_request: types: @@ -10,10 +11,12 @@ on: jobs: main: - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment + steps: + # Step 1: Use the 'amannn/action-semantic-pull-request' action to validate the PR commit - uses: amannn/action-semantic-pull-request@v3.4.2 with: - validateSingleCommit: true + validateSingleCommit: true # Specify to validate a single commit env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Authenticate using the GitHub token diff --git a/.github/workflows/namespace-check.yml b/.github/workflows/namespace-check.yml index 896be91fb..013fd3c52 100644 --- a/.github/workflows/namespace-check.yml +++ b/.github/workflows/namespace-check.yml @@ -1,24 +1,35 @@ -# .github/workflows/namespace-check.yml - name: "Namespace Check" + +# Triggers on push event on all branches, excluding the 'prod' branch on: push: branches-ignore: - - prod + - prod # Exclude the 'prod' branch from triggering this workflow jobs: - test: - runs-on: ubuntu-latest + namespace-check: + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment + steps: - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + # Step 1: Check out the repository code + - name: Checkout code + uses: actions/checkout@v3 + + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds - - uses: actions/checkout@v3 - - uses: bahmutov/npm-install@v1 + # Step 3: Install project dependencies using Yarn + - name: Install dependencies + run: yarn + # Step 4: Build the component library in 'dist/' directory - name: Build component library in dist/ run: yarn build + # Step 5: Run the Namespace Checking script - name: Namespace Checking run: yarn namespace-check diff --git a/.github/workflows/push-tests.yml b/.github/workflows/push-tests.yml index 6ab1ee97a..99cc79d41 100644 --- a/.github/workflows/push-tests.yml +++ b/.github/workflows/push-tests.yml @@ -1,54 +1,86 @@ name: Push Tests +# Workflow event triggers on: push: branches: - - main + - main # Triggered on pushes to the 'main' branch pull_request: - branches: "*" + branches: "*" # Triggered on pull requests for any branch jobs: lint: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment steps: - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + # Step 1: Check out the repository code + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 - - uses: actions/checkout@v3 - - uses: bahmutov/npm-install@v1 + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + # Step 3: Install project dependencies using Yarn + - name: Install dependencies + run: yarn + + # Step 4: Build the component library in 'dist/' directory - name: Build component library in dist/ run: yarn build + # Step 5: Run linting - name: Lint - run: | - yarn lint + run: yarn lint test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - name: Run Tests - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + # Step 1: Check out the repository code + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds - - uses: actions/checkout@v3 - - uses: bahmutov/npm-install@v1 + # Step 3: Install project dependencies using Yarn + - name: Install dependencies + run: yarn + # Step 4: Run tests - name: Test - run: | - yarn test + run: yarn test build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + # Step 1: Check out the repository code + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 - - uses: actions/checkout@v3 - - uses: bahmutov/npm-install@v1 + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + # Step 3: Install project dependencies using Yarn + - name: Install dependencies + run: yarn + + # Step 4: Build - name: Build - run: | - yarn build + run: yarn build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a62c8a8b9..b4782f3d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,6 @@ name: Release + +# triggers on pushes to the 'prod' branch on: push: # NOTE(thuang): Since REGEX is not supported for branches, we cannot target @@ -6,89 +8,177 @@ on: # .releaserc.js. So we'll need to manually add such branch's name here manually branches: - prod - - next - - next-major - - beta - - alpha jobs: + # Job 1 release: name: Release - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment + steps: + # Step 1: Check out the repository code - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Setup Node.js + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js and Cache yarn uses: actions/setup-node@v3 with: - node-version-file: ".node-version" + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + # Step 3: Set up npm and authentication - name: "Setup npm" run: | - npm set registry=//registry.npmjs.org/:_authToken=${NPM_TOKEN} - npm set "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v2 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: "**/node_modules" - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- + npm set "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + # Step 4: Ensure npm access + - name: Ensure NPM access + run: npm whoami + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + # Step 5: Install project dependencies using Yarn - name: Install dependencies - if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn ci + # Step 6: Build the component library in 'dist/' directory - name: Build component library in dist/ run: yarn build - - name: Bump Prod Version Graduate - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - continue-on-error: true - id: graduateRelease + # Step 7: Configure git user for pushing release changes back to prod branch + - name: Config git user run: | - git config user.name "${{ github.actor }}" - git config user.email "${{ github.actor}}@users.noreply.github.com" - yarn lerna-version + git config --global user.name "${{ github.actor }}" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" - - name: Bump Prod Version Fallback + # Step 8: Lerna Version + - name: Lerna Version env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - if: ${{ always() && steps.graduateRelease.outcome == 'failure' }} - run: | - git config user.name "${{ github.actor }}" - git config user.email "${{ github.actor}}@users.noreply.github.com" - echo Falling back to non-graduate release due to https://github.com/lerna/lerna/issues/2532 - git stash - yarn lerna-version-fallback + run: yarn version:ci + # Step 9: Commit changes - name: Commit changes env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} uses: stefanzweifel/git-auto-commit-action@v4 with: + commit_message: "chore(release): Publish" branch: ${{ github.head_ref }} + # Step 10: Publish NPM packages - name: Lerna Publish env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - run: yarn release + run: yarn publish:ci + # Step 11: Post breaking changes to a Slack channel - name: Post breaking changes to a Slack channel env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_URL: ${{ secrets.SDS_BREAKING_CHANGES_SLACK_WEBHOOK }} uses: act10ns/slack@v1 with: status: complete - config: .github/workflows/slack-breaking-changes.yml - if: contains(payload.commits.*.message, 'breaking changes') + channel: "#sci-design-system-breaking-changes" + config: .github/config/slack.yml + if: contains(toJson(github.event.commits.*.message), 'BREAKING CHANGE') + + # Step 12: Merge prod branch into main + - name: Create PR to merge prod into main + id: createpr + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/github-script@v6 + with: + script: | + const ownerAndRepo = '${{ github.repository }}'; + const [owner, repo] = ownerAndRepo.split('/'); + const head = "prod"; + const base = "main"; + const title = "feat: Merge prod into main"; + const pr = await github.rest.pulls.list({owner, repo, base, head: `${owner}:${head}`}) + if (pr.data.length>0) { + return pr.data[0].number; + } + const result = await github.rest.pulls.create({ + owner, + repo, + head, + base, + title, + }); + return result.data.number; + + # Steps 13 - 15 are temporarily disable until we find a solution + # to the issue of GitHub Actions not being able to merge PRs + + # Step 13: Automerge PR + # - name: Enable Automerge PR + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # uses: peter-evans/enable-pull-request-automerge@v3 + # with: + # pull-request-number: ${{steps.createpr.outputs.result}} + # merge-method: squash + + # Step 14: Generate token for autoapproving PR + # - name: Generate token + # id: generate_token + # uses: chanzuckerberg/github-app-token@v1.1.4 + # with: + # app_id: ${{ secrets.CZI_GITHUB_HELPER_APP_ID }} + # private_key: ${{ secrets.CZI_GITHUB_HELPER_PK }} + + # Step 15: Autoapprove PR + # - name: Autoapprove PR + # run: gh pr review --approve "${{steps.createpr.outputs.result}}" + # env: + # GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + + # Job 2 + create-version-matrix: + needs: release + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + # Step 1: Check out the repository code + - name: Checkout Repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: prod + + # Step 2: Create a matrix of package versions and names + - name: Create Versions Matrix + id: set-matrix + run: | + matrix="[" + for package_json in $(find ./packages -name package.json); do + version=$(jq -r .version "$package_json") + name=$(jq -r .name "$package_json") + matrix="${matrix}{\"name\":\"${name}\", \"version\":\"${version}\"}," + done + matrix="${matrix%,}" # Remove trailing comma + matrix="${matrix}]" # Close the JSON array + echo "matrix=${matrix}" >> $GITHUB_OUTPUT + + # Job 3 + create-github-release: + needs: create-version-matrix + runs-on: ubuntu-latest + strategy: + matrix: + cfg: ${{fromJson(needs.create-version-matrix.outputs.matrix)}} + steps: + # Step 1: Create a GitHub release for the latest version + - name: Release + uses: softprops/action-gh-release@v1 + with: + tag_name: "${{ matrix.cfg.name }}@${{ matrix.cfg.version }}" diff --git a/.github/workflows/storybook-tests.yml b/.github/workflows/storybook-tests.yml index c8e889674..673b4dbd3 100644 --- a/.github/workflows/storybook-tests.yml +++ b/.github/workflows/storybook-tests.yml @@ -1,30 +1,51 @@ -# .github/workflows/storybook-tests.yml - name: "Storybook Tests" + +# Triggers on push to all branches, excluding the 'prod' branch on: push: branches-ignore: - - prod + - prod # Exclude the 'prod' branch from triggering this workflow jobs: test: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment + steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + # Step 1: Check out the repository code + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 with: - node-version-file: ".node-version" + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + + # Step 3: Install project dependencies using Yarn - name: Install dependencies run: yarn + + # Step 4: Install Playwright for testing - name: Install Playwright run: npx playwright install --with-deps + + # Step 5: Build Storybook - name: Build Storybook run: yarn build-storybook --quiet - - name: Run accessibility tests 🤟 + + # Step 6: Run accessibility tests on Storybook + - name: Run accessibility tests run: yarn storybook:axeOnly + + # Step 7: Serve Storybook and run tests concurrently - name: Serve Storybook and run tests + # (Node version >= 18) it's now necessary to explicitly + # declare the IP address (127.0.0.1) in this context. run: | npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \ "npx http-server docs-build --port 6006 --silent" \ - "npx wait-on tcp:6006 && yarn test-storybook" + "npx wait-on tcp:127.0.0.1:6006 && yarn test-storybook" diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index bd09ba4ad..a29dc6670 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -1,28 +1,40 @@ -# Doc: https://dev.to/kouts/deploy-storybook-to-github-pages-3bij name: Build and Deploy + +# Triggers on pushes to the 'main' branch on: push: branches: - main + jobs: build-and-deploy: - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Use the latest version of the Ubuntu runner environment + steps: - - name: Checkout 🛎️ + # Step 1: Check out the repository code + - name: Checkout repository uses: actions/checkout@v3 with: - persist-credentials: false - - uses: actions/setup-node@v3 + fetch-depth: 0 + + # Step 2: Set up Node.js environment and cache Yarn dependencies + - name: Setup Node.js + uses: actions/setup-node@v3 with: - node-version-file: ".node-version" - - name: Install and Build 🔧 - run: | # Install npm packages and build the Storybook files - yarn install + node-version-file: ".node-version" # Specify the Node.js version from '.node-version' file + cache: "yarn" # Cache Yarn dependencies for faster builds + + # Step 3: Install npm packages and build the Storybook files + - name: Install and Build + run: | + yarn yarn build-storybook - - name: Deploy 🚀 + + # Step 4: Deploy to GitHub Pages using the 'github-pages-deploy-action' + - name: Deploy uses: JamesIves/github-pages-deploy-action@v4 with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Authenticate using the GitHub token BRANCH: gh-pages # The branch the action should deploy to. FOLDER: docs-build # The folder that the build-storybook script generates files. CLEAN: true # Automatically remove deleted files from the deploy branch diff --git a/.node-version b/.node-version index d9289897d..a9d087399 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -16.15.1 +18.19.0 diff --git a/.storybook/main.js b/.storybook/main.js index 73fc484f5..26c51641b 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,3 +1,4 @@ +import { dirname, join } from "path"; const path = require("path"); const toPath = (filePath) => path.join(process.cwd(), filePath); module.exports = { @@ -28,15 +29,15 @@ module.exports = { "../packages/data-viz/src/**/*.stories.@(js|jsx|ts|tsx)", ], addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-interactions", - "@storybook/addon-a11y", - "@storybook/react", - "storybook-addon-pseudo-states", + getAbsolutePath("@storybook/addon-links"), + getAbsolutePath("@storybook/addon-essentials"), + getAbsolutePath("@storybook/addon-interactions"), + getAbsolutePath("@storybook/addon-a11y"), + getAbsolutePath("@storybook/react"), + getAbsolutePath("storybook-addon-pseudo-states"), ], framework: { - name: "@storybook/react-webpack5", + name: getAbsolutePath("@storybook/react-webpack5"), options: {}, }, webpackFinal: async (config) => { @@ -62,3 +63,10 @@ module.exports = { autodocs: false, }, }; +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value) { + return dirname(require.resolve(join(value, "package.json"))); +} diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html index f5039bb6e..37555a6a0 100644 --- a/.storybook/manager-head.html +++ b/.storybook/manager-head.html @@ -10,6 +10,7 @@ SDS Design System