Fix runs-on image for build_arm64 #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Continuous Deployment (Docker multi-arch) | |
| on: | |
| push: | |
| branches: [ main, add-ci-cd ] | |
| tags: ['v*', 'v*.*', 'v*.*.*'] | |
| pull_request: | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_PREFIX: ${{ github.repository_owner }}/pyigmap | |
| SERVICES_CSV: fastp | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| jobs: | |
| matrix: | |
| name: Prepare services matrix | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| services: ${{ steps.mkjson.outputs.services }} | |
| steps: | |
| - name: Expand SERVICES_CSV -> JSON | |
| id: mkjson | |
| run: | | |
| IFS=',' read -ra arr <<< "${SERVICES_CSV}" | |
| printf '{"service":[%s]}\n' "$(printf '"%s",' "${arr[@]}" | sed 's/,$//')" > services.json | |
| echo "services=$(cat services.json)" >> "$GITHUB_OUTPUT" | |
| precheck: | |
| name: Precheck version existence | |
| needs: matrix | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.matrix.outputs.services) }} | |
| outputs: | |
| skip: ${{ steps.out.outputs.skip }} | |
| version: ${{ steps.out.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Parse version from pyproject.toml | |
| id: get_ver | |
| run: | | |
| set -euo pipefail | |
| FILE="./bin/${{ matrix.service }}/pyproject.toml" | |
| VERSION="" | |
| if [[ -f "$FILE" ]]; then | |
| VERSION=$(awk ' | |
| /^\[project\]/ { in_proj=1; next } | |
| in_proj && $0 ~ /^version[[:space:]]*=/ { | |
| match($0, /"([^"]+)"/, m); if (m[1]!="") { print m[1]; exit } | |
| }' "$FILE" || true) | |
| fi | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "Detected version: ${VERSION:-<empty>}" | |
| - name: Login to GHCR | |
| if: steps.get_ver.outputs.version != '' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check tag existence in GHCR | |
| id: exist | |
| run: | | |
| set -euo pipefail | |
| if [[ -z "${{ steps.get_ver.outputs.version }}" ]]; then | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}:${{ steps.get_ver.outputs.version }}" | |
| if docker buildx imagetools inspect "${IMAGE}" >/dev/null 2>&1; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| echo "Checked ${IMAGE}: exists=${{ steps.exist.outputs.exists }}" | |
| - name: Expose outputs | |
| id: out | |
| run: | | |
| SKIP=$([[ "${{ steps.exist.outputs.exists }}" == "true" ]] && echo true || echo false) | |
| echo "skip=$SKIP" >> "$GITHUB_OUTPUT" | |
| echo "version=${{ steps.get_ver.outputs.version }}" >> "$GITHUB_OUTPUT" | |
| build_amd64: | |
| name: Build & push (amd64) | |
| needs: [matrix, precheck] | |
| if: needs.precheck.outputs.skip != 'true' | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.matrix.outputs.services) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Login to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker metadata (amd64 tags) — без branch tag | |
| id: meta_amd | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }} | |
| tags: | | |
| type=raw,value=${{ needs.precheck.outputs.version }},enable=${{ needs.precheck.outputs.version != '' }} | |
| type=sha | |
| type=semver,pattern={{version}} | |
| type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} | |
| flavor: | | |
| suffix=-amd64 | |
| - name: Build & push image (amd64) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ./bin/${{ matrix.service }} | |
| file: ./bin/${{ matrix.service }}/Dockerfile | |
| platforms: linux/amd64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta_amd.outputs.tags }} | |
| labels: ${{ steps.meta_amd.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| sbom: false | |
| build_arm64: | |
| name: Build & push (arm64) | |
| needs: [matrix, precheck] | |
| if: needs.precheck.outputs.skip != 'true' | |
| runs-on: ubuntu-24.04-arm | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.matrix.outputs.services) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Login to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker metadata (arm64 tags) | |
| id: meta_arm | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }} | |
| tags: | | |
| type=raw,value=${{ needs.precheck.outputs.version }},enable=${{ needs.precheck.outputs.version != '' }} | |
| type=sha | |
| type=semver,pattern={{version}} | |
| type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} | |
| flavor: | | |
| suffix=-arm64 | |
| - name: Build & push image (arm64) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ./bin/${{ matrix.service }} | |
| file: ./bin/${{ matrix.service }}/Dockerfile | |
| platforms: linux/arm64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta_arm.outputs.tags }} | |
| labels: ${{ steps.meta_arm.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| sbom: false | |
| manifest: | |
| name: Assemble multi-arch manifest | |
| needs: [matrix, precheck, build_amd64, build_arm64] | |
| if: github.event_name != 'pull_request' && needs.precheck.outputs.skip != 'true' | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.matrix.outputs.services) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Login to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker metadata (final tags) | |
| id: meta_final | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }} | |
| tags: | | |
| type=raw,value=${{ needs.precheck.outputs.version }},enable=${{ needs.precheck.outputs.version != '' }} | |
| type=sha | |
| type=semver,pattern={{version}} | |
| type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} | |
| - name: Create multi-arch manifest using buildx imagetools | |
| env: | |
| TAGS: ${{ steps.meta_final.outputs.tags }} | |
| run: | | |
| set -euo pipefail | |
| echo "$TAGS" | tr ' ' '\n' | while read -r TARGET; do | |
| [ -z "$TARGET" ] && continue | |
| BASE="${TARGET%:*}" | |
| TAG="${TARGET##*:}" | |
| AMD="${BASE}:${TAG}-amd64" | |
| ARM="${BASE}:${TAG}-arm64" | |
| echo "Creating manifest ${TARGET} from:" | |
| echo " - ${AMD}" | |
| echo " - ${ARM}" | |
| docker buildx imagetools create \ | |
| --tag "${TARGET}" \ | |
| "${AMD}" \ | |
| "${ARM}" | |
| docker buildx imagetools inspect "${TARGET}" | |
| done |