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: build: runs-on: ubuntu-latest strategy: matrix: include: - image: xingrin-server dockerfile: docker/server/Dockerfile context: . platforms: linux/amd64,linux/arm64 - image: xingrin-frontend dockerfile: docker/frontend/Dockerfile context: . platforms: linux/amd64 # ARM64 构建时 Next.js 在 QEMU 下会崩溃 - image: xingrin-worker dockerfile: docker/worker/Dockerfile context: . platforms: linux/amd64,linux/arm64 - image: xingrin-nginx dockerfile: docker/nginx/Dockerfile context: . platforms: linux/amd64,linux/arm64 - image: xingrin-agent dockerfile: docker/agent/Dockerfile context: . platforms: linux/amd64,linux/arm64 steps: - name: Checkout uses: actions/checkout@v4 - name: Free disk space (for large builds like worker) run: | echo "=== Before cleanup ===" df -h sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /opt/hostedtoolcache/CodeQL sudo docker image prune -af echo "=== After cleanup ===" df -h - 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" echo "SSL certificates generated for CI build" - name: Set up QEMU uses: docker/setup-qemu-action@v3 - 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 from git tag 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: Build and push uses: docker/build-push-action@v5 with: context: ${{ matrix.context }} file: ${{ matrix.dockerfile }} platforms: ${{ matrix.platforms }} push: true tags: | ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }} ${{ steps.version.outputs.IS_RELEASE == 'true' && format('{0}/{1}:latest', env.IMAGE_PREFIX, matrix.image) || '' }} build-args: | IMAGE_TAG=${{ steps.version.outputs.VERSION }} cache-from: type=gha cache-to: type=gha,mode=max provenance: false sbom: false # 所有镜像构建成功后,更新 VERSION 文件 update-version: runs-on: ubuntu-latest needs: build if: startsWith(github.ref, 'refs/tags/v') steps: - name: Checkout uses: actions/checkout@v4 with: ref: main token: ${{ secrets.GITHUB_TOKEN }} - name: Update VERSION file run: | VERSION="${GITHUB_REF#refs/tags/}" echo "$VERSION" > VERSION echo "Updated VERSION to $VERSION" - 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 ${GITHUB_REF#refs/tags/}" git push