mirror of
https://github.com/sligter/LandPPT.git
synced 2026-08-28 23:31:06 +08:00
222 lines
7.3 KiB
YAML
222 lines
7.3 KiB
YAML
# LandPPT Docker Build & Push Workflow
|
||
# 自动构建并推送 Docker 镜像到容器注册表
|
||
|
||
name: Docker Build and Push
|
||
|
||
on:
|
||
# 在 main 分支推送时触发
|
||
push:
|
||
branches:
|
||
- main
|
||
- master
|
||
# 仅当以下文件变更时触发
|
||
paths:
|
||
- 'Dockerfile'
|
||
- 'docker-compose.yml'
|
||
- 'docker-entrypoint.sh'
|
||
- 'docker-healthcheck.sh'
|
||
- 'run.py'
|
||
- 'src/**'
|
||
- 'template_examples/**'
|
||
- '.env.example'
|
||
- 'pyproject.toml'
|
||
- 'uv.lock'
|
||
- '.github/workflows/docker-build.yml'
|
||
|
||
# 在 PR 时进行构建测试(不推送)
|
||
pull_request:
|
||
branches:
|
||
- main
|
||
- master
|
||
|
||
# 手动触发
|
||
workflow_dispatch:
|
||
inputs:
|
||
push_image:
|
||
description: '是否推送镜像到注册表'
|
||
required: false
|
||
default: 'true'
|
||
type: boolean
|
||
|
||
env:
|
||
# Docker 镜像名称 - 请根据实际情况修改
|
||
IMAGE_NAME: landppt
|
||
# 构建平台
|
||
PLATFORMS: linux/amd64
|
||
|
||
jobs:
|
||
build:
|
||
name: Build Docker Image
|
||
runs-on: ubuntu-latest
|
||
|
||
permissions:
|
||
contents: write
|
||
packages: write
|
||
|
||
steps:
|
||
# 检出代码
|
||
- name: Checkout Repository
|
||
uses: actions/checkout@v4
|
||
|
||
# 清理磁盘空间(防止构建时空间不足)
|
||
- name: Free Disk Space
|
||
run: |
|
||
sudo rm -rf /usr/share/dotnet
|
||
sudo rm -rf /usr/local/lib/android
|
||
sudo rm -rf /opt/ghc
|
||
sudo rm -rf /opt/hostedtoolcache/CodeQL
|
||
sudo docker system prune -af
|
||
df -h
|
||
|
||
# 设置 Docker Buildx(用于高级构建功能)
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
# 登录到 GitHub Container Registry (ghcr.io)
|
||
- name: Login to GitHub Container Registry
|
||
if: github.event_name != 'pull_request'
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
# 登录到 Docker Hub(可选 - 如果需要推送到 Docker Hub)
|
||
# 需要在 Repository Settings > Secrets 中设置 DOCKERHUB_USERNAME 和 DOCKERHUB_TOKEN
|
||
- name: Login to Docker Hub
|
||
if: github.event_name != 'pull_request'
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||
continue-on-error: true
|
||
|
||
# 提取 Docker 元数据(标签、标签等)
|
||
- name: Extract Docker Metadata
|
||
id: meta
|
||
uses: docker/metadata-action@v5
|
||
with:
|
||
images: |
|
||
ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
|
||
tags: |
|
||
# 最新标签(仅在 main/master 分支)
|
||
type=raw,value=latest,enable={{is_default_branch}}
|
||
# Git SHA,供 Argo CD values-argocd.yaml 精确引用
|
||
type=raw,value=git-${{ github.sha }}
|
||
# Git 短 SHA
|
||
type=sha,prefix=
|
||
# 分支名称
|
||
type=ref,event=branch
|
||
# PR 编号
|
||
type=ref,event=pr
|
||
# 语义化版本(如果有标签)
|
||
type=semver,pattern={{version}}
|
||
type=semver,pattern={{major}}.{{minor}}
|
||
# 日期标签
|
||
type=raw,value={{date 'YYYYMMDD-HHmmss'}}
|
||
|
||
# 构建并推送 Docker 镜像
|
||
- name: Build and Push Docker Image
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: .
|
||
file: ./Dockerfile
|
||
platforms: ${{ env.PLATFORMS }}
|
||
# PR 时不推送,仅构建验证
|
||
push: ${{ github.event_name != 'pull_request' && (github.event.inputs.push_image != 'false') }}
|
||
tags: ${{ steps.meta.outputs.tags }}
|
||
labels: ${{ steps.meta.outputs.labels }}
|
||
# 利用 GitHub Actions 缓存加速构建
|
||
cache-from: type=gha
|
||
cache-to: type=gha,mode=max
|
||
# 构建参数(如需要可添加)
|
||
build-args: |
|
||
BUILDTIME=${{ github.event.repository.updated_at }}
|
||
VERSION=${{ github.sha }}
|
||
|
||
# 源码变更后,把新镜像 tag 写回 Argo CD values 文件。
|
||
# Argo CD 监听 helm/landppt/values-argocd.yaml,检测到该提交后会自动同步部署。
|
||
- name: Update Argo CD image tag
|
||
if: github.event_name != 'pull_request' && (github.event.inputs.push_image != 'false')
|
||
env:
|
||
IMAGE_REPOSITORY: ghcr.io/${{ github.repository_owner }}/landppt
|
||
IMAGE_TAG: git-${{ github.sha }}
|
||
VALUES_FILE: helm/landppt/values-argocd.yaml
|
||
run: |
|
||
python - <<'PY'
|
||
import os
|
||
from pathlib import Path
|
||
|
||
path = Path(os.environ["VALUES_FILE"])
|
||
repository = os.environ["IMAGE_REPOSITORY"]
|
||
tag = os.environ["IMAGE_TAG"]
|
||
|
||
lines = path.read_text().splitlines()
|
||
in_image = False
|
||
for index, line in enumerate(lines):
|
||
if line == "image:":
|
||
in_image = True
|
||
continue
|
||
if in_image and line and not line.startswith(" "):
|
||
in_image = False
|
||
if in_image and line.startswith(" repository:"):
|
||
lines[index] = f" repository: {repository}"
|
||
elif in_image and line.startswith(" tag:"):
|
||
lines[index] = f" tag: {tag}"
|
||
elif in_image and line.startswith(" pullPolicy:"):
|
||
lines[index] = " pullPolicy: IfNotPresent"
|
||
|
||
path.write_text("\n".join(lines) + "\n")
|
||
PY
|
||
|
||
git config user.name "github-actions[bot]"
|
||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||
git add "$VALUES_FILE"
|
||
if git diff --cached --quiet; then
|
||
echo "No image tag change to commit."
|
||
else
|
||
git commit -m "chore(deploy): update image to ${IMAGE_TAG} [skip ci]"
|
||
git push origin HEAD:${GITHUB_REF_NAME}
|
||
fi
|
||
|
||
# 输出镜像摘要
|
||
- name: Image Digest
|
||
run: |
|
||
echo "### Docker Image Built Successfully! :rocket:" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "**Image Tags:**" >> $GITHUB_STEP_SUMMARY
|
||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "**Argo CD image tag:** \`git-${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||
|
||
# 安全扫描(可选但推荐)
|
||
security-scan:
|
||
name: Security Scan
|
||
runs-on: ubuntu-latest
|
||
needs: build
|
||
if: github.event_name != 'pull_request'
|
||
|
||
steps:
|
||
- name: Checkout Repository
|
||
uses: actions/checkout@v4
|
||
|
||
# 使用 Trivy 扫描 Dockerfile 漏洞
|
||
- name: Run Trivy vulnerability scanner
|
||
uses: aquasecurity/trivy-action@master
|
||
with:
|
||
scan-type: 'config'
|
||
scan-ref: '.'
|
||
format: 'sarif'
|
||
output: 'trivy-results.sarif'
|
||
continue-on-error: true
|
||
|
||
# 上传扫描结果到 GitHub Security
|
||
- name: Upload Trivy scan results
|
||
uses: github/codeql-action/upload-sarif@v3
|
||
with:
|
||
sarif_file: 'trivy-results.sarif'
|
||
continue-on-error: true
|