sadpandajoe commented on code in PR #45755:
URL: https://github.com/apache/superset/pull/45755#discussion_r4395961276
##########
scripts/docker-build-extra-flags.sh:
##########
@@ -77,6 +84,15 @@ case "$BUILD_PRESET" in
;;
esac
+case "$PLATFORM" in
+ ""|linux/amd64) ;;
+ linux/arm64) CACHE_REF="${CACHE_REF}-arm64" ;;
Review Comment:
With arm64 now writing to the `-arm64` ref, the unsuffixed ref is written
only by the amd64 job, so it holds no arm64 layers. `tag-release.yml` still
builds `linux/arm64` and `linux/amd64` in one job, calling this helper without
a platform, and `docker-compose*.yml` `cache_from` reads the same unsuffixed
ref. The arm64 half of each release build and arm64 developer builds therefore
get no registry cache hits, which restores the cold emulated arm64 build this
PR is trying to avoid. Should the release build and the compose `cache_from`
entries also read the `-arm64` ref?
##########
.github/workflows/docker.yml:
##########
@@ -330,28 +377,168 @@ jobs:
assert_cache_push_for_master lean "3.11-slim-trixie-lean"
assert_cache_push_for_master py311 "3.11-slim-bookworm"
assert_cache_push_for_master py312 "3.12-slim-bookworm"
+ assert_platform_cache_refs superset linux/amd64 "3.11-slim-trixie"
+ assert_platform_cache_refs superset linux/arm64
"3.11-slim-trixie-arm64"
+ assert_platform_cache_refs dev linux/arm64
"3.11-slim-trixie-dev-arm64"
+ assert_platform_cache_refs py312 linux/arm64
"3.12-slim-bookworm-arm64"
+ assert_platform_master_tag superset linux/amd64 master
+ assert_platform_master_tag superset linux/arm64 master-arm
+ assert_platform_master_tag dev linux/amd64 master-dev
+ assert_platform_master_tag dev linux/arm64 master-dev-arm
+ assert_platform_master_tag py311 linux/arm64 master-py311-arm
assert_release_tag superset "6.1.0"
assert_release_tag dev "6.1.0-dev"
assert_release_tag lean "6.1.0-lean"
assert_release_tag py311 "6.1.0-py311"
assert_release_tag py312 "6.1.0-py312"
assert_release_ref_swap
- echo "Docker build command verified for Python versions, cache refs,
cache export, publish guard, master tags, release tags, and the release ref
swap"
+ echo "Docker build command verified for Python versions, cache refs,
cache export, publish guard, master tags, per-platform plans/cache refs/tags,
release tags, and the release ref swap"
+
+ # Master publishes are multi-platform. Building linux/arm64 under QEMU on
+ # an amd64 runner took most of a 30+ minute build, so each platform is now
+ # built natively in its own job: this one pushes the linux/arm64 image
+ # under supersetbot's `-arm` suffixed tags (see getDockerTags in
+ # apache-superset/supersetbot), and docker-build below, which runs after
+ # it, pushes linux/amd64 under the unsuffixed tags and then folds both
+ # into one multi-platform manifest list per tag. Pull requests and version
+ # branches only validate a linux/amd64 build, so this job is skipped there.
+ docker-build-arm64:
+ name: docker-build (arm64)
+ needs: [setup_matrix, changes, check-freshness]
+ if: >-
+ needs.check-freshness.outputs.is-current == 'true' &&
+ github.event_name == 'push' &&
+ github.ref == 'refs/heads/master' &&
+ needs.setup_matrix.outputs.has-secrets &&
+ (needs.changes.outputs.python == 'true' ||
+ needs.changes.outputs.frontend == 'true' ||
+ needs.changes.outputs.docker == 'true')
+ runs-on: ubuntu-26.04-arm
+ timeout-minutes: 60
+ permissions:
+ contents: read
+ strategy:
+ matrix:
+ build_preset: ${{fromJson(needs.setup_matrix.outputs.matrix_config)}}
+ fail-fast: false
+ # Same per-preset publish queue as docker-build, kept separate so the two
+ # platforms of one commit build concurrently.
+ concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.build_preset
}}-arm64
+ cancel-in-progress: false
+ env:
+ DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
+ DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
+ BUILD_PLATFORM: linux/arm64
+ IMAGE_TAG: apache/superset:GHA-${{ matrix.build_preset }}-${{
github.run_id }}-arm64
+
+ steps:
+ - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #
v7.0.1
+ with:
+ persist-credentials: false
+
+ - name: Free up disk space
+ shell: bash
+ run: |
+ echo "Disk before cleanup:"; df -h /
+ sudo rm -rf \
+ /usr/share/dotnet \
+ /usr/local/lib/android \
+ /opt/ghc \
+ /usr/local/.ghcup \
+ /opt/hostedtoolcache/CodeQL \
+ /usr/local/share/boost || true
+ echo "Disk after cleanup:"; df -h /
+
+ - name: Setup Docker Environment
+ uses: $/.github/actions/setup-docker
+ with:
+ dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
+ dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
+ build: "true"
+
+ - name: Setup supersetbot
+ uses: $/.github/actions/setup-supersetbot/
+
+ # Same stale-commit check as docker-build; see the comment there.
+ - name: Guard against publishing a superseded master commit
+ id: publish_guard
+ shell: bash
+ run: |
+ set -euo pipefail
+ TIP_SHA=""
+ for attempt in 1 2 3; do
+ if TIP_SHA="$(git ls-remote
"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" refs/heads/master | cut -f1)" &&
+ [ -n "$TIP_SHA" ]; then
+ break
+ fi
+ if [ "$attempt" -eq 3 ]; then
+ echo "::error::could not read the master tip to validate
$GITHUB_SHA"
+ exit 1
+ fi
+ echo "::warning::ls-remote attempt ${attempt} failed; retrying in
10s..."
+ sleep 10
+ done
+ eval "$(bash scripts/docker-publish-guard.sh "$GITHUB_EVENT_NAME"
"$GITHUB_REF" "$GITHUB_SHA" "$TIP_SHA")"
+ if [ "$PUBLISH" != "true" ]; then
+ echo "::notice::master advanced to ${TIP_SHA} while ${GITHUB_SHA}
was queued; skipping this build"
+ fi
+ echo "publish=$PUBLISH" >> "$GITHUB_OUTPUT"
+
+ - name: Build Docker Image (linux/arm64)
+ if: steps.publish_guard.outputs.publish == 'true'
+ shell: bash
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ BUILD_PRESET: ${{ matrix.build_preset }}
+ run: |
+ set -euo pipefail
+ eval "$(bash scripts/docker-build-plan.sh "$GITHUB_EVENT_NAME"
"$GITHUB_REF" "${GITHUB_REF_NAME:-}" "$BUILD_PLATFORM")"
+ export PUBLISH_DOCKER_CACHE
+ # The platform argument selects the arm64 registry cache ref; see
+ # scripts/docker-build-extra-flags.sh.
+ EXTRA_FLAGS="$(scripts/docker-build-extra-flags.sh "$BUILD_PRESET"
"$IMAGE_TAG" ci "$BUILD_PLATFORM")"
+
+ for attempt in 1 2 3; do
+ if DOCKERHUB_TOKEN= supersetbot docker \
+ $PUSH_OR_LOAD \
+ --preset "$BUILD_PRESET" \
+ --context "$BUILD_CONTEXT" \
+ --context-ref "$BUILD_CONTEXT_REF" \
+ --extra-flags "$EXTRA_FLAGS" \
+ $PLATFORM_ARG; then
+ break
+ fi
+ if [ "$attempt" -eq 3 ]; then
+ echo "::error::supersetbot docker build failed after 3 attempts"
+ exit 1
+ fi
+ echo "::warning::Build attempt ${attempt} failed; retrying in
30s..."
+ sleep 30
+ done
docker-build:
name: docker-build
- needs: [setup_matrix, changes, check-freshness]
+ needs: [setup_matrix, changes, check-freshness, docker-build-arm64]
# Only master pushes publish images (see scripts/docker-build-plan.sh).
# Without the Docker Hub credentials (e.g. on a fork or mirror) they can
# publish nothing, so they are skipped there. Version-branch pushes and
# pull_request builds only load the image to validate that it builds, so
# they run everywhere. check-freshness.outputs.is-current is always
# 'true' for pull_request (it bypasses the check there — a PR build has
# no branch tip to race against, and staleness is instead handled by
- # this job's own cancel-in-progress: true below), so this only narrows
- # push triggers superseded by a newer commit on the same branch.
+ # cancel-in-progress on the concurrency group), and is false for push
+ # triggers superseded by a newer commit on the same branch. On master
+ # this job also needs the native arm64 build to have pushed its `-arm`
+ # tags first (it merges them below); a skipped arm64 job is the
+ # pull_request / version-branch case, a failed one must not leave
+ # amd64-only images under the multi-platform tags.
if: >-
+ !cancelled() &&
needs.check-freshness.outputs.is-current == 'true' &&
+ (needs.docker-build-arm64.result == 'success' ||
Review Comment:
`needs.docker-build-arm64.result` is the aggregate of the whole arm64
matrix, and it is `failure` (or `cancelled`) if any single preset leg fails,
even with `fail-fast: false`. Every amd64 leg is then skipped, including
presets whose `-arm` images pushed fine. Scenario: the arm64 `py312` leg fails
its third retry on a Docker Hub error, so `master`, `master-dev` and
`master-lean` are not published for that commit. Once a newer commit lands, the
publish guard skips a re-run of the failed jobs, so that commit is never
published. Before this change each preset published independently. Is blocking
all presets on the slowest or flakiest arm64 leg intended, or should the amd64
job wait only on its own preset's arm64 leg?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]