Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CD - Docker Publish

on:
push:
branches:
- main
- release/**
- hotfix/**
workflow_dispatch:

permissions:
contents: read
packages: write

env:
DOCKERHUB_IMAGE: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/eventmanagerapp
DOCKERHUB_COMPOSE: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/eventmanagerapp-compose

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

jobs:
build-and-push:
name: Build and publish Docker image
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Resolve compose tag
id: compose_tag
shell: bash
run: |
SHA="${{ github.sha }}"
SHORT_SHA="${SHA:0:7}"

if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "tag=main-${SHORT_SHA}" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "push" ]; then
BRANCH="${{ github.ref_name }}"
SAFE_BRANCH="${BRANCH//\//-}"
echo "tag=${SAFE_BRANCH}-${SHORT_SHA}" >> $GITHUB_OUTPUT
else
echo "tag=manual-${SHORT_SHA}" >> $GITHUB_OUTPUT
fi

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKERHUB_IMAGE }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=tag
type=sha,format=short

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Publish docker-compose.aws.yaml as OCI artifact
if: ${{ github.event_name == 'push' && (github.ref_name == 'main' || startsWith(github.ref_name, 'release/') || startsWith(github.ref_name, 'hotfix/')) }}
run: |
docker compose -f docker-compose.aws.yaml publish \
${{ env.DOCKERHUB_COMPOSE }}:${{ steps.compose_tag.outputs.tag }}

199 changes: 111 additions & 88 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,10 @@ concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
unit:
name: Unit tests
ci:
name: Build + Unit + Selenium
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: maven

- name: Ensure Maven wrapper is executable
run: chmod +x mvnw

- name: Run unit profile tests
run: ./mvnw -B -Punit test

- name: Upload surefire reports (unit)
if: always()
uses: actions/upload-artifact@v4
with:
name: surefire-unit
path: target/surefire-reports/**
if-no-files-found: ignore

selenium:
name: Selenium tests (${{ matrix.suiteName }})
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- suiteName: Auth
suiteInclude: "**/selenium/views/AuthViewsSeleniumTest.java"
- suiteName: Home
suiteInclude: "**/selenium/views/HomeViewSeleniumTest.java"
- suiteName: Event
suiteInclude: "**/selenium/views/EventViewsSeleniumTest.java"
- suiteName: User
suiteInclude: "**/selenium/views/UserViewsSeleniumTest.java"
- suiteName: GiftAndTicket
suiteInclude: "**/selenium/views/GiftAndTicketViewsSeleniumTest.java"
timeout-minutes: 20

services:
postgres:
Expand All @@ -93,80 +49,147 @@ jobs:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
MINIO_BUCKET_NAME: event-manager-images
SPRING_JPA_HIBERNATE_DDL_AUTO: create-drop

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'
cache: maven

- name: Ensure Maven wrapper is executable
run: chmod +x mvnw
- name: Install Maven
run: |
sudo apt-get update
sudo apt-get install -y maven

- name: Start MinIO
run: |
docker run -d --name minio-ci \
MINIO_CONTAINER_NAME="minio-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${GITHUB_JOB}"
sudo docker rm -f minio-ci >/dev/null 2>&1 || true
sudo docker rm -f "$MINIO_CONTAINER_NAME" >/dev/null 2>&1 || true
sudo docker run -d --name "$MINIO_CONTAINER_NAME" \
-p 9000:9000 -p 9001:9001 \
-e MINIO_ROOT_USER=${MINIO_ACCESS_KEY} \
-e MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY} \
minio/minio:RELEASE.2024-01-16T16-07-38Z server /data --console-address ":9001"

- name: Run selenium profile tests (shard)
run: ./mvnw -B -Pselenium,selenium-ci -Dselenium.includes="${{ matrix.suiteInclude }}" test
- name: Build frontend (Vue + Vite)
run: |
cd frontend
npm ci
npm run build
cd ..

- name: Upload surefire reports (selenium)
- name: Copy frontend dist to backend static resources
run: |
rm -rf src/main/resources/static
mkdir -p src/main/resources/static
cp -r frontend/dist/* src/main/resources/static/

- name: Build backend with frontend (skip tests)
run: |
mvn -B -DskipTests clean package \
-Dskip.frontend.node.install=true \
-Dskip.frontend.npm.install=true \
-Dskip.frontend.npm.build=true \
-Dskip.frontend.copy.resources=true

- name: Unit tests + JaCoCo
if: always()
run: |
mvn -B -Punit verify \
-Dskip.openapi.generate=true \
-Dskip.frontend.node.install=true \
-Dskip.frontend.npm.install=true \
-Dskip.frontend.npm.build=true \
-Dskip.frontend.copy.resources=true \
-Djacoco.destFile=target/jacoco-unit.exec \
-Djacoco.dataFile=target/jacoco-unit.exec \
-Djacoco.outputDirectory=target/site/jacoco-unit \
| tee target/unit-test.log
exit ${PIPESTATUS[0]}

- name: Upload surefire reports (unit)
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: surefire-selenium
name: surefire-unit
path: target/surefire-reports/**
if-no-files-found: ignore

- name: Upload backend startup log
- name: Upload JaCoCo site (unit)
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: backend-log-${{ matrix.suiteName }}
path: app.log
if-no-files-found: ignore

coverage:
name: Coverage (JaCoCo)
runs-on: ubuntu-latest
timeout-minutes: 35

steps:
- name: Checkout
uses: actions/checkout@v4
name: coverage-unit-site
path: target/site/jacoco-unit/**
if-no-files-found: error

- name: Set up JDK 21
uses: actions/setup-java@v4
- name: Upload JaCoCo XML (unit)
if: always()
uses: actions/upload-artifact@v7
with:
distribution: temurin
java-version: '21'
cache: maven
name: coverage-unit-xml
path: target/site/jacoco-unit/jacoco.xml
if-no-files-found: error

- name: Ensure Maven wrapper is executable
run: chmod +x mvnw
- name: Selenium tests + JaCoCo
if: always()
run: |
mvn -B -Pselenium verify \
-Dskip.openapi.generate=true \
-Dskip.frontend.node.install=true \
-Dskip.frontend.npm.install=true \
-Dskip.frontend.npm.build=true \
-Dskip.frontend.copy.resources=true \
-Djacoco.destFile=target/jacoco-selenium.exec \
-Djacoco.dataFile=target/jacoco-selenium.exec \
-Djacoco.outputDirectory=target/site/jacoco-selenium \
| tee target/selenium-test.log
exit ${PIPESTATUS[0]}

- name: Run verify with unit profile (JaCoCo report)
run: ./mvnw -B -Punit verify
- name: Upload surefire reports (selenium)
if: always()
uses: actions/upload-artifact@v7
with:
name: surefire-selenium
path: target/surefire-reports/**
if-no-files-found: ignore

- name: Upload JaCoCo site
uses: actions/upload-artifact@v4
- name: Upload JaCoCo site (selenium)
if: always()
uses: actions/upload-artifact@v7
with:
name: jacoco-site
path: target/site/jacoco/**
name: coverage-selenium-site
path: target/site/jacoco-selenium/**
if-no-files-found: error

- name: Upload JaCoCo XML
uses: actions/upload-artifact@v4
- name: Upload JaCoCo XML (selenium)
if: always()
uses: actions/upload-artifact@v7
with:
name: jacoco-xml
path: target/site/jacoco/jacoco.xml
name: coverage-selenium-xml
path: target/site/jacoco-selenium/jacoco.xml
if-no-files-found: error

- name: Upload backend startup log
if: failure()
uses: actions/upload-artifact@v7
with:
name: backend-log
path: |
app.log
target/unit-test.log
target/selenium-test.log
if-no-files-found: ignore

- name: Cleanup MinIO
if: always()
run: |
sudo docker rm -f minio-ci >/dev/null 2>&1 || true
sudo docker rm -f "minio-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${GITHUB_JOB}" >/dev/null 2>&1 || true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@ truststore*

# Docker image exports
*.tar

# act (GitHub Actions local emulator) artifacts and logs
.act-artifacts/
act-*.txt
Loading