Skip to content

Build Preview Docker Image #53

Build Preview Docker Image

Build Preview Docker Image #53

Workflow file for this run

name: Build and Push Docker Image
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
workflow_dispatch:
inputs:
version:
description: '版本号 (例如: 1.0.0)'
required: true
type: string
changelog:
description: '更新日志'
required: false
type: string
default: ''
is_release:
description: '是否为正式版本'
required: true
type: boolean
default: false
env:
DOCKER_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/skyimage
jobs:
build-and-push:
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_IMAGE }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=build-${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=build-${{ matrix.platform }}
outputs: type=image,name=${{ env.DOCKER_IMAGE }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests-${{ strategy.job-index }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name != 'pull_request'
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Determine tags
id: tags
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.is_release }}" = "true" ]; then
# 正式版本:使用输入的版本号
VERSION="${{ inputs.version }}"
TAGS="${{ env.DOCKER_IMAGE }}:${VERSION}"
TAGS="${TAGS},${{ env.DOCKER_IMAGE }}:latest"
# 提取主版本号和次版本号
MAJOR=$(echo $VERSION | cut -d. -f1)
MINOR=$(echo $VERSION | cut -d. -f1-2)
TAGS="${TAGS},${{ env.DOCKER_IMAGE }}:${MAJOR}"
TAGS="${TAGS},${{ env.DOCKER_IMAGE }}:${MINOR}"
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# 手动触发但非正式版
VERSION="${{ inputs.version }}"
TAGS="${{ env.DOCKER_IMAGE }}:${VERSION}-preview"
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "version=${VERSION}-preview" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
else
# 自动提交构建:预览版
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
TAGS="${{ env.DOCKER_IMAGE }}:preview"
TAGS="${TAGS},${{ env.DOCKER_IMAGE }}:preview-${SHORT_SHA}"
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "version=preview-${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
fi
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
TAGS_ARRAY=($(echo "${{ steps.tags.outputs.tags }}" | tr ',' ' '))
TAG_ARGS=""
for tag in "${TAGS_ARRAY[@]}"; do
TAG_ARGS="$TAG_ARGS -t $tag"
done
docker buildx imagetools create $TAG_ARGS \
$(printf '${{ env.DOCKER_IMAGE }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.tags.outputs.version }}
- name: Prepare release notes
if: github.event_name == 'workflow_dispatch' && inputs.is_release == true
env:
CHANGELOG: ${{ inputs.changelog }}
run: |
echo "## 更新日志" > release_notes.md
echo "" >> release_notes.md
echo "$CHANGELOG" | sed 's/### /\n### /g; s/#### /\n#### /g; s/- /\n- /g' | sed '/^$/d' >> release_notes.md
echo "" >> release_notes.md
echo "---" >> release_notes.md
echo "" >> release_notes.md
echo "## Docker 镜像" >> release_notes.md
echo "- \`${{ env.DOCKER_IMAGE }}:${{ inputs.version }}\`" >> release_notes.md
echo "- \`${{ env.DOCKER_IMAGE }}:latest\`" >> release_notes.md
- name: Create GitHub Release
if: github.event_name == 'workflow_dispatch' && inputs.is_release == true
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ inputs.version }}
name: Release v${{ inputs.version }}
body_path: release_notes.md
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update Docker Hub description
if: steps.tags.outputs.is_release == 'true'
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ env.DOCKER_IMAGE }}
short-description: ${{ github.event.repository.description }}
readme-filepath: ./README.md
- name: Build summary
run: |
echo "## 构建完成 ✅" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**版本:** ${{ steps.tags.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**标签:** ${{ steps.tags.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo "**类型:** ${{ steps.tags.outputs.is_release == 'true' && '正式版' || '预览版' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.tags.outputs.is_release }}" = "true" ]; then
echo "🎉 正式版本已发布!" >> $GITHUB_STEP_SUMMARY
else
echo "🔍 预览版本已构建,仅供测试使用" >> $GITHUB_STEP_SUMMARY
fi