Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit bc5d2a2

Browse files
authored
chore: Initial service layer repo setup (#1)
1 parent e287719 commit bc5d2a2

File tree

24 files changed

+684
-234
lines changed

24 files changed

+684
-234
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
3+
name: $(Build.SourceBranchName)-$(Date:yyyyMMdd)_$(Rev:r)
4+
5+
trigger: none
6+
pr: none
7+
8+
pool:
9+
# vmImage: ubuntu-latest
10+
name: private-pool-dev-uks
11+
12+
resources:
13+
repositories:
14+
- repository: dtos-devops-templates
15+
type: github
16+
name: NHSDigital/dtos-devops-templates
17+
ref: f8141ab50ec0f3630044fa0f531952d2dbbd1e85
18+
endpoint: NHSDigital
19+
20+
variables:
21+
- group: DEV_audit_backend
22+
- group: DEV_hub_backend_remote_state
23+
- name: TF_DIRECTORY
24+
value: $(System.DefaultWorkingDirectory)/$(System.TeamProject)/infrastructure/tf-audit
25+
- name: TF_VERSION
26+
value: 1.9.2
27+
- name: TF_PLAN_ARTIFACT
28+
value: tf_plan_audit_DEV
29+
- name: ENVIRONMENT
30+
value: development
31+
32+
stages:
33+
- stage: terraform_plan
34+
displayName: Terraform Plan
35+
condition: eq(variables['Build.Reason'], 'Manual')
36+
variables:
37+
tfVarsFile: environments/$(ENVIRONMENT).tfvars
38+
jobs:
39+
- job: init_and_plan
40+
displayName: Init, plan, store artifact
41+
steps:
42+
- checkout: self
43+
- checkout: dtos-devops-templates
44+
- template: .azuredevops/templates/steps/tf_plan.yaml@dtos-devops-templates
45+
46+
- stage: terraform_apply
47+
displayName: Terraform Apply
48+
dependsOn: [terraform_plan]
49+
condition: and(eq(dependencies.terraform_plan.outputs['init_and_plan.TerraformPlan.changesPresent'], 'true'), eq(variables['Build.Reason'], 'Manual'))
50+
jobs:
51+
- deployment: terraform_apply
52+
displayName: Init, get plan artifact, apply
53+
environment: $(ENVIRONMENT)
54+
strategy:
55+
runOnce:
56+
deploy:
57+
steps:
58+
- checkout: self
59+
- checkout: dtos-devops-templates
60+
- template: .azuredevops/templates/steps/tf_apply.yaml@dtos-devops-templates
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
3+
name: $(Build.SourceBranchName)-$(Date:yyyyMMdd)_$(Rev:r)
4+
5+
trigger: none
6+
pr: none
7+
8+
pool:
9+
# vmImage: ubuntu-latest
10+
name: private-pool-dev-uks
11+
12+
resources:
13+
repositories:
14+
- repository: dtos-devops-templates
15+
type: github
16+
name: NHSDigital/dtos-devops-templates
17+
ref: f8141ab50ec0f3630044fa0f531952d2dbbd1e85
18+
endpoint: NHSDigital
19+
20+
variables:
21+
- group: DEV_core_backend
22+
- group: DEV_audit_backend_remote_state
23+
- group: DEV_hub_backend_remote_state
24+
- name: TF_DIRECTORY
25+
value: $(System.DefaultWorkingDirectory)/$(System.TeamProject)/infrastructure/tf-core
26+
- name: TF_VERSION
27+
value: 1.9.2
28+
- name: TF_PLAN_ARTIFACT
29+
value: tf_plan_core_DEV
30+
- name: ENVIRONMENT
31+
value: development
32+
33+
stages:
34+
- stage: terraform_plan
35+
displayName: Terraform Plan
36+
condition: eq(variables['Build.Reason'], 'Manual')
37+
variables:
38+
tfVarsFile: environments/$(ENVIRONMENT).tfvars
39+
jobs:
40+
- job: init_and_plan
41+
displayName: Init, plan, store artifact
42+
steps:
43+
- checkout: self
44+
- checkout: dtos-devops-templates
45+
- template: .azuredevops/templates/steps/tf_plan.yaml@dtos-devops-templates
46+
47+
- stage: terraform_apply
48+
displayName: Terraform Apply
49+
dependsOn: [terraform_plan]
50+
condition: and(eq(dependencies.terraform_plan.outputs['init_and_plan.TerraformPlan.changesPresent'], 'true'), eq(variables['Build.Reason'], 'Manual'))
51+
jobs:
52+
- deployment: terraform_apply
53+
displayName: Init, get plan artifact, apply
54+
environment: $(ENVIRONMENT)
55+
strategy:
56+
runOnce:
57+
deploy:
58+
steps:
59+
- checkout: self
60+
- checkout: dtos-devops-templates
61+
- template: .azuredevops/templates/steps/tf_apply.yaml@dtos-devops-templates

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ trim_trailing_whitespace = true
1111
[*.md]
1212
indent_size = unset
1313

14+
[*.cs]
15+
indent_size = 4
16+
1417
[*.py]
1518
indent_size = 4
1619

.github/actions/perform-static-analysis/action.yaml

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,60 @@ description: "Perform static analysis"
33
inputs:
44
sonar_organisation_key:
55
description: "Sonar organisation key, used to identify the project"
6-
required: false
6+
required: true
77
sonar_project_key:
88
description: "Sonar project key, used to identify the project"
9-
required: false
9+
required: true
1010
sonar_token:
1111
description: "Sonar token, the API key"
12-
required: false
12+
required: true
1313
runs:
1414
using: "composite"
1515
steps:
16-
- name: "Check prerequisites for performing static analysis"
17-
shell: bash
18-
id: check
19-
run: echo "secret_exist=${{ inputs.sonar_token != '' }}" >> $GITHUB_OUTPUT
20-
- name: "Perform static analysis"
16+
- name: Set up JDK 17
17+
uses: actions/setup-java@v4
18+
with:
19+
java-version: 17
20+
distribution: "zulu" # Alternative distribution options are available.
21+
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
24+
- name: Install .NET SDK 9 (or your required version)
25+
uses: actions/setup-dotnet@v4
26+
with:
27+
dotnet-version: 9.0.x # C
28+
- name: Cache SonarQube Cloud packages
29+
uses: actions/cache@v4
30+
with:
31+
path: ~\sonar\cache
32+
key: ${{ runner.os }}-sonar
33+
restore-keys: ${{ runner.os }}-sonar
34+
- name: Cache SonarQube Cloud scanner
35+
id: cache-sonar-scanner
36+
uses: actions/cache@v4
37+
with:
38+
path: .\.sonar\scanner
39+
key: ${{ runner.os }}-sonar-scanner
40+
restore-keys: ${{ runner.os }}-sonar-scanner
41+
- name: Install SonarQube Cloud scanner
42+
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
43+
shell: bash # Change from powershell to bash
44+
run: |
45+
mkdir -p .sonar/scanner
46+
dotnet tool install dotnet-sonarscanner --tool-path ./.sonar/scanner
47+
dotnet tool install dotnet-coverage --tool-path ./.sonar/scanner
48+
- name: Build and analyze
2149
shell: bash
22-
if: steps.check.outputs.secret_exist == 'true'
2350
run: |
24-
export BRANCH_NAME=${GITHUB_HEAD_REF:-$(echo $GITHUB_REF | sed 's#refs/heads/##')}
25-
export SONAR_ORGANISATION_KEY=${{ inputs.sonar_organisation_key }}
26-
export SONAR_PROJECT_KEY=${{ inputs.sonar_project_key }}
27-
export SONAR_TOKEN=${{ inputs.sonar_token }}
28-
./scripts/reports/perform-static-analysis.sh
51+
echo "${{ inputs.sonar_project_key }}"
52+
echo "${{ inputs.sonar_organisation_key }}"
53+
echo "${{ inputs.sonar_token }}"
54+
./.sonar/scanner/dotnet-sonarscanner begin /k:"${{ inputs.sonar_project_key }}" /o:"${{ inputs.sonar_organisation_key }}" /d:sonar.token="${{ inputs.sonar_token }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths="coverage.xml" /d:sonar.typescript.lcov.reportsPaths="src/web/coverage/lcov.info" /d:sonar.lang.patterns.ts=**/*.ts,**/*.tsx,**/*.cts,**/*.mts /d:sonar.lang.patterns.js=**/*.js,**/*.jsx,**/*.cjs,**/*.mjs,**/*.vue /d:sonar.javascript.enabled=false
55+
dotnet build src/api/ParticipantManager.API.sln
56+
./.sonar/scanner/dotnet-coverage collect -f xml -o coverage.xml dotnet test src/api/ServiceLayer.API.sln
57+
cd src/web
58+
npm ci
59+
npm run test:unit:coverage -- --coverageDirectory=coverage --coverageReporters=lcov
60+
sed -i 's|^SF:|SF:src/web/|g' coverage/lcov.info
61+
cd ../..
62+
./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${{ inputs.sonar_token }}"

.github/dependabot.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ updates:
1212
schedule:
1313
interval: "daily"
1414

15+
- package-ecosystem: "nuget"
16+
directory: "/"
17+
schedule:
18+
interval: "daily"
19+
1520
- package-ecosystem: "npm"
1621
directory: "/"
1722
schedule:

.github/workflows/cicd-1-pull-request.yaml

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ on:
1010
types: [opened, reopened]
1111

1212
jobs:
13+
1314
metadata:
14-
name: "Set CI/CD metadata"
15+
name: Set CI/CD metadata
1516
runs-on: ubuntu-latest
1617
timeout-minutes: 1
18+
permissions:
19+
pull-requests: read
1720
outputs:
1821
build_datetime_london: ${{ steps.variables.outputs.build_datetime_london }}
1922
build_datetime: ${{ steps.variables.outputs.build_datetime }}
@@ -22,11 +25,14 @@ jobs:
2225
nodejs_version: ${{ steps.variables.outputs.nodejs_version }}
2326
python_version: ${{ steps.variables.outputs.python_version }}
2427
terraform_version: ${{ steps.variables.outputs.terraform_version }}
28+
environment_tag: ${{ steps.variables.outputs.environment_tag }}
2529
version: ${{ steps.variables.outputs.version }}
2630
does_pull_request_exist: ${{ steps.pr_exists.outputs.does_pull_request_exist }}
2731
steps:
2832
- name: "Checkout code"
2933
uses: actions/checkout@v4
34+
with:
35+
submodules: 'true'
3036
- name: "Set CI/CD variables"
3137
id: variables
3238
run: |
@@ -40,10 +46,11 @@ jobs:
4046
echo "python_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
4147
echo "terraform_version=$(grep "^terraform" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
4248
echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
49+
echo "environment_tag=development" >> $GITHUB_OUTPUT
4350
- name: "Check if pull request exists for this branch"
4451
id: pr_exists
4552
env:
46-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53+
GH_TOKEN: ${{ github.token }}
4754
run: |
4855
branch_name=${GITHUB_HEAD_REF:-$(echo $GITHUB_REF | sed 's#refs/heads/##')}
4956
echo "Current branch is '$branch_name'"
@@ -54,7 +61,7 @@ jobs:
5461
echo "Pull request doesn't exist"
5562
echo "does_pull_request_exist=false" >> $GITHUB_OUTPUT
5663
fi
57-
- name: "List variables"
64+
- name: List variables
5865
run: |
5966
export BUILD_DATETIME_LONDON="${{ steps.variables.outputs.build_datetime_london }}"
6067
export BUILD_DATETIME="${{ steps.variables.outputs.build_datetime }}"
@@ -63,11 +70,12 @@ jobs:
6370
export NODEJS_VERSION="${{ steps.variables.outputs.nodejs_version }}"
6471
export PYTHON_VERSION="${{ steps.variables.outputs.python_version }}"
6572
export TERRAFORM_VERSION="${{ steps.variables.outputs.terraform_version }}"
73+
export ENVIRONMENT_TAG="${{ steps.variables.outputs.environment_tag }}"
6674
export VERSION="${{ steps.variables.outputs.version }}"
6775
export DOES_PULL_REQUEST_EXIST="${{ steps.pr_exists.outputs.does_pull_request_exist }}"
6876
make list-variables
6977
commit-stage: # Recommended maximum execution time is 2 minutes
70-
name: "Commit stage"
78+
name: Commit stage
7179
needs: [metadata]
7280
uses: ./.github/workflows/stage-1-commit.yaml
7381
with:
@@ -92,23 +100,21 @@ jobs:
92100
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
93101
version: "${{ needs.metadata.outputs.version }}"
94102
secrets: inherit
95-
build-stage: # Recommended maximum execution time is 3 minutes
96-
name: "Build stage"
97-
needs: [metadata, test-stage]
98-
uses: ./.github/workflows/stage-3-build.yaml
99-
if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
103+
build-image-stage: # Recommended maximum execution time is 3 minutes
104+
name: Image build stage
105+
needs: [metadata, commit-stage, test-stage]
106+
uses: NHSDigital/dtos-devops-templates/.github/workflows/stage-3-build-images.yaml@main
107+
if: needs.metadata.outputs.does_pull_request_exist == 'true' || github.ref == 'refs/heads/main' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
100108
with:
101-
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
102-
build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
103-
build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
104-
nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
105-
python_version: "${{ needs.metadata.outputs.python_version }}"
106-
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
107-
version: "${{ needs.metadata.outputs.version }}"
109+
docker_compose_file: ./compose.yaml
110+
excluded_containers_csv_list: azurite,azurite-setup,sql-database,database-setup
111+
environment_tag: ${{ needs.metadata.outputs.environment_tag }}
112+
function_app_source_code_path: src
113+
project_name: service-layer
108114
secrets: inherit
109115
acceptance-stage: # Recommended maximum execution time is 10 minutes
110-
name: "Acceptance stage"
111-
needs: [metadata, build-stage]
116+
name: Acceptance stage
117+
needs: [metadata, build-image-stage]
112118
uses: ./.github/workflows/stage-4-acceptance.yaml
113119
if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
114120
with:
@@ -120,3 +126,20 @@ jobs:
120126
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
121127
version: "${{ needs.metadata.outputs.version }}"
122128
secrets: inherit
129+
validate-title-stage:
130+
name: Validate PR title
131+
runs-on: ubuntu-latest
132+
permissions:
133+
pull-requests: write
134+
env:
135+
GITHUB_TOKEN: ${{ github.token }}
136+
if: github.event_name == 'pull_request'
137+
steps:
138+
- uses: amannn/action-semantic-pull-request@v5
139+
id: validate
140+
141+
- uses: thollander/actions-comment-pull-request@v3
142+
if: ${{ failure() && steps.validate.conclusion == 'failure' }}
143+
with:
144+
message: |
145+
Your Pull Request title must meet the conventional commit standards, please see the following documentation - https://www.conventionalcommits.org/en/v1.0.0/#specification

.github/workflows/cicd-2-publish.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ jobs:
2323
steps:
2424
- name: "Checkout code"
2525
uses: actions/checkout@v4
26+
with:
27+
submodules: 'true'
2628
- name: "Set CI/CD variables"
2729
id: variables
2830
run: |

.github/workflows/stage-1-commit.yaml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
uses: actions/checkout@v4
4343
with:
4444
fetch-depth: 0 # Full history is needed to scan all commits
45+
submodules: 'true'
4546
- name: "Scan secrets"
4647
uses: ./.github/actions/scan-secrets
4748
check-file-format:
@@ -105,22 +106,3 @@ jobs:
105106
idp_aws_report_upload_region: "${{ secrets.IDP_AWS_REPORT_UPLOAD_REGION }}"
106107
idp_aws_report_upload_role_name: "${{ secrets.IDP_AWS_REPORT_UPLOAD_ROLE_NAME }}"
107108
idp_aws_report_upload_bucket_endpoint: "${{ secrets.IDP_AWS_REPORT_UPLOAD_BUCKET_ENDPOINT }}"
108-
scan-dependencies:
109-
name: "Scan dependencies"
110-
runs-on: ubuntu-latest
111-
permissions:
112-
id-token: write
113-
contents: read
114-
timeout-minutes: 2
115-
steps:
116-
- name: "Checkout code"
117-
uses: actions/checkout@v4
118-
- name: "Scan dependencies"
119-
uses: ./.github/actions/scan-dependencies
120-
with:
121-
build_datetime: "${{ inputs.build_datetime }}"
122-
build_timestamp: "${{ inputs.build_timestamp }}"
123-
idp_aws_report_upload_account_id: "${{ secrets.IDP_AWS_REPORT_UPLOAD_ACCOUNT_ID }}"
124-
idp_aws_report_upload_region: "${{ secrets.IDP_AWS_REPORT_UPLOAD_REGION }}"
125-
idp_aws_report_upload_role_name: "${{ secrets.IDP_AWS_REPORT_UPLOAD_ROLE_NAME }}"
126-
idp_aws_report_upload_bucket_endpoint: "${{ secrets.IDP_AWS_REPORT_UPLOAD_BUCKET_ENDPOINT }}"

.github/workflows/stage-2-test.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ jobs:
4040
steps:
4141
- name: "Checkout code"
4242
uses: actions/checkout@v4
43+
with:
44+
submodules: "true"
45+
- name: "Setup dotnet"
46+
uses: actions/setup-dotnet@v4
47+
with:
48+
dotnet-version: "9.x"
4349
- name: "Run unit test suite"
4450
run: |
4551
make test-unit

0 commit comments

Comments
 (0)