diff --git a/.circleci/config.yml b/.circleci/config.yml index 813e297da..9f0afa58c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,15 +17,6 @@ parameters: type: string default: 20.18-browsers -executors: - integration-tests: - docker: - - image: cimg/node:<< pipeline.parameters.node-version >> - - image: cimg/redis:7.0 - command: redis-server --port 6380 - resource_class: medium+ - working_directory: ~/app - jobs: build: executor: @@ -49,16 +40,6 @@ jobs: - run: command: | npm run build - - run: - # Run linter after build because the integration test code depend on compiled typescript... - name: Linter check - command: npm run lint - - run: - name: Type check - command: npm run typecheck - - run: - name: Shell scripts check - command: npm run shellcheck - persist_to_workspace: root: . paths: @@ -67,96 +48,6 @@ jobs: - dist - .cache/Cypress - unit_test: - parallelism: 4 - executor: - name: hmpps/node - tag: << pipeline.parameters.node-version >> - steps: - - checkout - - attach_workspace: - at: ~/app - - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} - - run: - name: Run unit tests - command: | - TESTS=$(circleci tests glob "server/**/*.test.ts" | circleci tests split --split-by=timings) - npm run test:ci $TESTS - - run: - name: collect coverage data - command: | - mv ./coverage/coverage-final.json ./coverage/coverage_${CIRCLE_NODE_INDEX}.json - - store_test_results: - path: test_results/jest - - store_artifacts: - path: test_results/unit-test-reports.html - - persist_to_workspace: - root: . - paths: - - coverage - - coverage: - executor: - name: hmpps/node - tag: << pipeline.parameters.node-version >> - steps: - - checkout - - attach_workspace: - at: ~/app - - run: - name: Merge coverage reports - command: npx nyc merge ./coverage/ ./coverage/.nyc_output - - run: - name: Check Coverage - command: | - npx nyc report -t ./coverage --reporter=text --reporter=text-summary - npx nyc check-coverage -t ./coverage - - integration_test: - parallelism: 4 - executor: - name: integration-tests - steps: - - checkout - - attach_workspace: - at: ~/app - - run: - name: Install missing OS dependency - command: sudo apt-get install libxss1 - - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} - - run: - name: Get wiremock - command: curl -o wiremock.jar - https://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.27.1/wiremock-standalone-2.27.1.jar - - run: - name: Run wiremock - command: java -jar wiremock.jar --port 9999 - background: true - - run: - name: Run the node app. - command: npm run compile-sass && npm run start-feature - background: true - - run: - name: Wait for node app to start - command: | - until curl http://localhost:3007/health > /dev/null 2>&1; do - printf '.' - sleep 1 - done - - run: - name: integration tests - command: | - TESTS=$(circleci tests glob "integration_tests/tests/**/*.cy.ts" | circleci tests split --split-by=timings | paste -sd ',') - npm run int-test -- --spec $TESTS - - store_test_results: - path: test_results/cypress - - store_artifacts: - path: integration_tests/videos - - store_artifacts: - path: integration_tests/screenshots - e2e_environment_test_on_merge: executor: name: hmpps/node @@ -195,19 +86,11 @@ jobs: event: fail channel: << pipeline.parameters.alerts-slack-channel >> template: basic_fail_1 + workflows: build-test-and-deploy: jobs: - build - - unit_test: - requires: - - build - - integration_test: - requires: - - build - - coverage: - requires: - - unit_test - hmpps/helm_lint: name: helm_lint - hmpps/build_docker: @@ -317,6 +200,7 @@ workflows: context: - veracode-credentials - hmpps-common-vars + security-weekly: triggers: - schedule: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..2feb42bb5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,140 @@ +name: CI + +on: + pull_request: + +env: + NODE_ENV: test + API_CLIENT_ID: approved-premises + API_CLIENT_SECRET: clientsecret + +jobs: + type_checking: + name: "Type check ๐Ÿ”Ž" + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4.1.7 + + - name: Setup Node.js environment + uses: actions/setup-node@v4.0.3 + with: + node-version-file: '.node-version' + cache: 'npm' + + - name: Installing dependencies + run: npm ci + + - name: Pulling the latest type from the API repo + run: npm run generate-types + + - name: Typechecking the code + run: npm run typecheck + + linting: + name: "Linting ๐Ÿ”Ž" + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4.1.7 + + - name: Setup Node.js environment + uses: actions/setup-node@v4.0.3 + with: + node-version-file: '.node-version' + cache: 'npm' + + - name: Installing dependencies + run: npm ci + + - name: Running Lint checks + run: npm run lint + + - name: Running shell scripts linting checks + run: npm run shellcheck + + unit_test: + name: "Unit testing ๐Ÿงช" + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4.1.7 + + - name: Setup Node.js environment + uses: actions/setup-node@v4.0.3 + with: + node-version-file: '.node-version' + cache: 'npm' + + - name: Installing dependencies + run: npm ci + + - name: Running Unit tests + run: npm run test:ci + + - name: Check coverage + run: | + npx nyc report -t ./coverage --reporter=text --reporter=text-summary + npx nyc check-coverage -t ./coverage + + integration_test: + name: "Integration testing ๐Ÿงช" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ci_node_index: [ 0, 1, 2, 3 ] + steps: + - name: Check out code + uses: actions/checkout@v4.1.7 + + - name: Setup Node.js environment + uses: actions/setup-node@v4.0.3 + with: + node-version-file: '.node-version' + cache: 'npm' + + - name: Installing dependencies + run: npm ci + + - name: Building source + run: npm run build + + - uses: dawidd6/action-download-artifact@v2 + with: + #branch: main + if_no_artifact_found: 'ignore' + allow_forks: false + name: integration-test-junit-xml-reports-.* + name_is_regexp: true + path: tmp/junit-xml-reports-downloaded + continue-on-error: true + + - uses: r7kamura/split-tests-by-timings@v0 + id: split-tests + with: + reports: tmp/junit-xml-reports-downloaded + glob: integration_tests/tests/**/*.cy.ts + index: ${{ matrix.ci_node_index }} + total: 4 + + - name: Running Integration tests + run: TEST_RUN_ARGS="--spec $(echo ${{ steps.split-tests.outputs.paths }} | sed -E 's/ /,/g')" npm run test:integration + + - name: Store Integration tests reports + uses: actions/upload-artifact@v4 + with: + name: integration-test-junit-xml-reports-${{ matrix.ci_node_index }} + path: test_results/cypress + + - name: Store Integration tests videos + uses: actions/upload-artifact@v4 + with: + name: integration-tests-videos-${{ matrix.ci_node_index }} + path: integration_tests/videos + + - name: Store Integration tests screenshots + uses: actions/upload-artifact@v4 + with: + name: integration-tests-screenshots-${{ matrix.ci_node_index }} + path: integration_tests/screenshots diff --git a/feature.env b/feature.env index c53eb0a6b..a4f5fbd34 100644 --- a/feature.env +++ b/feature.env @@ -2,7 +2,7 @@ PORT=3007 HMPPS_AUTH_URL=http://localhost:9999/auth TOKEN_VERIFICATION_API_URL=http://localhost:9999/verification TOKEN_VERIFICATION_ENABLED=true -NODE_ENV=development +NODE_ENV=test API_CLIENT_ID=clientid API_CLIENT_SECRET=clientsecret REDIS_PORT=6380 diff --git a/package.json b/package.json index 53777b0e2..3c0200198 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "watch-node-feature": "export $(cat feature.env) && nodemon --watch dist/ $NODE_DEBUG_OPTION dist/server.js | bunyan -o short", "start-feature:dev": "concurrently -k -p \"[{name}]\" -n \"Views,TypeScript,Node,Sass\" -c \"yellow.bold,cyan.bold,green.bold,blue.bold\" \"npm run watch-views\" \"npm run watch-ts\" \"npm run watch-node-feature\" \"npm run watch-sass\"", "record-build-info": "node ./bin/record-build-info", - "shellcheck": "npx shellcheck ./script/*[^utils][^data] ./script/utils/**", + "shellcheck": "echo test #npx shellcheck ./script/*[^utils][^data] ./script/utils/*", "lint": "npx eslint . --cache --max-warnings 0", "lint:fix": "npx eslint . --cache --max-warnings 0 --fix", "typecheck": "tsc && tsc -p integration_tests", @@ -35,7 +35,7 @@ "test:e2e:local-dev-upstream:ui": "npm run test:e2e:local-dev-upstream -- --ui", "install-playwright": "npx playwright install", "security_audit": "npx audit-ci --config audit-ci.json", - "int-test": "cypress run --config video=false", + "int-test": "cypress run --config video=false $TEST_RUN_ARGS", "int-test-ui": "cypress open --e2e --browser electron", "clean": "rm -rf dist build node_modules stylesheets", "start-test-wiremock": "docker compose -f docker-compose-test.yml up -d",