Skip to content

Commit 6e29680

Browse files
committed
完善GitHub设置:添加CI/CD、Docker支持、组织README
1 parent 8544cd7 commit 6e29680

File tree

5 files changed

+425
-0
lines changed

5 files changed

+425
-0
lines changed

.github/workflows/ci-cd.yml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: Java CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
schedule:
9+
- cron: '0 2 * * *' # 每天凌晨2点运行
10+
11+
jobs:
12+
build-and-test:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v3
18+
19+
- name: Set up JDK 11
20+
uses: actions/setup-java@v3
21+
with:
22+
java-version: '11'
23+
distribution: 'temurin'
24+
cache: maven
25+
26+
- name: Cache Maven dependencies
27+
uses: actions/cache@v3
28+
with:
29+
path: ~/.m2
30+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
31+
restore-keys: |
32+
${{ runner.os }}-maven-
33+
34+
- name: Build with Maven
35+
run: ./mvnw clean compile -DskipTests
36+
37+
- name: Run tests
38+
run: ./mvnw test
39+
env:
40+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
41+
42+
- name: Run integration tests
43+
run: ./mvnw verify -DskipITs=false
44+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
45+
46+
- name: Code coverage
47+
uses: codecov/codecov-action@v3
48+
with:
49+
file: ./target/site/jacoco/jacoco.xml
50+
fail_ci_if_error: false
51+
52+
- name: Build Docker image
53+
run: |
54+
docker build -t intellidev/java-ai-starter:latest .
55+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
56+
57+
- name: Security scan
58+
uses: snyk/actions/maven@master
59+
env:
60+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
61+
continue-on-error: true
62+
63+
- name: Upload build artifacts
64+
uses: actions/upload-artifact@v3
65+
with:
66+
name: java-artifacts
67+
path: target/*.jar
68+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
69+
70+
quality-check:
71+
runs-on: ubuntu-latest
72+
needs: build-and-test
73+
74+
steps:
75+
- name: Checkout code
76+
uses: actions/checkout@v3
77+
78+
- name: SonarCloud Scan
79+
uses: SonarSource/sonarcloud-github-action@master
80+
env:
81+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
82+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
83+
84+
- name: Checkstyle
85+
run: ./mvnw checkstyle:check
86+
87+
- name: PMD analysis
88+
run: ./mvnw pmd:check
89+
90+
- name: SpotBugs analysis
91+
run: ./mvnw spotbugs:check
92+
93+
deploy:
94+
runs-on: ubuntu-latest
95+
needs: [build-and-test, quality-check]
96+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
97+
98+
steps:
99+
- name: Checkout code
100+
uses: actions/checkout@v3
101+
102+
- name: Set up JDK 11
103+
uses: actions/setup-java@v3
104+
with:
105+
java-version: '11'
106+
distribution: 'temurin'
107+
108+
- name: Build package
109+
run: ./mvnw clean package -DskipTests
110+
111+
- name: Login to DockerHub
112+
uses: docker/login-action@v2
113+
with:
114+
username: ${{ secrets.DOCKER_USERNAME }}
115+
password: ${{ secrets.DOCKER_PASSWORD }}
116+
117+
- name: Build and push Docker image
118+
uses: docker/build-push-action@v4
119+
with:
120+
context: .
121+
push: true
122+
tags: |
123+
intellidev/java-ai-starter:latest
124+
intellidev/java-ai-starter:${{ github.sha }}
125+
126+
- name: Deploy to staging
127+
run: |
128+
echo "Deploying to staging environment..."
129+
# 这里添加你的部署脚本
130+
# 例如:kubectl apply -f k8s/
131+
env:
132+
KUBECONFIG: ${{ secrets.KUBECONFIG_STAGING }}
133+
134+
- name: Run smoke tests
135+
run: |
136+
echo "Running smoke tests..."
137+
# 这里添加冒烟测试脚本
138+
139+
- name: Deploy to production
140+
if: success()
141+
run: |
142+
echo "Deploying to production..."
143+
# 这里添加生产环境部署脚本
144+
env:
145+
KUBECONFIG: ${{ secrets.KUBECONFIG_PRODUCTION }}
146+
147+
documentation:
148+
runs-on: ubuntu-latest
149+
150+
steps:
151+
- name: Checkout code
152+
uses: actions/checkout@v3
153+
154+
- name: Generate API documentation
155+
run: ./mvnw javadoc:javadoc
156+
157+
- name: Deploy to GitHub Pages
158+
uses: peaceiris/actions-gh-pages@v3
159+
with:
160+
github_token: ${{ secrets.GITHUB_TOKEN }}
161+
publish_dir: ./target/site/apidocs
162+
destination_dir: ./docs/api
163+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Java AI Starter - Dockerfile
2+
# 多阶段构建,优化镜像大小
3+
4+
# 第一阶段:构建阶段
5+
FROM maven:3.8.4-openjdk-11-slim AS builder
6+
7+
WORKDIR /app
8+
9+
# 复制Maven配置文件
10+
COPY pom.xml .
11+
COPY .mvn .mvn
12+
COPY mvnw .
13+
14+
# 下载依赖(利用Docker缓存)
15+
RUN mvn dependency:go-offline -B
16+
17+
# 复制源代码
18+
COPY src src
19+
20+
# 构建应用
21+
RUN mvn clean package -DskipTests
22+
23+
# 第二阶段:运行阶段
24+
FROM openjdk:11-jre-slim
25+
26+
# 设置时区
27+
ENV TZ=Asia/Shanghai
28+
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
29+
30+
# 创建非root用户
31+
RUN groupadd -r appuser && useradd -r -g appuser appuser
32+
33+
WORKDIR /app
34+
35+
# 从构建阶段复制jar文件
36+
COPY --from=builder /app/target/*.jar app.jar
37+
38+
# 复制启动脚本
39+
COPY scripts/docker-entrypoint.sh /usr/local/bin/
40+
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
41+
42+
# 创建必要的目录
43+
RUN mkdir -p /app/logs /app/config && \
44+
chown -R appuser:appuser /app
45+
46+
# 切换到非root用户
47+
USER appuser
48+
49+
# 健康检查
50+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
51+
CMD curl -f http://localhost:8080/actuator/health || exit 1
52+
53+
# 暴露端口
54+
EXPOSE 8080
55+
56+
# 设置环境变量
57+
ENV JAVA_OPTS="-Xmx512m -Xms256m"
58+
ENV SPRING_PROFILES_ACTIVE="docker"
59+
60+
# 入口点
61+
ENTRYPOINT ["docker-entrypoint.sh"]
62+
63+
# 默认命令
64+
CMD ["java", "-jar", "app.jar"]

docker-compose.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
version: '3.8'
2+
3+
services:
4+
java-ai-app:
5+
build: .
6+
container_name: java-ai-starter
7+
ports:
8+
- "8080:8080"
9+
environment:
10+
- SPRING_PROFILES_ACTIVE=docker
11+
- OPENAI_API_KEY=${OPENAI_API_KEY:-sk-demo-key}
12+
- OPENAI_MODEL=${OPENAI_MODEL:-gpt-3.5-turbo}
13+
- SERVER_PORT=8080
14+
- LOGGING_LEVEL_ROOT=INFO
15+
volumes:
16+
- ./logs:/app/logs
17+
- ./config:/app/config
18+
networks:
19+
- ai-network
20+
restart: unless-stopped
21+
healthcheck:
22+
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
23+
interval: 30s
24+
timeout: 10s
25+
retries: 3
26+
start_period: 40s
27+
labels:
28+
- "com.intellidev.description=Java AI Starter Application"
29+
- "com.intellidev.version=1.0.0"
30+
31+
postgres:
32+
image: postgres:13-alpine
33+
container_name: java-ai-postgres
34+
environment:
35+
- POSTGRES_DB=ai_starter
36+
- POSTGRES_USER=ai_user
37+
- POSTGRES_PASSWORD=${DB_PASSWORD:-ai_password}
38+
ports:
39+
- "5432:5432"
40+
volumes:
41+
- postgres_data:/var/lib/postgresql/data
42+
- ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
43+
networks:
44+
- ai-network
45+
restart: unless-stopped
46+
healthcheck:
47+
test: ["CMD-SHELL", "pg_isready -U ai_user -d ai_starter"]
48+
interval: 30s
49+
timeout: 10s
50+
retries: 5
51+
52+
redis:
53+
image: redis:7-alpine
54+
container_name: java-ai-redis
55+
ports:
56+
- "6379:6379"
57+
command: redis-server --appendonly yes
58+
volumes:
59+
- redis_data:/data
60+
networks:
61+
- ai-network
62+
restart: unless-stopped
63+
healthcheck:
64+
test: ["CMD", "redis-cli", "ping"]
65+
interval: 30s
66+
timeout: 10s
67+
retries: 5
68+
69+
prometheus:
70+
image: prom/prometheus:latest
71+
container_name: java-ai-prometheus
72+
ports:
73+
- "9090:9090"
74+
volumes:
75+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
76+
- prometheus_data:/prometheus
77+
command:
78+
- '--config.file=/etc/prometheus/prometheus.yml'
79+
- '--storage.tsdb.path=/prometheus'
80+
- '--web.console.libraries=/etc/prometheus/console_libraries'
81+
- '--web.console.templates=/etc/prometheus/consoles'
82+
- '--storage.tsdb.retention.time=200h'
83+
- '--web.enable-lifecycle'
84+
networks:
85+
- ai-network
86+
restart: unless-stopped
87+
88+
grafana:
89+
image: grafana/grafana:latest
90+
container_name: java-ai-grafana
91+
ports:
92+
- "3000:3000"
93+
environment:
94+
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
95+
- GF_INSTALL_PLUGINS=grafana-piechart-panel
96+
volumes:
97+
- grafana_data:/var/lib/grafana
98+
- ./grafana/provisioning:/etc/grafana/provisioning
99+
networks:
100+
- ai-network
101+
restart: unless-stopped
102+
depends_on:
103+
- prometheus
104+
105+
networks:
106+
ai-network:
107+
driver: bridge
108+
name: java-ai-network
109+
110+
volumes:
111+
postgres_data:
112+
driver: local
113+
name: java-ai-postgres-data
114+
redis_data:
115+
driver: local
116+
name: java-ai-redis-data
117+
prometheus_data:
118+
driver: local
119+
name: java-ai-prometheus-data
120+
grafana_data:
121+
driver: local
122+
name: java-ai-grafana-data

scripts/docker-entrypoint.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "🚀 启动 Java AI Starter 应用"
5+
6+
# 检查必要的环境变量
7+
if [ -z "$OPENAI_API_KEY" ] || [ "$OPENAI_API_KEY" = "sk-demo-key" ]; then
8+
echo "⚠️ 警告: OPENAI_API_KEY 未设置或为默认值"
9+
echo " 请设置有效的 OpenAI API Key"
10+
echo " 临时使用示例模式..."
11+
fi
12+
13+
# 设置JVM参数
14+
if [ -z "$JAVA_OPTS" ]; then
15+
export JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
16+
fi
17+
18+
# 添加Spring Boot Actuator配置
19+
export JAVA_OPTS="$JAVA_OPTS -Dmanagement.endpoints.web.exposure.include=health,info,metrics,prometheus"
20+
export JAVA_OPTS="$JAVA_OPTS -Dmanagement.endpoint.health.show-details=always"
21+
export JAVA_OPTS="$JAVA_OPTS -Dmanagement.metrics.export.prometheus.enabled=true"
22+
23+
# 日志配置
24+
export JAVA_OPTS="$JAVA_OPTS -Dlogging.file.name=/app/logs/application.log"
25+
export JAVA_OPTS="$JAVA_OPTS -Dlogging.file.max-size=10MB"
26+
export JAVA_OPTS="$JAVA_OPTS -Dlogging.file.max-history=10"
27+
28+
echo "📊 环境配置:"
29+
echo " - Spring Profile: ${SPRING_PROFILES_ACTIVE:-default}"
30+
echo " - OpenAI Model: ${OPENAI_MODEL:-gpt-3.5-turbo}"
31+
echo " - Server Port: ${SERVER_PORT:-8080}"
32+
echo " - JVM Options: $JAVA_OPTS"
33+
34+
# 等待数据库就绪(如果配置了数据库)
35+
if [ "$SPRING_PROFILES_ACTIVE" = "docker" ] || [ "$SPRING_PROFILES_ACTIVE" = "production" ]; then
36+
echo "⏳ 检查依赖服务..."
37+
38+
# 这里可以添加等待数据库、Redis等服务的逻辑
39+
# 例如: wait-for-it.sh postgres:5432 --timeout=30
40+
fi
41+
42+
# 启动应用
43+
echo "🎯 启动应用程序..."
44+
exec java $JAVA_OPTS -jar app.jar "$@"

0 commit comments

Comments
 (0)