mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-01-31 11:46:16 +08:00
271 lines
8.9 KiB
YAML
271 lines
8.9 KiB
YAML
name: Build and Push Docker Images
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*' # 只在推送 v 开头的 tag 时触发(如 v1.0.0)
|
||
workflow_dispatch: # 手动触发
|
||
|
||
# 并发控制:同一分支只保留最新的构建,取消之前正在运行的
|
||
concurrency:
|
||
group: ${{ github.workflow }}-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
env:
|
||
REGISTRY: docker.io
|
||
IMAGE_PREFIX: yyhuni
|
||
|
||
permissions:
|
||
contents: write
|
||
|
||
jobs:
|
||
# AMD64 构建(原生 x64 runner)
|
||
build-amd64:
|
||
runs-on: ubuntu-latest
|
||
strategy:
|
||
matrix:
|
||
include:
|
||
- image: xingrin-server
|
||
dockerfile: docker/server/Dockerfile
|
||
context: .
|
||
- image: xingrin-frontend
|
||
dockerfile: docker/frontend/Dockerfile
|
||
context: .
|
||
- image: xingrin-worker
|
||
dockerfile: docker/worker/Dockerfile
|
||
context: .
|
||
- image: xingrin-nginx
|
||
dockerfile: docker/nginx/Dockerfile
|
||
context: .
|
||
- image: xingrin-agent
|
||
dockerfile: docker/agent/Dockerfile
|
||
context: .
|
||
- image: xingrin-postgres
|
||
dockerfile: docker/postgres/Dockerfile
|
||
context: docker/postgres
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Free disk space
|
||
run: |
|
||
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
|
||
sudo docker image prune -af
|
||
|
||
- name: Generate SSL certificates for nginx build
|
||
if: matrix.image == 'xingrin-nginx'
|
||
run: |
|
||
mkdir -p docker/nginx/ssl
|
||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||
-keyout docker/nginx/ssl/privkey.pem \
|
||
-out docker/nginx/ssl/fullchain.pem \
|
||
-subj "/CN=localhost"
|
||
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||
|
||
- name: Get version
|
||
id: version
|
||
run: |
|
||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Build and push AMD64
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: ${{ matrix.context }}
|
||
file: ${{ matrix.dockerfile }}
|
||
platforms: linux/amd64
|
||
push: true
|
||
tags: ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }}-amd64
|
||
build-args: IMAGE_TAG=${{ steps.version.outputs.VERSION }}
|
||
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-amd64
|
||
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-amd64,mode=max
|
||
provenance: false
|
||
sbom: false
|
||
|
||
# ARM64 构建(原生 ARM64 runner)
|
||
build-arm64:
|
||
runs-on: ubuntu-22.04-arm
|
||
strategy:
|
||
matrix:
|
||
include:
|
||
- image: xingrin-server
|
||
dockerfile: docker/server/Dockerfile
|
||
context: .
|
||
- image: xingrin-frontend
|
||
dockerfile: docker/frontend/Dockerfile
|
||
context: .
|
||
- image: xingrin-worker
|
||
dockerfile: docker/worker/Dockerfile
|
||
context: .
|
||
- image: xingrin-nginx
|
||
dockerfile: docker/nginx/Dockerfile
|
||
context: .
|
||
- image: xingrin-agent
|
||
dockerfile: docker/agent/Dockerfile
|
||
context: .
|
||
- image: xingrin-postgres
|
||
dockerfile: docker/postgres/Dockerfile
|
||
context: docker/postgres
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Generate SSL certificates for nginx build
|
||
if: matrix.image == 'xingrin-nginx'
|
||
run: |
|
||
mkdir -p docker/nginx/ssl
|
||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||
-keyout docker/nginx/ssl/privkey.pem \
|
||
-out docker/nginx/ssl/fullchain.pem \
|
||
-subj "/CN=localhost"
|
||
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||
|
||
- name: Get version
|
||
id: version
|
||
run: |
|
||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Build and push ARM64
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: ${{ matrix.context }}
|
||
file: ${{ matrix.dockerfile }}
|
||
platforms: linux/arm64
|
||
push: true
|
||
tags: ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }}-arm64
|
||
build-args: IMAGE_TAG=${{ steps.version.outputs.VERSION }}
|
||
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-arm64
|
||
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-arm64,mode=max
|
||
provenance: false
|
||
sbom: false
|
||
|
||
# 合并多架构 manifest
|
||
merge-manifests:
|
||
runs-on: ubuntu-latest
|
||
needs: [build-amd64, build-arm64]
|
||
strategy:
|
||
matrix:
|
||
image:
|
||
- xingrin-server
|
||
- xingrin-frontend
|
||
- xingrin-worker
|
||
- xingrin-nginx
|
||
- xingrin-agent
|
||
- xingrin-postgres
|
||
steps:
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||
|
||
- name: Get version
|
||
id: version
|
||
run: |
|
||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||
echo "IS_RELEASE=true" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||
echo "IS_RELEASE=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Create and push multi-arch manifest
|
||
run: |
|
||
VERSION=${{ steps.version.outputs.VERSION }}
|
||
IMAGE=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}
|
||
|
||
docker manifest create ${IMAGE}:${VERSION} \
|
||
${IMAGE}:${VERSION}-amd64 \
|
||
${IMAGE}:${VERSION}-arm64
|
||
docker manifest push ${IMAGE}:${VERSION}
|
||
|
||
if [[ "${{ steps.version.outputs.IS_RELEASE }}" == "true" ]]; then
|
||
docker manifest create ${IMAGE}:latest \
|
||
${IMAGE}:${VERSION}-amd64 \
|
||
${IMAGE}:${VERSION}-arm64
|
||
docker manifest push ${IMAGE}:latest
|
||
fi
|
||
|
||
# 更新 VERSION 文件
|
||
update-version:
|
||
runs-on: ubuntu-latest
|
||
needs: merge-manifests
|
||
if: startsWith(github.ref, 'refs/tags/v')
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # 获取完整历史,用于判断 tag 所在分支
|
||
token: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
- name: Determine source branch and version
|
||
id: branch
|
||
run: |
|
||
VERSION="${GITHUB_REF#refs/tags/}"
|
||
|
||
# 查找包含此 tag 的分支
|
||
BRANCHES=$(git branch -r --contains ${{ github.ref_name }})
|
||
echo "Branches containing tag: $BRANCHES"
|
||
|
||
# 判断 tag 来自哪个分支
|
||
if echo "$BRANCHES" | grep -q "origin/main"; then
|
||
TARGET_BRANCH="main"
|
||
UPDATE_LATEST="true"
|
||
elif echo "$BRANCHES" | grep -q "origin/dev"; then
|
||
TARGET_BRANCH="dev"
|
||
UPDATE_LATEST="false"
|
||
else
|
||
echo "Warning: Tag not found in main or dev branch, defaulting to main"
|
||
TARGET_BRANCH="main"
|
||
UPDATE_LATEST="false"
|
||
fi
|
||
|
||
echo "BRANCH=$TARGET_BRANCH" >> $GITHUB_OUTPUT
|
||
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
||
echo "UPDATE_LATEST=$UPDATE_LATEST" >> $GITHUB_OUTPUT
|
||
echo "Will update VERSION on branch: $TARGET_BRANCH"
|
||
|
||
- name: Checkout target branch
|
||
run: |
|
||
git checkout ${{ steps.branch.outputs.BRANCH }}
|
||
|
||
- name: Update VERSION file
|
||
run: |
|
||
VERSION="${{ steps.branch.outputs.VERSION }}"
|
||
echo "$VERSION" > VERSION
|
||
echo "Updated VERSION to $VERSION on branch ${{ steps.branch.outputs.BRANCH }}"
|
||
|
||
- name: Commit and push
|
||
run: |
|
||
git config user.name "github-actions[bot]"
|
||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||
git add VERSION
|
||
git diff --staged --quiet || git commit -m "chore: bump version to ${{ steps.branch.outputs.VERSION }}"
|
||
git push origin ${{ steps.branch.outputs.BRANCH }}
|