Skip to content

Commit

Permalink
Merge pull request #2171 from ministryofjustice/CHORE/github-actions-…
Browse files Browse the repository at this point in the history
…pipeline

Move PR tests to GitHub Actions
  • Loading branch information
froddd authored Feb 3, 2025
2 parents a33e15c + d8e4f95 commit bb6d84c
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 121 deletions.
120 changes: 2 additions & 118 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -317,6 +200,7 @@ workflows:
context:
- veracode-credentials
- hmpps-common-vars

security-weekly:
triggers:
- schedule:
Expand Down
145 changes: 145 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
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/[email protected]

- name: Setup Node.js environment
uses: actions/[email protected]
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/[email protected]

- name: Setup Node.js environment
uses: actions/[email protected]
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/[email protected]

- name: Setup Node.js environment
uses: actions/[email protected]
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/[email protected]

- name: Setup Node.js environment
uses: actions/[email protected]
with:
node-version-file: '.node-version'
cache: 'npm'

- name: Installing dependencies
run: npm ci

- name: Building source
run: npm run build

- name: Downloading test reports from previous runs
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

- name: Determining tests splitting by timing
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: Fix Cypress JUnit XML reports
run: script/fix-cypress-junit-xml

- 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
2 changes: 1 addition & 1 deletion feature.env
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "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",
Expand All @@ -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",
Expand Down
23 changes: 23 additions & 0 deletions script/fix-cypress-junit-xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

# script/fix-cypress-junit-xml: adds the `file` attribute found in the 'Root Suite' testsuite node to all other
# testuite nodes, so the split-test utility can correctly identify test run times.

# Directory containing Junit XML files
directory="./test_results/cypress"

cd "$(dirname "$0")/.." || exit

# Iterate over all XML files in the directory
find "$directory" -name "*.xml" | while read -r xml_file; do
# Extract the 'file' attribute (from the "Root Suite" testsuite)
file=$(grep -o 'file="[^"]*"' "$xml_file")

# If the 'file' attribute was found, apply it to all other testsuite nodes
if [ -n "$file" ]; then
# Use sed to add the 'file' attribute to all testsuite nodes except 'Root Suite'
sed -i'' -e "/<testsuite [^>]*name=\"Root Suite\"[^>]*>/!s|<testsuite |<testsuite $file |" "$xml_file"
else
echo "No 'file' attribute found in $xml_file, skipping..."
fi
done

0 comments on commit bb6d84c

Please sign in to comment.