# CI: Maven build + unit tests on every push/PR to main or master. # CD: Build Docker image and push to GitHub Container Registry (ghcr.io) on push to main/master. # Optional: SSH deploy when repository variable ENABLE_SSH_DEPLOY=true and deploy secrets are set. # # Repository variables (Settings → Secrets and variables → Actions → Variables): # ENABLE_SSH_DEPLOY = true (optional; omit or false to skip deploy job) # # Optional deploy secrets (Settings → Secrets and variables → Actions → Secrets): # DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_SCRIPT # DEPLOY_SCRIPT: multiline shell to run on the server (e.g. cd /opt/app && docker compose pull && docker compose up -d) # # Pull the image as: ghcr.io//:latest or : name: CI/CD on: push: branches: [main, master] pull_request: branches: [main, master] workflow_dispatch: permissions: contents: read packages: write env: JAVA_VERSION: "21" jobs: build-and-test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{ env.JAVA_VERSION }} cache: maven # Unit tests only; @EnabledIfEnvironmentVariable(RUN_INTEGRATION_TESTS) tests stay skipped unless you add a separate job with secrets. - name: Maven verify run: mvn -B -ntp verify docker-build-push: needs: build-and-test if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Image name (lowercase for GHCR) id: image run: | IMG=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') echo "name=ghcr.io/${IMG}" >> "$GITHUB_OUTPUT" - name: Build and push uses: docker/build-push-action@v6 with: context: . push: true tags: | ${{ steps.image.outputs.name }}:latest ${{ steps.image.outputs.name }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max deploy: needs: docker-build-push # Set ENABLE_SSH_DEPLOY=true in repo Variables to run this job; otherwise skipped. if: vars.ENABLE_SSH_DEPLOY == 'true' runs-on: ubuntu-latest # Optional: uncomment for manual approval gates (create "production" in Environments first). # environment: production steps: - name: Deploy over SSH uses: appleboy/ssh-action@v1.2.2 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} script: ${{ secrets.DEPLOY_SCRIPT }}