diff --git a/azure/apigee-build.yml b/azure/apigee-build.yml new file mode 100644 index 0000000..e53b896 --- /dev/null +++ b/azure/apigee-build.yml @@ -0,0 +1,298 @@ +parameters: + - name: service_name + type: string + - name: short_service_name + type: string + - name: variables + type: object + default: [] + - name: secret_file_ids + type: object + default: [] + - name: secret_ids + type: object + default: [] + - name: config_ids + type: object + default: [] + - name: test_steps + type: stepList + default: [] + - name: post_ecs_push + type: stepList + default: [] + - name: notify + type: boolean + default: true + - name: cache_steps + type: stepList + default: [] + - name: python_version + type: string + default: "3.8" + - name: agent_pool + type: string + default: "AWS-ECS" + +jobs: + - job: build + displayName: Build & Test + timeoutInMinutes: 30 + pool: + name: ${{ parameters.agent_pool }} + workspace: + clean: all + variables: + ${{ each var in parameters.variables }}: + ${{ var.key }}: ${{ var.value }} + steps: + + - bash: | + if [ ! -z "$(ls -A \"$(Pipeline.Workspace)/s/${{ parameters.service_name }}\" 2>/dev/null)" ]; then + echo "workspace directory is not empty!" + exit 1 + fi + displayName: "check workspace is clean" + + - bash: | + instance_id="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)" + echo instance-id: "${instance_id}" + echo connect to: https://eu-west-2.console.aws.amazon.com/systems-manager/session-manager/${instance_id} + echo sudo su - ubuntu + or + echo ssh ubuntu@${instance_id} + echo working directory: $(System.DefaultWorkingDirectory) + displayName: print aws info + + - template: azure/components/aws-clean-config.yml@common + + - ${{ if parameters.notify }}: + - template: azure/components/aws-assume-role.yml@common + parameters: + role: "auto-ops" + profile: "apm_ptl" + + - template: azure/components/get-aws-secrets-and-ssm-params.yml@common + parameters: + secret_file_ids: + - ${{ each secret_file_id in parameters.secret_file_ids }}: + - ${{ secret_file_id }} + secret_ids: + - ptl/access-tokens/github/repo-status-update/GITHUB_ACCESS_TOKEN + - ${{ each secret_id in parameters.secret_ids }}: + - ${{ secret_id }} + config_ids: + - /ptl/azure-devops/GITHUB_USER + - ${{ each config_id in parameters.config_ids }}: + - ${{ config_id }} + + - bash: | + echo "Build.SourceBranch: $(Build.SourceBranch)" + echo "Build.SourceBranchName: $(Build.SourceBranchName)" + echo "Build.SourceVersion: $(Build.SourceVersion)" + echo "Build.SourceVersionMessage: $(Build.SourceVersionMessage)" + + if [[ ! -z $(NOTIFY_COMMIT_SHA) ]]; then + echo "##[debug]Using already provided NOTIFY_COMMIT_SHA=$(NOTIFY_COMMIT_SHA)" + else + NOTIFY_COMMIT_SHA="" + + if [[ "$(Build.SourceBranch)" =~ ^refs/tags/.+$ ]]; then + echo "##[debug]Build appears to be a tag build" + echo "##[debug]Using Build.SourceVersion as NOTIFY_COMMIT_SHA" + NOTIFY_COMMIT_SHA="$(Build.SourceVersion)" + fi + + if [[ "$(Build.SourceBranch)" =~ ^refs/pull/.+$ ]]; then + echo "##[debug]Build appears to be a pull request build" + echo "##[debug]Extracting NOTIFY_COMMIT_SHA from Build.SourceVersionMessage" + NOTIFY_COMMIT_SHA=`echo "$(Build.SourceVersionMessage)" | cut -d' ' -f2` + fi + + if [[ -z $NOTIFY_COMMIT_SHA ]]; then + echo "##[debug]Build does not appear to be pull or tag build" + echo "##[debug]Using Build.SourceVersion as NOTIFY_COMMIT_SHA" + NOTIFY_COMMIT_SHA="$(Build.SourceVersion)" + fi + + echo "##vso[task.setvariable variable=NOTIFY_COMMIT_SHA]$NOTIFY_COMMIT_SHA" + fi + displayName: Set NOTIFY_COMMIT_SHA + condition: always() + + - template: 'azure/components/update-github-status.yml@common' + parameters: + state: pending + description: "Build started" + + - bash: | + if [[ ! -z $(UTILS_PR_NUMBER) ]]; then + echo "##[debug]Triggered from utils repository, PR_NUMBER=$(UTILS_PR_NUMBER)" + echo "##vso[task.setvariable variable=PR_NUMBER]$(UTILS_PR_NUMBER)" + else + echo "##[debug]PR_NUMBER=$(System.PullRequest.PullRequestNumber)" + echo "##vso[task.setvariable variable=PR_NUMBER]$(System.PullRequest.PullRequestNumber)" + fi + displayName: Set PR_NUMBER + + - checkout: self + path: "s/${{ parameters.service_name }}" + submodules: true + + - template: azure/templates/setup-build-name.yml@common + parameters: + service_name: "${{ parameters.service_name }}" + + - bash: | + PATCH=$(curl -s https://api.github.com/repos/actions/python-versions/releases \ + | jq -r '[.[] | .tag_name | select(startswith("3.13"))] | .[]' \ + | sort -V | tail -n 1 | cut -d- -f1) + echo "Resolved latest python version: $PATCH" + echo "##vso[task.setvariable variable=LD_LIBRARY_PATH;]/agent/_work/_tool/Python/${PATCH}/x64/lib/" + displayName: "Query and set python tool cache path" + + - task: UsePythonVersion@0 + displayName: "Use Python ${{ parameters.python_version }}" + inputs: + versionSpec: ${{ parameters.python_version }} + + - ${{ each cache_step in parameters.cache_steps }}: + - ${{ cache_step }} + + - bash: | + n=0 + until [ "$n" -ge 3 ] + do + make install && break + n=$((n+1)) + done + workingDirectory: "${{ parameters.service_name }}" + displayName: Install project dependencies + + - bash: "make lint" + workingDirectory: "${{ parameters.service_name }}" + displayName: Lint + + - ${{ each test_step in parameters.test_steps }}: + - ${{ test_step }} + + - bash: "make publish" + workingDirectory: "${{ parameters.service_name }}" + displayName: Compile spec + + - bash: "make release" + workingDirectory: "${{ parameters.service_name }}" + displayName: Build release package + + - bash: | + if [[ -f ecs-proxies-containers.yml ]]; then + echo "##vso[task.setvariable variable=build_containers]true" + else + echo "##vso[task.setvariable variable=build_containers]false" + fi + workingDirectory: ${{ parameters.service_name }} + displayName: "Check for ECS proxy" + + - checkout: common + path: "s/${{ parameters.service_name }}/utils" + + - task: s3-cache-action@1 + inputs: + key: poetry | $(System.DefaultWorkingDirectory) | ${{ parameters.service_name }}/utils/poetry.lock + location: "${{ parameters.service_name }}/utils/.venv" + debug: true + alias: 'Utils' + displayName: cache utils dependencies + + - bash: | + make install + sleep 5 + workingDirectory: "${{ parameters.service_name }}/utils" + condition: ne(variables['CacheRestored-Utils'], 'true') + displayName: "Install utils " + + - bash: | + export out_dir="$(realpath ${{ parameters.service_name }}/dist)" + export commit_hash="$(git -C ${{ parameters.service_name }} rev-parse --short HEAD)" + # sha prefix is required docker gets upset if names contain -0 iirc + export build_label="$(Build.BuildId)-sha${commit_hash}" + export pr_number="$(PR_NUMBER)" + export service_name="${{ parameters.service_name }}" + export service_id="${{ parameters.short_service_name }}" + export ANSIBLE_FORCE_COLOR=yes + make --no-print-directory -C ${{ parameters.service_name }}/utils/ansible create-build-env-vars + displayName: output build env vars for artifact + condition: and(succeeded(), eq(variables['build_containers'], 'true')) + + - bash: | + tfenv use 0.14.6 + displayName: use terraforn + condition: and(succeeded(), eq(variables['build_containers'], 'true')) + + - bash: | + source "${{ parameters.service_name }}/dist/.build_env_vars" + account=ptl make --no-print-directory -C ${{ parameters.service_name }}/utils/ansible create-ecr-build-role + echo "##vso[task.setvariable variable=BUILD_ROLE]build-${service_id}" + displayName: "ensure build role" + condition: and(succeeded(), eq(variables['build_containers'], 'true')) + + - template: azure/components/aws-assume-role.yml@common + parameters: + role: "$(BUILD_ROLE)" + profile: "$(BUILD_ROLE)" + + - bash: | + source "${{ parameters.service_name }}/dist/.build_env_vars" + CONTAINER_VARS_FILE="$(realpath ${{ parameters.service_name }}/ecs-proxies-containers.yml)" \ + make --no-print-directory -C ${{ parameters.service_name }}/utils/ansible build-ecs-proxies + displayName: "Build and push ECS proxies" + condition: and(succeeded(), eq(variables['build_containers'], 'true')) + + - ${{ each post_ecs_push in parameters.post_ecs_push }}: + - ${{ post_ecs_push }} + + - bash: | + cp ${{ parameters.service_name }}/ecs-*.yml ${{ parameters.service_name }}/dist || true + displayName: "Copy ecs-proxies-deploy configs into build artifact" + condition: and(succeeded(), eq(variables['build_containers'], 'true')) + + - bash: | + rsync -a utils dist --exclude .venv + workingDirectory: "${{ parameters.service_name }}" + displayName: "Copy utils into artifact" + + - bash: | + set -euo pipefail + export DIST_DIR=`pwd`/dist + export ANSIBLE_FORCE_COLOR=yes + if [ -f manifest.yml ]; then + rsync -a manifest.yml dist + make -C utils/ansible validate-manifest + elif [ -f manifest_template.yml ]; then + rsync -a manifest_template.yml dist + make -C utils/ansible template-manifest + make -C utils/ansible validate-manifest + fi + workingDirectory: "${{ parameters.service_name }}" + displayName: "Validate manifest (template) and copy to artifact" + + - bash: | + cd ${{ parameters.service_name }}/utils + git rev-parse HEAD > ../dist/.utils-version + displayName: Snapshot utils version + + - publish: ${{ parameters.service_name}}/dist + artifact: "$(Build.BuildNumber)" + + - ${{ if parameters.notify }}: + - template: 'azure/components/update-github-status.yml@common' + parameters: + state: success + on_success: true + description: "Build succeeded" + + - template: 'azure/components/update-github-status.yml@common' + parameters: + state: failure + on_failure: true + description: "Build failed" diff --git a/azure/azure-build-pipeline.yml b/azure/azure-build-pipeline.yml index 19fc7a4..bac87d0 100644 --- a/azure/azure-build-pipeline.yml +++ b/azure/azure-build-pipeline.yml @@ -22,9 +22,10 @@ resources: variables: - template: project.yml + extends: - template: azure/common/apigee-build.yml@common + template: apigee-build.yml parameters: - python_version: 3.10 + python_version: 3.13 service_name: ${{ variables.service_name }} short_service_name: ${{ variables.short_service_name }} diff --git a/poetry.lock b/poetry.lock index 4670642..76a2834 100644 --- a/poetry.lock +++ b/poetry.lock @@ -37,8 +37,6 @@ mypy-extensions = ">=0.4.3" packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -505,69 +503,7 @@ files = [ {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"}, ] -[[package]] -name = "tomli" -version = "2.3.0" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, - {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, - {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, - {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, - {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, - {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, - {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, - {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, - {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, - {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, - {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, - {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, - {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, - {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "479f43b007424549e9ec6bde3b66e17cf904e956a5f68991dbccbd647e884db4" +python-versions = "^3.13" +content-hash = "dd43c64103218bfbce8169ceafc002810eff774c72298525047b2b587c598590" diff --git a/pyproject.toml b/pyproject.toml index 636cc5a..a6dc6f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [project] -python = "^3.10" +python = "^3.13" name = "nhs-app" [tool.poetry] @@ -23,7 +23,7 @@ keywords = ["healthcare", "uk", "nhs"] #TODO add additional keywords package-mode = false [tool.poetry.dependencies] -python = "^3.10" +python = "^3.13" pyyaml = "^6.0" docopt = "^0.6.2" jsonpath-rw = "^1.4.0"