diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml new file mode 100644 index 00000000..397436de --- /dev/null +++ b/.github/workflows/backend.yml @@ -0,0 +1,55 @@ +name: Backend Lint and Unit Tests + +on: + pull_request: + workflow_dispatch: + +env: + TEST_COGNITO_JWT_URL: ${{ secrets.TEST_COGNITO_JWT_URL }} + +jobs: + lint-backend: + runs-on: ubuntu-latest + container: + image: maven:3.9.9-amazoncorretto-21-alpine + + defaults: + run: + working-directory: ./backend/application/ + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run backend linting (Checkstyle) + run: | + echo "Running backend linting..." + mvn -f ./backendService/pom.xml clean checkstyle:check + echo "Backend linting passed" + + unit-test-backend: + runs-on: ubuntu-latest + needs: lint-backend + container: + image: maven:3.9.9-amazoncorretto-21-alpine + + defaults: + run: + working-directory: ./backend/application/ + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Prepare application.yml for tests + run: | + echo "Copying the test-application.yml into a application.yml file..." + cp ./backendService/src/main/resources/test-application.example.yml ./backendService/src/main/resources/application.yml + cp ./backendService/src/test/resources/application.example.yml ./backendService/src/test/resources/application.yml + echo "Copying completed" + + - name: Run unit tests + run: | + echo "Running unit tests..." + mvn -f ./backendService/pom.xml clean test -DTEST_COGNITO_JWT_URL=$TEST_COGNITO_JWT_URL + echo "Unit tests passed" diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml new file mode 100644 index 00000000..95fceb8a --- /dev/null +++ b/.github/workflows/frontend.yml @@ -0,0 +1,59 @@ +name: Lint and Test Frontend +on: + pull_request: + workflow_dispatch: + +jobs: + lint-frontend: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./frontend + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - name: Install dependencies + run: npm ci + + - name: Set environment variables + run: | + echo "API_KEY=Test" >> $GITHUB_ENV + + - name: Lint frontend + run: npm run lint + + component-tests: + runs-on: ubuntu-latest + needs: lint-frontend + defaults: + run: + working-directory: ./frontend + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - name: Install dependencies + run: npm ci + + - name: Set test environment variables + run: | + echo "API_KEY=Test" >> $GITHUB_ENV + + - name: Cypress.io component tests + uses: cypress-io/github-action@v6.5.0 + with: + working-directory: ./frontend + command: npm run cy:run:ct diff --git a/.github/workflows/infrastructure.yml b/.github/workflows/infrastructure.yml new file mode 100644 index 00000000..4bd5f325 --- /dev/null +++ b/.github/workflows/infrastructure.yml @@ -0,0 +1,24 @@ +name: Infrastructure Lint +on: + pull_request: + +jobs: + lint-and-security-scan-infrastructure: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: ./infrastructure + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup TFLint + uses: terraform-linters/setup-tflint@v4.1.1 + + - name: Initialise TFLint + run: tflint --init + + - name: Run TFLint + run: tflint --recursive diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 2f745b9b..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,28 +0,0 @@ -stages: - - triggers - -# Create a trigger for running the frontend workflow -trigger_frontend_workflow: - stage: triggers - trigger: - include: product/CICD/gitlab/frontend.yml - -# Create a trigger for running the backend workflow -trigger_backend_workflow: - stage: triggers - trigger: - include: product/CICD/gitlab/backend.yml - -# This will be included after issues with the runners are resolved - -# Run Terraform workflow if there are changes in the terraform directory -# trigger_terraform_workflow: -# stage: triggers -# rules: -# - if: '$CI_COMMIT_REF_NAME == "main" || $CI_COMMIT_REF_NAME == "development" || $CI_COMMIT_REF_NAME == "terraform-updates"' -# changes: -# - product/infrastructure/* -# when: on_success -# - when: manual -# trigger: -# include: product/.gitlab/workflows/terraform.yml \ No newline at end of file diff --git a/CICD/gitlab/backend.yml b/CICD/gitlab/backend.yml deleted file mode 100644 index 50c7b8b6..00000000 --- a/CICD/gitlab/backend.yml +++ /dev/null @@ -1,31 +0,0 @@ -stages: - - build - - test - -before_script: - - echo "Setting up the environment..." - - cd ./backend/ - -lint_backend: - stage: test - image: maven:3.9.9-amazoncorretto-21-alpine - script: - - echo "Running backend linting..." - - cd ./application/ - - mvn clean checkstyle:check - - echo "Backend linting passed" - -unit_test_backend: - stage: test - image: maven:3.9.9-amazoncorretto-21-alpine - variables: - TEST_COGNITO_JWT_URL: $TEST_COGNITO_JWT_URL - script: - - echo "Copying the test-application.yml into a application.yml file..." - - cp ./application/backendService/src/main/resources/test-application.example.yml ./application/backendService/src/main/resources/application.yml - - cp ./application/backendService/src/test/resources/application.example.yml ./application/backendService/src/test/resources/application.yml - - echo "Copying completed" - - echo "Running unit tests..." - - cd ./application/ - - mvn -f ./backendService/pom.xml clean test -DTEST_COGNITO_JWT_URL=$TEST_COGNITO_JWT_URL - - echo "Unit tests passed" diff --git a/CICD/gitlab/frontend.yml b/CICD/gitlab/frontend.yml deleted file mode 100644 index c28b40e9..00000000 --- a/CICD/gitlab/frontend.yml +++ /dev/null @@ -1,34 +0,0 @@ -image: node:23-alpine - -stages: - - lint - - test - -default: - cache: - key: $CI_COMMIT_REF_SLUG - paths: - - .npm/ - before_script: - - cd ./frontend/ - - echo "Installing dependencies..." - - npm ci --cache .npm --prefer-offline - -lint_frontend: - stage: lint - script: - - echo "Running frontend linting..." - - npm run lint - -knip_frontend: - stage: lint - script: - - echo "Running frontend knip..." - - export API_KEY="Test" # Added mock api key for knip - - npm run knip - -component_test_frontend: - stage: test - script: - - echo "Running frontend component tests..." - - npm run cy:run:ct \ No newline at end of file diff --git a/CICD/gitlab/terraform.yml b/CICD/gitlab/terraform.yml deleted file mode 100644 index b8c7e143..00000000 --- a/CICD/gitlab/terraform.yml +++ /dev/null @@ -1,13 +0,0 @@ -stages: - - lint - -before_script: - - echo "Setting up the environment..." - - cd ./infrastructure - -terraform_init: - stage: lint - image: hashicorp/terraform:latest - script: - - terraform init - diff --git a/frontend/src/app/api/billing/payments/route.ts b/frontend/src/app/api/billing/payments/route.ts index f6f1f708..817d1419 100644 --- a/frontend/src/app/api/billing/payments/route.ts +++ b/frontend/src/app/api/billing/payments/route.ts @@ -1,4 +1,3 @@ -// File: app/api/billing/subscriptions/route.ts (for App Router) import stripe from "@/utils/stripe"; import { NextRequest, NextResponse } from "next/server"; diff --git a/frontend/src/app/api/billing/subscriptions/route.ts b/frontend/src/app/api/billing/subscriptions/route.ts index 35fc79e1..34ff8c20 100644 --- a/frontend/src/app/api/billing/subscriptions/route.ts +++ b/frontend/src/app/api/billing/subscriptions/route.ts @@ -1,4 +1,3 @@ -// File: app/api/billing/subscriptions/route.ts (for App Router) import stripe, { findExistingSubscriptionByCustomerId } from "@/utils/stripe"; import { NextRequest, NextResponse } from "next/server"; import Stripe from "stripe"; diff --git a/frontend/src/components/ui/Sidebar.tsx b/frontend/src/components/ui/Sidebar.tsx index cbf5a814..995a45b0 100644 --- a/frontend/src/components/ui/Sidebar.tsx +++ b/frontend/src/components/ui/Sidebar.tsx @@ -42,10 +42,10 @@ export function Sidebar() { const userBilling = useQuery(GET_USER_BILLING); const accountId = userBilling.data?.getUserBilling?.accountId; - + // Filter out the Items page from sidebar links if no account ID exists - const filteredSidebarLinks = sidebarLinks.filter(link => - link.name !== "Items" || accountId + const filteredSidebarLinks = sidebarLinks.filter( + (link) => link.name !== "Items" || accountId, ); return ( diff --git a/frontend/src/utils/stripe.ts b/frontend/src/utils/stripe.ts index b73bb773..daecf9bd 100644 --- a/frontend/src/utils/stripe.ts +++ b/frontend/src/utils/stripe.ts @@ -3,9 +3,7 @@ import Stripe from "stripe"; if (!process.env.STRIPE_SECRET_KEY) { throw new Error("Stripe secret key is not configured."); } -const stripe = new Stripe( - "sk_test_51QNhlTGlnq0aqIkWUh4pGdNEkLo6qGgkXU885vaJexq15ykuThU9JDTxo77RTjCqNxRP6QkW30y7cZEIOLEpn6KD00uBKttude", -); +const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); export default stripe; /** diff --git a/infrastructure/remote/modules/cicd/main.tf b/infrastructure/remote/modules/cicd/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/cicd/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/cicd/secrets.tf b/infrastructure/remote/modules/cicd/secrets.tf index 9516dec7..a22ce642 100644 --- a/infrastructure/remote/modules/cicd/secrets.tf +++ b/infrastructure/remote/modules/cicd/secrets.tf @@ -1,4 +1,3 @@ -data "aws_region" "current" {} resource "aws_secretsmanager_secret" "gitlab_credentials" { name = "GITLAB_CREDENTIALS_${var.environment}" diff --git a/infrastructure/remote/modules/cicd/variables.tf b/infrastructure/remote/modules/cicd/variables.tf index e0a77391..9f45436f 100644 --- a/infrastructure/remote/modules/cicd/variables.tf +++ b/infrastructure/remote/modules/cicd/variables.tf @@ -8,11 +8,6 @@ variable "environment" { } } -variable "aws_region" { - description = "The AWS region to deploy to" - type = string -} - variable "aws_account_id" { description = "The AWS account ID" type = string diff --git a/infrastructure/remote/modules/cognito/main.tf b/infrastructure/remote/modules/cognito/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/cognito/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/ecr/main.tf b/infrastructure/remote/modules/ecr/main.tf index 1b6aabc6..5643dd52 100644 --- a/infrastructure/remote/modules/ecr/main.tf +++ b/infrastructure/remote/modules/ecr/main.tf @@ -1,3 +1,13 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} + resource "aws_ecr_repository" "ecr_repo" { name = var.name image_tag_mutability = "IMMUTABLE" diff --git a/infrastructure/remote/modules/ecs/main.tf b/infrastructure/remote/modules/ecs/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/ecs/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/elasticache/main.tf b/infrastructure/remote/modules/elasticache/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/elasticache/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/elasticache/variables.tf b/infrastructure/remote/modules/elasticache/variables.tf index ee365fb2..7483b524 100644 --- a/infrastructure/remote/modules/elasticache/variables.tf +++ b/infrastructure/remote/modules/elasticache/variables.tf @@ -9,11 +9,6 @@ variable "environment" { } } -variable "availability_zones" { - description = "The availability zones for the database" - type = list(string) -} - variable "private_subnet_ids" { description = "The IDs of the private subnets" type = list(string) diff --git a/infrastructure/remote/modules/iam/ecs.tf b/infrastructure/remote/modules/iam/ecs.tf index 8abe1ea5..b23437e8 100644 --- a/infrastructure/remote/modules/iam/ecs.tf +++ b/infrastructure/remote/modules/iam/ecs.tf @@ -119,7 +119,7 @@ resource "aws_iam_policy" "ecs_dynamodb_admin_logs_policy" { "dynamodb:BatchWriteItem", "dynamodb:DescribeTable" ] - Resource = "${var.admin_access_logs_table_arn}" + Resource = var.admin_access_logs_table_arn }, ] diff --git a/infrastructure/remote/modules/iam/main.tf b/infrastructure/remote/modules/iam/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/iam/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/kafka/main.tf b/infrastructure/remote/modules/kafka/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/kafka/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/networking/main.tf b/infrastructure/remote/modules/networking/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/networking/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/rds/main.tf b/infrastructure/remote/modules/rds/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/rds/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/route53/certificates.tf b/infrastructure/remote/modules/route53/certificates.tf index 268f652c..60731e4e 100644 --- a/infrastructure/remote/modules/route53/certificates.tf +++ b/infrastructure/remote/modules/route53/certificates.tf @@ -1,10 +1,10 @@ resource "aws_acm_certificate" "acm_certificate" { - domain_name = var.environment == "prod" ? "${var.domain}" : "${var.environment}.${var.domain}" + domain_name = var.environment == "prod" ? var.domain : "${var.environment}.${var.domain}" validation_method = "DNS" subject_alternative_names = [ - "www.${var.environment == "prod" ? "${var.domain}" : "${var.environment}.${var.domain}"}", + "www.${var.environment == "prod" ? var.domain : "${var.environment}.${var.domain}"}", ] lifecycle { diff --git a/infrastructure/remote/modules/route53/main.tf b/infrastructure/remote/modules/route53/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/route53/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/route53/routes.tf b/infrastructure/remote/modules/route53/routes.tf index fddfd198..47dd5339 100644 --- a/infrastructure/remote/modules/route53/routes.tf +++ b/infrastructure/remote/modules/route53/routes.tf @@ -2,7 +2,7 @@ # Record to the alb resource "aws_route53_record" "route_53_alb_record" { zone_id = aws_route53_zone.route_53_hosted_zone.zone_id - name = var.environment == "prod" ? "${var.domain}" : "${var.environment}.${var.domain}" + name = var.environment == "prod" ? var.domain : "${var.environment}.${var.domain}" type = "A" alias { diff --git a/infrastructure/remote/modules/s3/main.tf b/infrastructure/remote/modules/s3/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/s3/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/modules/ses/main.tf b/infrastructure/remote/modules/ses/main.tf index 3fbed97a..124bd279 100644 --- a/infrastructure/remote/modules/ses/main.tf +++ b/infrastructure/remote/modules/ses/main.tf @@ -1,3 +1,13 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} + data "aws_region" "current" {} resource "aws_ses_domain_identity" "ses_domain" { diff --git a/infrastructure/remote/modules/ssm/main.tf b/infrastructure/remote/modules/ssm/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/remote/modules/ssm/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/remote/variables.tf b/infrastructure/remote/variables.tf index dcf3716a..983dd0c3 100644 --- a/infrastructure/remote/variables.tf +++ b/infrastructure/remote/variables.tf @@ -61,11 +61,11 @@ variable "backend_image_tag" { default = "latest" } -variable "apollo_gateway_image_tag" { - description = "The tag of the apollo gateway Docker image to deploy" - type = string - default = "latest" -} +# variable "apollo_gateway_image_tag" { +# description = "The tag of the apollo gateway Docker image to deploy" +# type = string +# default = "latest" +# } # SSM variable "nextauth_secret" { diff --git a/infrastructure/shared/dynamodb/main.tf b/infrastructure/shared/dynamodb/main.tf new file mode 100644 index 00000000..b408648f --- /dev/null +++ b/infrastructure/shared/dynamodb/main.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} \ No newline at end of file diff --git a/infrastructure/shared/s3/images-bucket.tf b/infrastructure/shared/s3/images-bucket.tf index 80fdbc74..1bd7a9d9 100644 --- a/infrastructure/shared/s3/images-bucket.tf +++ b/infrastructure/shared/s3/images-bucket.tf @@ -1,3 +1,13 @@ +terraform { + required_version = ">= 1.9" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.60.0" + } + } +} + resource "aws_s3_bucket" "images_bucket" { bucket = "${var.environment}-subshop-images-bucket" force_destroy = true