convertor/.github/workflows/docker-publish.yml

284 lines
10 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: Docker
# thanks to https://github.com/sredevopsorg/multi-arch-docker-github-workflow
# This workflow builds and publishes to GHCR (GitHub Container Registry)
# For Docker Hub releases, see release.yml
on:
push:
branches: ["main"]
tags: ["v*.*.*"]
pull_request:
branches: ["main"]
workflow_dispatch:
env:
# GitHub Container Registry image name
GHCR_IMAGE: ghcr.io/${{ github.repository }}
# Docker Hub image name (for merge job)
DOCKER_IMAGE: convertx/convertx-cn
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# The build job builds the Docker image for each platform specified in the matrix.
build:
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
permissions:
contents: write
packages: write
attestations: write
id-token: write
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-24.04' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }}
name: Build Docker image for ${{ matrix.platform }}
steps:
- name: Prepare environment for current platform
# This step sets up the environment for the current platform being built.
# It replaces the '/' character in the platform name with '-' and sets it as an environment variable.
# This is useful for naming artifacts and other resources that cannot contain '/'.
# The environment variable PLATFORMS_PAIR will be used later in the workflow.
id: prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4
# ========================================
# 清理磁碟空間(解決 no space left on device
# ========================================
# 🔥 GitHub Actions Runner 只有約 14GB 可用空間
# 大型模型 build 需要清理更多預裝軟體
# ========================================
- name: Free disk space (aggressive)
run: |
echo "🧹 Aggressive disk cleanup for large model builds..."
echo "========================================"
echo "📊 初始磁碟空間:"
df -h /
echo "========================================"
# ========================================
# 移除大型預裝軟體(約可釋放 30-40GB
# ========================================
echo "🗑️ 移除預裝開發工具..."
# .NET SDK約 2-3GB
sudo rm -rf /usr/share/dotnet || true
# Android SDK約 10-15GB- 最大宗!
sudo rm -rf /usr/local/lib/android || true
# Haskell/GHC約 1GB
sudo rm -rf /opt/ghc || true
# CodeQL約 1GB
sudo rm -rf /opt/hostedtoolcache/CodeQL || true
# Boost約 500MB
sudo rm -rf /usr/local/share/boost || true
# Swift約 1.5GB
sudo rm -rf /usr/share/swift || true
# Hosted Tool Cache約 5-8GB
sudo rm -rf /opt/hostedtoolcache || true
# Azure CLI約 500MB
sudo rm -rf /usr/share/az_* || true
sudo rm -rf /opt/az || true
# Google Cloud SDK約 500MB
sudo rm -rf /usr/lib/google-cloud-sdk || true
# PowerShell約 200MB
sudo rm -rf /usr/local/share/powershell || true
# Miniconda約 500MB
sudo rm -rf /usr/share/miniconda || true
# ========================================
# 清理系統 cache
# ========================================
echo "🗑️ 清理系統 cache..."
# apt cache
sudo apt-get clean || true
sudo apt-get autoremove -y || true
sudo rm -rf /var/lib/apt/lists/* || true
# npm/yarn global cache
sudo rm -rf /usr/local/share/.cache || true
# ========================================
# 清理 Docker 舊資料
# ========================================
echo "🗑️ 清理 Docker cache..."
docker system prune -af --volumes || true
# ========================================
# 清理 BuildKit cache關鍵解決 overlayfs 爆空間)
# ========================================
echo "🗑️ 清理 BuildKit cache..."
# BuildKit 的 blob 和 layer cache 可能佔用大量空間
sudo rm -rf /var/lib/docker/buildkit || true
echo "========================================"
echo "📊 清理後磁碟空間:"
df -h /
echo "========================================"
- name: downcase REPO
run: |
echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}"
- name: Docker meta default
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ env.REPO }}
# ========================================
# 設定 Docker Buildx針對大型模型優化
# ========================================
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: ${{ matrix.platform }}
# 🔥 使用 docker-container driver 以獲得更好的 cache 控制
driver-opts: |
image=moby/buildkit:latest
network=host
- name: Login to GitHub Container Registry
# here we only login to ghcr.io since the this only pushes internal images
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# ========================================
# Build and Push針對大型模型優化
# ========================================
# 🔥 注意事項:
# - 使用 registry cache 而非 GHA cache避免 10GB 限制)
# - 啟用 compression 減少傳輸量
# - 使用 inline cache 確保 layer 可重用
# ========================================
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
env:
DOCKER_BUILDKIT: 1
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
outputs: type=image,name=ghcr.io/${{ env.REPO }},push-by-digest=true,name-canonical=true,oci-mediatypes=true,compression=zstd,compression-level=3
push: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)) }}
# 🔥 使用 registry cache 取代 GHA cache
# registry cache 沒有 10GB 限制,更適合大型模型
cache-from: type=registry,ref=ghcr.io/${{ env.REPO }}:buildcache-${{ env.PLATFORM_PAIR }}
cache-to: type=registry,ref=ghcr.io/${{ env.REPO }}:buildcache-${{ env.PLATFORM_PAIR }},mode=max,compression=zstd
# 設定 build 參數
# 🔥 CACHE_BUST 使用時間戳強制重新執行模型下載層
build-args: |
BUILDKIT_INLINE_CACHE=1
CACHE_BUST=${{ github.run_id }}${{ github.run_attempt }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)) }}
name: Merge Docker manifests
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: downcase REPO
run: |
echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}"
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ env.REPO }}
${{ env.DOCKER_IMAGE }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Get execution timestamp with RFC3339 format
id: timestamp
run: |
echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
--annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \
$(printf 'ghcr.io/${{ env.REPO }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect 'ghcr.io/${{ env.REPO }}:${{ steps.meta.outputs.version }}'