ci: rewrite CI/CD with semantic-release and GHCR Docker push

- Rewrite release.yml: semantic-release for auto-versioning + Docker
  image build and push to GitHub Container Registry (ghcr.io)
- Rewrite ci.yml: remove continue-on-error on lint
- Add .releaserc.json with changelog and git plugins
- Add semantic-release dependencies to package.json
- Fix Dockerfile: remove --frozen-lockfile from production install
- Update .dockerignore with comprehensive exclusions
- Update docker-compose.yml to pull from GHCR by default
- Remove obsolete pnpm packageManager field
- Remove obsolete kubernetes.yaml from .gitignore
This commit is contained in:
jeffusion
2026-03-03 18:18:10 +08:00
committed by 路遥知码力
parent 7d492ce775
commit c0fe893997
9 changed files with 1093 additions and 59 deletions

View File

@@ -1,10 +1,48 @@
# 忽略所有 node_modules # Git
node_modules/ .git
frontend/node_modules/ .gitignore
.github
# 忽略 .env 文件 # Docker (prevent recursion)
Dockerfile
docker-compose*.yml
# Build outputs (rebuilt in container)
dist
# Node modules (installed in container)
node_modules
frontend/node_modules
# Logs
logs
*.log
# Test files
*.test.ts
*.spec.ts
__tests__
coverage
e2e
# Development files
.env .env
.env.*
# 忽略 kubernetes.yaml
kubernetes.yaml
config-overrides.json config-overrides.json
# IDE and editor files
.vscode
.idea
.cursor
.sisyphus
*.swp
*.swo
.DS_Store
# Documentation (not needed in container)
*.md
docs
# CI/CD config
.releaserc.json
biome.json

View File

@@ -22,7 +22,6 @@ jobs:
- name: Lint - name: Lint
run: bun run lint run: bun run lint
continue-on-error: true # Pre-existing lint violations — non-blocking until cleanup
- name: Type check - name: Type check
run: bun run build run: bun run build

View File

@@ -4,23 +4,23 @@ on:
push: push:
branches: branches:
- main - main
tags:
- 'v*'
permissions: permissions:
contents: read contents: write
issues: write
pull-requests: write
id-token: write
packages: write packages: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs: jobs:
test: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GH_TOKEN }}
- name: Set up Bun - name: Set up Bun
uses: oven-sh/setup-bun@v2 uses: oven-sh/setup-bun@v2
@@ -32,7 +32,6 @@ jobs:
- name: Lint - name: Lint
run: bun run lint run: bun run lint
continue-on-error: true
- name: Type check - name: Type check
run: bun run build run: bun run build
@@ -40,42 +39,36 @@ jobs:
- name: Run tests - name: Run tests
run: bun test run: bun test
docker: - name: Run semantic-release
needs: test run: bunx semantic-release
runs-on: ubuntu-latest env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Docker build and push
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry - name: Log in to GitHub Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) - name: Extract version from package.json
id: meta id: package-version
uses: docker/metadata-action@v5 run: |
with: VERSION=$(node -p "require('./package.json').version")
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} echo "version=$VERSION" >> $GITHUB_OUTPUT
tags: | echo "Detected version: $VERSION"
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image - name: Build and push Docker image
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: |
labels: ${{ steps.meta.outputs.labels }} ghcr.io/${{ github.repository_owner }}/gitea-ai-assistant:latest
ghcr.io/${{ github.repository_owner }}/gitea-ai-assistant:${{ steps.package-version.outputs.version }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max

1
.gitignore vendored
View File

@@ -1,7 +1,6 @@
node_modules/ node_modules/
dist/ dist/
.env .env
kubernetes.yaml
config-overrides.json config-overrides.json
.sisyphus/ .sisyphus/
e2e/.env.e2e e2e/.env.e2e

16
.releaserc.json Normal file
View File

@@ -0,0 +1,16 @@
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/git",
{
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
"@semantic-release/github"
]
}

View File

@@ -1,33 +1,26 @@
# ---- Stage 1: Frontend Builder ---- # ---- Stage 1: Frontend Builder ----
FROM oven/bun:1 as frontend-builder FROM oven/bun:1 AS frontend-builder
WORKDIR /app/frontend WORKDIR /app/frontend
# 拷贝前端的 package.json 和 lockfile
COPY frontend/package.json frontend/bun.lock* ./ COPY frontend/package.json frontend/bun.lock* ./
# 安装前端依赖
RUN bun install --frozen-lockfile RUN bun install --frozen-lockfile
# 拷贝所有前端代码
COPY frontend/ . COPY frontend/ .
# 构建前端静态文件
RUN bun run build RUN bun run build
# ---- Stage 2: Backend Builder ---- # ---- Stage 2: Backend Builder ----
FROM oven/bun:1 as backend-builder FROM oven/bun:1 AS backend-builder
WORKDIR /app WORKDIR /app
# 拷贝后端的 package.json 和 lockfile
COPY package.json bun.lock* ./ COPY package.json bun.lock* ./
# 只安装生产环境依赖 RUN bun install --production
RUN bun install --frozen-lockfile --production
# 拷贝所有后端代码
COPY src ./src COPY src ./src
COPY tsconfig.json . COPY tsconfig.json .
@@ -37,16 +30,13 @@ FROM oven/bun:1-slim
WORKDIR /app WORKDIR /app
# 从后端构建器拷贝依赖和代码
COPY --from=backend-builder /app/node_modules ./node_modules COPY --from=backend-builder /app/node_modules ./node_modules
COPY --from=backend-builder /app/src ./src COPY --from=backend-builder /app/src ./src
COPY --from=backend-builder /app/package.json . COPY --from=backend-builder /app/package.json .
COPY --from=backend-builder /app/tsconfig.json . COPY --from=backend-builder /app/tsconfig.json .
# 从前端构建器拷贝构建好的静态文件到 public 目录
COPY --from=frontend-builder /app/frontend/dist ./public COPY --from=frontend-builder /app/frontend/dist ./public
EXPOSE 3000 EXPOSE 3000
# 启动服务
CMD ["bun", "run", "start"] CMD ["bun", "run", "start"]

990
bun.lock

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,34 @@
version: '3.8'
services: services:
gitea-assistant: gitea-assistant:
image: ghcr.io/${GITHUB_REPOSITORY_OWNER:-jeffusion}/gitea-ai-assistant:${VERSION:-latest}
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
image: registry.kuiper.com/gitea-assistant:latest
container_name: gitea-assistant container_name: gitea-assistant
restart: unless-stopped
ports: ports:
- "3000:3000" - "3000:3000"
volumes: volumes:
- ./config-overrides.json:/app/config-overrides.json - ./config-overrides.json:/app/config-overrides.json
env_file: env_file:
- .env - .env
restart: unless-stopped
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/"] test: ["CMD", "curl", "-f", "http://localhost:3000/"]
interval: 30s interval: 30s
timeout: 5s timeout: 5s
retries: 3 retries: 3
start_period: 5s start_period: 5s
deploy: deploy:
resources: resources:
limits: limits:
memory: 512M memory: 512M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

View File

@@ -18,9 +18,13 @@
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^1.9.4", "@biomejs/biome": "^1.9.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^11.0.6",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.10", "@types/node": "^22.13.10",
"concurrently": "^9.2.1", "concurrently": "^9.2.1",
"semantic-release": "^24.2.9",
"typescript": "^5.8.2" "typescript": "^5.8.2"
}, },
"files": [ "files": [
@@ -47,5 +51,4 @@
], ],
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee"
} }