77 tags :
88 - ' v*.*.*'
99 branches :
10- - ' mydev' # 增加了这一行
11- - ' main' # 增加了这一行
12- - ' dev' # 增加了这一行
10+ - ' mydev'
11+ - ' main'
12+ - ' dev'
1313 workflow_dispatch :
1414
15- # 定义一个 job
1615jobs :
17- build-and-push :
18- # 运行在最新的 ubuntu 系统上
19- runs-on : ubuntu-latest
20- # 授予 job 的权限
16+ # 第一阶段:AMD64 和 ARM64 并行原生构建,各自推送到 GHCR(不 push 完整 manifest)
17+ build :
18+ strategy :
19+ matrix :
20+ include :
21+ - platform : linux/amd64
22+ runner : ubuntu-latest
23+ - platform : linux/arm64
24+ runner : ubuntu-24.04-arm
25+ runs-on : ${{ matrix.runner }}
2126 permissions :
2227 contents : read
2328 packages : write
2429
25- # job 的执行步骤
2630 steps :
27- # 第一步:拉取代码
2831 - name : Check out the repo
29- uses : actions/checkout@v4
32+ uses : actions/checkout@v6
3033
31- # 第二步:提取版本号,并判断是否为正式发布
32- - name : Extract version and release status
34+ - name : Extract version
3335 id : extract_version
3436 run : |
3537 if [[ $GITHUB_REF == refs/tags/* ]]; then
@@ -40,71 +42,124 @@ jobs:
4042 echo "IS_RELEASE=false" >> $GITHUB_ENV
4143 fi
4244 echo "VERSION=$VERSION" >> $GITHUB_ENV
43- echo "Version is: $VERSION"
4445
45- # 第三步:动态生成 Docker 镜像的标签 (已更新为总是包含 latest)
46- - name : Generate Docker tags
46+ - name : Generate image name
4747 id : meta
4848 run : |
49- # 强制将所有相关名称转为小写,以符合 Docker 命名规范
49+ GHCR_REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
50+ echo "image=ghcr.io/$GHCR_REPO_LOWER" >> $GITHUB_OUTPUT
51+ # 平台标识符用于 digest artifact 名(斜线替换为横线)
52+ PLATFORM_SLUG=$(echo "${{ matrix.platform }}" | tr '/' '-')
53+ echo "platform_slug=$PLATFORM_SLUG" >> $GITHUB_OUTPUT
54+
55+ - name : Log in to Docker Hub
56+ uses : docker/login-action@v4
57+ with :
58+ username : ${{ secrets.DOCKERHUB_USERNAME }}
59+ password : ${{ secrets.DOCKERHUB_TOKEN }}
60+
61+ - name : Log in to GitHub Container Registry
62+ uses : docker/login-action@v4
63+ with :
64+ registry : ghcr.io
65+ username : ${{ github.actor }}
66+ password : ${{ secrets.GITHUB_TOKEN }}
67+
68+ - name : Set up Docker Buildx
69+ uses : docker/setup-buildx-action@v4
70+ with :
71+ driver-opts : |
72+ image=moby/buildkit:latest
73+ network=host
74+
75+ - name : Build and push by digest
76+ id : build
77+ uses : docker/build-push-action@v7
78+ with :
79+ context : .
80+ platforms : ${{ matrix.platform }}
81+ push : true
82+ outputs : type=image,name=${{ steps.meta.outputs.image }},push-by-digest=true,name-canonical=true
83+ cache-from : type=registry,ref=${{ steps.meta.outputs.image }}:buildcache-${{ steps.meta.outputs.platform_slug }}
84+ cache-to : type=registry,ref=${{ steps.meta.outputs.image }}:buildcache-${{ steps.meta.outputs.platform_slug }},mode=max
85+
86+ # digest 传给下一个 job
87+ - name : Export digest
88+ run : |
89+ mkdir -p /tmp/digests
90+ digest="${{ steps.build.outputs.digest }}"
91+ touch "/tmp/digests/${digest#sha256:}"
92+
93+ - name : Upload digest artifact
94+ uses : actions/upload-artifact@v4
95+ with :
96+ name : digest-${{ steps.meta.outputs.platform_slug }}
97+ path : /tmp/digests/*
98+ if-no-files-found : error
99+ retention-days : 1
100+
101+ # 第二阶段:merge 两个平台的 digest,推送最终 manifest
102+ merge :
103+ needs : build
104+ runs-on : ubuntu-latest
105+ permissions :
106+ contents : read
107+ packages : write
108+
109+ steps :
110+ - name : Download digests
111+ uses : actions/download-artifact@v4
112+ with :
113+ path : /tmp/digests
114+ pattern : digest-*
115+ merge-multiple : true
116+
117+ - name : Generate tags
118+ id : meta
119+ run : |
120+ GHCR_REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
50121 DOCKERHUB_USER_LOWER=$(echo "${{ secrets.DOCKERHUB_USERNAME }}" | tr '[:upper:]' '[:lower:]')
51122 REPO_NAME_LOWER=$(echo "${{ github.event.repository.name }}" | tr '[:upper:]' '[:lower:]')
52- DOCKER_IMAGE_DOCKERHUB="$DOCKERHUB_USER_LOWER/$REPO_NAME_LOWER"
53- GHCR_REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
54- DOCKER_IMAGE_GHCR="ghcr.io/$GHCR_REPO_LOWER"
123+ GHCR_IMAGE="ghcr.io/$GHCR_REPO_LOWER"
55124
56- # 新增的智能判断逻辑 (只推送到GHCR)
57125 if [[ $GITHUB_REF == refs/tags/* ]]; then
58- # 如果是发布 (打tag),就使用 latest 和版本号标签
59- echo "是正式发布,使用 latest 和版本号标签: ${{ env.VERSION }}"
60- TAGS="$DOCKER_IMAGE_GHCR:latest,$DOCKER_IMAGE_GHCR:${{ env.VERSION }}"
126+ VERSION=${GITHUB_REF#refs/tags/v}
127+ TAGS="$GHCR_IMAGE:latest $GHCR_IMAGE:$VERSION"
61128 else
62- # 如果是推送到分支 (比如 mydev),就使用分支名作为标签
63129 BRANCH_NAME=${GITHUB_REF#refs/heads/}
64- echo "是开发分支推送,使用分支名 '${BRANCH_NAME}' 作为标签"
65- TAGS="$DOCKER_IMAGE_GHCR:${BRANCH_NAME}"
130+ TAGS="$GHCR_IMAGE:${BRANCH_NAME}"
66131 fi
67132
68- echo "tags=${TAGS}" >> $GITHUB_OUTPUT
69- echo "Generated tags: ${TAGS}"
70-
71- # 输出 cache ref (用于 buildx)
72- echo "cache-ref=$DOCKER_IMAGE_GHCR:buildcache" >> $GITHUB_OUTPUT
133+ echo "tags=$TAGS" >> $GITHUB_OUTPUT
134+ echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
73135
74- # 第四步:设置 QEMU,用于多平台构建
75- - name : Set up QEMU
76- uses : docker/setup-qemu-action@v3
77-
78- # 第五步:登录到 Docker Hub (在 buildx 之前登录,避免 rate limit)
79136 - name : Log in to Docker Hub
80- uses : docker/login-action@v3
137+ uses : docker/login-action@v4
81138 with :
82139 username : ${{ secrets.DOCKERHUB_USERNAME }}
83140 password : ${{ secrets.DOCKERHUB_TOKEN }}
84141
85- # 第六步:设置 Docker Buildx,新一代的构建工具
86- - name : Set up Docker Buildx
87- uses : docker/setup-buildx-action@v3
88- with :
89- driver-opts : |
90- image=moby/buildkit:latest
91- network=host
92-
93- # 第七步:登录到 GitHub Container Registry (GHCR)
94142 - name : Log in to GitHub Container Registry
95- uses : docker/login-action@v3
143+ uses : docker/login-action@v4
96144 with :
97145 registry : ghcr.io
98146 username : ${{ github.actor }}
99147 password : ${{ secrets.GITHUB_TOKEN }}
100148
101- # 第八步:构建并推送 Docker 镜像
102- - name : Build and push Docker image
103- uses : docker/build-push-action@v5
104- with :
105- context : .
106- push : true
107- tags : ${{ steps.meta.outputs.tags }}
108- platforms : linux/amd64,linux/arm64
109- cache-from : type=registry,ref=${{ steps.meta.outputs.cache-ref }}
110- cache-to : type=registry,ref=${{ steps.meta.outputs.cache-ref }},mode=max
149+ - name : Set up Docker Buildx
150+ uses : docker/setup-buildx-action@v4
151+
152+ - name : Create and push manifest
153+ working-directory : /tmp/digests
154+ run : |
155+ IMAGE="${{ steps.meta.outputs.image }}"
156+ # 构建 --amend 参数列表
157+ AMENDS=""
158+ for digest in *; do
159+ AMENDS="$AMENDS --amend $IMAGE@sha256:$digest"
160+ done
161+ # 为每个 tag 创建并推送 manifest
162+ for tag in ${{ steps.meta.outputs.tags }}; do
163+ docker buildx imagetools create $AMENDS --tag "$tag"
164+ echo "Pushed manifest: $tag"
165+ done
0 commit comments