diff --git a/.editorconfig b/.editorconfig index 02e8abc..fd5c354 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,3 +19,13 @@ indent_size = 4 [{Makefile,*.mk,go.mod,go.sum,*.go,.gitmodules}] indent_style = tab + +# Ignore paths +[Gemfile.lock] +charset = unset +end_of_line = unset +insert_final_newline = unset +trim_trailing_whitespace = unset +indent_style = unset +indent_size = unset +generated_code = true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index eea1664..44937ff 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,16 +1,11 @@ # NHS Notify Code Owners -* @NHSDigital/nhs-notify-iam-webauth - -/.github/ @NHSDigital/nhs-notify-iam-admins -*.code-workspace @NHSDigital/nhs-notify-iam-admins -/docs/ @NHSDigital/nhs-notify-iam-webauth -/docs/testing/ @NHSDigital/nhs-notify-iam-webauth-testers -/tests/test-team/ @NHSDigital/nhs-notify-iam-webauth-testers +# Notify default owners +* @rossbugginsnhs @m-houston @aidenvaines-bjss @timireland # Codeowners must be final check -/.github/CODEOWNERS @NHSDigital/nhs-notify-code-owners -/CODEOWNERS @NHSDigital/nhs-notify-code-owners +/.github/CODEOWNERS @NHSDigital/nhs-notify-code-owners +/CODEOWNERS @NHSDigital/nhs-notify-code-owners # Each NHS Notify repository should have clear code owners set. diff --git a/.github/actions/lint-terraform/action.yaml b/.github/actions/lint-terraform/action.yaml index d5dfe35..28d990c 100644 --- a/.github/actions/lint-terraform/action.yaml +++ b/.github/actions/lint-terraform/action.yaml @@ -16,5 +16,6 @@ runs: run: | stacks=${{ inputs.root-modules }} for dir in $(find infrastructure/environments -maxdepth 1 -mindepth 1 -type d; echo ${stacks//,/$'\n'}); do + dir=$dir opts='-backend=false' make terraform-init dir=$dir make terraform-validate done diff --git a/.gitignore b/.gitignore index f4f157e..a0ad8fe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,61 +6,8 @@ *vulnerabilities*report*.json *report*json.zip .version - +version.json *.code-workspace !project.code-workspace # Please, add your custom content below! - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* - -# local env files -.env*.local -.env - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -# reports -.reports - -# typescript -*.tsbuildinfo -next-env.d.ts -/test-results/ -/playwright-report/ -/blob-report/ -/playwright/.cache/ - -# playwright -tests/test-team/test-results/ -tests/test-team/playwright-report/ -tests/test-team/blob-report/ -tests/test-team/playwright/.cache/ - -#plugin-cache -plugin-cache/ diff --git a/.gitleaksignore b/.gitleaksignore index cceb449..1c92293 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -1,3 +1,5 @@ # SEE: https://github.com/gitleaks/gitleaks/blob/master/README.md#gitleaksignore cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:generic-api-key:37 +96096685ab3d6876671e2bc9a6ff4d48fc56e521:src/helloworld/helloworld.sln:ipv4:4 +4f4e8c15629b2cb09356a7fed4d72953590227ce:docs/Gemfile.lock:ipv4:4 diff --git a/.tool-versions b/.tool-versions index 3483d5b..13b6acd 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,11 +1,9 @@ -# This file is for you! Please, updated to the versions agreed by your team. - -terraform 1.9.2 -pre-commit 3.6.0 -nodejs 20.13.1 -direnv 2.32.1 +act 0.2.64 gitleaks 8.18.4 +pre-commit 3.6.0 +terraform 1.9.2 tfsec 1.28.10 +vale 3.6.0 # ============================================================================== # The section below is reserved for Docker image versions. diff --git a/Makefile b/Makefile index 2c893b2..ea70e95 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ dependencies: # Install dependencies needed to build and test the project @Pipel # TODO: Implement installation of your project dependencies build: # Build the project artefact @Pipeline - # TODO: Implement the artefact build step + (cd docs && make build) publish: # Publish the project artefact @Pipeline # TODO: Implement the artefact publishing step @@ -20,12 +20,16 @@ deploy: # Deploy the project artefact to the target environment @Pipeline # TODO: Implement the artefact deployment step clean:: # Clean-up project resources (main) @Operations + rm -f .version # TODO: Implement project resources clean-up step -config:: # Configure development environment (main) @Configuration - # TODO: Use only 'make' targets that are specific to this project, e.g. you may not need to install Node.js - make _install-dependencies +config:: _install-dependencies version # Configure development environment (main) @Configuration + (cd docs && make install) +version: + rm -f .version + make version-create-effective-file dir=. + echo "{ \"schemaVersion\": 1, \"label\": \"version\", \"message\": \"$$(head -n 1 .version 2> /dev/null || echo unknown)\", \"color\": \"orange\" }" > version.json # ============================================================================== ${VERBOSE}.SILENT: \ diff --git a/infrastructure/images/.gitkeep b/infrastructure/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/infrastructure/modules/.gitkeep b/infrastructure/modules/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/infrastructure/terraform/.gitignore b/infrastructure/terraform/.gitignore index ed83c6d..579b641 100644 --- a/infrastructure/terraform/.gitignore +++ b/infrastructure/terraform/.gitignore @@ -3,6 +3,13 @@ # Transient backends components/**/backend_tfscaffold.tf +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + # Compiled files **/*.tfstate **/*.tfplan @@ -14,9 +21,6 @@ components/**/backend_tfscaffold.tf **/work/* **/*tfstate.lock.info -# NHS Notify Build context -bootstrap - # Scaffold Plugin Cache plugin-cache/* diff --git a/infrastructure/terraform/README b/infrastructure/terraform/README new file mode 100644 index 0000000..838d177 --- /dev/null +++ b/infrastructure/terraform/README @@ -0,0 +1,3 @@ +This is an implementation of https://github.com/tfutils/tfscaffold for NHS Notify + +Update the `etc/global.tfvars` file according to your NHS Notify Domain, and follow https://github.com/tfutils/tfscaffold?tab=readme-ov-file#bootstrapping to get your tfstate s3 bucket set up diff --git a/scripts/config/gitleaks.toml b/scripts/config/gitleaks.toml index af5f0bb..188bfdf 100644 --- a/scripts/config/gitleaks.toml +++ b/scripts/config/gitleaks.toml @@ -16,4 +16,15 @@ regexes = [ ] [allowlist] -paths = ['''.terraform.lock.hcl''', '''poetry.lock''', '''yarn.lock'''] +paths = [ + '''.terraform.lock.hcl''', + '''poetry.lock''', + '''yarn.lock''', + '''Gemfile.lock''', +] + +# Exclude Chrome version in user agent +regexTarget = "line" +regexes = [ + '''Chrome/[\d.]+''' +] diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index 37ca637..5a5ba09 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -1,40 +1,59 @@ repos: -- repo: local - hooks: - - id: scan-secrets - name: Scan secrets - entry: ./scripts/githooks/scan-secrets.sh - args: ["check=staged-changes"] - language: script - pass_filenames: false -- repo: local - hooks: - - id: check-file-format - name: Check file format - entry: ./scripts/githooks/check-file-format.sh - args: ["check=staged-changes"] - language: script - pass_filenames: false -- repo: local - hooks: - - id: check-markdown-format - name: Check Markdown format - entry: ./scripts/githooks/check-markdown-format.sh - args: ["check=staged-changes"] - language: script - pass_filenames: false -- repo: local - hooks: - - id: check-english-usage - name: Check English usage - entry: ./scripts/githooks/check-english-usage.sh - args: ["check=staged-changes"] - language: script - pass_filenames: false -- repo: local - hooks: - - id: lint-terraform - name: Lint Terraform - entry: ./scripts/githooks/check-terraform-format.sh - language: script - pass_filenames: false + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 # Use the ref you want to point at + hooks: + - id: trailing-whitespace + - id: detect-aws-credentials + args: [--allow-missing-credentials] + - id: check-added-large-files + - id: check-symlinks + - id: detect-private-key + - id: end-of-file-fixer + exclude: .+\.cs + - id: forbid-new-submodules + - id: mixed-line-ending + - id: pretty-format-json + args: ['--autofix'] + # - id: ... + - repo: local + hooks: + - id: sort-dictionary + name: Sort dictionary + entry: ./scripts/githooks/sort-dictionary.sh + language: script + pass_filenames: false + - repo: local + hooks: + - id: scan-secrets + name: Scan secrets + entry: /usr/bin/env check=whole-history ./scripts/githooks/scan-secrets.sh + language: script + pass_filenames: false + - repo: local + hooks: + - id: check-file-format + name: Check file format + entry: /usr/bin/env check=branch ./scripts/githooks/check-file-format.sh + language: script + pass_filenames: false + - repo: local + hooks: + - id: check-markdown-format + name: Check Markdown format + entry: /usr/bin/env check=branch ./scripts/githooks/check-markdown-format.sh + language: script + pass_filenames: false + - repo: local + hooks: + - id: check-english-usage + name: Check English usage + entry: /usr/bin/env check=branch ./scripts/githooks/check-english-usage.sh + language: script + pass_filenames: false + - repo: local + hooks: + - id: lint-terraform + name: Lint Terraform + entry: ./scripts/githooks/check-terraform-format.sh + language: script + pass_filenames: false diff --git a/scripts/config/vale/styles/config/vocabularies/words/accept.txt b/scripts/config/vale/styles/config/vocabularies/words/accept.txt index 797ee07..3b07d50 100644 --- a/scripts/config/vale/styles/config/vocabularies/words/accept.txt +++ b/scripts/config/vale/styles/config/vocabularies/words/accept.txt @@ -1,23 +1,26 @@ [A-Z]+s Bitwarden bot -config +Cognito Cyber Dependabot draw.io drawio +endcapture endfor endraw -env GitHub Gitleaks Grype idempotence +Jira OAuth Octokit onboarding Podman Python +rawContent +sed Syft Terraform toolchain diff --git a/scripts/docker/examples/python/assets/hello_world/requirements.txt b/scripts/docker/examples/python/assets/hello_world/requirements.txt index f2bb03a..a3611c8 100644 --- a/scripts/docker/examples/python/assets/hello_world/requirements.txt +++ b/scripts/docker/examples/python/assets/hello_world/requirements.txt @@ -6,7 +6,7 @@ itsdangerous==2.1.2 Jinja2==3.1.4 MarkupSafe==2.1.3 pip==23.3 -setuptools==70.0.0 +setuptools==65.5.1 Werkzeug==3.0.3 wheel==0.41.1 WTForms==3.0.1 diff --git a/scripts/git-repo/auto-link.md b/scripts/git-repo/auto-link.md new file mode 100644 index 0000000..dfb68a6 --- /dev/null +++ b/scripts/git-repo/auto-link.md @@ -0,0 +1,11 @@ +# GitHub + +## Auto link Protection Rules + +This will create the auto link to Jira. + +```sh +./auto-link.sh $reponame $PAT +``` + +PAT must have `administration:write`. [Create an auto link](https://docs.github.com/en/rest/repos/autolinks?apiVersion=2022-11-28#create-an-autolink-for-a-repository) diff --git a/scripts/git-repo/auto-link.sh b/scripts/git-repo/auto-link.sh new file mode 100644 index 0000000..a827bd0 --- /dev/null +++ b/scripts/git-repo/auto-link.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $2" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/NHSDigital/$1/autolinks \ + -d '{"key_prefix":"CCM-","url_template":" https://nhsd-jira.digital.nhs.uk/browse/CCM-","is_alphanumeric":true}' diff --git a/scripts/git-repo/branch-protection.md b/scripts/git-repo/branch-protection.md new file mode 100644 index 0000000..0e513f8 --- /dev/null +++ b/scripts/git-repo/branch-protection.md @@ -0,0 +1,11 @@ +# GitHub + +## Branch Protection Rules + +This will create the default branch protection rules using GitHub API. + +```sh +./branch-protection.sh $reponame $PAT +``` + +PAT must have `administration:write`. [Create a repository rule set](https://docs.github.com/en/rest/repos/rules?apiVersion=2022-11-28#create-a-repository-ruleset) diff --git a/scripts/git-repo/branch-protection.sh b/scripts/git-repo/branch-protection.sh new file mode 100755 index 0000000..f98597a --- /dev/null +++ b/scripts/git-repo/branch-protection.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +curl --location "https://api.github.com/repos/NHSDigital/$1/rulesets" \ +--header 'X-GitHub-Api-Version: 2022-11-28' \ +--header 'Accept: application/vnd.github+json' \ +--header "Authorization: Bearer $2" \ +--header 'Content-Type: application/json' \ +--data '{ + "name": "nhs-notify-default", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "~DEFAULT_BRANCH" + ] + } + }, + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 1, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_review_thread_resolution": true + } + }, + { + "type": "required_signatures" + }, + { + "type": "required_status_checks", + "parameters": { + "strict_required_status_checks_policy": true, + "required_status_checks": [] + } + } + ] +}' diff --git a/scripts/githooks/check-markdown-format.sh b/scripts/githooks/check-markdown-format.sh index 698df4a..c39a080 100755 --- a/scripts/githooks/check-markdown-format.sh +++ b/scripts/githooks/check-markdown-format.sh @@ -38,7 +38,7 @@ function main() { check=${check:-working-tree-changes} case $check in "all") - files="$(find ./ -type f -name "*.md")" + files="$(git ls-files "*.md")" ;; "staged-changes") files="$(git diff --diff-filter=ACMRT --name-only --cached "*.md")" diff --git a/scripts/githooks/sort-dictionary.sh b/scripts/githooks/sort-dictionary.sh new file mode 100755 index 0000000..45a3952 --- /dev/null +++ b/scripts/githooks/sort-dictionary.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -euo pipefail + +# Pre-commit git hook to sort the Vale dictionary in a consistent manner to avoid future merge conflicts and aid insertion of new terms +# +# Usage: +# $ [options] ./sort-dictionary.sh +# +# Options: +# +# +# Exit codes: +# 0 - Successfully sorted the dictionary +# non-zero - failed to sort dictionary + +# ============================================================================== + +function main() { + root=scripts/config/vale/styles/config/vocabularies/words + opts="--dictionary-order --ignore-case -s" + sort $opts $root/accept.txt > $root/accept.sorted.txt + sort $opts $root/reject.txt > $root/reject.sorted.txt + + mv $root/accept.sorted.txt $root/accept.txt + mv $root/reject.sorted.txt $root/reject.txt + + git add -uv $root/* +} + +# ============================================================================== + +function is-arg-true() { + + if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then + return 0 + else + return 1 + fi +} + +# ============================================================================== + +is-arg-true "${VERBOSE:-false}" && set -x + +main "$@" + +exit 0 diff --git a/scripts/terraform/terraform.lib.sh b/scripts/terraform/terraform.lib.sh index 7793b9b..d94213e 100644 --- a/scripts/terraform/terraform.lib.sh +++ b/scripts/terraform/terraform.lib.sh @@ -53,8 +53,12 @@ function terraform-destroy() { # dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is '.'] # opts=[options to pass to the Terraform fmt command, default is '-recursive'] function terraform-fmt() { + for d in "${PWD}infrastructure/"*; do + if [ -d "$d" ]; then + terraform fmt --recursive "${d}" + fi + done - _terraform fmt -recursive # 'dir' and 'opts' are passed to the function as environment variables, if set } # Validate Terraform code. diff --git a/scripts/terraform/terraform.mk b/scripts/terraform/terraform.mk index c5b587b..4a2783a 100644 --- a/scripts/terraform/terraform.mk +++ b/scripts/terraform/terraform.mk @@ -4,11 +4,6 @@ # Custom implementation - implementation of a make target should not exceed 5 lines of effective code. # In most cases there should be no need to modify the existing make targets. -# TF_ENV ?= dev -# STACK ?= ${stack} -# TERRAFORM_STACK ?= $(or ${STACK}, infrastructure/terraform) -# dir ?= ${TERRAFORM_STACK} - terraform-init: # Initialise Terraform - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform init command, default is none/empty] @Development make _terraform cmd="init" \ dir=$(or ${terraform_dir}, ${dir}) \ @@ -64,6 +59,8 @@ terraform-sec: # TFSEC check against Terraform files - optional: terraform_dir|d tfsec infrastructure/terraform \ --force-all-dirs \ --exclude-downloaded-modules \ + --tfvars-file infrastructure/terraform/etc/global.tfvars \ + --tfvars-file infrastructure/terraform/etc/env_eu-west-2_main.tfvars \ --config-file scripts/config/tfsec.yml # ============================================================================== diff --git a/scripts/tests/unit.sh b/scripts/tests/unit.sh index b31ff84..c589be5 100755 --- a/scripts/tests/unit.sh +++ b/scripts/tests/unit.sh @@ -11,7 +11,7 @@ cd "$(git rev-parse --show-toplevel)" # # rails test:unit # python manage.py test - npm run test:unit +# npm run test # # or whatever is appropriate to your project. You should *only* run your fast # tests from here. If you want to run other test suites, see the predefined