.circleci/config.yml

Summary

Maintainability
Test Coverage
version: 2.1

orbs:
  browser-tools: circleci/browser-tools@1.4.4

# Configuration
job_defaults_var: &job_defaults
  working_directory: ~/workspace/app
  docker:
    - image: cimg/node:18.16.0-browsers

# Yarn cache key
cache_var: &cache_key yarn-packages-v4-{{ .Branch }}-{{ checksum "yarn.lock" }}

# Install yarn packages
yarn_install_var: &yarn_install
  run:
    name: Yarn Install Packages
    # We install deps based on the frozen yarn file, so we know it's always the same
    command: yarn install --frozen-lockfile --non-interactive

# Save yarn cache
save_cache_var: &save_cache
  save_cache:
    name: Save Yarn Package Cache and Cypress binary
    key: *cache_key
    paths:
      - ~/.cache
      - node_modules

# Restore yarn cache
restore_cache_var: &restore_cache
  restore_cache:
    name: Restore Yarn Package Cache
    keys:
      - *cache_key
      - yarn-packages-v4-master
      - yarn-packages-v4

# Persist the whole working space so we can share it between jobs
persist_workspace_var: &persist_workspace
  persist_to_workspace:
    # Must be an absolute path, or relative path from working_directory. This is a directory on the container which is
    # taken to be the root directory of the workspace.
    root: ~/workspace
    # Must be relative path from root
    paths:
      - app

# Attach working space
attach_workspace_var: &attach_workspace
  attach_workspace:
    # Must be absolute path or relative path from working_directory
    at: ~/workspace

#
# Jobs
#
jobs:
  build:
    <<: *job_defaults
    steps:
      # npm link will fail if we don't override the global install path to a path where we have right permissions
      - run:
          name: Set NPM global path
          command: echo 'prefix = ~/.npm' > ~/.npmrc
      - checkout
      - *restore_cache
      - *yarn_install
      - *save_cache
      - run:
          name: Compile NGXS
          command: yarn build
      - run:
          name: Create Pack
          command: yarn pack --filename ngxs-core.tgz
      - *persist_workspace
      - store_artifacts:
          path: ngxs-core.tgz
          destination: dist/ngxs-core.tgz

  eslint:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - run:
          name: Run ESLint analyzer
          command: yarn nx run-many --target=lint --all

  unit_tests:
    <<: *job_defaults
    environment:
      # variables used by karma to export a circleci test insights
      JUNIT_REPORT_PATH: coverage/junit/unit_tests
    steps:
      - *attach_workspace
      - run:
          name: Unit Tests
          command: yarn nx run-many --target=test --all --configuration=ci --maxWorkers=4
      - store_test_results:
          path: coverage/junit
      - store_artifacts:
          path: coverage/junit
          destination: junit
      - persist_to_workspace:
          root: ~/workspace
          paths:
            - app/coverage

  integration_tests:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - run:
          name: Integration Tests
          command: yarn test:ci:integration
      - *persist_workspace
      - store_artifacts:
          path: dist-integration
          destination: dist-integration

  cypress:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - *restore_cache
      - run:
          name: Run E2E tests
          command: yarn test:ci:e2e

  integration_ssr_tests:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - *restore_cache
      - run:
          name: Run integration tests for the SSR build application
          command: yarn test:ci:integration:ssr

  integration_ng16_tests:
    <<: *job_defaults
    steps:
      - *attach_workspace
      # https://github.com/CircleCI-Public/browser-tools-orb/issues/75
      - browser-tools/install-browser-tools:
          chrome-version: '116.0.5845.96'
          replace-existing-chrome: true
      - run:
          name: Run integration tests for ng16 application
          command: yarn integration:ng16
      - persist_to_workspace:
          root: ~/workspace
          paths:
            - app/integrations/hello-world-ng16/dist-integration

  integration_ng17_tests:
    <<: *job_defaults
    steps:
      - *attach_workspace
      # https://github.com/CircleCI-Public/browser-tools-orb/issues/75
      - browser-tools/install-browser-tools:
          chrome-version: '116.0.5845.96'
          replace-existing-chrome: true
      - run:
          name: Run integration tests for ng17 application
          command: yarn integration:ng17
      - persist_to_workspace:
          root: ~/workspace
          paths:
            - app/integrations/hello-world-ng17/dist-integration

  integration_test_types:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - run:
          name: Test types
          command: yarn test:types

  upload_coverage:
    <<: *job_defaults
    environment:
      - CC_TEST_REPORTER_ID: 3f4c9a9d57ded045e0f9ab5d23e5bbcbf709bb85637bea555f1233e72134b818
    steps:
      - *attach_workspace
      - run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > /tmp/cc-test-reporter
      - run: chmod +x /tmp/cc-test-reporter
      - run: node tools/merge-reports.js --coverageDir=coverage/packages --reporterBinaryPath=/tmp/cc-test-reporter
      - deploy:
          name: Upload coverage results to Code Climate
          command: /tmp/cc-test-reporter upload-coverage -i tmp/codeclimate-final.json

  # Publish latest build to npm under the @next tag
  publish_dev_build_to_npm:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - run:
          name: Set NPM publish token
          command: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
      - deploy:
          name: Publish development builds to all @ngxs packages
          command: yarn publish:dev

  # Publish tagged build to npm under the @latest tag
  publish_tagged_build_to_npm:
    <<: *job_defaults
    steps:
      - *attach_workspace
      - run:
          name: Set NPM publish token
          command: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
      - deploy:
          name: Publish tagged builds to all @ngxs packages
          command: yarn publish:tagged
#
# Workflow
#
workflows:
  version: 2
  build-workflow:
    jobs:
      # Run build for all branches and tags
      - build:
          filters:
            tags:
              only: /.*/

      - eslint:
          requires:
            - build

      - unit_tests:
          requires:
            - build

      ### - integration_tests:
      ###     requires:
      ###       - build
      ###
      ### - cypress:
      ###     requires:
      ###       - integration_tests
      ###
      ### - integration_ssr_tests:
      ###     requires:
      ###       - build

      - integration_ng16_tests:
          requires:
            - build

      - integration_test_types:
          requires:
            - build

      - upload_coverage:
          requires:
            - unit_tests
            ### - integration_tests
            ### - integration_ssr_tests
            - integration_test_types

      # Publish @dev builds if no tag is specified
      - publish_dev_build_to_npm:
          filters:
            branches:
              only:
                - master
            tags:
              ignore: /.*/
          requires:
            - unit_tests
            ### - integration_tests
            ### - integration_ssr_tests
            - integration_test_types

      # Publish package.version @latest when a v.* git tag is present
      - publish_tagged_build_to_npm:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
          requires:
            - unit_tests
            ### - integration_tests
            ### - integration_ssr_tests
            - integration_test_types