| name: Build and Push Docker Image |
|
|
| on: |
| push: |
| tags: |
| - 'v*' |
| workflow_dispatch: |
| inputs: |
| tag: |
| description: '手动指定镜像标签' |
| required: false |
| default: 'manual' |
|
|
| env: |
| REGISTRY: ghcr.io |
| IMAGE_NAME: ${{ github.repository }} |
|
|
| jobs: |
| |
| |
| |
| build: |
| strategy: |
| fail-fast: false |
| matrix: |
| platform: |
| - linux/amd64 |
| - linux/arm64 |
| runs-on: ubuntu-latest |
| permissions: |
| contents: read |
| packages: write |
|
|
| steps: |
| - name: Prepare |
| run: | |
| platform=${{ matrix.platform }} |
| echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV |
| echo "IMAGE_NAME_LC=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV |
| |
| - name: Checkout |
| uses: actions/checkout@v4 |
|
|
| - name: Set up QEMU |
| uses: docker/setup-qemu-action@v3 |
|
|
| - name: Set up Docker Buildx |
| uses: docker/setup-buildx-action@v3 |
|
|
| - name: Log in to Registry |
| uses: docker/login-action@v3 |
| with: |
| registry: ${{ env.REGISTRY }} |
| username: ${{ github.actor }} |
| password: ${{ secrets.GITHUB_TOKEN }} |
|
|
| - name: Extract metadata |
| id: meta |
| uses: docker/metadata-action@v5 |
| with: |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }} |
|
|
| - name: Build and push by digest |
| id: build |
| uses: docker/build-push-action@v6 |
| with: |
| context: . |
| platforms: ${{ matrix.platform }} |
| labels: ${{ steps.meta.outputs.labels }} |
| outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }},push-by-digest=true,name-canonical=true,push=true |
| cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }} |
| cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }},mode=max |
| build-args: | |
| VERSION=${{ github.ref_name }} |
| COMMIT=${{ github.sha }} |
| |
| - 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@v4 |
| with: |
| name: digests-${{ env.PLATFORM_PAIR }} |
| path: /tmp/digests/* |
| if-no-files-found: error |
| retention-days: 1 |
|
|
| |
| |
| |
| merge: |
| runs-on: ubuntu-latest |
| needs: build |
| permissions: |
| contents: read |
| packages: write |
| attestations: write |
| id-token: write |
|
|
| steps: |
| - name: Prepare |
| run: | |
| echo "IMAGE_NAME_LC=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV |
| |
| - 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 Registry |
| uses: docker/login-action@v3 |
| with: |
| registry: ${{ env.REGISTRY }} |
| username: ${{ github.actor }} |
| password: ${{ secrets.GITHUB_TOKEN }} |
|
|
| - name: Extract metadata |
| id: meta |
| uses: docker/metadata-action@v5 |
| with: |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }} |
| tags: | |
| type=semver,pattern={{version}} |
| type=semver,pattern={{major}}.{{minor}} |
| type=semver,pattern={{major}} |
| type=raw,value=latest,enable=${{ github.event_name == 'push' }} |
| type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag != '' }} |
| |
| - name: Create manifest list |
| working-directory: /tmp/digests |
| run: | |
| docker buildx imagetools create \ |
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ |
| $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}@sha256:%s ' *) |
| |
| - name: Inspect image |
| run: | |
| docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:${{ steps.meta.outputs.version }} |
| |