Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
6b0f825
Move towards using URL-based env var names.
davidhamill1-nhs Apr 15, 2026
a4675a8
Resolve this TODO later.
davidhamill1-nhs Apr 15, 2026
0202c90
Broaden vocabulary.
davidhamill1-nhs Apr 15, 2026
8d2f8a1
Log the client details.
davidhamill1-nhs Apr 16, 2026
dea2c64
Use env vars and pass those through an .env file in the make deploy c…
davidhamill1-nhs Apr 16, 2026
4204308
Make number go up.
davidhamill1-nhs Apr 16, 2026
899ba50
Make number go up.
davidhamill1-nhs Apr 16, 2026
4f47fa9
Make number go up.
davidhamill1-nhs Apr 16, 2026
d80e86e
Make explicit environment variables being passed to container.
davidhamill1-nhs Apr 16, 2026
67ef071
Make mypy happy again.
davidhamill1-nhs Apr 16, 2026
b289500
Place env vars in to app config.
davidhamill1-nhs Apr 16, 2026
69a2929
Pass URLs to controller.
davidhamill1-nhs Apr 16, 2026
5268215
Remove default URLs
davidhamill1-nhs Apr 16, 2026
3cdecdb
Tidy up.
davidhamill1-nhs Apr 16, 2026
ba67227
Improve make commands to build up env files for different environments.
davidhamill1-nhs Apr 16, 2026
c54bb04
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 16, 2026
5b41732
FLASK env vars are not actually variable. Leave them hardcoded.
davidhamill1-nhs Apr 20, 2026
a2866c5
Enable test environment to be set up easily.
davidhamill1-nhs Apr 21, 2026
a0a47d3
Define shell.
davidhamill1-nhs Apr 21, 2026
e6e1c14
Inject env correctly and safely.
davidhamill1-nhs Apr 21, 2026
78663fa
Remove duplicate/unused make commands.
davidhamill1-nhs Apr 21, 2026
15528f8
Add simple logging to clients to demonstrate URLs being used.
davidhamill1-nhs Apr 21, 2026
629c53c
Remove unused pipeline env var.
davidhamill1-nhs Apr 21, 2026
405a7af
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 21, 2026
71cf237
Don't need to do some TODOs
davidhamill1-nhs Apr 21, 2026
0c29fb2
Resolve some TODOs
davidhamill1-nhs Apr 22, 2026
3dd80ff
Handle unit test enviroment variables better.
davidhamill1-nhs Apr 22, 2026
c82811f
Simplify local vs remote paths.
davidhamill1-nhs Apr 22, 2026
247881f
Always overwrite.
davidhamill1-nhs Apr 22, 2026
d850d0e
Update docs. Improve env-ci output.
davidhamill1-nhs Apr 22, 2026
c3d633f
Tidy up.
davidhamill1-nhs Apr 22, 2026
2aafbee
Place the test user in to the env variables.
davidhamill1-nhs Apr 22, 2026
928d629
Tidy up.
davidhamill1-nhs Apr 22, 2026
9290a0a
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 22, 2026
04092fd
Make linter happy.
davidhamill1-nhs Apr 22, 2026
0b7e583
More tightly define type.
davidhamill1-nhs Apr 22, 2026
bda2bb6
Doesn't seem to 'omit'
davidhamill1-nhs Apr 22, 2026
55a234b
Resolved to do.
davidhamill1-nhs Apr 22, 2026
bab15e1
Place make env file eariler in commands to run.
davidhamill1-nhs Apr 22, 2026
cff2eff
Update creation of .env.test. steps.
davidhamill1-nhs Apr 22, 2026
5fc19a2
Add an orangebox environment that would reflect env-organebox behaviour.
davidhamill1-nhs Apr 22, 2026
4082b47
Correctly print out logs.
davidhamill1-nhs Apr 22, 2026
f9be003
Make orange box test patient FHIR compliant.
davidhamill1-nhs Apr 22, 2026
5ded7c5
Update FHIR Parameters resource to include required name field.
davidhamill1-nhs Apr 22, 2026
03aff72
Add explicit return statements.
davidhamill1-nhs Apr 22, 2026
80bedaf
Add a default case for the test user - none. It should only be needed…
davidhamill1-nhs Apr 22, 2026
762b10b
Add local secret handling for int
davidhamill1-nhs Apr 23, 2026
f9f1319
Removing noise from "make deploy" output
davidhamill1-nhs Apr 23, 2026
5c99f53
Only log pertinent, non-sensitive env vars.
davidhamill1-nhs Apr 23, 2026
dd2c50b
Do not log sensitive headers.
davidhamill1-nhs Apr 23, 2026
b5445c5
clean up.
davidhamill1-nhs Apr 23, 2026
519efda
Remove env vars that did not exist before fiddling with the env vars.
davidhamill1-nhs Apr 23, 2026
057a4c4
Options not supported at this level.
davidhamill1-nhs Apr 23, 2026
548c49d
Do not log sensitive headers.
davidhamill1-nhs Apr 23, 2026
158f4c0
Stub for int environment, until 397 is worked.
davidhamill1-nhs Apr 23, 2026
c22c719
Provide useful error messages if env files do not exist.
davidhamill1-nhs Apr 23, 2026
9d39d0e
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 23, 2026
d043161
Provide explanation around the expected secrets.
davidhamill1-nhs Apr 23, 2026
7a4fc64
Correct env file check.
davidhamill1-nhs Apr 23, 2026
f84e63e
Refine logger setup; test url that instantiates the client is being u…
davidhamill1-nhs Apr 23, 2026
5d2266e
Rename class to better reflect behaviour.
davidhamill1-nhs Apr 23, 2026
3775cb5
Test url that instantiates the controller is being used on the GET re…
davidhamill1-nhs Apr 23, 2026
c98e561
Remove unused fixture.
davidhamill1-nhs Apr 23, 2026
8c5c2fe
Provider a more helpful warning.
davidhamill1-nhs Apr 23, 2026
1212296
Explain what this decorator is doing.
davidhamill1-nhs Apr 23, 2026
b02ac58
Update fixture name.
davidhamill1-nhs Apr 23, 2026
71ea523
Remove toggling of sandbox/int services
davidhamill1-nhs Apr 23, 2026
f04a489
Remove toggling of sandbox/int services
davidhamill1-nhs Apr 23, 2026
f92a196
Use [[ over [
davidhamill1-nhs Apr 27, 2026
55c5362
Make pipeline fail.
davidhamill1-nhs Apr 27, 2026
60b3c2f
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 27, 2026
67300cc
Revert "Make pipeline fail."
davidhamill1-nhs Apr 27, 2026
316efb0
update vocab.
davidhamill1-nhs Apr 27, 2026
d48aec9
Don't log headers
davidhamill1-nhs Apr 27, 2026
8c5b9d6
Merge remote-tracking branch 'origin' into debt/GPCAPIM-359-sort-out-…
davidhamill1-nhs Apr 27, 2026
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
10 changes: 0 additions & 10 deletions .env.template

This file was deleted.

24 changes: 8 additions & 16 deletions .github/actions/run-test-suite/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,25 @@ inputs:
test-type:
description: "Type of test to run"
required: true
apigee-access-token:
description: "Apigee access token"
required: false
base-url:
description: "The URL of the environment to test"
required: false
env:
description: "Environment: local or remote"
description: "Environment to run tests against: ci, alpha-int, pr-<number> - see env.mk"
required: false
default: "remote"
default: "ci"

runs:
using: composite
steps:
- name: "Run ${{ inputs.test-type }} tests"
- name: Set up environment
shell: bash
env:
APIGEE_ACCESS_TOKEN: ${{ inputs.apigee-access-token }}
BASE_URL: ${{ inputs.base-url }}
ENV: ${{ inputs.env }}
run: make env-test-"${ENV}"

- name: "Run ${{ inputs.test-type }} tests"
shell: bash
env:
TEST_TYPE: ${{ inputs.test-type }}
run: |
if [[ -n "${APIGEE_ACCESS_TOKEN}" ]]; then
echo "::add-mask::${APIGEE_ACCESS_TOKEN}"
fi

# Clean test artefacts so each suite uploads only its own results
rm -rf gateway-api/test-artefacts/* || true
mkdir -p gateway-api/test-artefacts
make test-"${TEST_TYPE}"
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/start-app/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ inputs:
deploy-command:
description: "Command to start app"
required: false
default: "make deploy"
default: "make deploy-ci"
health-path:
description: "Health check path"
required: false
Expand Down
2 changes: 1 addition & 1 deletion .github/instructions/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This repository is for handling HTTP requests from "Consumer systems" and forwar

We use other NHSE services to assist in the validation and processing of the requests including PDS FHIR API for obtaining GP practice codes for the patient, SDS FHIR API for obtaining the "Provider system" details of that GP practice and Healthcare Worker FHIR API for obtaining details of the requesting practitioner using the "Consumer System" that will then be added to the forwarded request.

`make deploy` will build and start a container running Gateway API at `localhost:5000`.
`make deploy-dev` will build and start a container running Gateway API at `localhost:5000`.

After deploying the container locally, `make test` will run all tests and capture their coverage. Note: env variables control the use of stubs for the PDS FHIR API, SDS FHIR API, Healthcare Worker FHIR API and Provider system services.

Expand Down
38 changes: 4 additions & 34 deletions .github/workflows/alpha-integration-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ env:
TF_STATE_KEY: "dev/preview/alpha-integration.tfstate"
BRANCH_NAME: "alpha-integration"
ALB_RULE_PRIORITY: "900"
BASE_URL: "https://internal-dev.api.service.nhs.uk/clinical-data-gateway-api-poc-alpha-integration"
python_version: "3.14"
PROXYGEN_API_NAME: ${{ vars.PROXYGEN_API_NAME }}

Expand Down Expand Up @@ -196,63 +195,34 @@ jobs:
echo "http_result=unexpected-status" >> "$GITHUB_OUTPUT"
exit 0

- name: Retrieve Apigee Token
id: apigee-token
shell: bash
run: |
set -euo pipefail

APIGEE_TOKEN="$(proxygen pytest-nhsd-apim get-token | jq -r '.pytest_nhsd_apim_token' 2>/dev/null)"
if [ -z "$APIGEE_TOKEN" ] || [ "$APIGEE_TOKEN" = "null" ]; then
echo "::error::Failed to retrieve Apigee token"
exit 1
fi

echo "::add-mask::$APIGEE_TOKEN"
printf 'apigee-access-token=%s\n' "$APIGEE_TOKEN" >> "$GITHUB_OUTPUT"
echo "Token retrieved successfully (length: ${#APIGEE_TOKEN})"

- name: Run unit tests
uses: ./.github/actions/run-test-suite
with:
test-type: unit
env: local

- name: Run contract tests
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-alpha-integration"
with:
test-type: contract
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: alpha-int

- name: Run schema validation tests
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-alpha-integration"
with:
test-type: schema
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: alpha-int

- name: Run integration tests
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-alpha-integration"
with:
test-type: integration
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: alpha-int

- name: Run acceptance tests
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-alpha-integration"
with:
test-type: acceptance
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: alpha-int

- name: Remove mTLS temp files
run: rm -f /tmp/client1-key.pem /tmp/client1-cert.pem
Expand Down
38 changes: 4 additions & 34 deletions .github/workflows/preview-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ env:
ECR_REPOSITORY_NAME: "whoami"
TF_STATE_BUCKET: "cds-cdg-dev-tfstate-900119715266"
PREVIEW_STATE_PREFIX: "dev/preview/"
BASE_URL: "https://internal-dev.api.service.nhs.uk/clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}"
python_version: "3.14"
PROXYGEN_API_NAME: ${{ vars.PROXYGEN_API_NAME }}
PR_NUMBER: ${{ github.event.pull_request.number }}
Expand Down Expand Up @@ -314,28 +313,11 @@ jobs:

# ---------- QUALITY CHECKS (Test Suites) ----------

- name: Retrieve Apigee Token
id: apigee-token
shell: bash
run: |
set -euo pipefail

APIGEE_TOKEN="$(proxygen pytest-nhsd-apim get-token | jq -r '.pytest_nhsd_apim_token' 2>/dev/null)"
if [ -z "$APIGEE_TOKEN" ] || [ "$APIGEE_TOKEN" = "null" ]; then
echo "::error::Failed to retrieve Apigee token"
exit 1
fi

echo "::add-mask::$APIGEE_TOKEN"
printf 'apigee-access-token=%s\n' "$APIGEE_TOKEN" >> "$GITHUB_OUTPUT"
echo "Token retrieved successfully (length: ${#APIGEE_TOKEN})"

- name: "Run unit tests"
if: github.event.action != 'closed'
uses: ./.github/actions/run-test-suite
with:
test-type: unit
env: local

- name: "Run load tests"
if: github.event.action != 'closed' && steps.smoke-test.outputs.http_result != 'unexpected-status'
Expand All @@ -349,42 +331,30 @@ jobs:
- name: "Run contract tests"
if: github.event.action != 'closed'
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}"
with:
test-type: contract
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: pr-${{ github.event.pull_request.number }}

- name: "Run schema validation tests"
if: github.event.action != 'closed'
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}"
with:
test-type: schema
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: pr-${{ github.event.pull_request.number }}

- name: "Run integration tests"
if: github.event.action != 'closed'
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}"
with:
test-type: integration
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: pr-${{ github.event.pull_request.number }}

- name: "Run acceptance tests"
if: github.event.action != 'closed'
uses: ./.github/actions/run-test-suite
env:
PROXY_BASE_PATH: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}"
with:
test-type: acceptance
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
base-url: ${{ env.BASE_URL }}
env: pr-${{ github.event.pull_request.number }}

# Cleanup after tests
- name: Remove mTLS temp files
Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/stage-2-test.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
name: "Test stage"

env:
BASE_URL: "http://localhost:5000"
HOST: "localhost"
STUB_SDS: "true"
STUB_PDS: "true"
STUB_PROVIDER: "true"

on:
workflow_call:
inputs:
Expand Down Expand Up @@ -45,6 +38,8 @@ jobs:
uses: ./.github/actions/setup-python-project
with:
python-version: ${{ inputs.python_version }}
- name: Set environment variables
run: make env-test-ci
- name: "Run unit test suite"
run: make test-unit
- name: "Upload unit test results"
Expand Down Expand Up @@ -75,6 +70,8 @@ jobs:
uses: ./.github/actions/start-app
with:
python-version: ${{ inputs.python_version }}
- name: Set environment variables
run: make env-test-ci
- name: "Run contract tests"
run: make test-contract
- name: "Upload contract test results"
Expand Down Expand Up @@ -105,6 +102,8 @@ jobs:
uses: ./.github/actions/start-app
with:
python-version: ${{ inputs.python_version }}
- name: Set environment variables
run: make env-test-ci
- name: "Run schema validation tests"
run: make test-schema
- name: "Upload schema test results"
Expand Down Expand Up @@ -135,6 +134,8 @@ jobs:
uses: ./.github/actions/start-app
with:
python-version: ${{ inputs.python_version }}
- name: Set environment variables
run: make env-test-ci
- name: "Run integration test"
run: make test-integration
- name: "Upload integration test results"
Expand Down Expand Up @@ -166,6 +167,8 @@ jobs:
with:
python-version: ${{ inputs.python_version }}
max-seconds: 90
- name: Set environment variables
run: make env-test-ci
- name: "Run acceptance test"
run: make test-acceptance
- name: "Upload acceptance test results"
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ gateway-api/test-artefacts/
**/.env.*
**/.DS_Store
**/.terraform.lock.hcl

# Any file within .secrets
.secrets/**
!.secrets/README.md
19 changes: 19 additions & 0 deletions .secrets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Secrets

This directory is used to store secrets.

The secrets are accessed through `make env-<int|int-pds|int-sds>` which sets the secrets required for PDS FHIR API and SDS FHIR API to `.env` file, which is then fed in to the locally deployed application through `make deploy`.

## PDS

PDS FHIR API requires [signed JWT for application-resrtictecd access](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/application-restricted-restful-apis-signed-jwt-authentication). As such, the following three secrets enable the Gateway API to authenticate:

* `.secrets/pds/api_token` - the API key of the application through which the Gateway API will consume NHSE APIs.
* `.secrets/pds/api_secret` - the private key of the public/private key pair created for application identified by `api_token`
* `.secrets/pds/api_kid` - the key identifier for the private/public key pair used for the `api_secret`.

## SDS

SDS FHIR API requires [API key authentication](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/application-restricted-restful-apis-api-key-authentication) for application-restricted access. As such, the only secret required is

* `.secrets/sds/api_token` - the API key of the application through which the Gateway API will consume NHSE APIs.
Empty file added .secrets/pds/.gitkeep
Empty file.
Empty file added .secrets/sds/.gitkeep
Empty file.
2 changes: 2 additions & 0 deletions .vscode/cspell-dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ eamodio
errstr
Farsley
fhir
getfixturevalue
getstructuredrecord
gocloc
GPCAPIM
Expand Down Expand Up @@ -73,6 +74,7 @@ NOSONAR
NPFIT
ONESHELL
opencollection
orangebox
pipefail
PIPX
pkce
Expand Down
23 changes: 6 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,13 @@ build: build-gateway-api # Build the project artefact @Pipeline
publish: # Publish the project artefact @Pipeline
# TODO [GPCAPIM-283]: Implement the artefact publishing step

deploy: clean build # Deploy the project artefact to the target environment @Pipeline
deploy: clean build # Build project artefact and deploy locally @Pipeline
@$(docker) network inspect gateway-local >/dev/null 2>&1 || $(docker) network create gateway-local
# Build up list of environment variables to pass to the container
@ENVIRONMENT_STRING="" ; \
if [[ -n "$${STUB_PROVIDER}" ]]; then \
ENVIRONMENT_STRING="$${ENVIRONMENT_STRING} -e STUB_PROVIDER=$${STUB_PROVIDER}" ; \
fi ; \
if [[ -n "$${STUB_PDS}" ]]; then \
ENVIRONMENT_STRING="$${ENVIRONMENT_STRING} -e STUB_PDS=$${STUB_PDS}" ; \
fi ; \
if [[ -n "$${STUB_SDS}" ]]; then \
ENVIRONMENT_STRING="$${ENVIRONMENT_STRING} -e STUB_SDS=$${STUB_SDS}" ; \
fi ; \
if [[ -n "$${CDG_DEBUG}" ]]; then \
ENVIRONMENT_STRING="$${ENVIRONMENT_STRING} -e CDG_DEBUG=$${CDG_DEBUG}" ; \
fi ; \
if [[ -n "$${IN_BUILD_CONTAINER}" ]]; then \
echo "Starting using local docker network ..." ; \
$(docker) run --platform linux/amd64 --name gateway-api -p 5000:8080 --network gateway-local $${ENVIRONMENT_STRING} -d ${IMAGE_NAME} ; \
$(docker) run --platform linux/amd64 --name gateway-api -p 5000:8080 --network gateway-local --env-file .env -d ${IMAGE_NAME} ; \
else \
$(docker) run --platform linux/amd64 --name gateway-api -p 5000:8080 $${ENVIRONMENT_STRING} -d ${IMAGE_NAME} ; \
$(docker) run --platform linux/amd64 --name gateway-api -p 5000:8080 --env-file .env -d ${IMAGE_NAME} ; \
fi
@max_attempts=5 ; \
attempt=1 ; \
Expand All @@ -88,6 +74,9 @@ deploy: clean build # Deploy the project artefact to the target environment @Pip
$(docker) logs gateway-api ; \
exit 1

deploy-%: # Build project artefact and deploy locally as specified environment - mandatory: name=[name of the environment, e.g. 'dev'] @Pipeline
make env-$* deploy

clean:: stop # Clean-up project resources (main) @Operations
@echo "Removing Gateway API container..."
@$(docker) rm gateway-api || echo "No Gateway API container currently exists."
Expand Down
Loading
Loading