我的 CircleCI 测试需要一个更“干”的解决方案

问题描述

目前我有一个可用的 circleci yaml 文件,但它为每个应用程序运行一个单独的测试脚本。这不是“DRY”,我认为更好的解决方案是从根运行测试脚本并循环遍历每个应用程序......但我不知道如何做到这一点。我看过一些例子,但每当我尝试应用它们时,圆似乎都找不到三叶草文件,所以我不确定我做错了什么。我也很想并行运行所有内容,但我的首要任务是消除所有额外的步骤。

这是当前设置:

文件系统结构:

- apps
  - **app1**
    - coverage
      - clover.xml
      - coverage-final.json
    - src
      - test-files
    package.json
  - **app2**
    - coverage
      - clover.xml
      - coverage-final.json
    - src
      - test-files
    package.json
  - **app3**
    - coverage
      - clover.xml
      - coverage-final.json
    - src
      - test-files
    package.json
- package.json

root/package.json 脚本

{
  "scripts": {
    "lint": "lerna run lint --concurrency=2","build": "lerna run build --concurrency=1 --stream","bootstrap:ci": "lerna bootstrap --ci --concurrency=2"
    "test": "CI=true lerna run test:coverage --concurrency=2 --stream -- --coverage","test:app1": "cd apps/enhanced-date-editor && npm run test:coverage","test:app2": "cd apps/input-fields-group && npm run test:coverage","test:app3": "cd apps/markdown-items-list && npm run test:coverage",},"devDependencies": {
    "lerna": "^3.22.1"
  }
}

app[1/2/3]/package.json 脚本

{
  "scripts": {
    "build": "react-scripts build","test": "react-scripts test","test:coverage": "npm t -- --coverage","deploy": "s3 bucket script","jest": {
    "collectCoverageFrom": [
      "**/*.{js,jsx,tsx}","!**/node_modules/**","!**/vendor/**"
    ]
  }
}

circleci/config.yml

version: 2.1
executors:
  node:
    docker:
      - image: cimg/node:14.15.4

jobs:
  prepare:
    executor: node
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: |
            npm i
            npm run bootstrap:ci
      - persist_to_workspace:
          root: .
          paths:
            - .

  lint:
    executor: node
    steps:
      - attach_workspace:
          at: .
      - run:
          name: lint
          command: npm run lint
  test-reporter:
    executor: node
    steps:
      - run:
          name: Setup Code climate test-reporter
          command: |
            # download test reporter as a static binary
            mkdir -p testing-workspace/test-results/coverage
            curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > testing-workspace/cc-test-reporter
            chmod +x testing-workspace/cc-test-reporter
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - cc-test-reporter
  test-app1:
    executor: node
    steps:
      - attach_workspace:
          at: .
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: Testing and formatting for codeclimate
          command: |
            testing-workspace/cc-test-reporter before-build
            npm run test:app1
            testing-workspace/cc-test-reporter format-coverage \
              "apps/app1/coverage/clover.xml" \
              --input-type clover \
              --output testing-workspace/test-results/coverage/coverage.app1.json
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - test-results/coverage/coverage.app1.json
  test-app2:
    executor: node
    steps:
      - attach_workspace:
          at: .
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: Testing and formatting for codeclimate
          command: |
            testing-workspace/cc-test-reporter before-build
            npm run test:app2
            testing-workspace/cc-test-reporter format-coverage \
              "apps/app2/coverage/clover.xml" \
              --input-type clover \
              --output testing-workspace/test-results/coverage/coverage.app2.json
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - test-results/coverage/coverage.app2.json
  test-app3:
    executor: node
    steps:
      - attach_workspace:
          at: .
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: Testing and formatting for codeclimate
          command: |
            testing-workspace/cc-test-reporter before-build
            npm run test:app3
            testing-workspace/cc-test-reporter format-coverage \
              "apps/app3/coverage/clover.xml" \
              --input-type clover \
              --output testing-workspace/test-results/coverage/coverage.app3.json
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - test-results/coverage/coverage.app3.json
  ship-all-the-test-results:
    executor: node
    steps:
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: sum coverage
          command: testing-workspace/cc-test-reporter sum-coverage -o testing-workspace/test-results/coverage/coverage.total.json testing-workspace/test-results/coverage/coverage.*.json;
      - run:
          name: ship results to code climate
          command: testing-workspace/cc-test-reporter upload-coverage --input testing-workspace/test-results/coverage/coverage.total.json
      - store_artifacts:
          path: testing-workspace/test-results
          destination: test-results
      - store_test_results:
          path: testing-workspace/test-results
workflows:
  build-test-deploy:
    jobs:
      - prepare
      - lint:
          requires:
            - prepare
      - test-reporter:
          requires:
            - lint
      - test-app1:
          requires:
            - test-reporter
      - test-app2:
          requires:
            - test-reporter
      - test-app3:
          requires:
            - test-reporter
      - ship-all-the-test-results:
          requires:
            - test-app1
            - test-app2
            - test-app3

我尝试过的例子

testing-workspace/cc-test-reporter before-build
npm run test
testing-workspace/cc-test-reporter format-coverage apps/**/coverage/clover.xml --input-type clover --output apps/**/coverage/coverage-final.json
testing-workspace/cc-test-reporter sum-coverage apps/**/coverage/coverage-final.json --output testing-workspace/test-results/coverage/codeclimate.total.json
testing-workspace/cc-test-reporter upload-coverage --input testing-workspace/test-results/coverage/coverage.total.json
testing-workspace/cc-test-reporter after-build --exit-code $?

错误 git head does not match

我尝试过的另一个例子

#!/bin/bash -eo pipefail
# notify codeclimate that a build is coming
testing-workspace/cc-test-reporter before-build
# run tests
# will receive a list of test files and the CircleCI CLI will split them by timing data.
TESTFILES=$(circleci tests glob "apps/**.js" | circleci tests split)
npm run test ${TESTFILES}
# format test results
testing-workspace/cc-test-reporter format-coverage "**/**/clover.xml" --input-type clover --output "apps/**/coverage/coverage-final.json"
# combine test results
testing-workspace/cc-test-reporter sum-coverage -o testing-workspace/test-results/coverage/coverage.total.json "apps/**/coverage/coverage-final.json"
# upload test results to codeclimate
testing-workspace/cc-test-reporter upload-coverage --input testing-workspace/test-results/coverage/coverage.total.json
# notify codeclimate that build is completed
testing-workspace/cc-test-reporter after-build --exit-code $?

错误是```找不到覆盖文件//clover.xml 在三叶草的搜索路径中找不到任何文件搜索路径为://clover.xml、build/logs/clover.xml、clover.xml``

解决方法

CircleCI 配置语法中没有循环,但您可以通过将应用的参数添加到您的测试应用作业来使配置更加 DRY。

version: 2.1
executors:
  node:
    docker:
      - image: cimg/node:14.15.4

jobs:
  prepare:
    executor: node
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: |
            npm i
            npm run bootstrap:ci
      - persist_to_workspace:
          root: .
          paths:
            - .

  lint:
    executor: node
    steps:
      - attach_workspace:
          at: .
      - run:
          name: lint
          command: npm run lint
  test-reporter:
    executor: node
    steps:
      - run:
          name: Setup Code Climate test-reporter
          command: |
            # download test reporter as a static binary
            mkdir -p testing-workspace/test-results/coverage
            curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > testing-workspace/cc-test-reporter
            chmod +x testing-workspace/cc-test-reporter
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - cc-test-reporter
  test-app:
    executor: node
    parameters:
      app_name:
        type: string
    steps:
      - attach_workspace:
          at: .
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: Testing and formatting for codeclimate
          command: |
            testing-workspace/cc-test-reporter before-build
            npm run test:<< parameters.app_name >>
            testing-workspace/cc-test-reporter format-coverage \
              "apps/<< parameters.app_name >>/coverage/clover.xml" \
              --input-type clover \
              --output testing-workspace/test-results/coverage/coverage.<< parameters.app_name >>.json
      - persist_to_workspace:
          root: testing-workspace
          paths:
            - test-results/coverage/coverage.<< parameters.app_name >>.json
  ship-all-the-test-results:
    executor: node
    steps:
      - attach_workspace:
          at: ~/project/testing-workspace
      - run:
          name: sum coverage
          command: testing-workspace/cc-test-reporter sum-coverage -o testing-workspace/test-results/coverage/coverage.total.json testing-workspace/test-results/coverage/coverage.*.json;
      - run:
          name: ship results to code climate
          command: testing-workspace/cc-test-reporter upload-coverage --input testing-workspace/test-results/coverage/coverage.total.json
      - store_artifacts:
          path: testing-workspace/test-results
          destination: test-results
      - store_test_results:
          path: testing-workspace/test-results
workflows:
  build-test-deploy:
    jobs:
      - prepare
      - lint:
          requires:
            - prepare
      - test-reporter:
          requires:
            - lint
      - test-app:
          name: test-app1
          app_name: app1
          requires:
            - test-reporter
      - test-app:
          name: test-app2
          app_name: app2
          requires:
            - test-reporter
      - test-app:
          name: test-app3
          app_name: app3
          requires:
            - test-reporter
      - ship-all-the-test-results:
          requires:
            - test-app1
            - test-app2
            - test-app3