Compare commits

59 Commits

Author SHA1 Message Date
a56d191ed1 Refactor GitLab CI/CD pipelines 2025-05-02 10:45:37 +02:00
2253e9a3a8 Refactor GitLab CI/CD pipelines 2025-05-02 10:41:38 +02:00
a557a7efd0 Add docker login step to CI jobs before building images 2025-05-02 10:27:10 +02:00
f71e107a0b Update registry variable in GitLab CI configuration 2025-05-02 10:19:57 +02:00
f3d71cbb43 Refactor GitLab CI pipeline paths and dependencies 2025-05-02 10:17:15 +02:00
a1253d7869 Add dockerize stage and update GitLab CI pipeline 2025-05-02 10:13:36 +02:00
fade3bf680 Add Dockerfiles for service and base images 2025-05-02 10:11:45 +02:00
74e12ef6bd Add Docker build and push jobs to GitLab CI pipeline 2025-05-02 10:09:16 +02:00
52e33a0310 Set specific Maven Docker image for backend build job 2025-05-02 09:50:54 +02:00
63d6d54195 Update GitLab CI build job for backend project 2025-05-02 09:39:44 +02:00
e2b3bc4f21 Fix frontend GitLab CI job directory context 2025-04-28 08:37:03 +02:00
8a7a8bf179 Enable use of 'any' in TypeScript ESLint configuration 2025-04-28 08:35:14 +02:00
f35724be35 Remove try-catch block 2025-04-28 08:32:38 +02:00
4ebd3c57eb Update frontend build script in .gitlab-ci.yml to include directory change 2025-04-28 08:29:01 +02:00
8bfafa0c34 Move Node.js image declaration to the specific job section 2025-04-28 08:28:17 +02:00
87b9197a93 Add Dockerization stage and setup in GitLab CI pipelines 2025-04-28 08:26:51 +02:00
727cca8850 Unused files 2025-04-28 08:19:49 +02:00
GitLab CI
086e2baeef Merge remote-tracking branch 'origin/production' into dev 2025-04-27 21:05:24 +00:00
4eb4c9b581 remove added character 2025-04-27 23:04:54 +02:00
390dd25a90 add some character for testing 2025-04-27 23:04:18 +02:00
GitLab CI
0208cf2c98 Merge remote-tracking branch 'origin/production' into dev 2025-04-27 20:48:51 +00:00
62027a41c8 Merge remote-tracking branch 'origin/dev' into dev 2025-04-27 22:46:21 +02:00
1f0bcbae9d Merge production back to dev 2025-04-27 22:46:09 +02:00
c4f37882a4 Merge production back to dev 2025-04-27 22:46:09 +02:00
d4d3aa4f08 Merge production back to dev 2025-04-27 22:46:09 +02:00
ce1f044fef Merge production back to dev 2025-04-27 22:46:09 +02:00
178702f468 Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 22:46:09 +02:00
e77fe53b15 Update CI configurations to use Node 22 Docker image
- Replaced alpine/git v2.47.2 image with node:22 image for the sync_branches job.
- Added node:22 image to the frontend_build_job for consistency in builds.
- This ensures compatibility with Node.js-based tasks and streamlines CI setup.
2025-04-27 22:46:06 +02:00
5a0cdd0bfd Merge production back to dev 2025-04-27 22:45:08 +02:00
aa2003fc17 Merge production back to dev 2025-04-27 22:45:08 +02:00
953c3c96fd Merge production back to dev 2025-04-27 22:45:08 +02:00
400b742243 Simplify CI configurations for frontend and backend projects. 2025-04-27 22:45:08 +02:00
a40e28bf91 Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 22:45:08 +02:00
88de266dc1 Moved sync stage to the end of the pipeline and adapt the stage to use an Alpine Git image 2025-04-27 22:45:08 +02:00
9a5b82939e Merge production back to dev 2025-04-27 22:45:08 +02:00
1e594f31f9 Reorder stages in .gitlab-ci.yml for correct execution order.
- Moved the 'deploy' stage to the end of the stages list.
2025-04-27 22:45:06 +02:00
03a04ac49c Simplify CI configurations for frontend and backend projects. 2025-04-27 22:40:55 +02:00
0ea4bc3be0 Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 22:40:53 +02:00
910207b03b Merge production back to dev 2025-04-27 22:33:33 +02:00
c239229df2 Merge production back to dev 2025-04-27 22:33:33 +02:00
3fdf5e53d0 Merge production back to dev 2025-04-27 22:33:33 +02:00
d639840ba5 Merge production back to dev 2025-04-27 22:33:27 +02:00
d5a7fb3265 Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 22:33:25 +02:00
81ec50f034 Update CI configurations to use Node 22 Docker image
- Replaced alpine/git v2.47.2 image with node:22 image for the sync_branches job.
- Added node:22 image to the frontend_build_job for consistency in builds.
- This ensures compatibility with Node.js-based tasks and streamlines CI setup.
2025-04-27 22:31:16 +02:00
537bea25b1 Merge production back to dev 2025-04-27 22:19:40 +02:00
0f3fdcf2df Merge production back to dev 2025-04-27 22:19:40 +02:00
68f63ea9e7 Fix wrong image definition. 2025-04-27 22:15:52 +02:00
0257c00d19 Merge branch 'production' into dev 2025-04-27 22:13:57 +02:00
81c6405825 Merge branch 'production' into dev
# Conflicts:
#	.gitlab-ci.yml
2025-04-27 22:10:35 +02:00
911d3ced68 Merge production back to dev 2025-04-27 22:06:56 +02:00
efc906297e Simplify CI configurations for frontend and backend projects. 2025-04-27 22:06:56 +02:00
338eb8e92d Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 22:06:56 +02:00
838bd2744d Moved sync stage to the end of the pipeline and adapt the stage to use an Alpine Git image 2025-04-27 22:00:38 +02:00
62a60a3ff9 Merge branch 'production' into 'dev'
Merge production back to dev

See merge request rheinsw/rheinsw!4
2025-04-27 19:43:17 +00:00
5d01facb42 Merge production back to dev 2025-04-27 19:43:17 +00:00
4de500608c Reorder stages in .gitlab-ci.yml for correct execution order.
- Moved the 'deploy' stage to the end of the stages list.
2025-04-27 21:08:38 +02:00
ac30a7be71 Update GitLab CI includes 2025-04-27 21:06:35 +02:00
5e659d0175 Simplify CI configurations for frontend and backend projects. 2025-04-27 21:05:41 +02:00
46676c1e4a Add GitLab CI/CD pipeline configuration (dummy) 2025-04-27 20:17:08 +02:00
10 changed files with 193 additions and 72 deletions

View File

@@ -1,15 +1,22 @@
image: docker:20.10@sha256:2967f0819c84dd589ed0a023b9d25dcfe7a3c123d5bf784ffbb77edf55335f0c image: docker:20.10@sha256:2967f0819c84dd589ed0a023b9d25dcfe7a3c123d5bf784ffbb77edf55335f0c
include: include:
- local: 'ci-templates.yml'
- local: 'backend/.gitlab-ci.yml' - local: 'backend/.gitlab-ci.yml'
- local: 'frontend/.gitlab-ci.yml' - local: 'frontend/.gitlab-ci.yml'
stages: stages:
- backend_build - backend_build
- frontend_build - frontend_build
- dockerize
- deploy - deploy
- sync - sync
variables:
CI_REGISTRY_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
RAW_TAG: $CI_COMMIT_REF_NAME
TAG: "${RAW_TAG//\//_}" # replace "/" with "_"
sync_branches: sync_branches:
stage: sync stage: sync
image: node:22@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95 image: node:22@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95

View File

@@ -1,7 +0,0 @@
stages:
- backend_build
backend_build_job:
stage: backend_build
script:
- echo "Building backend project on branch: $CI_COMMIT_BRANCH"

View File

@@ -1,7 +1,46 @@
stages: stages:
- backend_build - backend_build
variables:
REGISTRY: registry.gitlab.com/$CI_PROJECT_PATH
backend_build_job: backend_build_job:
stage: backend_build stage: backend_build
image: maven:3.9.9-eclipse-temurin-21@sha256:2e3824afeb41f61761adee95318814e6669bd59aaf61255b2af47064b8755c02
script: script:
- echo "Building backend project" - cd backend
- mvn package
artifacts:
paths:
- backend/shared/target/
- backend/gateway/target/
- backend/discoveryServer/target/
- backend/services/**/target
expire_in: 1 hour
build_shared_base_image:
stage: dockerize
extends: .docker_build_template
variables:
DOCKER_CONTEXT: backend
DOCKERFILE: Dockerfile.base
DOCKER_IMAGE: "$DOCKER_IMAGE/shared-base"
DOCKER_BUILD_ARGS: ""
build_gateway_image:
stage: dockerize
extends: .docker_build_template
variables:
DOCKER_CONTEXT: backend
DOCKERFILE: Dockerfile.service
DOCKER_IMAGE: "$DOCKER_IMAGE/gateway"
DOCKER_BUILD_ARGS: "--build-arg JAR_FILE=gateway/target/gateway-*.jar"
build_discovery_image:
stage: dockerize
extends: .docker_build_template
variables:
DOCKER_CONTEXT: backend
DOCKERFILE: Dockerfile.service
DOCKER_IMAGE: "$DOCKER_IMAGE/discovery-server"
DOCKER_BUILD_ARGS: "--build-arg JAR_FILE=discoveryServer/target/discoveryServer-*.jar"

6
backend/Dockerfile.base Normal file
View File

@@ -0,0 +1,6 @@
# Dockerfile.base
FROM eclipse-temurin:21-jre-alpine
WORKDIR /shared
COPY backend/shared/target/shared-*.jar shared.jar

View File

@@ -0,0 +1,9 @@
# Dockerfile.service
FROM your-registry/shared-base:latest
WORKDIR /app
ARG JAR_FILE=app.jar
COPY backend/gateway/target/gateway-*.jar app.jar
# Use JarLauncher and include shared.jar in classpath
ENTRYPOINT ["java", "-cp", "/shared/shared.jar:/app/app.jar", "org.springframework.boot.loader.JarLauncher"]

17
ci-templates.yml Normal file
View File

@@ -0,0 +1,17 @@
.docker_build_template:
image: docker:20.10@sha256:2967f0819c84dd589ed0a023b9d25dcfe7a3c123d5bf784ffbb77edf55335f0c
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin
- if [ -z "$TAG" ]; then echo "ERROR: TAG variable is empty"; exit 1; fi
script:
- cd $DOCKER_CONTEXT
- |
echo "Building Docker image for $DOCKER_IMAGE with tag $TAG"
docker build $DOCKER_BUILD_ARGS -t $DOCKER_IMAGE:$TAG -f $DOCKERFILE .
- |
if [[ "$RAW_TAG" == "dev" || "$RAW_TAG" == "production" ]]; then
echo "Pushing Docker image $DOCKER_IMAGE:$TAG"
docker push $DOCKER_IMAGE:$TAG
else
echo "Skipping Docker push for non-dev or production branch: $RAW_TAG"
fi

View File

@@ -1,7 +0,0 @@
stages:
- frontend_build
frontend_build_job:
stage: frontend_build
script:
- echo "Building frontend project on branch: $CI_COMMIT_BRANCH"

View File

@@ -1,8 +1,35 @@
stages: stages:
- frontend_build - frontend_build
- dockerize
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .next/cache/
variables:
NEXT_PUBLIC_ENV: "production"
OUTPUT_DIR: ".next"
PROJECT_NAME: $CI_PROJECT_NAME
DOCKER_IMAGE: $CI_REGISTRY_IMAGE
frontend_build_job: frontend_build_job:
stage: frontend_build stage: frontend_build
image: node:22@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95 image: node:22@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95
script: script:
- echo "Building frontend project" - cd frontend
- npm install
- npx next build
- npm run lint
dockerize_frontend:
stage: dockerize
extends: .docker_build_template
variables:
DOCKER_CONTEXT: frontend
DOCKERFILE: Dockerfile
DOCKER_IMAGE: $DOCKER_IMAGE
DOCKER_BUILD_ARGS: ""
needs:
- job: frontend_build_job

View File

@@ -1,8 +1,8 @@
'use client'; 'use client';
import React, { useState } from "react"; import React, {useState} from "react";
import { motion } from "framer-motion"; import {motion} from "framer-motion";
import { useThemeColors } from "@/utils/useThemeColors"; import {useThemeColors} from "@/utils/useThemeColors";
import HCaptcha from "@hcaptcha/react-hcaptcha"; import HCaptcha from "@hcaptcha/react-hcaptcha";
const ContactFormSection = () => { const ContactFormSection = () => {
@@ -28,7 +28,7 @@ const ContactFormSection = () => {
: "ES_ff59a664dc764f92870bf2c7b4eab7c5"; : "ES_ff59a664dc764f92870bf2c7b4eab7c5";
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setForm({ ...form, [e.target.name]: e.target.value }); setForm({...form, [e.target.name]: e.target.value});
}; };
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
@@ -42,23 +42,21 @@ const ContactFormSection = () => {
return; return;
} }
try {
const res = await fetch("/api/contact", { const res = await fetch("/api/contact", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: {"Content-Type": "application/json"},
body: JSON.stringify({ ...form, captcha: captchaToken }), body: JSON.stringify({...form, captcha: captchaToken}),
}); });
if (res.ok) { if (res.ok) {
setSubmitted(true); setSubmitted(true);
setForm({ name: "", email: "", company: "", phone: "", website: "", message: "" }); setForm({name: "", email: "", company: "", phone: "", website: "", message: ""});
} else { } else {
const resJson = await res.json(); const resJson = await res.json();
setError(resJson?.error || "Ein Fehler ist aufgetreten. Bitte versuche es später erneut."); setError(resJson?.error || "Ein Fehler ist aufgetreten. Bitte versuche es später erneut.");
} }
} catch (_err) {
setError("Serverfehler. Bitte versuche es später erneut.");
}
setLoading(false); setLoading(false);
}; };
@@ -67,46 +65,77 @@ const ContactFormSection = () => {
<div className="w-full px-6 sm:px-12 py-20 text-left transition-theme"> <div className="w-full px-6 sm:px-12 py-20 text-left transition-theme">
<motion.h2 <motion.h2
className="text-2xl sm:text-3xl font-bold mb-2" className="text-2xl sm:text-3xl font-bold mb-2"
style={{ color: colors.primaryText }} style={{color: colors.primaryText}}
initial={{ opacity: 0, y: 20 }} initial={{opacity: 0, y: 20}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5 }} transition={{duration: 0.5}}
> >
Schreib uns eine Nachricht Schreib uns eine Nachricht
</motion.h2> </motion.h2>
<motion.p <motion.p
className="text-sm mb-8 max-w-xl" className="text-sm mb-8 max-w-xl"
style={{ color: colors.secondaryText }} style={{color: colors.secondaryText}}
initial={{ opacity: 0, y: 10 }} initial={{opacity: 0, y: 10}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5, delay: 0.2 }} transition={{duration: 0.5, delay: 0.2}}
> >
Wir freuen uns über dein Interesse und melden uns schnellstmöglich bei dir zurück. Wir freuen uns über dein Interesse und melden uns schnellstmöglich bei dir zurück.
</motion.p> </motion.p>
{submitted ? ( {submitted ? (
<div className="text-green-600 font-semibold text-lg"> Deine Nachricht wurde erfolgreich gesendet!</div> <div className="text-green-600 font-semibold text-lg"> Deine Nachricht wurde erfolgreich
gesendet!</div>
) : ( ) : (
<form className="space-y-6" onSubmit={handleSubmit}> <form className="space-y-6" onSubmit={handleSubmit}>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{[ {[
{ label: "Dein Name *", name: "name", type: "text", required: true, placeholder: "Max Mustermann" }, {
{ label: "Deine E-Mail *", name: "email", type: "email", required: true, placeholder: "max@example.com" }, label: "Dein Name *",
{ label: "Firmenname (optional)", name: "company", type: "text", required: false, placeholder: "Mustermann GmbH" }, name: "name",
{ label: "Telefonnummer (optional)", name: "phone", type: "tel", required: false, placeholder: "+49 123 456789" }, type: "text",
{ label: "Webseite (optional)", name: "website", type: "url", required: false, placeholder: "https://..." }, required: true,
placeholder: "Max Mustermann"
},
{
label: "Deine E-Mail *",
name: "email",
type: "email",
required: true,
placeholder: "max@example.com"
},
{
label: "Firmenname (optional)",
name: "company",
type: "text",
required: false,
placeholder: "Mustermann GmbH"
},
{
label: "Telefonnummer (optional)",
name: "phone",
type: "tel",
required: false,
placeholder: "+49 123 456789"
},
{
label: "Webseite (optional)",
name: "website",
type: "url",
required: false,
placeholder: "https://..."
},
].map((field, index) => ( ].map((field, index) => (
<motion.div <motion.div
key={field.name} key={field.name}
initial={{ opacity: 0, y: 10 }} initial={{opacity: 0, y: 10}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5, delay: index * 0.1 }} transition={{duration: 0.5, delay: index * 0.1}}
> >
<label className="block font-semibold mb-1" style={{ color: colors.primaryText }}> <label className="block font-semibold mb-1" style={{color: colors.primaryText}}>
{field.label} {field.label}
</label> </label>
<input <input
@@ -128,12 +157,12 @@ const ContactFormSection = () => {
</div> </div>
<motion.div <motion.div
initial={{ opacity: 0, y: 10 }} initial={{opacity: 0, y: 10}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5, delay: 0.6 }} transition={{duration: 0.5, delay: 0.6}}
> >
<label className="block font-semibold mb-1" style={{ color: colors.primaryText }}> <label className="block font-semibold mb-1" style={{color: colors.primaryText}}>
Deine Nachricht * Deine Nachricht *
</label> </label>
<textarea <textarea
@@ -154,12 +183,12 @@ const ContactFormSection = () => {
<motion.div <motion.div
className="pt-2" className="pt-2"
initial={{ opacity: 0, y: 10 }} initial={{opacity: 0, y: 10}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5, delay: 0.7 }} transition={{duration: 0.5, delay: 0.7}}
> >
<HCaptcha sitekey={hCaptchaSiteKey} onVerify={setCaptchaToken} /> <HCaptcha sitekey={hCaptchaSiteKey} onVerify={setCaptchaToken}/>
</motion.div> </motion.div>
{error && ( {error && (
@@ -170,10 +199,10 @@ const ContactFormSection = () => {
<motion.div <motion.div
className="pt-4 flex justify-end" className="pt-4 flex justify-end"
initial={{ opacity: 0, y: 10 }} initial={{opacity: 0, y: 10}}
whileInView={{ opacity: 1, y: 0 }} whileInView={{opacity: 1, y: 0}}
viewport={{ once: true }} viewport={{once: true}}
transition={{ duration: 0.5, delay: 0.8 }} transition={{duration: 0.5, delay: 0.8}}
> >
<button <button
type="submit" type="submit"

View File

@@ -18,8 +18,9 @@ const eslintConfig = [
{ {
argsIgnorePattern: '^_', argsIgnorePattern: '^_',
varsIgnorePattern: '^_' varsIgnorePattern: '^_'
} },
] ],
'@typescript-eslint/no-explicit-any': 'off'
} }
}) })
]; ];