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