diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9dd2a13 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +# Exclude build output and IDE files to reduce Docker build context size +target +**/target + +# Git and local metadata +.git +.gitignore +.DS_Store + +# Local editor / IDE +.idea +.vscode +*.iml +*.sublime-* + +# Build artifacts and temporary files +*.class +*.log +tmp/ +build/ + +# Swap / editor backups +*.swp + +# Internal Docker +.dockerignore +docker/ + +# Project specific ignores +README.md +LICENSE + +# CI Files +.github/ +.k8s/ \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..f468a5a --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,165 @@ +name: ci + +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: ./mvnw clean package -DskipTests + + run-tests: + runs-on: ubuntu-latest + needs: [ build ] + + steps: + + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Running Tests with Maven + run: ./mvnw test + + docker: + needs: [ build, run-tests ] + if: github.ref_name == 'main' || github.ref_name == 'develop' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write # required to push to ghcr.io + id-token: write # optional for OIDC if you use it + + steps: + - uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Prepare image tags + run: | + OWNER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]') + REPO=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]') + + # Determine tag + if [ "${GITHUB_REF_NAME}" = "main" ]; then + TAG="latest" + else + TAG="dev" + fi + + SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) + IMAGE_BASE="ghcr.io/${OWNER}/${REPO}" + + echo "IMAGE_LATEST=${IMAGE_BASE}:${TAG}" >> $GITHUB_ENV + echo "IMAGE_SHA=${IMAGE_BASE}:sha-${SHORT_SHA}" >> $GITHUB_ENV + + - name: Build and push Docker image (with registry cache) + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ${{ env.IMAGE_LATEST }} + ${{ env.IMAGE_SHA }} + cache-from: type=gha + cache-to: type=gha,mode=max + + deploy: + needs: [docker] + runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == 'main') + environment: + name: ${{ github.ref_name == 'main' && 'production' || 'dev' }} + url: https://${{ vars.KUBE_DOMAIN }} + env: + # Kubernetes Specific + KUBE_NAMESPACE: ${{ vars.KUBE_NAMESPACE }} + KUBE_API_DOMAIN: ${{ vars.KUBE_API_DOMAIN }} + WORKER_NODE_LABEL: ${{ vars.WORKER_NODE_LABEL }} + # Application Specific + FRONTEND_PATH: ${{ vars.FRONTEND_PATH }} + + steps: + - uses: actions/checkout@v4 + - uses: azure/setup-kubectl@v4 + + - name: Set Up Kubeconfig + uses: azure/k8s-set-context@v4 + with: + kubeconfig: ${{ secrets.PORTFOLIO_KUBECONFIG }} + + - name: Prepare Image Tag + run: | + OWNER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]') + REPO=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]') + SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) + + IMAGE_BASE="ghcr.io/${OWNER}/${REPO}" + IMAGE_TAG="sha-${SHORT_SHA}" + + echo "IMAGE_BASE=${IMAGE_BASE}" >> $GITHUB_ENV + echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV + + - name: Import SOPS GPG Key + run: | + echo "${{ secrets.PORTFOLIO_GPG_PRIVATE_KEY }}" | gpg --import + + - name: Install SOPS + run: | + curl -L https://github.com/mozilla/sops/releases/download/v3.9.1/sops-v3.9.1.linux.amd64 -o /usr/local/bin/sops + chmod +x /usr/local/bin/sops + + - name: Decrypt SOPS Secrets Test + run: | + cd .k8s + sops -d secrets.enc.yml secrets.yml + + - name: Apply Kubernetes Manifests - Configuration + run: cat .k8s/config.template.yml | envsubst | kubectl apply -f - + + - name: Apply Kubernetes Manifests - Secrets + run: cat .k8s/secrets.yml | envsubst | kubectl apply -f - + + - name: Apply Kubernetes Manifests - Postgres Cluster + run: cat .k8s/postgres-cluster.template.yml | envsubst | kubectl apply -f - + + - name: Apply Kubernetes Manifests - Redis Cluster + run: cat .k8s/redis.template.yml | envsubst | kubectl apply -f - + + - name: Apply Kubernetes Manifests - Deployment + run: | + cat .k8s/deployment.template.yml | envsubst | kubectl apply -f - + cat .k8s/deployment.yaml | envsubst | kubectl rollout status deployment/frontend-deployment -n ${KUBE_NAMESPACE} --timeout=120s + + - name: Apply Kubernetes Manifests - Service + run: cat .k8s/service.template.yml | envsubst | kubectl apply -f - + + - name: Apply Kubernetes Manifests - Ingress + run: cat .k8s/ingress.template.yml | envsubst | kubectl apply -f - diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml deleted file mode 100644 index e2fac91..0000000 --- a/.github/workflows/docker-image.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: ci - -on: - push: - branches: - - 'main' - -jobs: - docker: - - runs-on: ubuntu-latest - steps: - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v2 - with: - platforms: linux/amd64,linux/arm64 - push: true - tags: yoshiunfriendly/backend-hideyoshi.com:latest - - run-dispatcher: - needs: docker - runs-on: ubuntu-latest - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Runs Infra-Hideyoshi.com Deployment Dispatcher - run: | - curl -X POST https://api.github.com/repos/HideyoshiSolutions/infra-hideyoshi.com/dispatches \ - -H 'Accept: application/vnd.github.everest-preview+json' \ - -u ${{ secrets.ACTIONS_KEY }} \ - --data '{"event_type": "refresh-deployments", "client_payload": { "deployments": "backend-deployment" }}' \ No newline at end of file diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 5c6906a..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: ci -on: - push - -jobs: - run-tests: - runs-on: ubuntu-latest - - steps: - - - uses: actions/checkout@v3 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Running Tests with Maven - run: ./mvnw test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 13dcb63..953f756 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,9 @@ build/ ### VS Code ### .vscode/ -src/main/resources/application-devel.yml +src/main/resources/application*.yml +!src/main/resources/application.yml +!src/main/resources/application-no-oauth.yml ### Maven ### target/ @@ -45,4 +47,15 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties # https://github.com/takari/maven-wrapper#usage-without-binary-jar -.mvn/wrapper/maven-wrapper.jar \ No newline at end of file +.mvn/wrapper/maven-wrapper.jar + +### Certs ### +*.pem + +### Secrets and Envs ### +.env* +*.secret + +.k8s/*.yml +!.k8s/*.template.yml +!.k8s/*.enc.yml \ No newline at end of file diff --git a/.k8s/.sops.yaml b/.k8s/.sops.yaml new file mode 100644 index 0000000..44705ed --- /dev/null +++ b/.k8s/.sops.yaml @@ -0,0 +1,5 @@ +creation_rules: + - path_regex: ^secrets(\.enc)?\.yml$ + encrypted_regex: '^(data|stringData)$' + pgp: >- + 8C8D94A7639C87559B0F2F64B7E1F62F69798EB6 \ No newline at end of file diff --git a/.k8s/config.template.yml b/.k8s/config.template.yml new file mode 100644 index 0000000..1dec8f3 --- /dev/null +++ b/.k8s/config.template.yml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: backend-config + namespace: ${KUBE_NAMESPACE} +data: + FRONTEND_PATH: ${FRONTEND_PATH} + STORAGE_SERVICE_INTERNAL_URL: storage-service + STORAGE_SERVICE_PORT: "8000" \ No newline at end of file diff --git a/.k8s/deployment.template.yml b/.k8s/deployment.template.yml new file mode 100644 index 0000000..fccaba7 --- /dev/null +++ b/.k8s/deployment.template.yml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-deployment + namespace: ${KUBE_NAMESPACE} +spec: + replicas: 1 + selector: + matchLabels: + app: backend + template: + metadata: + labels: + app: backend + spec: + nodeSelector: + ${WORKER_NODE_LABEL} + imagePullSecrets: + - name: ghcr-secret + containers: + - name: backend + image: ${IMAGE_BASE}:${IMAGE_TAG} + imagePullPolicy: Always + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "1000m" + ports: + - containerPort: 8070 + readinessProbe: + httpGet: + path: /health + port: 8070 + initialDelaySeconds: 60 + livenessProbe: + httpGet: + path: /health + port: 8070 + initialDelaySeconds: 60 + envFrom: + - configMapRef: + name: backend-config + - secretRef: + name: backend-secret + env: + - name: PORT + value: "8070" + + - name: REDIS_URL + value: backend-redis-service + + - name: REDIS_PORT + value: "6379" + + - name: POSTGRES_URL + valueFrom: + secretKeyRef: + name: backend-postgres-cluster-app + key: host + + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: backend-postgres-cluster-app + key: dbname + + - name: DATABASE_URL + value: "postgresql://$(POSTGRES_URL):5432/$(POSTGRES_DB)" + + - name: DATABASE_USERNAME + valueFrom: + secretKeyRef: + name: backend-postgres-cluster-app + key: user + + - name: DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: backend-postgres-cluster-app + key: password + + - name: STORAGE_SERVICE_URL + valueFrom: + configMapKeyRef: + name: backend-config + key: STORAGE_SERVICE_INTERNAL_URL + + - name: STORAGE_SERVICE_PORT + valueFrom: + configMapKeyRef: + name: backend-config + key: STORAGE_SERVICE_PORT + + - name: STORAGE_SERVICE_PATH + value: "http://$(STORAGE_SERVICE_URL):$(STORAGE_SERVICE_PORT)" + diff --git a/.k8s/ingress.template.yml b/.k8s/ingress.template.yml new file mode 100644 index 0000000..517ee9e --- /dev/null +++ b/.k8s/ingress.template.yml @@ -0,0 +1,25 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: backend-ingress + namespace: ${KUBE_NAMESPACE} + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + tls: + - hosts: + - ${KUBE_API_DOMAIN} + secretName: letsencrypt-cluster-certificate-tls + rules: + - host: ${KUBE_API_DOMAIN} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: backend-service + port: + number: 8070 \ No newline at end of file diff --git a/.k8s/postgres-cluster.template.yml b/.k8s/postgres-cluster.template.yml new file mode 100644 index 0000000..86366ac --- /dev/null +++ b/.k8s/postgres-cluster.template.yml @@ -0,0 +1,22 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: backend-postgres-cluster + namespace: ${KUBE_NAMESPACE} +spec: + instances: 3 + primaryUpdateStrategy: unsupervised + imageName: ghcr.io/cloudnative-pg/postgresql:14.10-18 + + storage: + size: 5Gi + + resources: + requests: + memory: "256Mi" + cpu: "200m" + limits: + memory: "512Mi" + cpu: "500m" + + affinity: {} diff --git a/.k8s/redis.template.yml b/.k8s/redis.template.yml new file mode 100644 index 0000000..f4ce8ff --- /dev/null +++ b/.k8s/redis.template.yml @@ -0,0 +1,47 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: ${KUBE_NAMESPACE} + name: backend-redis-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: backend-redis + template: + metadata: + labels: + app: backend-redis + spec: + containers: + - name: redis + image: valkey/valkey:8.0.6-alpine + imagePullPolicy: "IfNotPresent" + resources: + requests: + memory: "256Mi" + cpu: "75m" + limits: + memory: "256Mi" + cpu: "256m" + ports: + - containerPort: 6379 + env: + - name: VALKEY_PASSWORD + valueFrom: + secretKeyRef: + name: backend-secret + key: REDIS_PASSWORD + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: ${KUBE_NAMESPACE} + name: backend-redis-service +spec: + selector: + app: backend-redis + ports: + - port: 6379 + type: ClusterIP \ No newline at end of file diff --git a/.k8s/secrets.enc.yml b/.k8s/secrets.enc.yml new file mode 100644 index 0000000..fa34e89 --- /dev/null +++ b/.k8s/secrets.enc.yml @@ -0,0 +1,46 @@ +apiVersion: v1 +kind: Secret +metadata: + name: backend-secret + namespace: ${KUBE_NAMESPACE} +data: + ACCESS_TOKEN_DURATION: ENC[AES256_GCM,data:UID13ASjuH9hrFfx,iv:D9cTYN60Q8KL1ZdEMPAQ/RP+uqsMbA95cOqngMtxyF8=,tag:Q4cCzqzzRiuf2wyTW86kXg==,type:str] + DEFAULT_USER_EMAIL: ENC[AES256_GCM,data:DJ/3gHT47OidWhevnCHBdzwrFhmCDQeYzjL3siAi+e/Op3Ge,iv:AqUg21UnGl5tJP6TIewcL9wdpAJBGS7Af6olHRm+auU=,tag:+PX5bjMslR0FVqd9fSXnBg==,type:str] + DEFAULT_USER_FULLNAME: ENC[AES256_GCM,data:WGQEQ1/5NhDYudrW8nBnQUXmcC0=,iv:BvysE7IGiXzFUqse0AtzrW1eO4Y52TgD1RX1hxXjqnQ=,tag:nqHCPt7Aa53OTBOTkQGSDA==,type:str] + DEFAULT_USER_PASSWORD: ENC[AES256_GCM,data:N+q5z+cYXPPf7peJdGKx+A6ou5A=,iv:kmOdcNStwIJOnO1RQ+KOcpW3wxrzR13xtdBwSTvC834=,tag:esM/CE+Y4oCFKs7w573qLw==,type:str] + DEFAULT_USER_USERNAME: ENC[AES256_GCM,data:IXWTfhIKBgs+/zUCRBN5SHcn3Ig=,iv:0RegOxvd7WzoSW8u6sjJLdn6kPoSJzstj+OyStS5zNA=,tag:Lv5XR//V9FD0Aa1kLEmOUA==,type:str] + GITHUB_CLIENT_ID: ENC[AES256_GCM,data:Wg8YoSkLie3HgAMUi2Y25GV/0Di+gs0i6KznVg==,iv:4tsj0GvTa21O/CUZ/54B0VnX9Ebi0pX8Y0cBlwQ9uGQ=,tag:uS9WRW9SEeP+PXERUAUDqg==,type:str] + GITHUB_CLIENT_SECRET: ENC[AES256_GCM,data:xA1jb1YcQzLYOtWQWnY1t6DP701Q4P7JXKVCA9m2t9npettwy4FR2Gt1WqrYkyuMrp8CYYdVnlY=,iv:ThCZid05MBY/6W4/H9Xi85bsT6AzOpdhGVWBEc4zNYE=,tag:hP3CO+ElBug0n3f4P708BA==,type:str] + GITHUB_REDIRECT_URL: ENC[AES256_GCM,data:YI1CWaPAtTilqq7ZAmKKGtn9fQs4/urH874s2Nc51Rnqc5/xjYbTpbd/2MMg0vmyrFK8Twcg2RtnfLFa,iv:viH3P9FPCUsd9KoEwVdNTYNl+v24gcGCnVMJzB4AvxM=,tag:b7oSX1Vn5SiFiMhWBsLEDQ==,type:str] + GOOGLE_CLIENT_ID: ENC[AES256_GCM,data:GaKQG4al/kl1PyVGLyQ3gKI0y93IvyPWoxlWd1Iu8YUkcP6vQ80S4fQ1LCGGS8BA0f83SnwTZT37vrFz7h6V3+po6a7CjXE/gSRsu/HIuOG+O4gyAw07KWHorLpcD8pL,iv:RGskspn8CEq3rwinaOe4T/KajAUMHVBJLnGOgBT8L78=,tag:YuSQgDuowd8LLhf5Rdcj2w==,type:str] + GOOGLE_CLIENT_SECRET: ENC[AES256_GCM,data:6sQAluZFxc6mEOZffPJV5Al64APVHJyHHZzneofu17nflE6eslzH0SfL1Uo/ngu6,iv:Za9MHjCSWsGCik9OgJXYmLfFLmcVPQ7V4bLeeflVVOw=,tag:cZfo/pdl42n+eiKPrwFGMg==,type:str] + GOOGLE_REDIRECT_URL: ENC[AES256_GCM,data:3smhd+Hp3/q2uRVHoASTnm7j1F90TAaauCVuWsCUG1aKb++eXkdLEqP5j77szzFmWmBpgeW3hjP7dipL,iv:CPUxKja1YLSnKQpVeEHGkxxmQg1qJnQxRJ48Mw/k75Q=,tag:YJ/c5N1QLLRbCXsi2D2X4g==,type:str] + REDIS_PASSWORD: ENC[AES256_GCM,data:9kexm1c0M7A=,iv:MUSnfOdUbbsJReQtuzyVrJcsc3NqptE96w3Kh1jbqjo=,tag:SvSHTW8Sm3UMIKismYubng==,type:str] + REFRESH_TOKEN_DURATION: ENC[AES256_GCM,data:MCz6j6RI9hKcD8Zzqvt1Iw==,iv:nsw3cTtVJo+/1foTp/M78ByF5p8K6uw720GY8sAJypU=,tag:Usq/7VvLn7MGpoYbZgXAtg==,type:str] + TOKEN_SECRET: ENC[AES256_GCM,data:ESHASgGJZYspUVua,iv:52aZ1Ds984u8rZR48lNjPhBM07vnWGTpEOE6c7cItUU=,tag:Xc/6w/PqDDspl3r/krgdTg==,type:str] +sops: + lastmodified: "2025-11-07T23:43:53Z" + mac: ENC[AES256_GCM,data:38dHNBEQuExxNeouXp7LotuV5aYTUcrhovYEB0v9SPK8q5ViwXSiU730BTyqF3iya6AuugT3xuFZZG0BFxAOv57FXpiX32pVOb9OQEf/vo1I6+lKjYCg0NiP6qvtpH59z4m35SG6zUXICf5zJucOr+n+UeRMsLO4tbjg9s5A+DU=,iv:vlXW79iMy1qBY+hzqkX2McB3746oJZI/6vqeSi9HNNw=,tag:kGhNHSh/aAXDv3Qz3k3gOg==,type:str] + pgp: + - created_at: "2025-11-07T23:43:53Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQIMAwzdivR1H/BQAQ//ffQ2BHDvlwBU7Ck4BfM3sN5XYFCMVY1Nd1WxNB+Mso7+ + Rx4WD1UfNufJhzXIDwGICyNghrfy16UEZZxq2uM/vE/PeQjOwTmkBAB+izzOP8cM + 219UV0RG+qh5/n8v5szcaOvpwI2rU5OvRJs/M7N2563rTy+GtXxM3F8zdMFX6ilQ + PNwo0Ah2ag45PEuu/RH9BQ7egdPx4niKESbBX8Ixp95BndcIUqqDmg7mq7oIeg5K + 5nu6D0AAf41D5vqTDNpT5P+KiY5adStW22vwTehfBklVXK65scDbEp7BQjMlfWMX + a2DVv0axxOvqPuXaABoVtbHFH9UMnUCe3rcq1An4id/DHU7WrRt0SkHcvHPYxbsO + IWxtl8Au9NH7hjpYO5uTP1HfUYw/MkZ0kC27ZoIg/QxCM1HkYQJU85J9VrK+GhJT + /HbXGb9PE6XIH/Nh0PNJ7cHdpM0tXSE/AyTjdyN5DSnub6sT28vORbsHQkV4oykq + k03gDtT50qT5t0x9oYydJPBCcTd8vhNfNqxYA0ppuGJo3iv+81LDPRSTvGRSU8UJ + bbX56ryJMO/942oBp4u5dsL2q7u0/5cPBJ7UN8v9dJkSAuSHTVNYhhFzKnLsGbr1 + ZpBzfg1Mp0zySv2CZpY5xDu1SFs+kaDVPRrOlPz8jFsyt1WNjRNun0521Gfc/CbS + XgEpMev76yzSjkbNSwRS/2U13w7fh76F2MO6ftOwcWS89Do+drdyWJq15ou0LJZE + cqV6ojX5hhtFsH2YTS/+kGDTGf0mNEHtglSzwUT4M0bHBO2vld7p7SNkzMKrwkE= + =vkjm + -----END PGP MESSAGE----- + fp: 8C8D94A7639C87559B0F2F64B7E1F62F69798EB6 + encrypted_regex: ^(data|stringData)$ + version: 3.11.0 diff --git a/.k8s/service.template.yml b/.k8s/service.template.yml new file mode 100644 index 0000000..acd188e --- /dev/null +++ b/.k8s/service.template.yml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: ${KUBE_NAMESPACE} + name: backend-service +spec: + selector: + app: backend + ports: + - port: 8070 + protocol: TCP + targetPort: 8070 + type: ClusterIP \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 38e7828..732dd0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,24 @@ -# -# Build stage -# FROM maven:3.9.3-ibm-semeru-17-focal AS build -COPY src /home/app/src -COPY pom.xml /home/app -RUN mvn -Dmaven.test.skip -f /home/app/pom.xml clean package + +WORKDIR /home/app + +COPY pom.xml mvnw ./ +COPY .mvn/ .mvn/ + +# Download dependencies into /root/.m2 (use BuildKit cache if available). +# If BuildKit isn't enabled this still works as a normal mvn dependency:go-offline. +RUN --mount=type=cache,target=/root/.m2 mvn -B -Dmaven.test.skip=true dependency:go-offline + +COPY src ./src +RUN --mount=type=cache,target=/root/.m2 mvn -B -Dmaven.test.skip=true package # # Package stage # FROM ibm-semeru-runtimes:open-17-jdk-focal +WORKDIR /app -COPY --from=build /home/app/target/*.jar app.jar -COPY src/main/resources/* credentials/ +# Copy final artifact +COPY --from=build /home/app/target/*.jar ./app.jar -ENTRYPOINT ["java","-XX:TieredStopAtLevel=1","-Xverify:none","-jar","/app.jar"] \ No newline at end of file +ENTRYPOINT ["java","-XX:TieredStopAtLevel=1","-Xverify:none","-jar","/app/app.jar"] diff --git a/src/main/java/br/com/hideyoshi/auth/controller/UserController.java b/src/main/java/br/com/hideyoshi/auth/controller/UserController.java index 5349b37..7ad0d46 100644 --- a/src/main/java/br/com/hideyoshi/auth/controller/UserController.java +++ b/src/main/java/br/com/hideyoshi/auth/controller/UserController.java @@ -8,7 +8,6 @@ import br.com.hideyoshi.auth.model.microservice.StorageServiceUploadResponse; import br.com.hideyoshi.auth.security.service.AuthService; import br.com.hideyoshi.auth.service.UserService; import br.com.hideyoshi.auth.service.microservice.StorageService; -import br.com.hideyoshi.auth.util.exception.AuthenticationInvalidException; import br.com.hideyoshi.auth.util.exception.BadRequestException; import br.com.hideyoshi.auth.util.guard.UserResourceGuard; import br.com.hideyoshi.auth.util.guard.UserResourceGuardEnum; @@ -21,9 +20,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import java.io.IOException; import java.net.URI; import java.util.List; diff --git a/src/main/java/br/com/hideyoshi/auth/util/validator/email/unique/EmailUnique.java b/src/main/java/br/com/hideyoshi/auth/util/validator/email/unique/EmailUnique.java index 5804ebb..d583514 100644 --- a/src/main/java/br/com/hideyoshi/auth/util/validator/email/unique/EmailUnique.java +++ b/src/main/java/br/com/hideyoshi/auth/util/validator/email/unique/EmailUnique.java @@ -19,7 +19,7 @@ public class EmailUnique implements ConstraintValidator { @Override public boolean isValid(String email, ConstraintValidatorContext constraintValidatorContext) { - AtomicReference emailValid = new AtomicReference(); + AtomicReference emailValid = new AtomicReference<>(); this.userRepository.findByEmail(email).ifPresentOrElse( (value) -> { emailValid.set(false);