diff --git a/.circleci/config.yml b/.circleci/config.yml index 08dbf85c..3b91b357 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,17 +1,11 @@ version: 2.1 - orbs: hmpps: ministryofjustice/hmpps@9 slack: circleci/slack@4.12.5 - parameters: - alerts-slack-channel: - type: string - default: probation-integration-notifications releases-slack-channel: type: string default: probation-integration-notifications - jobs: validate: executor: @@ -24,18 +18,16 @@ jobs: - hmpps/install_aws_cli - run: name: Wait for SQS to be ready - command: curl -4 --connect-timeout 30 --retry-connrefused --retry 2 - --retry-delay 5 http://localhost:4566 + command: curl -4 --connect-timeout 30 --retry-connrefused --retry 2 --retry-delay 5 http://localhost:4566 - restore_cache: keys: - gradle-{{ checksum "build.gradle.kts" }} - gradle- - run: - command: ./gradlew -Dorg.gradle.jvmargs="--illegal-access=permit" - -Dkotlin.daemon.jvm.options="--illegal-access=permit" check + command: ./gradlew -Dorg.gradle.jvmargs="--illegal-access=permit" -Dkotlin.daemon.jvm.options="--illegal-access=permit" check - when: condition: - equal: [ main, << pipeline.git.branch >> ] + equal: [main, << pipeline.git.branch >>] steps: - slack/notify: event: fail @@ -52,7 +44,6 @@ jobs: - store_artifacts: path: build/reports/coverage destination: coverage - workflows: version: 2 build-test-and-deploy: @@ -120,32 +111,3 @@ workflows: requires: - request-prod-approval helm_timeout: 5m - - security: - triggers: - - schedule: - cron: "45 9 * * 1-5" - filters: - branches: - only: - - main - jobs: - - hmpps/veracode_pipeline_scan: - slack_channel: << pipeline.parameters.alerts-slack-channel >> - context: - - hmpps-common-vars - - veracode-credentials - security-weekly: - triggers: - - schedule: - cron: "32 5 * * 1" - filters: - branches: - only: - - main - jobs: - - hmpps/veracode_policy_scan: - slack_channel: << pipeline.parameters.alerts-slack-channel >> - context: - - veracode-credentials - - hmpps-common-vars diff --git a/.circleci/config.yml.bak.20250226_172318 b/.circleci/config.yml.bak.20250226_172318 new file mode 100644 index 00000000..08dbf85c --- /dev/null +++ b/.circleci/config.yml.bak.20250226_172318 @@ -0,0 +1,151 @@ +version: 2.1 + +orbs: + hmpps: ministryofjustice/hmpps@9 + slack: circleci/slack@4.12.5 + +parameters: + alerts-slack-channel: + type: string + default: probation-integration-notifications + releases-slack-channel: + type: string + default: probation-integration-notifications + +jobs: + validate: + executor: + name: hmpps/java_localstack_postgres + jdk_tag: "21.0" + localstack_tag: "3" + postgres_tag: "16" + steps: + - checkout + - hmpps/install_aws_cli + - run: + name: Wait for SQS to be ready + command: curl -4 --connect-timeout 30 --retry-connrefused --retry 2 + --retry-delay 5 http://localhost:4566 + - restore_cache: + keys: + - gradle-{{ checksum "build.gradle.kts" }} + - gradle- + - run: + command: ./gradlew -Dorg.gradle.jvmargs="--illegal-access=permit" + -Dkotlin.daemon.jvm.options="--illegal-access=permit" check + - when: + condition: + equal: [ main, << pipeline.git.branch >> ] + steps: + - slack/notify: + event: fail + channel: << pipeline.parameters.alerts-slack-channel >> + template: basic_fail_1 + - save_cache: + paths: + - ~/.gradle + key: gradle-{{ checksum "build.gradle.kts" }} + - store_test_results: + path: build/test-results + - store_artifacts: + path: build/reports/tests/test + - store_artifacts: + path: build/reports/coverage + destination: coverage + +workflows: + version: 2 + build-test-and-deploy: + jobs: + - validate: + context: hmpps-common-vars + filters: + tags: + ignore: /.*/ + - hmpps/helm_lint: + name: helm_lint + - hmpps/build_docker: + name: build_docker + filters: + branches: + only: + - main + - hmpps/deploy_env: + name: deploy_dev + env: "dev" + jira_update: true + jira_env_type: development + context: hmpps-common-vars + filters: + branches: + only: + - main + requires: + - validate + - build_docker + - helm_lint + helm_timeout: 5m + - hmpps/deploy_env: + name: deploy_preprod + env: "preprod" + jira_update: true + jira_env_type: staging + context: + - hmpps-common-vars + - hmpps-tier-preprod + filters: + branches: + only: + - main + requires: + - validate + - build_docker + - helm_lint + helm_timeout: 5m + - request-prod-approval: + type: approval + requires: + - deploy_preprod + - deploy_dev + - hmpps/deploy_env: + name: deploy_prod + env: "prod" + jira_update: true + jira_env_type: production + slack_notification: true + slack_channel_name: << pipeline.parameters.releases-slack-channel >> + context: + - hmpps-common-vars + - hmpps-tier-prod + requires: + - request-prod-approval + helm_timeout: 5m + + security: + triggers: + - schedule: + cron: "45 9 * * 1-5" + filters: + branches: + only: + - main + jobs: + - hmpps/veracode_pipeline_scan: + slack_channel: << pipeline.parameters.alerts-slack-channel >> + context: + - hmpps-common-vars + - veracode-credentials + security-weekly: + triggers: + - schedule: + cron: "32 5 * * 1" + filters: + branches: + only: + - main + jobs: + - hmpps/veracode_policy_scan: + slack_channel: << pipeline.parameters.alerts-slack-channel >> + context: + - veracode-credentials + - hmpps-common-vars diff --git a/.github/workflows/kotlin_localstack_postgres_validate.yml b/.github/workflows/kotlin_localstack_postgres_validate.yml new file mode 100644 index 00000000..5c6a09a2 --- /dev/null +++ b/.github/workflows/kotlin_localstack_postgres_validate.yml @@ -0,0 +1,106 @@ +name: validate template for kotlin with localstack and postgres + +on: + workflow_call: + inputs: + working_directory: + type: string + required: false + default: '~/app' + java_version: + type: string + required: false + default: '21' + java_options: + type: string + default: 'default: -Xmx512m -XX:ParallelGCThreads=2 -XX:ConcGCThreads=2 -Djava.util.concurrent.ForkJoinPool.common.parallelism=2 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy=in-process -Dorg.gradle.workers.max=1' + required: false + postgres_tag: + type: string + required: true + postgres_password: + type: string + default: 'dev' + required: false + postgres_username: + type: string + default: 'root' + required: true + postgres_db: + type: string + default: 'postgres' + required: false + services: + type: string + default: 's3,sqs,sns,es,ec2,lambda' + required: false + localstack_tag: + type: string + default: 'latest' + required: false + +permissions: + contents: read + +jobs: + template_job: + runs-on: ubuntu-latest + # Label used to access the service container + services: + postgres: + # Docker Hub PostgreSQL image + image: postgres:${{ inputs.postgres_tag }} + # Provide the password for postgres + env: + POSTGRES_USER: ${{ inputs.postgres_username }} + POSTGRES_PASSWORD: ${{ inputs.postgres_password }} + POSTGRES_DB: ${{ inputs.postgres_db}} + + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + # Maps tcp port 5432 on service container to the host + - 5432:5432 + localstack: + image: localstack/localstack:${{ inputs.localstack_tag }} + ports: + - 4566:4566 + - 4571:4571 + env: + ES_PORT_EXTERNAL: 4571 + DOCKER_HOST: 'unix:///var/run/docker.sock' + AWS_EXECUTION_ENV: True + PERSISTENCE: 1 + SERVICES: "${{ inputs.services }}" + steps: + - uses: actions/checkout@v4 + - name: refresh cache + id: initial-cache + uses: actions/cache@v4 + env: + cache-name: kotlin-cache + with: + path: | + - gradle-{{ checksum "build.gradle.kts" }} + - gradle- + key: ${{ runner.os }}-gradle-${{ env.cache-name }}-${{ hashFiles('build.gradle.kts') }} + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '${{ inputs.java_version }}' + cache: 'gradle' + cache-dependency-path: | + *.gradle* + **/gradle-wrapper.properties + - run: ./gradlew check + - name: upload the artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: upload kotlin valdation results + path: | + build/test-results + build/reports/tests diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml new file mode 100644 index 00000000..baee5c5e --- /dev/null +++ b/.github/workflows/pipeline.yml @@ -0,0 +1,77 @@ +name: Pipeline [test -> build -> deploy] +on: + push: + branches: + - '**' + workflow_dispatch: + inputs: + additional_docker_tag: + description: Additional docker tag that can be used to specify stable or testing tags + required: false + default: '' + type: string + push: + description: Push docker image to registry flag + required: true + default: false + type: boolean +permissions: + contents: read + packages: write +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} +jobs: + helm_lint: + strategy: + matrix: + environments: ['dev', 'preprod', 'prod'] + name: helm lint + uses: ministryofjustice/hmpps-github-actions/.github/workflows/test_helm_lint.yml@v2 # WORKFLOW VERSION + secrets: inherit + with: + environment: ${{ matrix.environments }} + kotlin_validate: + name: Validate the kotlin + uses: ./.github/workflows/kotlin_localstack_postgres_validate.yml + with: + postgres_tag: '16' + postgres_username: 'root' + postgres_password: 'dev' + secrets: inherit + build: + name: Build docker image from hmpps-github-actions + if: github.ref == 'refs/heads/main' + uses: ministryofjustice/hmpps-github-actions/.github/workflows/docker_build.yml@v2 # WORKFLOW_VERSION + needs: + - kotlin_validate + with: + docker_registry: 'ghcr.io' + registry_org: 'ministryofjustice' + additional_docker_tag: ${{ inputs.additional_docker_tag }} + push: ${{ inputs.push || true }} + docker_multiplatform: false + deploy_dev: + name: Deploy to the dev environment + if: github.ref == 'refs/heads/main' + needs: + - build + - helm_lint + uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION + secrets: inherit + with: + environment: 'dev' + app_version: '${{ needs.build.outputs.app_version }}' + helm_timeout: '5m' + deploy_preprod: + name: Deploy to the preprod environment + if: github.ref == 'refs/heads/main' + needs: + - build + - helm_lint + uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION + secrets: inherit + with: + environment: 'preprod' + app_version: '${{ needs.build.outputs.app_version }}' + helm_timeout: '5m' \ No newline at end of file diff --git a/.github/workflows/security_owasp.yml b/.github/workflows/security_owasp.yml new file mode 100644 index 00000000..6f10aecb --- /dev/null +++ b/.github/workflows/security_owasp.yml @@ -0,0 +1,12 @@ +name: Security OWASP dependency check +on: + workflow_dispatch: + schedule: + - cron: "39 6 * * MON-FRI" # Every weekday at 06:39 UTC +jobs: + security-kotlin-owasp-check: + name: Kotlin security OWASP dependency check + uses: ministryofjustice/hmpps-github-actions/.github/workflows/security_owasp.yml@v2 # WORKFLOW_VERSION + with: + channel_id: ${{ vars.SECURITY_ALERTS_SLACK_CHANNEL_ID || 'NO_SLACK' }} + secrets: inherit diff --git a/.github/workflows/security_trivy.yml b/.github/workflows/security_trivy.yml new file mode 100644 index 00000000..4f9345d5 --- /dev/null +++ b/.github/workflows/security_trivy.yml @@ -0,0 +1,12 @@ +name: Security trivy dependency check +on: + workflow_dispatch: + schedule: + - cron: "39 6 * * MON-FRI" # Every weekday at 06:39 UTC +jobs: + security-kotlin-trivy-check: + name: Project security trivy dependency check + uses: ministryofjustice/hmpps-github-actions/.github/workflows/security_trivy.yml@v2 # WORKFLOW_VERSION + with: + channel_id: ${{ vars.SECURITY_ALERTS_SLACK_CHANNEL_ID || 'NO_SLACK' }} + secrets: inherit diff --git a/.github/workflows/security_veracode_pipeline_scan.yml b/.github/workflows/security_veracode_pipeline_scan.yml new file mode 100644 index 00000000..1c9601ea --- /dev/null +++ b/.github/workflows/security_veracode_pipeline_scan.yml @@ -0,0 +1,12 @@ +name: Security veracode pipeline scan +on: + workflow_dispatch: + schedule: + - cron: "39 6 * * MON-FRI" # Every weekday at 06:39 UTC +jobs: + security-veracode-pipeline-scan: + name: Project security veracode pipeline scan + uses: ministryofjustice/hmpps-github-actions/.github/workflows/security_veracode_pipeline_scan.yml@v2 # WORKFLOW_VERSION + with: + channel_id: ${{ vars.SECURITY_ALERTS_SLACK_CHANNEL_ID || 'NO_SLACK' }} + secrets: inherit diff --git a/.github/workflows/security_veracode_policy_scan.yml b/.github/workflows/security_veracode_policy_scan.yml new file mode 100644 index 00000000..13181241 --- /dev/null +++ b/.github/workflows/security_veracode_policy_scan.yml @@ -0,0 +1,12 @@ +name: Security veracode policy scan +on: + workflow_dispatch: + schedule: + - cron: "6 6 * * 1" # Every Monday at 06:06 UTC +jobs: + security-veracode-policy-check: + name: Project security veracode policy scan + uses: ministryofjustice/hmpps-github-actions/.github/workflows/security_veracode_policy_scan.yml@v2 # WORKFLOW_VERSION + with: + channel_id: ${{ vars.SECURITY_ALERTS_SLACK_CHANNEL_ID || 'NO_SLACK' }} + secrets: inherit