Initial commit: demo-java-api with CI/CD
Some checks failed
Build & Deploy Java API / build (push) Has been cancelled
Some checks failed
Build & Deploy Java API / build (push) Has been cancelled
This commit is contained in:
77
.gitea/workflows/build.yml
Normal file
77
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
name: Build & Deploy Java API
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: harbor.cjjhc.top/library
|
||||||
|
APP_NAME: demo-java-api
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: self-hosted
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Prepare workspace
|
||||||
|
run: |
|
||||||
|
WORK=/root/.cache/${{ env.APP_NAME }}
|
||||||
|
rm -rf "$WORK"
|
||||||
|
mkdir -p "$WORK"
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.APP_NAME }}
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
- name: Cache Maven packages
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.m2/repository
|
||||||
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-maven-
|
||||||
|
|
||||||
|
- name: Login to Harbor
|
||||||
|
run: docker login ${{ env.REGISTRY }} -u admin -p "${{ secrets.HARBOR_PASSWORD }}"
|
||||||
|
|
||||||
|
- name: Build with Maven
|
||||||
|
run: |
|
||||||
|
cd ${{ env.APP_NAME }}
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
- name: Build & push Docker image
|
||||||
|
run: |
|
||||||
|
cd ${{ env.APP_NAME }}
|
||||||
|
SHORT=${GITHUB_SHA::8}
|
||||||
|
TAG="${{ env.REGISTRY }}/${{ env.APP_NAME }}:${SHORT}"
|
||||||
|
LATEST="${{ env.REGISTRY }}/${{ env.APP_NAME }}:latest"
|
||||||
|
|
||||||
|
docker build -t "${TAG}" -t "${LATEST}" .
|
||||||
|
docker push "${TAG}"
|
||||||
|
docker push "${LATEST}"
|
||||||
|
echo "✓ Pushed ${TAG}"
|
||||||
|
|
||||||
|
- name: Update image tag in values.yaml (commit-back GitOps)
|
||||||
|
run: |
|
||||||
|
cd ${{ env.APP_NAME }}
|
||||||
|
SHORT=${GITHUB_SHA::8}
|
||||||
|
|
||||||
|
# Update tag in values.yaml
|
||||||
|
sed -i "s/^ tag:.*/ tag: \"${SHORT}\"/" deploy/helm/values.yaml
|
||||||
|
|
||||||
|
# Configure git
|
||||||
|
git config user.email "ci@local"
|
||||||
|
git config user.name "gitea-ci"
|
||||||
|
|
||||||
|
# Commit and push
|
||||||
|
git add deploy/helm/values.yaml
|
||||||
|
git commit -m "ci: update image tag to ${SHORT}" || echo "nothing to commit"
|
||||||
|
git push origin main
|
||||||
|
echo "✓ Pushed values.yaml with tag ${SHORT}"
|
||||||
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Multi-stage build for Spring Boot
|
||||||
|
FROM maven:3.9-eclipse-temurin-17 AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY pom.xml .
|
||||||
|
COPY src ./src
|
||||||
|
RUN mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM eclipse-temurin:17-jre-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/target/*.jar app.jar
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s CMD wget -q -O- http://localhost:8080/actuator/health || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
44
README.md
Normal file
44
README.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Demo Java API
|
||||||
|
|
||||||
|
A simple Spring Boot API for CI/CD demonstration.
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
| Endpoint | Method | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/` | GET | Returns API info with timestamp |
|
||||||
|
| `/healthz` | GET | Health check endpoint |
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./mvnw spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Docker Image
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t demo-java-api .
|
||||||
|
docker run -p 8080:8080 demo-java-api
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
demo-java-api/
|
||||||
|
├── pom.xml # Maven config
|
||||||
|
├── Dockerfile # Multi-stage Docker build
|
||||||
|
├── src/
|
||||||
|
│ └── main/
|
||||||
|
│ ├── java/com/example/demo/
|
||||||
|
│ │ └── DemoJavaApiApplication.java
|
||||||
|
│ └── resources/
|
||||||
|
│ └── application.properties
|
||||||
|
├── deploy/helm/
|
||||||
|
│ ├── Chart.yaml
|
||||||
|
│ ├── values.yaml
|
||||||
|
│ └── templates/
|
||||||
|
│ └── deployment.yaml
|
||||||
|
└── .gitea/workflows/
|
||||||
|
└── build.yml # Gitea CI workflow
|
||||||
|
```
|
||||||
6
deploy/helm/Chart.yaml
Normal file
6
deploy/helm/Chart.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: demo-java-api
|
||||||
|
description: A Helm chart for demo-java-api
|
||||||
|
type: application
|
||||||
|
version: 1.0.0
|
||||||
|
appVersion: "1.0.0"
|
||||||
88
deploy/helm/templates/deployment.yaml
Normal file
88
deploy/helm/templates/deployment.yaml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{{- define "fullname" -}}
|
||||||
|
{{- .Chart.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ .Chart.Name }}
|
||||||
|
labels:
|
||||||
|
app: {{ .Chart.Name }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: {{ .Chart.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{ .Chart.Name }}
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- containerPort: {{ .Values.service.port }}
|
||||||
|
name: http
|
||||||
|
livenessProbe:
|
||||||
|
{{- if .Values.probes.liveness.enabled }}
|
||||||
|
httpGet:
|
||||||
|
path: {{ .Values.probes.liveness.path }}
|
||||||
|
port: {{ .Values.probes.liveness.port }}
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
{{- else }}
|
||||||
|
exec:
|
||||||
|
command: ["true"]
|
||||||
|
{{- end }}
|
||||||
|
readinessProbe:
|
||||||
|
{{- if .Values.probes.readiness.enabled }}
|
||||||
|
httpGet:
|
||||||
|
path: {{ .Values.probes.readiness.path }}
|
||||||
|
port: {{ .Values.probes.readiness.port }}
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
{{- else }}
|
||||||
|
exec:
|
||||||
|
command: ["true"]
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
env:
|
||||||
|
{{- toYaml .Values.env | nindent 12 }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ .Chart.Name }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: {{ .Chart.Name }}
|
||||||
|
{{- if .Values.ingress.enabled }}
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ .Chart.Name }}
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.host }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: {{ .Values.ingress.path }}
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ .Chart.Name }}
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.port }}
|
||||||
|
{{- end }}
|
||||||
38
deploy/helm/values.yaml
Normal file
38
deploy/helm/values.yaml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Default values
|
||||||
|
image:
|
||||||
|
registry: harbor.cjjhc.top/library
|
||||||
|
name: demo-java-api
|
||||||
|
tag: "latest"
|
||||||
|
pullPolicy: Always
|
||||||
|
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: traefik
|
||||||
|
host: demo-java-api.local
|
||||||
|
path: /
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 1Gi
|
||||||
|
|
||||||
|
env: []
|
||||||
|
|
||||||
|
probes:
|
||||||
|
liveness:
|
||||||
|
enabled: true
|
||||||
|
path: /healthz
|
||||||
|
port: 8080
|
||||||
|
readiness:
|
||||||
|
enabled: true
|
||||||
|
path: /healthz
|
||||||
|
port: 8080
|
||||||
43
pom.xml
Normal file
43
pom.xml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.example</groupId>
|
||||||
|
<artifactId>demo-java-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>demo-java-api</name>
|
||||||
|
<description>Demo Java API for CI/CD testing</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
35
src/main/java/com/example/demo/DemoJavaApiApplication.java
Normal file
35
src/main/java/com/example/demo/DemoJavaApiApplication.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package com.example.demo;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@RestController
|
||||||
|
public class DemoJavaApiApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DemoJavaApiApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public Map<String, Object> home() {
|
||||||
|
Map<String, Object> response = new HashMap<>();
|
||||||
|
response.put("message", "Hello from Java API");
|
||||||
|
response.put("version", "1.0.0");
|
||||||
|
response.put("timestamp", Instant.now().toString());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/healthz")
|
||||||
|
public Map<String, String> health() {
|
||||||
|
Map<String, String> response = new HashMap<>();
|
||||||
|
response.put("status", "OK");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/main/resources/application.properties
Normal file
5
src/main/resources/application.properties
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
server.port=8080
|
||||||
|
spring.application.name=demo-java-api
|
||||||
|
|
||||||
|
management.endpoints.web.exposure.include=health,info
|
||||||
|
management.endpoint.health.show-details=always
|
||||||
Reference in New Issue
Block a user