From 08e8009bfd9162e5c08e997cd4eefa51c940a2f9 Mon Sep 17 00:00:00 2001 From: Denis Lugowski Date: Fri, 14 Nov 2025 19:22:16 +0100 Subject: [PATCH] feat: Add Gitea pipelines for frontend and backend --- .gitea/workflows/backend.yaml | 99 ++++++++++++++++++++++++ .gitea/workflows/demo.yaml | 19 ----- .gitea/workflows/frontend.yaml | 104 ++++++++++++++++++++++++++ legalconsenthub-backend/.dockerignore | 15 ++++ legalconsenthub-backend/Dockerfile | 34 +++++++++ legalconsenthub/.dockerignore | 15 ++++ legalconsenthub/Dockerfile | 31 ++++++++ 7 files changed, 298 insertions(+), 19 deletions(-) create mode 100644 .gitea/workflows/backend.yaml delete mode 100644 .gitea/workflows/demo.yaml create mode 100644 .gitea/workflows/frontend.yaml create mode 100644 legalconsenthub-backend/.dockerignore create mode 100644 legalconsenthub-backend/Dockerfile create mode 100644 legalconsenthub/.dockerignore create mode 100644 legalconsenthub/Dockerfile diff --git a/.gitea/workflows/backend.yaml b/.gitea/workflows/backend.yaml new file mode 100644 index 0000000..1e6b99b --- /dev/null +++ b/.gitea/workflows/backend.yaml @@ -0,0 +1,99 @@ +name: Backend CI/CD +run-name: ${{ gitea.actor }} triggered backend pipeline on ${{ gitea.ref_name }} + +on: + pull_request: + paths: + - 'legalconsenthub-backend/**' + - '.gitea/workflows/backend.yaml' + push: + branches: + - main + paths: + - 'legalconsenthub-backend/**' + - '.gitea/workflows/backend.yaml' + +jobs: + build-and-test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./legalconsenthub-backend + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + + - name: Setup Gradle cache + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + legalconsenthub-backend/.gradle + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Make gradlew executable + run: chmod +x gradlew + + - name: Build application + run: ./gradlew build -x test + + - name: Run ktlint check + run: ./gradlew ktlintCheck + + - name: Run tests with Testcontainers + run: ./gradlew test + env: + SPRING_PROFILES_ACTIVE: testcontainers + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: gitea.lugnas.de + username: ${{ gitea.actor }} + password: ${{ gitea.token }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub-backend + tags: | + type=raw,value=latest,enable=${{ gitea.ref == 'refs/heads/main' }} + type=sha,prefix=,format=long + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./legalconsenthub-backend + push: ${{ gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Image built successfully + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + run: | + echo "✅ Docker image built and pushed successfully" + echo "📦 Image: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub-backend:latest" + echo "📦 Image: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub-backend:${{ gitea.sha }}" + + - name: Dry-run completed + if: gitea.event_name == 'pull_request' + run: | + echo "✅ Dry-run build completed successfully (image not pushed)" + diff --git a/.gitea/workflows/demo.yaml b/.gitea/workflows/demo.yaml deleted file mode 100644 index c537cc6..0000000 --- a/.gitea/workflows/demo.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Gitea Actions Demo -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 -on: [push] - -jobs: - Explore-Gitea-Actions: - runs-on: ubuntu-latest - steps: - - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - - name: Check out repository code - uses: actions/checkout@v4 - - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ gitea.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.gitea/workflows/frontend.yaml b/.gitea/workflows/frontend.yaml new file mode 100644 index 0000000..db354c8 --- /dev/null +++ b/.gitea/workflows/frontend.yaml @@ -0,0 +1,104 @@ +name: Frontend CI/CD +run-name: ${{ gitea.actor }} triggered frontend pipeline on ${{ gitea.ref_name }} + +on: + pull_request: + paths: + - 'legalconsenthub/**' + - '.gitea/workflows/frontend.yaml' + push: + branches: + - main + paths: + - 'legalconsenthub/**' + - '.gitea/workflows/frontend.yaml' + +jobs: + build-and-test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./legalconsenthub + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.16.0' + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.13.1 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITEA_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build application + run: pnpm build + + - name: Run linting + run: pnpm lint + + - name: Run type checking + run: pnpm type-check + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: gitea.lugnas.de + username: ${{ gitea.actor }} + password: ${{ gitea.token }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub + tags: | + type=raw,value=latest,enable=${{ gitea.ref == 'refs/heads/main' }} + type=sha,prefix=,format=long + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./legalconsenthub + push: ${{ gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Image built successfully + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + run: | + echo "✅ Docker image built and pushed successfully" + echo "📦 Image: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub:latest" + echo "📦 Image: gitea.lugnas.de/${{ gitea.repository_owner }}/legalconsenthub:${{ gitea.sha }}" + + - name: Dry-run completed + if: gitea.event_name == 'pull_request' + run: | + echo "✅ Dry-run build completed successfully (image not pushed)" + diff --git a/legalconsenthub-backend/.dockerignore b/legalconsenthub-backend/.dockerignore new file mode 100644 index 0000000..f54af39 --- /dev/null +++ b/legalconsenthub-backend/.dockerignore @@ -0,0 +1,15 @@ +.git +.gitignore +README.md +*.md +.gradle +build +bin +!gradle/wrapper +postgres-data +docker-compose.yaml +.idea +.vscode +*.log +*.iml + diff --git a/legalconsenthub-backend/Dockerfile b/legalconsenthub-backend/Dockerfile new file mode 100644 index 0000000..8ca12a6 --- /dev/null +++ b/legalconsenthub-backend/Dockerfile @@ -0,0 +1,34 @@ +FROM eclipse-temurin:21-jdk-alpine AS builder + +WORKDIR /workspace/app + +COPY gradlew . +COPY gradle gradle +COPY build.gradle . +COPY settings.gradle . +COPY api api + +RUN chmod +x ./gradlew + +RUN ./gradlew dependencies --no-daemon + +COPY src src + +RUN ./gradlew bootJar -x test --no-daemon + +FROM eclipse-temurin:21-jre-alpine AS runner + +WORKDIR /app + +RUN addgroup -S spring && adduser -S spring -G spring +USER spring:spring + +COPY --from=builder /workspace/app/build/libs/*.jar app.jar + +ENV SPRING_PROFILES_ACTIVE=prod +ENV JAVA_OPTS="-Xms256m -Xmx512m" + +EXPOSE 8080 + +ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app/app.jar"] + diff --git a/legalconsenthub/.dockerignore b/legalconsenthub/.dockerignore new file mode 100644 index 0000000..fdbf1c0 --- /dev/null +++ b/legalconsenthub/.dockerignore @@ -0,0 +1,15 @@ +node_modules +.nuxt +.output +.git +.gitignore +README.md +.api-client +.api-client-middleware +*.log +.DS_Store +coverage +.vscode +.idea +dist + diff --git a/legalconsenthub/Dockerfile b/legalconsenthub/Dockerfile new file mode 100644 index 0000000..8c4f145 --- /dev/null +++ b/legalconsenthub/Dockerfile @@ -0,0 +1,31 @@ +FROM node:22.16.0-alpine AS builder + +WORKDIR /app + +RUN npm install -g pnpm@10.13.1 + +COPY package.json pnpm-lock.yaml ./ + +RUN pnpm install --frozen-lockfile + +COPY . . + +RUN pnpm build + +FROM node:22.16.0-alpine AS runner + +WORKDIR /app + +RUN npm install -g pnpm@10.13.1 + +COPY --from=builder /app/.output /app/.output +COPY --from=builder /app/package.json /app/package.json + +ENV NODE_ENV=production +ENV HOST=0.0.0.0 +ENV PORT=3000 + +EXPOSE 3000 + +CMD ["node", ".output/server/index.mjs"] +