Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions .github/actions/init-mise/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@ runs:
cache: true
install: true

- name: Cache node_modules
- name: Cache bun install
uses: actions/cache@v5
with:
path: |
node_modules
ui/node_modules
lambdas/node_modules
tests/node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
path: ~/.bun/install/cache
key: bun-cache-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
restore-keys: |
node-modules-${{ runner.os }}-
bun-cache-${{ runner.os }}-

- name: Install npm dependencies
- name: Install bun dependencies
shell: bash
run: |
echo "::group::Install npm dependencies"
echo "::group::Install bun dependencies"
mise run install-npm
echo "::endgroup::"
4 changes: 2 additions & 2 deletions .github/actions/run-npm-tests/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: "Run NPM Tests"
description: "Run Jest tests with coverage reporting"
inputs:
working-directory:
description: "Directory containing the npm project (e.g., ui, lambdas)"
description: "Directory containing the project (e.g., ui, lambdas)"
required: true
nodejs-version:
description: "Node.js version to use"
Expand All @@ -27,7 +27,7 @@ runs:
steps:
- name: "Run test suite"
shell: bash
run: mise exec -- npm --prefix ${{ inputs.working-directory }} run test -- --ci
run: mise exec -- bun run --cwd ${{ inputs.working-directory }} test --ci
env:
FORCE_COLOR: true

Expand Down
28 changes: 14 additions & 14 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<!-- vale Vale.Terms = NO -->

`hometest-service` is an NHS England service that allows patients to order self-test HIV kits at home. It is a TypeScript monorepo with four independent packages. Each has its own `package.json` and is installed separately via `npm --prefix` — this is **not** an npm workspaces setup.
`hometest-service` is an NHS England service that allows patients to order self-test HIV kits at home. It is a TypeScript monorepo with four independent packages. Each has its own `package.json` and is installed separately via `bun install --cwd` — this is **not** a bun workspaces setup.

<!-- vale Vale.Terms = YES -->

Expand Down Expand Up @@ -109,37 +109,37 @@ local-environment/ Docker Compose + LocalStack + Terraform for local dev

```bash
# Install all workspace dependencies (also installs ui/, lambdas/, tests/ via postinstall)
npm ci
bun install

# Build and package lambdas (required before first start or after lambda changes)
npm run build:lambdas
npm run package:lambdas
bun run build:lambdas
bun run package:lambdas

# Start the full local environment (Docker + LocalStack + Terraform deploy + UI)
npm start
bun start

# Stop the local environment and destroy Terraform state
npm run stop
bun run stop

# Restart the local environment
npm run local:restart
bun run local:restart

# Start only the backend (Docker + DB migration)
npm run local:backend:start
bun run local:backend:start

# Start only the frontend (Docker UI container)
npm run local:frontend:start
bun run local:frontend:start

# Run all unit tests (ui + lambdas)
npm test
bun test

# Run Playwright tests (reads URLs from Terraform outputs)
npm run test:playwright
bun run test:playwright

# Individual service controls
npm run local:service:db:start # start Postgres only
npm run local:service:db:migrate # run DB migrations
npm run local:service:localstack:start # start LocalStack only
bun run local:service:db:start # start Postgres only
bun run local:service:db:migrate # run DB migrations
bun run local:service:localstack:start # start LocalStack only
```

## Review Philosophy
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/playwright-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ jobs:

- name: "Install Playwright browsers"
working-directory: tests
run: npx playwright install --with-deps
run: bunx playwright install --with-deps

- name: "Start the application"
run: |
npm run start
bun run local:start

- name: "Show application status"
run: |
Expand Down Expand Up @@ -112,7 +112,7 @@ jobs:
FILTER="${{ inputs.test_filter }}"

# Build the command
CMD="npx playwright test"
CMD="bunx playwright test"

# Add browser project
if [ "$BROWSER" != "all" ]; then
Expand Down
21 changes: 18 additions & 3 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
[settings]
locked = true
lockfile = true
install_before = "7d"

[settings.python]
compile = false

# Disable to avoid calling Github API
[settings.aqua]
cosign = false

[tools]
# Custom registries are not included in mise-versions
# https://mise-versions.jdx.dev/
Expand All @@ -28,7 +36,7 @@ terraform-docs = "0.22.0"
awscli = "2.34.26"

# https://devguide.python.org/versions/
python = "3.14.3"
python = "3.14.2"

## Security scanning

Expand All @@ -54,10 +62,17 @@ vale = "3.14.1"
# https://nodejs.org/en/download/releases
node = "24.14.1"

# https://github.com/oven-sh/bun/releases
bun = "1.3.12"

[tasks.pre-commit]
description = "Run pre-commit checks on all files"
run = "pre-commit run --all-files --show-diff-on-failure --color=always"

[tasks.pre-commit-main]
description = "Run pre-commit checks on all files comparing to main"
run = "pre-commit run --from-ref origin/main --to-ref HEAD --show-diff-on-failure --color=always"

[tasks.install-npm]
description = "Install npm dependencies"
run = "npm ci"
description = "Install bun dependencies"
run = "bun install --frozen-lockfile"
15 changes: 8 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,47 +32,47 @@ repos:

- id: prettier-formatting
name: prettier-formatting
entry: npm run format:pre-commit --
entry: bun run format:pre-commit --
language: system

- id: eslint-ui
name: ESLint (UI)
entry: npm --prefix ui run lint -- --fix
entry: bun run --cwd ui lint --fix
language: system
files: ^ui/.*\.(ts|tsx|js|jsx)$
pass_filenames: false

- id: eslint-lambdas
name: ESLint (Lambdas)
entry: npm --prefix lambdas run lint -- --fix
entry: bun run --cwd lambdas lint --fix
language: system
files: ^lambdas/.*\.(ts|js)$
pass_filenames: false

- id: eslint-tests
name: ESLint (Tests)
entry: npm --prefix tests run lint -- --fix
entry: bun run --cwd tests lint --fix
language: system
files: ^tests/.*\.(ts|js)$
pass_filenames: false

- id: check-typescript-ui
name: TypeScript (UI)
entry: npm --prefix ui run check-typescript
entry: bun run --cwd ui check-typescript
language: system
files: ^ui/.*\.(ts|tsx|js|jsx)$
pass_filenames: false

- id: check-typescript-lambdas
name: TypeScript (Lambdas)
entry: npm --prefix lambdas run check-typescript
entry: bun run --cwd lambdas check-typescript
language: system
files: ^lambdas/.*\.(ts|js)$
pass_filenames: false

- id: check-typescript-tests
name: TypeScript (Tests)
entry: npm --prefix tests run check-typescript
entry: bun run --cwd tests check-typescript
language: system
files: ^tests/.*\.(ts|js)$
pass_filenames: false
Expand All @@ -86,6 +86,7 @@ repos:
entry: yamllint
language: python
types: [file, yaml]
exclude: bun.lock

# Markdown linting
- repo: https://github.com/igorshubovych/markdownlint-cli
Expand Down
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dependency directories
node_modules/
package-lock.json
pnpm-lock.yaml

Comment on lines 1 to 4
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.prettierignore no longer ignores package-lock.json, but the repo still contains multiple package-lock.json files (root/ui/lambdas/tests), so Prettier hooks may waste time or create unwanted churn on lockfiles. Add package-lock.json (and Bun lockfiles like bun.lock* if applicable) back to the ignore list, or remove the lockfiles as part of the migration.

Copilot uses AI. Check for mistakes.
# Environment & runtime files
.env
Expand Down
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ infrastructure-as-code.
4. Install dependencies for the root, lambdas, and tests, start the local development environment

```shell
npm install && npm --prefix ./lambdas install
npm run start
bun install
bun run start
```

### Prerequisites
Expand Down Expand Up @@ -83,7 +83,7 @@ mise run pre-commit # Run the pre-commit task defined in .mise.toml
To spin up the entire local environment (LocalStack, Postgres, and the Next.js Frontend):

```shell
npm start
bun start
```

This command:
Expand All @@ -95,49 +95,49 @@ This command:
To stop the environment:

```shell
npm run stop
bun run stop
```

### Common local workflows

After running `npm start`, use targeted commands instead of restarting everything:
After running `bun start`, use targeted commands instead of restarting everything:

- **Lambda code changes** (build/package/deploy lambdas to LocalStack):

```shell
npm run local:deploy
bun run local:deploy
```

- **Database schema or seed changes** (rerun DB migration container, including goose migrations):

```shell
npm run local:service:db:migrate
bun run local:service:db:migrate
```

- **Terraform infrastructure changes** (apply infra updates to LocalStack without restarting containers):

```shell
npm run local:terraform:apply
bun run local:terraform:apply
```

This expects the backend containers, including LocalStack, to already be running. If they are not, start them first:

```shell
npm run local:backend:start
bun run local:backend:start
```

To switch local integrations between WireMock and real upstreams, pass Terraform variables when applying - some examples below.

To only use WireMock everywhere (default mode - only needed to switch over):

```shell
TF_VAR_local_service_mode=wiremock npm run local:terraform:apply # this is the default mode, only needed to switch over
TF_VAR_local_service_mode=wiremock bun run local:terraform:apply # this is the default mode, only needed to switch over
```

To not use WireMock anywhere (real downstream APIs):

```shell
TF_VAR_local_service_mode=real npm run local:terraform:apply
TF_VAR_local_service_mode=real bun run local:terraform:apply
```

To use WireMock except for specific services, pass only the overrides you need:
Expand All @@ -147,56 +147,56 @@ After running `npm start`, use targeted commands instead of restarting everythin
TF_VAR_local_supplier_service_url_override=https://supplier.example.com \
TF_VAR_local_use_ui_auth_url_override=https://auth.sandpit.signin.nhs.uk \
TF_VAR_local_postcode_lookup_base_url_override=https://api.os.uk/search/places/v1 \
npm run local:terraform:apply # npm run local:frontend:restart - if overriding UI auth
bun run local:terraform:apply # bun run local:frontend:restart - if overriding UI auth
```

If you change UI-facing auth settings, restart the frontend so it picks up the updated `ui/.env.local` values:

```shell
npm run local:frontend:restart
bun run local:frontend:restart
```

- **Restart backend containers only** (Postgres, LocalStack, WireMock, db-migrate):

```shell
npm run local:compose -- stop postgres-db localstack wiremock
npm run local:backend:start
bun run local:compose -- stop postgres-db localstack wiremock
bun run local:backend:start
```

- **Restart frontend only**:

```shell
npm run local:frontend:restart
bun run local:frontend:restart
```

- **Start/stop backend only**:

```shell
npm run local:backend:start
npm run local:compose -- stop postgres-db localstack wiremock
bun run local:backend:start
bun run local:compose -- stop postgres-db localstack wiremock
```

- **Start/stop frontend only**:

```shell
npm run local:frontend:start
npm run local:compose -- stop ui
bun run local:frontend:start
bun run local:compose -- stop ui
```

- **Start/stop specified lambda**

```shell
LAMBDA={lambda_name} npm run local:service:lambda:enable
LAMBDA={lambda_name} npm run local:service:lambda:disable
LAMBDA={lambda_name} bun run local:service:lambda:enable
LAMBDA={lambda_name} bun run local:service:lambda:disable
```

### Frontend

The frontend is a Next.js application located in the `/ui` directory.

1. cd to `/ui` directory.
2. Run `npm install`.
3. Run `npm run dev`.
2. Run `bun install`.
3. Run `bun run dev`.

- When creating a new page, use the PageLayout component found in `/ui/src/components`.
- To create a new route, create a directory with the name of your route in `/ui/src/app`, and add a `page.tsx` file within.
Expand Down
Loading
Loading