From 4543957b87f7e6548d5c672a8a3f2ce0a4608a04 Mon Sep 17 00:00:00 2001 From: root123 Date: Mon, 25 Aug 2025 23:15:26 -0400 Subject: [PATCH 1/4] feat(ci-cd-k8s): postgres schema fixes --- .github/workflows/ci-cd.yaml | 2 +- ...-config-map.yaml => postgres-config-map.yaml.bck} | 3 ++- k8s/statefulsets/postgres.yaml | 12 ++++++------ .../com/devsocket/ecommerce/order/entity/Order.java | 2 +- order-service/src/main/resources/application.yaml | 5 ++++- .../devsocket/ecommerce/product/entity/Category.java | 2 +- .../devsocket/ecommerce/product/entity/Product.java | 2 +- product-service/src/main/resources/application.yaml | 5 ++++- .../devsocket/ecommerce/userservice/entity/User.java | 2 +- user-service/src/main/resources/application.yaml | 5 ++++- 10 files changed, 25 insertions(+), 15 deletions(-) rename k8s/configmaps/{postgres-config-map.yaml => postgres-config-map.yaml.bck} (72%) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 6f427e5..538686e 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -3,7 +3,7 @@ name: Build and Deploy to Local Kubernetes on: push: branches: - - develop + - feature/ci_cd_k8s_support jobs: build-and-deploy: diff --git a/k8s/configmaps/postgres-config-map.yaml b/k8s/configmaps/postgres-config-map.yaml.bck similarity index 72% rename from k8s/configmaps/postgres-config-map.yaml rename to k8s/configmaps/postgres-config-map.yaml.bck index cac2567..d79a42c 100644 --- a/k8s/configmaps/postgres-config-map.yaml +++ b/k8s/configmaps/postgres-config-map.yaml.bck @@ -7,4 +7,5 @@ data: -- This script creates schemas for each microservice CREATE SCHEMA IF NOT EXISTS "user"; CREATE SCHEMA IF NOT EXISTS "product"; - CREATE SCHEMA IF NOT EXISTS "order"; \ No newline at end of file + CREATE SCHEMA IF NOT EXISTS "order"; + CREATE SCHEMA IF NOT EXISTS "categories"; \ No newline at end of file diff --git a/k8s/statefulsets/postgres.yaml b/k8s/statefulsets/postgres.yaml index 33b8b6f..d8142e1 100644 --- a/k8s/statefulsets/postgres.yaml +++ b/k8s/statefulsets/postgres.yaml @@ -40,12 +40,12 @@ spec: volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data - - name: init-script - mountPath: /docker-entrypoint-initdb.d - volumes: - - name: init-script - configMap: - name: postgres-init-script +# - name: init-script +# mountPath: /docker-entrypoint-initdb.d +# volumes: +# - name: init-script +# configMap: +# name: postgres-init-script volumeClaimTemplates: - metadata: name: postgres-storage diff --git a/order-service/src/main/java/com/devsocket/ecommerce/order/entity/Order.java b/order-service/src/main/java/com/devsocket/ecommerce/order/entity/Order.java index 296ce0a..7d1cd5c 100644 --- a/order-service/src/main/java/com/devsocket/ecommerce/order/entity/Order.java +++ b/order-service/src/main/java/com/devsocket/ecommerce/order/entity/Order.java @@ -9,7 +9,7 @@ import java.time.LocalDateTime; @Entity -@Table(name = "orders") +@Table(name = "orders", schema = "order") @Data @NoArgsConstructor @AllArgsConstructor diff --git a/order-service/src/main/resources/application.yaml b/order-service/src/main/resources/application.yaml index 8d72117..2d2d625 100644 --- a/order-service/src/main/resources/application.yaml +++ b/order-service/src/main/resources/application.yaml @@ -7,13 +7,16 @@ spring: spring: datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/orders} + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} username: ${SPRING_DATASOURCE_USERNAME:admin} password: ${SPRING_DATASOURCE_PASSWORD:passowrd} driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: + hibernate: + default_schema: order jwt: secret: ${JWT_SECRET:dev_secret_key} diff --git a/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Category.java b/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Category.java index 661b5a1..02631a4 100644 --- a/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Category.java +++ b/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Category.java @@ -8,7 +8,7 @@ @Data @Entity -@Table(name = "categories") +@Table(name = "categories", schema = "product") @NoArgsConstructor @AllArgsConstructor @Builder diff --git a/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Product.java b/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Product.java index dcd8e25..0bf4e3c 100644 --- a/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Product.java +++ b/product-service/src/main/java/com/devsocket/ecommerce/product/entity/Product.java @@ -9,7 +9,7 @@ import java.util.List; @Entity -@Table(name = "products") +@Table(name = "products", schema = "product") @Data @NoArgsConstructor @AllArgsConstructor diff --git a/product-service/src/main/resources/application.yaml b/product-service/src/main/resources/application.yaml index 1444025..4fe2ca9 100644 --- a/product-service/src/main/resources/application.yaml +++ b/product-service/src/main/resources/application.yaml @@ -7,13 +7,16 @@ spring: spring: datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/products} + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} username: ${SPRING_DATASOURCE_USERNAME:admin} password: ${SPRING_DATASOURCE_PASSWORD:passowrd} driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: + hibernate: + default_schema: product jwt: secret: ${JWT_SECRET:dev_secret_key} diff --git a/user-service/src/main/java/com/devsocket/ecommerce/userservice/entity/User.java b/user-service/src/main/java/com/devsocket/ecommerce/userservice/entity/User.java index be9ab6b..186e2aa 100644 --- a/user-service/src/main/java/com/devsocket/ecommerce/userservice/entity/User.java +++ b/user-service/src/main/java/com/devsocket/ecommerce/userservice/entity/User.java @@ -7,7 +7,7 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "users") +@Table(name = "users", schema = "user") @Data @NoArgsConstructor @AllArgsConstructor diff --git a/user-service/src/main/resources/application.yaml b/user-service/src/main/resources/application.yaml index 7208545..e4245df 100644 --- a/user-service/src/main/resources/application.yaml +++ b/user-service/src/main/resources/application.yaml @@ -7,13 +7,16 @@ spring: spring: datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/userdb} + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} username: ${SPRING_DATASOURCE_USERNAME:admin} password: ${SPRING_DATASOURCE_PASSWORD:password} driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: + hibernate: + default_schema: user jwt: secret: ${JWT_SECRET:dev_secret_key} From 576ab1c435fe83a8e4822fe2519a6c50f5de6391 Mon Sep 17 00:00:00 2001 From: root123 Date: Mon, 25 Aug 2025 23:35:13 -0400 Subject: [PATCH 2/4] feat(ci-cd-k8s): Added explicit entity scan for product service --- .../devsocket/ecommerce/product/ProductServiceApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/product-service/src/main/java/com/devsocket/ecommerce/product/ProductServiceApplication.java b/product-service/src/main/java/com/devsocket/ecommerce/product/ProductServiceApplication.java index dc6585d..c83adbd 100644 --- a/product-service/src/main/java/com/devsocket/ecommerce/product/ProductServiceApplication.java +++ b/product-service/src/main/java/com/devsocket/ecommerce/product/ProductServiceApplication.java @@ -2,12 +2,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(basePackages = { "com.devsocket.ecommerce" }) +@EntityScan("com.devsocket.ecommerce.product.entity") public class ProductServiceApplication { public static void main(String[] args) { SpringApplication.run(ProductServiceApplication.class, args); From 9cfa974a30d5f11360a7949ee1ee76ab44acbb5c Mon Sep 17 00:00:00 2001 From: root123 Date: Tue, 26 Aug 2025 00:16:06 -0400 Subject: [PATCH 3/4] feat(ci-cd-k8s): application.yaml files correction related to data source and jpa --- k8s/configmaps/postgres-config-map.yaml | 32 +++++++++++++++++++ k8s/configmaps/postgres-config-map.yaml.bck | 11 ------- k8s/statefulsets/postgres.yaml | 12 +++---- .../src/main/resources/application.yaml | 22 ++++++------- .../src/main/resources/application.yaml | 21 ++++++------ .../src/main/resources/application.yaml | 21 ++++++------ 6 files changed, 69 insertions(+), 50 deletions(-) create mode 100644 k8s/configmaps/postgres-config-map.yaml delete mode 100644 k8s/configmaps/postgres-config-map.yaml.bck diff --git a/k8s/configmaps/postgres-config-map.yaml b/k8s/configmaps/postgres-config-map.yaml new file mode 100644 index 0000000..86de0e5 --- /dev/null +++ b/k8s/configmaps/postgres-config-map.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-init-script +data: + init.sql: | + -- This script creates schemas for each microservice + CREATE SCHEMA IF NOT EXISTS "user"; + CREATE SCHEMA IF NOT EXISTS "product"; + CREATE SCHEMA IF NOT EXISTS "order"; + CREATE SCHEMA IF NOT EXISTS "categories"; + + CREATE TABLE IF NOT EXISTS product.categories ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL + ); + + CREATE TABLE IF NOT EXISTS product.products ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + price DOUBLE PRECISION, + available_quantity INTEGER + ); + + CREATE TABLE IF NOT EXISTS product.product_category ( + product_id BIGINT NOT NULL, + category_id BIGINT NOT NULL, + PRIMARY KEY (product_id, category_id), + FOREIGN KEY (product_id) REFERENCES product.products(id) ON DELETE CASCADE, + FOREIGN KEY (category_id) REFERENCES product.categories(id) ON DELETE CASCADE + ); diff --git a/k8s/configmaps/postgres-config-map.yaml.bck b/k8s/configmaps/postgres-config-map.yaml.bck deleted file mode 100644 index d79a42c..0000000 --- a/k8s/configmaps/postgres-config-map.yaml.bck +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: postgres-init-script -data: - init.sql: | - -- This script creates schemas for each microservice - CREATE SCHEMA IF NOT EXISTS "user"; - CREATE SCHEMA IF NOT EXISTS "product"; - CREATE SCHEMA IF NOT EXISTS "order"; - CREATE SCHEMA IF NOT EXISTS "categories"; \ No newline at end of file diff --git a/k8s/statefulsets/postgres.yaml b/k8s/statefulsets/postgres.yaml index d8142e1..33b8b6f 100644 --- a/k8s/statefulsets/postgres.yaml +++ b/k8s/statefulsets/postgres.yaml @@ -40,12 +40,12 @@ spec: volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data -# - name: init-script -# mountPath: /docker-entrypoint-initdb.d -# volumes: -# - name: init-script -# configMap: -# name: postgres-init-script + - name: init-script + mountPath: /docker-entrypoint-initdb.d + volumes: + - name: init-script + configMap: + name: postgres-init-script volumeClaimTemplates: - metadata: name: postgres-storage diff --git a/order-service/src/main/resources/application.yaml b/order-service/src/main/resources/application.yaml index 2d2d625..c99d833 100644 --- a/order-service/src/main/resources/application.yaml +++ b/order-service/src/main/resources/application.yaml @@ -5,18 +5,18 @@ spring: application: name: order-service - spring: - datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} - username: ${SPRING_DATASOURCE_USERNAME:admin} - password: ${SPRING_DATASOURCE_PASSWORD:passowrd} - driver-class-name: org.postgresql.Driver - jpa: + datasource: + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} + username: ${SPRING_DATASOURCE_USERNAME:admin} + password: ${SPRING_DATASOURCE_PASSWORD:passowrd} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: hibernate: - ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} - properties: - hibernate: - default_schema: order + default_schema: order + jwt: secret: ${JWT_SECRET:dev_secret_key} diff --git a/product-service/src/main/resources/application.yaml b/product-service/src/main/resources/application.yaml index 4fe2ca9..ebde19f 100644 --- a/product-service/src/main/resources/application.yaml +++ b/product-service/src/main/resources/application.yaml @@ -5,18 +5,17 @@ spring: application: name: product-service - spring: - datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} - username: ${SPRING_DATASOURCE_USERNAME:admin} - password: ${SPRING_DATASOURCE_PASSWORD:passowrd} - driver-class-name: org.postgresql.Driver - jpa: + datasource: + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} + username: ${SPRING_DATASOURCE_USERNAME:admin} + password: ${SPRING_DATASOURCE_PASSWORD:passowrd} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: hibernate: - ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} - properties: - hibernate: - default_schema: product + default_schema: product jwt: secret: ${JWT_SECRET:dev_secret_key} diff --git a/user-service/src/main/resources/application.yaml b/user-service/src/main/resources/application.yaml index e4245df..af98dd5 100644 --- a/user-service/src/main/resources/application.yaml +++ b/user-service/src/main/resources/application.yaml @@ -5,18 +5,17 @@ spring: application: name: user-service - spring: - datasource: - url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} - username: ${SPRING_DATASOURCE_USERNAME:admin} - password: ${SPRING_DATASOURCE_PASSWORD:password} - driver-class-name: org.postgresql.Driver - jpa: + datasource: + url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/ecommerce} + username: ${SPRING_DATASOURCE_USERNAME:admin} + password: ${SPRING_DATASOURCE_PASSWORD:password} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} + properties: hibernate: - ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update} - properties: - hibernate: - default_schema: user + default_schema: user jwt: secret: ${JWT_SECRET:dev_secret_key} From 31dfe8d56a4e2b7199c61d943d570fffc870ec00 Mon Sep 17 00:00:00 2001 From: root123 Date: Tue, 26 Aug 2025 00:43:20 -0400 Subject: [PATCH 4/4] feat(ci-cd-k8s): added separate pipelines for develop, feature and release --- .github/workflows/develop-pipeline.yaml | 33 +++++++ .../{ci-cd.yaml => feature-pipeline.yaml} | 20 ++--- .github/workflows/release-pipeline.yaml | 88 +++++++++++++++++++ 3 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/develop-pipeline.yaml rename .github/workflows/{ci-cd.yaml => feature-pipeline.yaml} (63%) create mode 100644 .github/workflows/release-pipeline.yaml diff --git a/.github/workflows/develop-pipeline.yaml b/.github/workflows/develop-pipeline.yaml new file mode 100644 index 0000000..b03356f --- /dev/null +++ b/.github/workflows/develop-pipeline.yaml @@ -0,0 +1,33 @@ +name: Build and Deploy to Local Kubernetes + +on: + push: + branches: + - feature/* + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + + - name: Build with Maven + run: mvn clean package -DskipTests + + - name: Log in to GitHub Container Registry + run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Build and Push Docker Image + run: | + for service in user-service order-service product-service; do + docker build -t ghcr.io/${{ github.repository_owner }}/$service:latest ./$service + docker push ghcr.io/${{ github.repository_owner }}/$service:latest + done diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/feature-pipeline.yaml similarity index 63% rename from .github/workflows/ci-cd.yaml rename to .github/workflows/feature-pipeline.yaml index 538686e..2087877 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/feature-pipeline.yaml @@ -3,7 +3,7 @@ name: Build and Deploy to Local Kubernetes on: push: branches: - - feature/ci_cd_k8s_support + - feature/* jobs: build-and-deploy: @@ -22,15 +22,15 @@ jobs: - name: Build with Maven run: mvn clean package -DskipTests - - name: Log in to GitHub Container Registry - run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - - name: Build and Push Docker Image - run: | - for service in user-service order-service product-service; do - docker build -t ghcr.io/${{ github.repository_owner }}/$service:latest ./$service - docker push ghcr.io/${{ github.repository_owner }}/$service:latest - done +# - name: Log in to GitHub Container Registry +# run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin +# +# - name: Build and Push Docker Image +# run: | +# for service in user-service order-service product-service; do +# docker build -t ghcr.io/${{ github.repository_owner }}/$service:latest ./$service +# docker push ghcr.io/${{ github.repository_owner }}/$service:latest +# done # - name: Set up kubectl # uses: azure/setup-kubectl@v3 # with: diff --git a/.github/workflows/release-pipeline.yaml b/.github/workflows/release-pipeline.yaml new file mode 100644 index 0000000..5de240c --- /dev/null +++ b/.github/workflows/release-pipeline.yaml @@ -0,0 +1,88 @@ +name: Release Pipeline + +on: + push: + branches: + - 'release/**' + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Needed to push tags & branches + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + + - name: Extract release version from branch name + id: vars + run: | + # Assuming branch name like release/1.2.3 + echo "RELEASE_VERSION=${GITHUB_REF#refs/heads/release/}" >> $GITHUB_OUTPUT + + - name: Build with Maven + run: mvn clean package -DskipTests + + - name: Create and push Git tag for release + env: + RELEASE_VERSION: ${{ steps.vars.outputs.RELEASE_VERSION }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag -a "v$RELEASE_VERSION" -m "Release $RELEASE_VERSION" + git push origin "v$RELEASE_VERSION" + + - name: Checkout master branch + run: git checkout master + + - name: Update master branch to latest release tag + env: + RELEASE_VERSION: ${{ steps.vars.outputs.RELEASE_VERSION }} + run: | + git reset --hard "v$RELEASE_VERSION" + git push origin master --force + + - name: Checkout develop branch + run: git checkout develop + + - name: Bump develop version to next SNAPSHOT + env: + RELEASE_VERSION: ${{ steps.vars.outputs.RELEASE_VERSION }} + run: | + # Extract major.minor.patch, then increment patch + add SNAPSHOT + IFS='.' read -r major minor patch <<< "${RELEASE_VERSION}" + next_patch=$((patch + 1)) + next_snapshot="${major}.${minor}.${next_patch}-SNAPSHOT" + + echo "Next develop version: $next_snapshot" + + # Update version in pom.xml or your version file + mvn versions:set -DnewVersion=$next_snapshot + mvn versions:commit + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add pom.xml + git commit -m "Bump develop version to $next_snapshot" + git push origin develop + + - name: Build and push Docker images + env: + RELEASE_VERSION: ${{ steps.vars.outputs.RELEASE_VERSION }} + GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} + run: | + echo "${GHCR_TOKEN}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + for service in user-service order-service product-service; do + docker build -t ghcr.io/${{ github.repository_owner }}/$service:$RELEASE_VERSION ./$service + docker push ghcr.io/${{ github.repository_owner }}/$service:$RELEASE_VERSION + done \ No newline at end of file