-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
169 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,179 @@ | ||
name: Docker Build and Push | ||
|
||
# 环境变量集中管理 | ||
env: | ||
DOCKER_REGISTRY: docker.io | ||
ALIYUN_REGISTRY: registry.cn-hangzhou.aliyuncs.com | ||
GITHUB_REGISTRY: ghcr.io | ||
IMAGE_NAME: telepace/voiceflow | ||
PLATFORMS: linux/amd64,linux/arm64 | ||
# 配置构建缓存的位置 | ||
CACHE_PATH: /tmp/.buildx-cache | ||
# 配置 Trivy 扫描设置 | ||
TRIVY_NO_PROGRESS: true | ||
TRIVY_EXIT_CODE: '0' | ||
|
||
on: | ||
# 优化定时任务执行时间,避开高峰期 | ||
schedule: | ||
- cron: '30 2 * * *' | ||
- cron: '30 2 * * *' # UTC 时间每天 2:30 运行 | ||
push: | ||
branches: | ||
- main | ||
- release-* | ||
- 'release/**' # 使用更严格的分支匹配模式 | ||
tags: | ||
- 'v*.*.*' # 例如 v1.0.0, v2.1.3 | ||
- 'v*.*.*-*' # 例如 v1.0.0-beta.1 | ||
workflow_dispatch: | ||
- 'v[0-9]+.[0-9]+.[0-9]+' # 严格的版本号匹配 | ||
- 'v[0-9]+.[0-9]+.[0-9]+-*' # 预发布版本 | ||
paths-ignore: # 忽略不需要触发构建的文件改动 | ||
- '**.md' | ||
- 'docs/**' | ||
- '.gitignore' | ||
workflow_dispatch: # 支持手动触发 | ||
inputs: | ||
debug_enabled: | ||
description: '启用调试模式' | ||
required: false | ||
default: false | ||
type: boolean | ||
|
||
jobs: | ||
steps: | ||
# 1. 检出代码 | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 # 确保获取所有标签 | ||
|
||
# 2. 设置 Docker Buildx | ||
- name: Set up Docker Buildx | ||
uses: docker/[email protected] | ||
|
||
- name: Cache Docker layers | ||
uses: actions/cache@v4 | ||
with: | ||
path: /tmp/.buildx-cache | ||
key: ${{ runner.os }}-buildx-${{ github.sha }} | ||
restore-keys: | | ||
${{ runner.os }}-buildx- | ||
# 3. 登录 Docker Hub | ||
- name: Log in to Docker Hub | ||
uses: docker/login-action@v3 | ||
with: | ||
username: ${{ secrets.DOCKER_USERNAME }} | ||
password: ${{ secrets.DOCKER_PASSWORD }} | ||
|
||
# 4. 登录阿里云容器注册表 | ||
- name: Log in to AliYun Docker Hub | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: registry.cn-hangzhou.aliyuncs.com | ||
username: ${{ secrets.ALIREGISTRY_USERNAME }} | ||
password: ${{ secrets.ALIREGISTRY_TOKEN }} | ||
|
||
# 5. 登录 GitHub Container Registry | ||
- name: Log in to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.repository_owner }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# 6. 获取 Docker Metadata | ||
- name: Get Docker metadata | ||
id: metadata | ||
uses: docker/[email protected] | ||
with: | ||
images: | | ||
docker.io/telepace/voiceflow | ||
registry.cn-hangzhou.aliyuncs.com/telepace/voiceflow | ||
ghcr.io/telepace/voiceflow | ||
tags: | | ||
type=ref,event=tag | ||
type=schedule | ||
type=ref,event=branch | ||
type=ref,event=pr | ||
type=semver,pattern={{version}} | ||
type=semver,pattern=v{{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=semver,pattern={{major}} | ||
type=sha | ||
# 7. 构建并推送 Docker 镜像 | ||
- name: Build and push Docker image for voiceflow | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
file: ./build/images/voiceflow/Dockerfile | ||
platforms: linux/amd64,linux/arm64 | ||
push: ${{ github.event_name != 'pull_request' }} | ||
tags: ${{ steps.meta1.outputs.tags }} | ||
labels: ${{ steps.meta1.outputs.labels }} | ||
cache-from: type=local,src=/tmp/.buildx-cache | ||
cache-to: type=local,dest=/tmp/.buildx-cache | ||
|
||
# 8. 可选:安全扫描(例如 Trivy) | ||
- name: Scan Docker image for vulnerabilities | ||
uses: aquasecurity/[email protected] | ||
with: | ||
image-ref: telepace/voiceflow:${{ steps.metadata.outputs.version }} | ||
format: 'table' | ||
exit-code: '0' | ||
|
||
# 9. 清理未使用的 Docker 镜像 | ||
- name: Clean up Docker | ||
run: docker system prune -f | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
# 添加并发控制,避免重复构建 | ||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
# 超时设置 | ||
timeout-minutes: 60 | ||
|
||
steps: | ||
# 1. 检出代码 | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 # 完整克隆以获取所有标签 | ||
|
||
# 2. 设置 QEMU 以支持多架构构建 | ||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v3 | ||
|
||
# 3. 设置 Docker Buildx | ||
- name: Set up Docker Buildx | ||
uses: docker/[email protected] | ||
with: | ||
platforms: ${{ env.PLATFORMS }} | ||
|
||
# 4. 缓存管理优化 | ||
- name: Cache Docker layers | ||
uses: actions/cache@v4 | ||
with: | ||
path: ${{ env.CACHE_PATH }} | ||
key: ${{ runner.os }}-buildx-${{ github.sha }} | ||
restore-keys: | | ||
${{ runner.os }}-buildx- | ||
# 5. 登录到各个容器仓库 | ||
- name: Login to Container Registries | ||
if: github.event_name != 'pull_request' | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ${{ matrix.registry.url }} | ||
username: ${{ matrix.registry.username }} | ||
password: ${{ matrix.registry.password }} | ||
strategy: | ||
matrix: | ||
registry: | ||
- url: ${{ env.DOCKER_REGISTRY }} | ||
username: ${{ secrets.DOCKER_USERNAME }} | ||
password: ${{ secrets.DOCKER_PASSWORD }} | ||
- url: ${{ env.ALIYUN_REGISTRY }} | ||
username: ${{ secrets.ALIREGISTRY_USERNAME }} | ||
password: ${{ secrets.ALIREGISTRY_TOKEN }} | ||
- url: ${{ env.GITHUB_REGISTRY }} | ||
username: ${{ github.repository_owner }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# 6. 获取版本信息 | ||
- name: Get Version Info | ||
id: version | ||
run: | | ||
echo "VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT | ||
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT | ||
echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | ||
# 7. 配置 Docker Metadata | ||
- name: Docker Metadata | ||
id: metadata | ||
uses: docker/[email protected] | ||
with: | ||
images: | | ||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }} | ||
${{ env.ALIYUN_REGISTRY }}/${{ env.IMAGE_NAME }} | ||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }} | ||
tags: | | ||
type=schedule,pattern={{date 'YYYYMMDD'}} | ||
type=ref,event=branch | ||
type=ref,event=tag | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=sha,prefix=sha-,format=short | ||
labels: | | ||
org.opencontainers.image.title=${{ env.IMAGE_NAME }} | ||
org.opencontainers.image.description=Voiceflow Docker Image | ||
org.opencontainers.image.created=${{ steps.version.outputs.BUILD_DATE }} | ||
org.opencontainers.image.revision=${{ steps.version.outputs.GIT_SHA }} | ||
org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} | ||
# 8. 构建和推送 | ||
- name: Build and Push | ||
uses: docker/build-push-action@v5 | ||
with: | ||
context: . | ||
file: ./build/images/voiceflow/Dockerfile | ||
platforms: ${{ env.PLATFORMS }} | ||
push: ${{ github.event_name != 'pull_request' }} | ||
tags: ${{ steps.metadata.outputs.tags }} | ||
labels: ${{ steps.metadata.outputs.labels }} | ||
cache-from: type=local,src=${{ env.CACHE_PATH }} | ||
cache-to: type=local,dest=${{ env.CACHE_PATH }}-new,mode=max | ||
build-args: | | ||
VERSION=${{ steps.version.outputs.VERSION }} | ||
BUILD_DATE=${{ steps.version.outputs.BUILD_DATE }} | ||
GIT_SHA=${{ steps.version.outputs.GIT_SHA }} | ||
# 9. 安全扫描 | ||
- name: Security Scan | ||
uses: aquasecurity/trivy-action@master | ||
if: github.event_name != 'pull_request' | ||
with: | ||
image-ref: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} | ||
format: 'table' | ||
exit-code: ${{ env.TRIVY_EXIT_CODE }} | ||
ignore-unfixed: true | ||
vuln-type: 'os,library' | ||
severity: 'CRITICAL,HIGH' | ||
|
||
# 10. 更新缓存 | ||
- name: Move cache | ||
run: | | ||
rm -rf ${{ env.CACHE_PATH }} | ||
mv ${{ env.CACHE_PATH }}-new ${{ env.CACHE_PATH }} | ||
# 11. 清理 | ||
- name: Cleanup | ||
if: always() | ||
run: | | ||
docker system prune -af | ||
docker builder prune -af | ||
# 12. 通知 | ||
- name: Notification | ||
if: always() | ||
uses: rtCamp/action-slack-notify@v2 | ||
env: | ||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | ||
SLACK_COLOR: ${{ job.status == 'success' && 'good' || 'danger' }} | ||
SLACK_MESSAGE: 'Docker build ${{ job.status }} for ${{ steps.version.outputs.VERSION }}' | ||
SLACK_TITLE: Docker Build Status |