diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..9d309aa --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,16 @@ +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/springboot-postgres/app" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/springboot-postgres/app" + schedule: + interval: "weekly" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/helm-ci.yaml b/.github/workflows/helm-ci.yaml index 777e1b0..c4e7032 100644 --- a/.github/workflows/helm-ci.yaml +++ b/.github/workflows/helm-ci.yaml @@ -1,82 +1,82 @@ -name: Helm CI - Build and Push - -on: - push: - branches: - - main - -jobs: - build-and-push: - name: Build and Push Docker Image - runs-on: ubuntu-latest - - outputs: - image-tag: ${{ steps.set-tag.outputs.tag }} - - env: - IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '17' - - - name: Build Spring Boot App - working-directory: ./app - run: ./mvnw clean package -DskipTests - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set Image Tag - id: set-tag - run: | - COMMIT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) - TAG="main-${COMMIT_SHA}" - echo "tag=$TAG" >> $GITHUB_OUTPUT - - - name: Build and Push Docker Image - run: | - docker build -t $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} ./app - docker push $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} - - update-values: - name: Update Helm values.yaml - needs: build-and-push - runs-on: ubuntu-latest - - env: - IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres - IMAGE_TAG: ${{ needs.build-and-push.outputs.image-tag }} - FILE: helm/springboot-postgres-prod/values.yaml - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure Git - run: | - git config --global user.name "${{ secrets.GIT_USER_NAME }}" - git config --global user.email "${{ secrets.GIT_USER_EMAIL }}" - - - name: Update values.yaml - run: | - echo "Updating $FILE with image: $IMAGE_NAME:$IMAGE_TAG" - sed -i.bak -E "s|image:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" "$FILE" - - git add "$FILE" - git commit -m "Update image tag to $IMAGE_TAG in Helm values.yaml" - - git pull origin auto/helm-update --rebase || true - git push origin HEAD:auto/helm-update-prod --force-with-lease \ No newline at end of file +# name: Helm CI - Build and Push + +# on: +# push: +# branches: +# - main + +# jobs: +# build-and-push: +# name: Build and Push Docker Image +# runs-on: ubuntu-latest + +# outputs: +# image-tag: ${{ steps.set-tag.outputs.tag }} + +# env: +# IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres + +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 + +# - name: Set up JDK 17 +# uses: actions/setup-java@v4 +# with: +# distribution: 'temurin' +# java-version: '17' + +# - name: Build Spring Boot App +# working-directory: ./app +# run: ./mvnw clean package -DskipTests + +# - name: Set up Docker Buildx +# uses: docker/setup-buildx-action@v3 + +# - name: Log in to DockerHub +# uses: docker/login-action@v3 +# with: +# username: ${{ secrets.DOCKERHUB_USERNAME }} +# password: ${{ secrets.DOCKERHUB_TOKEN }} + +# - name: Set Image Tag +# id: set-tag +# run: | +# COMMIT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) +# TAG="main-${COMMIT_SHA}" +# echo "tag=$TAG" >> $GITHUB_OUTPUT + +# - name: Build and Push Docker Image +# run: | +# docker build -t $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} ./app +# docker push $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} + +# update-values: +# name: Update Helm values.yaml +# needs: build-and-push +# runs-on: ubuntu-latest + +# env: +# IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres +# IMAGE_TAG: ${{ needs.build-and-push.outputs.image-tag }} +# FILE: helm/springboot-postgres-prod/values.yaml + +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 + +# - name: Configure Git +# run: | +# git config --global user.name "${{ secrets.GIT_USER_NAME }}" +# git config --global user.email "${{ secrets.GIT_USER_EMAIL }}" + +# - name: Update values.yaml +# run: | +# echo "Updating $FILE with image: $IMAGE_NAME:$IMAGE_TAG" +# sed -i.bak -E "s|image:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" "$FILE" + +# git add "$FILE" +# git commit -m "Update image tag to $IMAGE_TAG in Helm values.yaml" + +# git pull origin auto/helm-update --rebase || true +# git push origin HEAD:auto/helm-update-prod --force-with-lease \ No newline at end of file diff --git a/.github/workflows/kustomize-ci.yaml b/.github/workflows/kustomize-ci.yaml index 39e9ee4..9b464d8 100644 --- a/.github/workflows/kustomize-ci.yaml +++ b/.github/workflows/kustomize-ci.yaml @@ -1,93 +1,93 @@ -name: Kustomize CI - Build and Push - -on: - push: - branches: - - feature/development - - development - -concurrency: - group: kustomize-update - cancel-in-progress: true - -jobs: - build-and-push: - name: Build and Push Docker Image - runs-on: ubuntu-latest - - outputs: - image-tag: ${{ steps.set-tag.outputs.tag }} - - env: - IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '17' - - - name: Build Spring Boot App - working-directory: ./app - run: ./mvnw clean package -DskipTests - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set image tag - id: set-tag - run: | - COMMIT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) - BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | tr '/' '-') - TAG="${BRANCH}-${COMMIT_SHA}" - echo "tag=$TAG" >> "$GITHUB_OUTPUT" - - - name: Build and push Docker image - run: | - docker build -t $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} ./app - docker push $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} - - update-kustomize: - name: Update Kustomize Overlay - needs: build-and-push - runs-on: ubuntu-latest - - env: - IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres - IMAGE_TAG: ${{ needs.build-and-push.outputs.image-tag }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure git - run: | - git config --global user.name "${{ secrets.GIT_USER_NAME }}" - git config --global user.email "${{ secrets.GIT_USER_EMAIL }}" - - - name: Update image tag and push to branch - run: | - FILE="kustomize/overlays/dev/patch-deployment-image.yaml" - - echo "Updating $FILE with image: $IMAGE_NAME:$IMAGE_TAG" - - sed -i.bak -E "s|image:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" "$FILE" - - git checkout -B auto/kustomize-update - git add "$FILE" - git commit -m "Update image tag to $IMAGE_TAG" || echo "No changes to commit" - - git push origin auto/kustomize-update --force +# name: Kustomize CI - Build and Push + +# on: +# push: +# branches: +# - feature/development +# - development + +# concurrency: +# group: kustomize-update +# cancel-in-progress: true + +# jobs: +# build-and-push: +# name: Build and Push Docker Image +# runs-on: ubuntu-latest + +# outputs: +# image-tag: ${{ steps.set-tag.outputs.tag }} + +# env: +# IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres + +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 + +# - name: Set up JDK 17 +# uses: actions/setup-java@v4 +# with: +# distribution: 'temurin' +# java-version: '17' + +# - name: Build Spring Boot App +# working-directory: ./app +# run: ./mvnw clean package -DskipTests + +# - name: Set up Docker Buildx +# uses: docker/setup-buildx-action@v3 + +# - name: Log in to DockerHub +# uses: docker/login-action@v3 +# with: +# username: ${{ secrets.DOCKERHUB_USERNAME }} +# password: ${{ secrets.DOCKERHUB_TOKEN }} + +# - name: Set image tag +# id: set-tag +# run: | +# COMMIT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) +# BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | tr '/' '-') +# TAG="${BRANCH}-${COMMIT_SHA}" +# echo "tag=$TAG" >> "$GITHUB_OUTPUT" + +# - name: Build and push Docker image +# run: | +# docker build -t $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} ./app +# docker push $IMAGE_NAME:${{ steps.set-tag.outputs.tag }} + +# update-kustomize: +# name: Update Kustomize Overlay +# needs: build-and-push +# runs-on: ubuntu-latest + +# env: +# IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/springboot-postgres +# IMAGE_TAG: ${{ needs.build-and-push.outputs.image-tag }} + +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 + +# - name: Configure git +# run: | +# git config --global user.name "${{ secrets.GIT_USER_NAME }}" +# git config --global user.email "${{ secrets.GIT_USER_EMAIL }}" + +# - name: Update image tag and push to branch +# run: | +# FILE="kustomize/overlays/dev/patch-deployment-image.yaml" + +# echo "Updating $FILE with image: $IMAGE_NAME:$IMAGE_TAG" + +# sed -i.bak -E "s|image:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" "$FILE" + +# git checkout -B auto/kustomize-update +# git add "$FILE" +# git commit -m "Update image tag to $IMAGE_TAG" || echo "No changes to commit" + +# git push origin auto/kustomize-update --force \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d7ecab6 --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +# Spring Boot Postgres - Helm & Kustomize Deployment + +This project demonstrates a GitOps-style Continuous Integration (CI) pipeline for a **Spring Boot + PostgreSQL** application, leveraging: + + • **Kustomize and Helm** for Kubernetes manifests management + • **GitHub Actions** for building, testing, tagging, and pushing images + • **DockerHub** as the image registry + + The current focus is **CI only** — with clear automation of image updates through Git. **ArgoCD-based Continuous Deployment (CD)** will be implemented in the next stage. +--- + +## Project Structure + +``` +. +├── app # Spring Boot application (Dockerized) +├── helm # Helm chart for production deployments +│ └── springboot-postgres-prod +│ ├── Chart.yaml +│ └── templates/... +├── kustomize # Kustomize overlays for different environments +│ ├── base +│ ├── overlays/ +│ │ ├── dev +│ │ └── stage +├── .github/workflows # CI pipelines for Kustomize & Helm +│ ├── helm-ci.yaml +│ └── kustomize-ci.yaml +└── dependabot.yaml # Dependency automation +``` + +--- + +## Deployment Strategies + +### Kustomize – For Development Environments +- Manages environment-specific configurations using overlays (`dev`, `stage`, etc.). +- Uses patch files (`patch-deployment-image.yaml`, etc.) to inject settings. +- CI builds Docker image and automatically updates Kustomize overlays with the new image tag. +- Image tag changes are pushed to a dedicated branch (`auto/kustomize-update`). + +### Helm – For Production +- Used for production-grade deployments with templated configuration. +- Helm chart located in `helm/springboot-postgres-prod`. +- CI builds and pushes Docker image on `main` branch updates. +- Image tag is updated in `values.yaml` and pushed to a separate branch (`auto/helm-update`). + +--- + +## Branching Strategy + +### `main` +- Protected branch for production. +- Triggers **Helm CI** on push. +- Only accepts Pull Requests. + +### `development` +- Integration branch. +- Triggers **Kustomize CI** on push. +- Represents the latest working state of development. + +### `feature/*` +- Feature development. +- Merged into `development`. + +### `auto/kustomize-update` +- Auto-managed branch. +- CI pushes updated image tags to `kustomize/overlays/dev/patch-deployment-image.yaml`. + +### `auto/helm-update` +- Auto-managed branch. +- CI pushes updated image tag to `helm/springboot-postgres-prod/values.yaml`. + +--- + +## CI/CD Overview + +| Tool | Purpose | Trigger Branches | +|-------------------|----------------------------------------------|---------------------------| +| `kustomize-ci.yaml` | Builds Docker image, updates dev overlay | `feature/*`, `development`| +| `helm-ci.yaml` | Builds Docker image, updates Helm chart | `main` | + +- Docker image is tagged as: `branchname-`, e.g., `feature-login-abc1234`. + +--- + +## Docker Image + +- Docker image is built from `/app` and pushed to DockerHub. +- Image tag is dynamically generated in CI. + +--- + +## Prerequisites + +- GitHub PAT with `repo` scope (for pushing commits via Actions). +- DockerHub credentials stored in repository secrets: + - `DOCKERHUB_USERNAME` + - `DOCKERHUB_TOKEN` +- Git config secrets: + - `GIT_USER_NAME` + - `GIT_USER_EMAIL` + - `GH_PAT` (used in CI for authenticated pushes) + +--- + +## Future Enhancements + +- Add staging environment overlay in Kustomize. +- Implement CD using ArgoCD or Flux. +- Add unit and integration tests in CI. +- Add Helm chart versioning and publishing. + +--- + + +