diff --git a/.github/workflows/.builds.yml b/.github/workflows/.builds.yml new file mode 100644 index 00000000..2d04aa31 --- /dev/null +++ b/.github/workflows/.builds.yml @@ -0,0 +1,32 @@ +name: Build Containers + +on: + workflow_call: + inputs: + tags: + description: 'Tags to apply to the built containers multiline, separated by newlines' + required: true + type: string +permissions: + id-token: write # This is required for requesting the JWT + contents: write # This is required for actions/checkout + packages: write + pull-requests: write + security-events: write + attestations: write # This is required for uploading attestations to the Security tab +jobs: + # https://github.com/bcgov/action-builder-ghcr + builds: + name: Builds + runs-on: ubuntu-24.04 + strategy: + matrix: + # Only building frontend containers to run PR based e2e tests + package: [backend, migrations, frontend] + timeout-minutes: 10 + steps: + - uses: bcgov/action-builder-ghcr@v4.0.0 + with: + package: ${{ matrix.package }} + tags: ${{ inputs.tags }} + tag_fallback: test \ No newline at end of file diff --git a/.github/workflows/.tests.yml b/.github/workflows/.tests.yml index adeb1b76..889b7f0d 100644 --- a/.github/workflows/.tests.yml +++ b/.github/workflows/.tests.yml @@ -18,7 +18,7 @@ jobs: timeout-minutes: 5 services: postgres: - image: postgres + image: postgis/postgis:17-3.5 # Updated to PostgreSQL 17 with PostGIS 3.5 env: POSTGRES_PASSWORD: default options: >- @@ -29,9 +29,10 @@ jobs: ports: - 5432:5432 steps: - - uses: bcgov-nr/action-test-and-analyse@e2ba34132662c1638dbde806064eb7004b3761c3 # v1.3.0 + - uses: bcgov-nr/action-test-and-analyse@v1.3.0 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN_BACKEND }} + NODE_ENV: unittest with: commands: | npm ci @@ -54,7 +55,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 5 steps: - - uses: bcgov/action-test-and-analyse@e2ba34132662c1638dbde806064eb7004b3761c3 # v1.3.0 + - uses: bcgov/action-test-and-analyse@v1.3.0 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN_FRONTEND }} with: diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml index 96d04e43..3e63a81f 100644 --- a/.github/workflows/pr-open.yml +++ b/.github/workflows/pr-open.yml @@ -5,40 +5,33 @@ on: workflow_dispatch: -concurrency: - # Cancel in progress for PR open and close - group: ${{ github.event.number || 'latest' }} - cancel-in-progress: false permissions: id-token: write # This is required for requesting the JWT contents: write # This is required for actions/checkout packages: write pull-requests: write security-events: write + attestations: write # This is required for uploading attestations to the Security tab env: AWS_REGION: ca-central-1 jobs: # https://github.com/bcgov-nr/action-builder-ghcr builds: - name: Builds - runs-on: ubuntu-24.04 - strategy: - matrix: - package: [backend, migrations, frontend] - timeout-minutes: 10 - steps: - - uses: bcgov-nr/action-builder-ghcr@ec30e4ce1ac3c25c93ec26cf370ecba028dc478e # v3.0.1 - with: - package: ${{ matrix.package }} - tags: | - ${{ github.event.number || 'manual' }} - latest - pr-${{ github.event.number || 'manual' }} - tag_fallback: latest - triggers: ('${{ matrix.package }}/') - + concurrency: + # Cancel in progress for PR open and close + group: builds-${{ github.event.number || 'latest' }} + cancel-in-progress: true + uses: ./.github/workflows/.builds.yml + with: + tags: | + ${{ github.event.number || 'manual' }} + latest + plan-stack: name: Plan Stack + concurrency: + group: plan-stack-${{ github.event.number || 'latest' }} + cancel-in-progress: false uses: ./.github/workflows/.deploy_stack.yml with: environment_name: dev @@ -50,18 +43,28 @@ jobs: tests: name: Tests needs: builds + concurrency: + # Cancel in progress for PR open and close + group: tests-${{ github.event.number || 'latest' }} + cancel-in-progress: true uses: ./.github/workflows/.tests.yml with: tag: ${{ github.event.number || 'latest' }} resume-resources-dev: name: Resume Resources Dev if: (github.event_name == 'workflow_dispatch') + concurrency: + group: rrd-${{ github.event.number || 'latest' }} + cancel-in-progress: false needs: [builds] uses: ./.github/workflows/resume-resources.yml secrets: inherit deploy-to-dev: name: Deploy to Dev if: (github.event_name == 'workflow_dispatch') + concurrency: + group: deploy-dev-${{ github.event.number || 'latest' }} + cancel-in-progress: false needs: [resume-resources-dev] uses: ./.github/workflows/.deploy_stack.yml with: @@ -72,6 +75,9 @@ jobs: secrets: inherit results: name: PR Results + concurrency: + group: pr-results-${{ github.event.number || 'latest' }} + cancel-in-progress: true needs: [builds, plan-stack, tests] if: always() runs-on: ubuntu-24.04 diff --git a/README.md b/README.md index 2d51fe65..fc25f751 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Prerequisites: 1. Install JDK 17 and above. 2. Install Node.js 22 and above. - 3. Install Postgres 16.4 with Postgis extension. + 3. Install Postgres 17.4 with Postgis extension. 4. Download flyway.jar file Once all the softwares are installed follow below steps. diff --git a/backend/src/prisma.service.ts b/backend/src/prisma.service.ts index 1b231f46..c94decb4 100644 --- a/backend/src/prisma.service.ts +++ b/backend/src/prisma.service.ts @@ -7,7 +7,9 @@ const DB_PWD = encodeURIComponent(process.env.POSTGRES_PASSWORD || "default"); / const DB_PORT = process.env.POSTGRES_PORT || 5432; const DB_NAME = process.env.POSTGRES_DATABASE || "postgres"; const DB_SCHEMA = process.env.POSTGRES_SCHEMA || "app"; -const dataSourceURL = `postgresql://${DB_USER}:${DB_PWD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?schema=${DB_SCHEMA}&connection_limit=5`; +// SSL settings for PostgreSQL 17+ which requires SSL by default +const SSL_MODE = (process.env.NODE_ENV === 'local' || 'unittest') ? 'prefer' : 'require'; // 'require' for aws deployments, 'prefer' for local development or ut in gha +const dataSourceURL = `postgresql://${DB_USER}:${DB_PWD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?schema=${DB_SCHEMA}&connection_limit=5&sslmode=${SSL_MODE}`; @Injectable({ scope: Scope.DEFAULT}) class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { diff --git a/docker-compose.yml b/docker-compose.yml index 1c089e2c..4e5d4554 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ x-postgres-vars: &postgres-vars services: database: - image: postgis/postgis:16-3.4 # if using crunchy , make sure to align with crunchy version, currently it is at 16 and postgis 3.3 + image: postgis/postgis:17-3.5 # Updated to PostgreSQL 17 with PostGIS 3.4 container_name: database environment: <<: *postgres-vars @@ -38,7 +38,6 @@ services: depends_on: database: condition: service_healthy - schemaspy: image: schemaspy/schemaspy:6.2.4 profiles: ["schemaspy"] diff --git a/infrastructure/api/ecs.tf b/infrastructure/api/ecs.tf index 1c8211be..ab2d82ab 100644 --- a/infrastructure/api/ecs.tf +++ b/infrastructure/api/ecs.tf @@ -48,14 +48,14 @@ resource "aws_ecs_task_definition" "flyway_task" { execution_role_arn = aws_iam_role.ecs_task_execution_role.arn task_role_arn = aws_iam_role.app_container_role.arn container_definitions = jsonencode([ - { + { name = "${var.app_name}-flyway" image = "${var.flyway_image}" - essential = true + essential = true environment = [ { name = "FLYWAY_URL" - value = "jdbc:postgresql://${data.aws_rds_cluster.rds_cluster.endpoint}/${var.db_name}" + value = "jdbc:postgresql://${data.aws_rds_cluster.rds_cluster.endpoint}/${var.db_name}?sslmode=require" }, { name = "FLYWAY_USER" @@ -196,12 +196,11 @@ resource "aws_ecs_task_definition" "node_api_task" { name = "POSTGRES_DATABASE" value = var.db_name }, - { + { name = "POSTGRES_SCHEMA" value = "${var.db_schema}" - } - , - { + }, + { name = "PORT" value = "3000" } diff --git a/infrastructure/database/aurora-v2.tf b/infrastructure/database/aurora-v2.tf index cbd11be7..5c6272ec 100644 --- a/infrastructure/database/aurora-v2.tf +++ b/infrastructure/database/aurora-v2.tf @@ -25,25 +25,7 @@ resource "aws_db_subnet_group" "db_subnet_group" { data "aws_rds_engine_version" "postgresql" { engine = "aurora-postgresql" - version = "16.8" -} - -resource "aws_db_parameter_group" "db_postgresql" { - name = "${var.db_cluster_name}-parameter-group" - family = "aurora-postgresql16" - description = "${var.db_cluster_name}-parameter-group" - tags = { - managed-by = "terraform" - } -} - -resource "aws_rds_cluster_parameter_group" "db_postgresql" { - name = "${var.db_cluster_name}-cluster-parameter-group" - family = "aurora-postgresql16" - description = "${var.db_cluster_name}-cluster-parameter-group" - tags = { - managed-by = "terraform" - } + version = "17.4" } @@ -67,14 +49,14 @@ EOF module "aurora_postgresql_v2" { source = "terraform-aws-modules/rds-aurora/aws" version = "9.14.0" - + allow_major_version_upgrade = true name = var.db_cluster_name engine = data.aws_rds_engine_version.postgresql.engine engine_mode = "provisioned" engine_version = data.aws_rds_engine_version.postgresql.version storage_encrypted = true database_name = var.db_database_name - + vpc_id = data.aws_vpc.main.id vpc_security_group_ids = [data.aws_security_group.data.id] db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name @@ -92,8 +74,6 @@ module "aurora_postgresql_v2" { skip_final_snapshot = true auto_minor_version_upgrade = false - db_parameter_group_name = aws_db_parameter_group.db_postgresql.id - db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.db_postgresql.id deletion_protection = contains(["prod"], var.app_env) ? true : false serverlessv2_scaling_configuration = { min_capacity = var.min_capacity diff --git a/infrastructure/frontend/outputs.tf b/infrastructure/frontend/outputs.tf index eabdab53..180cb04f 100644 --- a/infrastructure/frontend/outputs.tf +++ b/infrastructure/frontend/outputs.tf @@ -3,6 +3,7 @@ output "cloudfront" { value = { domain_name = aws_cloudfront_distribution.s3_distribution.domain_name distribution_id = aws_cloudfront_distribution.s3_distribution.id + url= "https://${aws_cloudfront_distribution.s3_distribution.domain_name}" } }