From 53ca07e46f695669185af6ad59c2fb41d1b128b6 Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 20:07:54 +0800 Subject: [PATCH 01/10] chore(workflows): add strict_mode publish gate - replace gate_mode choice with strict_mode boolean input (default true) - run integration precheck only when strict_mode is enabled - keep matrix publish path available when precheck is skipped - preserve per-module self-check and multi-arch push behavior --- .../publish_latest_pd_store_server_image.yml | 275 ++++++++++++++---- 1 file changed, 216 insertions(+), 59 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index cb65d96..463ebec 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -7,9 +7,15 @@ on: required: false default: '' description: 'mvn build args, like "MAVEN_ARGS=-P stage"' - + strict_mode: + type: boolean + required: false + default: true + description: 'whether integration precheck is mandatory before publish' + jobs: - build_latest: + integration_precheck: + if: ${{ github.event.inputs.strict_mode == 'true' }} runs-on: ubuntu-latest env: REPOSITORY_URL: apache/hugegraph @@ -17,15 +23,15 @@ jobs: PD_IMAGE_URL: hugegraph/pd:latest STORE_IMAGE_URL: hugegraph/store:latest SERVER_IMAGE_URL: hugegraph/server:latest - MVN_ARGS: ${{inputs.mvn_args}} + MVN_ARGS: ${{ github.event.inputs.mvn_args || '' }} steps: - # - name: Maximize Build Space - # uses: easimon/maximize-build-space@master - # with: - # root-reserve-mb: 512 - # swap-size-mb: 1024 - # remove-dotnet: 'true' + - name: Checkout latest + uses: actions/checkout@v4 + with: + repository: ${{ env.REPOSITORY_URL }} + ref: ${{ env.BRANCH }} + fetch-depth: 2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -36,92 +42,243 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Checkout latest - uses: actions/checkout@v4 - with: - repository: ${{ env.REPOSITORY_URL }} - ref: ${{ env.BRANCH }} - fetch-depth: 2 + - name: Pre-build disk usage + run: | + df -h + docker system df || true + + - name: Pre-build cleanup + run: | + docker system prune -af || true + docker builder prune -af || true - - name: Build x86 PD Image + - name: Build x86 PD image for integration check uses: docker/build-push-action@v5 with: context: . file: ./hugegraph-pd/Dockerfile load: true tags: ${{ env.PD_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + cache-from: type=gha,scope=latest-pd + cache-to: type=gha,scope=latest-pd,mode=min build-args: ${{ env.MVN_ARGS }} - - name: Build x86 Store Image + - name: Build x86 Store image for integration check uses: docker/build-push-action@v5 with: context: . file: ./hugegraph-store/Dockerfile load: true tags: ${{ env.STORE_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + cache-from: type=gha,scope=latest-store + cache-to: type=gha,scope=latest-store,mode=min build-args: ${{ env.MVN_ARGS }} - - name: Build x86 Server Image + - name: Build x86 Server image for integration check uses: docker/build-push-action@v5 with: context: . file: ./hugegraph-server/Dockerfile-hstore load: true tags: ${{ env.SERVER_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + cache-from: type=gha,scope=latest-server + cache-to: type=gha,scope=latest-server,mode=min build-args: ${{ env.MVN_ARGS }} - - name: Test x86 Images + - name: Start compose stack with local images run: | - docker images - docker run -itd --name=pd --network host $PD_IMAGE_URL - sleep 10s - curl 0.0.0.0:8620 || exit - docker run -itd --name=store --network host $STORE_IMAGE_URL - sleep 10s - curl 0.0.0.0:8520 || exit - docker run -itd --name=server --network host $SERVER_IMAGE_URL - sleep 10s - curl 0.0.0.0:8080 || exit - docker ps -a - - - name: Push x86 & ARM PD Images - uses: docker/build-push-action@v5 + cat > /tmp/docker-compose.ci.override.yml <<'COMPOSE_OVERRIDE' + services: + pd: + image: hugegraph/pd:latest + pull_policy: never + store: + image: hugegraph/store:latest + pull_policy: never + server: + image: hugegraph/server:latest + pull_policy: never + COMPOSE_OVERRIDE + + docker compose \ + -p hg-ci-precheck \ + -f docker/docker-compose.yml \ + -f /tmp/docker-compose.ci.override.yml \ + up -d + + docker compose -p hg-ci-precheck -f docker/docker-compose.yml -f /tmp/docker-compose.ci.override.yml ps + + - name: Verify integration endpoints + run: | + wait_for_http() { + local url="$1" + local retries="${2:-40}" + local sleep_secs="${3:-5}" + + for _ in $(seq 1 "$retries"); do + if curl -fsS "$url" >/dev/null; then + echo "Ready: $url" + return 0 + fi + sleep "$sleep_secs" + done + + echo "Timeout waiting for: $url" + return 1 + } + + wait_for_http "http://127.0.0.1:8620/v1/health" + wait_for_http "http://127.0.0.1:8520/v1/health" + wait_for_http "http://127.0.0.1:8080/versions" + + - name: Dump compose logs on failure + if: ${{ failure() }} + run: | + docker compose -p hg-ci-precheck -f docker/docker-compose.yml -f /tmp/docker-compose.ci.override.yml logs --no-color --tail=200 || true + + - name: Stop compose stack + if: ${{ always() }} + run: | + docker compose \ + -p hg-ci-precheck \ + -f docker/docker-compose.yml \ + -f /tmp/docker-compose.ci.override.yml \ + down -v --remove-orphans || true + + - name: Post-check disk usage + if: ${{ always() }} + run: | + docker system df || true + df -h + + - name: Post-check cleanup + if: ${{ always() }} + run: | + docker system prune -af || true + docker builder prune -af || true + + publish_matrix: + needs: integration_precheck + if: ${{ needs.integration_precheck.result == 'success' || needs.integration_precheck.result == 'skipped' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - module: pd + image_url: hugegraph/pd:latest + dockerfile: ./hugegraph-pd/Dockerfile + container_port: 8620 + host_port: 18620 + probe_path: /v1/health + - module: store + image_url: hugegraph/store:latest + dockerfile: ./hugegraph-store/Dockerfile + container_port: 8520 + host_port: 18520 + probe_path: /v1/health + - module: server + image_url: hugegraph/server:latest + dockerfile: ./hugegraph-server/Dockerfile-hstore + container_port: 8080 + host_port: 18080 + probe_path: /versions + + env: + REPOSITORY_URL: apache/hugegraph + BRANCH: master + MVN_ARGS: ${{ github.event.inputs.mvn_args || '' }} + + steps: + - name: Checkout latest + uses: actions/checkout@v4 with: - context: . - file: ./hugegraph-pd/Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ env.PD_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max - build-args: ${{ env.MVN_ARGS }} + repository: ${{ env.REPOSITORY_URL }} + ref: ${{ env.BRANCH }} + fetch-depth: 2 + + - 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_PASSWORD }} + + - name: Pre-build disk usage (${{ matrix.module }}) + run: | + df -h + docker system df || true - - name: Push x86 & ARM Store Images + - name: Pre-build cleanup (${{ matrix.module }}) + run: | + docker system prune -af || true + docker builder prune -af || true + + - name: Build x86 image for self-check (${{ matrix.module }}) uses: docker/build-push-action@v5 with: context: . - file: ./hugegraph-store/Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ env.STORE_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + file: ${{ matrix.dockerfile }} + load: true + tags: ${{ matrix.image_url }} + cache-from: type=gha,scope=latest-${{ matrix.module }} + cache-to: type=gha,scope=latest-${{ matrix.module }},mode=min build-args: ${{ env.MVN_ARGS }} - - name: Push x86 & ARM Server Images + - name: Self-check x86 image (${{ matrix.module }}) + env: + IMAGE_URL: ${{ matrix.image_url }} + CONTAINER_PORT: ${{ matrix.container_port }} + HOST_PORT: ${{ matrix.host_port }} + PROBE_PATH: ${{ matrix.probe_path }} + run: | + container_name="hg-ci-${{ matrix.module }}" + docker rm -f "$container_name" >/dev/null 2>&1 || true + + docker run -d \ + --name "$container_name" \ + -p "$HOST_PORT:$CONTAINER_PORT" \ + "$IMAGE_URL" + + for _ in $(seq 1 30); do + if curl -fsS "http://127.0.0.1:$HOST_PORT$PROBE_PATH" >/dev/null; then + echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" + exit 0 + fi + sleep 5 + done + + echo "Self-check failed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" + docker logs "$container_name" || true + exit 1 + + - name: Stop self-check container (${{ matrix.module }}) + if: ${{ always() }} + run: | + docker rm -f "hg-ci-${{ matrix.module }}" >/dev/null 2>&1 || true + + - name: Build and push multi-arch image (${{ matrix.module }}) uses: docker/build-push-action@v5 with: context: . - file: ./hugegraph-server/Dockerfile-hstore + file: ${{ matrix.dockerfile }} platforms: linux/amd64,linux/arm64 push: true - tags: ${{ env.SERVER_IMAGE_URL }} - # cache-from: type=gha - # cache-to: type=gha,mode=max + tags: ${{ matrix.image_url }} + cache-from: type=gha,scope=latest-${{ matrix.module }} + cache-to: type=gha,scope=latest-${{ matrix.module }},mode=min build-args: ${{ env.MVN_ARGS }} + + - name: Post-build disk usage (${{ matrix.module }}) + if: ${{ always() }} + run: | + docker system df || true + df -h + + - name: Post-build cleanup (${{ matrix.module }}) + if: ${{ always() }} + run: | + docker system prune -af || true + docker builder prune -af || true From a4b2759758874ff35353fe383d21676481e87bf4 Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 20:20:23 +0800 Subject: [PATCH 02/10] Update publish_latest_pd_store_server_image.yml --- .../publish_latest_pd_store_server_image.yml | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 463ebec..1f8ef6a 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -34,10 +34,12 @@ jobs: fetch-depth: 2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 + with: + version: latest - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} @@ -53,7 +55,7 @@ jobs: docker builder prune -af || true - name: Build x86 PD image for integration check - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . file: ./hugegraph-pd/Dockerfile @@ -64,7 +66,7 @@ jobs: build-args: ${{ env.MVN_ARGS }} - name: Build x86 Store image for integration check - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . file: ./hugegraph-store/Dockerfile @@ -75,7 +77,7 @@ jobs: build-args: ${{ env.MVN_ARGS }} - name: Build x86 Server image for integration check - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . file: ./hugegraph-server/Dockerfile-hstore @@ -197,11 +199,16 @@ jobs: ref: ${{ env.BRANCH }} fetch-depth: 2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 + with: + version: latest - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} @@ -217,7 +224,7 @@ jobs: docker builder prune -af || true - name: Build x86 image for self-check (${{ matrix.module }}) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . file: ${{ matrix.dockerfile }} @@ -260,7 +267,7 @@ jobs: docker rm -f "hg-ci-${{ matrix.module }}" >/dev/null 2>&1 || true - name: Build and push multi-arch image (${{ matrix.module }}) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v7 with: context: . file: ${{ matrix.dockerfile }} @@ -268,7 +275,7 @@ jobs: push: true tags: ${{ matrix.image_url }} cache-from: type=gha,scope=latest-${{ matrix.module }} - cache-to: type=gha,scope=latest-${{ matrix.module }},mode=min + cache-to: type=gha,scope=latest-${{ matrix.module }},mode=max build-args: ${{ env.MVN_ARGS }} - name: Post-build disk usage (${{ matrix.module }}) From 9a867a6953bdcb6c8c5fb5e82101b5a00e048259 Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 20:52:33 +0800 Subject: [PATCH 03/10] Use resolved source SHA and improve publish workflow Add concurrency group and a new resolve_source job that fetches the master commit SHA from apache/hugegraph and exposes it as SOURCE_SHA. Use SOURCE_SHA for actions/checkout in integration_precheck and publish_matrix (replacing the previous hardcoded branch), and make publish_matrix depend on resolve_source with an updated success condition. Replace hardcoded local image names in the compose override with PD/STORE/SERVER image variables and remove quoted heredoc to enable substitution. Add curl connection and max timeouts for readiness probes to avoid hanging. --- .../publish_latest_pd_store_server_image.yml | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 1f8ef6a..11e35fd 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -13,13 +13,33 @@ on: default: true description: 'whether integration precheck is mandatory before publish' +concurrency: + group: publish-latest-pd-store-server + cancel-in-progress: false + jobs: + resolve_source: + runs-on: ubuntu-latest + outputs: + source_sha: ${{ steps.resolve.outputs.source_sha }} + steps: + - name: Resolve source SHA + id: resolve + run: | + source_sha="$(git ls-remote https://github.com/apache/hugegraph.git refs/heads/master | awk '{print $1}')" + if [ -z "$source_sha" ]; then + echo "Failed to resolve source SHA for apache/hugegraph master" + exit 1 + fi + echo "source_sha=$source_sha" >> "$GITHUB_OUTPUT" + integration_precheck: + needs: resolve_source if: ${{ github.event.inputs.strict_mode == 'true' }} runs-on: ubuntu-latest env: REPOSITORY_URL: apache/hugegraph - BRANCH: master + SOURCE_SHA: ${{ needs.resolve_source.outputs.source_sha }} PD_IMAGE_URL: hugegraph/pd:latest STORE_IMAGE_URL: hugegraph/store:latest SERVER_IMAGE_URL: hugegraph/server:latest @@ -30,7 +50,7 @@ jobs: uses: actions/checkout@v4 with: repository: ${{ env.REPOSITORY_URL }} - ref: ${{ env.BRANCH }} + ref: ${{ env.SOURCE_SHA }} fetch-depth: 2 - name: Set up Docker Buildx @@ -89,16 +109,16 @@ jobs: - name: Start compose stack with local images run: | - cat > /tmp/docker-compose.ci.override.yml <<'COMPOSE_OVERRIDE' + cat > /tmp/docker-compose.ci.override.yml </dev/null; then + if curl -fsS --connect-timeout 3 --max-time 8 "$url" >/dev/null; then echo "Ready: $url" return 0 fi @@ -160,8 +180,8 @@ jobs: docker builder prune -af || true publish_matrix: - needs: integration_precheck - if: ${{ needs.integration_precheck.result == 'success' || needs.integration_precheck.result == 'skipped' }} + needs: [resolve_source, integration_precheck] + if: ${{ needs.resolve_source.result == 'success' && (needs.integration_precheck.result == 'success' || needs.integration_precheck.result == 'skipped') }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -188,7 +208,7 @@ jobs: env: REPOSITORY_URL: apache/hugegraph - BRANCH: master + SOURCE_SHA: ${{ needs.resolve_source.outputs.source_sha }} MVN_ARGS: ${{ github.event.inputs.mvn_args || '' }} steps: @@ -196,7 +216,7 @@ jobs: uses: actions/checkout@v4 with: repository: ${{ env.REPOSITORY_URL }} - ref: ${{ env.BRANCH }} + ref: ${{ env.SOURCE_SHA }} fetch-depth: 2 - name: Set up QEMU @@ -250,7 +270,7 @@ jobs: "$IMAGE_URL" for _ in $(seq 1 30); do - if curl -fsS "http://127.0.0.1:$HOST_PORT$PROBE_PATH" >/dev/null; then + if curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:$HOST_PORT$PROBE_PATH" >/dev/null; then echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" exit 0 fi From d6d57f27bd9f331ca6fc9b3120eac216c3bec105 Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:03:36 +0800 Subject: [PATCH 04/10] fix(workflows): allow publish when precheck skipped - add always() to publish_matrix job condition - keep explicit needs result checks for resolve_source and precheck - ensure strict_mode=false path can still run matrix publish --- .github/workflows/publish_latest_pd_store_server_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 11e35fd..3a0006a 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -181,7 +181,7 @@ jobs: publish_matrix: needs: [resolve_source, integration_precheck] - if: ${{ needs.resolve_source.result == 'success' && (needs.integration_precheck.result == 'success' || needs.integration_precheck.result == 'skipped') }} + if: ${{ always() && needs.resolve_source.result == 'success' && (needs.integration_precheck.result == 'success' || needs.integration_precheck.result == 'skipped') }} runs-on: ubuntu-latest strategy: fail-fast: false From de4c9588d381242a63e26b0101cd2f5d4a7fd009 Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:11:52 +0800 Subject: [PATCH 05/10] Update .github/workflows/publish_latest_pd_store_server_image.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/publish_latest_pd_store_server_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 3a0006a..b4b9318 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -35,7 +35,7 @@ jobs: integration_precheck: needs: resolve_source - if: ${{ github.event.inputs.strict_mode == 'true' }} + if: ${{ inputs.strict_mode }} runs-on: ubuntu-latest env: REPOSITORY_URL: apache/hugegraph From 1bfb2aa0938e3cd9185aaffe79e2ad364c4adeea Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:20:31 +0800 Subject: [PATCH 06/10] fix(workflows): align self-check with image contracts - switch matrix self-check from raw docker run to compose-based startup - override target module image with local build and keep pull_policy never - use compose --wait with bounded 300s timeout for precheck and self-check - simplify integration probes to direct endpoint assertions after wait --- .../publish_latest_pd_store_server_image.yml | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 3a0006a..6266dd2 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -126,32 +126,15 @@ jobs: -p hg-ci-precheck \ -f docker/docker-compose.yml \ -f /tmp/docker-compose.ci.override.yml \ - up -d + up -d --wait --wait-timeout 300 docker compose -p hg-ci-precheck -f docker/docker-compose.yml -f /tmp/docker-compose.ci.override.yml ps - name: Verify integration endpoints run: | - wait_for_http() { - local url="$1" - local retries="${2:-40}" - local sleep_secs="${3:-5}" - - for _ in $(seq 1 "$retries"); do - if curl -fsS --connect-timeout 3 --max-time 8 "$url" >/dev/null; then - echo "Ready: $url" - return 0 - fi - sleep "$sleep_secs" - done - - echo "Timeout waiting for: $url" - return 1 - } - - wait_for_http "http://127.0.0.1:8620/v1/health" - wait_for_http "http://127.0.0.1:8520/v1/health" - wait_for_http "http://127.0.0.1:8080/versions" + curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:8620/v1/health" >/dev/null + curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:8520/v1/health" >/dev/null + curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:8080/versions" >/dev/null - name: Dump compose logs on failure if: ${{ failure() }} @@ -256,35 +239,53 @@ jobs: - name: Self-check x86 image (${{ matrix.module }}) env: + MODULE: ${{ matrix.module }} IMAGE_URL: ${{ matrix.image_url }} - CONTAINER_PORT: ${{ matrix.container_port }} HOST_PORT: ${{ matrix.host_port }} PROBE_PATH: ${{ matrix.probe_path }} run: | - container_name="hg-ci-${{ matrix.module }}" - docker rm -f "$container_name" >/dev/null 2>&1 || true - - docker run -d \ - --name "$container_name" \ - -p "$HOST_PORT:$CONTAINER_PORT" \ - "$IMAGE_URL" - - for _ in $(seq 1 30); do - if curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:$HOST_PORT$PROBE_PATH" >/dev/null; then - echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" - exit 0 - fi - sleep 5 - done - - echo "Self-check failed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" - docker logs "$container_name" || true - exit 1 - - - name: Stop self-check container (${{ matrix.module }}) + compose_project="hg-ci-selfcheck-${MODULE}" + compose_override="/tmp/docker-compose.self-check-${MODULE}.yml" + + cat > "$compose_override" </dev/null + echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" + + - name: Dump self-check compose logs on failure (${{ matrix.module }}) + if: ${{ failure() }} + env: + MODULE: ${{ matrix.module }} + run: | + compose_project="hg-ci-selfcheck-${MODULE}" + compose_override="/tmp/docker-compose.self-check-${MODULE}.yml" + docker compose -p "$compose_project" -f docker/docker-compose.yml -f "$compose_override" ps || true + docker compose -p "$compose_project" -f docker/docker-compose.yml -f "$compose_override" logs --no-color --tail=200 || true + + - name: Stop self-check compose stack (${{ matrix.module }}) if: ${{ always() }} + env: + MODULE: ${{ matrix.module }} run: | - docker rm -f "hg-ci-${{ matrix.module }}" >/dev/null 2>&1 || true + compose_project="hg-ci-selfcheck-${MODULE}" + compose_override="/tmp/docker-compose.self-check-${MODULE}.yml" + docker compose \ + -p "$compose_project" \ + -f docker/docker-compose.yml \ + -f "$compose_override" \ + down -v --remove-orphans || true + rm -f "$compose_override" - name: Build and push multi-arch image (${{ matrix.module }}) uses: docker/build-push-action@v7 From 10f67a695ed656680d9d88f6794631264dcdddbc Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:29:08 +0800 Subject: [PATCH 07/10] feat(workflows): add configurable wait timeout - add workflow_dispatch input wait_timeout_sec with default 300 - wire WAIT_TIMEOUT_SEC into precheck and matrix self-check compose waits - validate wait_timeout_sec as integer within 30-1800 before builds --- .../publish_latest_pd_store_server_image.yml | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 9c677f8..d31cc3f 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -12,6 +12,10 @@ on: required: false default: true description: 'whether integration precheck is mandatory before publish' + wait_timeout_sec: + required: false + default: '300' + description: 'docker compose wait timeout in seconds for precheck/self-check' concurrency: group: publish-latest-pd-store-server @@ -44,6 +48,7 @@ jobs: STORE_IMAGE_URL: hugegraph/store:latest SERVER_IMAGE_URL: hugegraph/server:latest MVN_ARGS: ${{ github.event.inputs.mvn_args || '' }} + WAIT_TIMEOUT_SEC: ${{ github.event.inputs.wait_timeout_sec || '300' }} steps: - name: Checkout latest @@ -64,6 +69,13 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} + - name: Validate wait timeout + run: | + if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then + echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." + exit 1 + fi + - name: Pre-build disk usage run: | df -h @@ -126,7 +138,7 @@ jobs: -p hg-ci-precheck \ -f docker/docker-compose.yml \ -f /tmp/docker-compose.ci.override.yml \ - up -d --wait --wait-timeout 300 + up -d --wait --wait-timeout "$WAIT_TIMEOUT_SEC" docker compose -p hg-ci-precheck -f docker/docker-compose.yml -f /tmp/docker-compose.ci.override.yml ps @@ -193,6 +205,7 @@ jobs: REPOSITORY_URL: apache/hugegraph SOURCE_SHA: ${{ needs.resolve_source.outputs.source_sha }} MVN_ARGS: ${{ github.event.inputs.mvn_args || '' }} + WAIT_TIMEOUT_SEC: ${{ github.event.inputs.wait_timeout_sec || '300' }} steps: - name: Checkout latest @@ -216,6 +229,13 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} + - name: Validate wait timeout (${{ matrix.module }}) + run: | + if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then + echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." + exit 1 + fi + - name: Pre-build disk usage (${{ matrix.module }}) run: | df -h @@ -258,7 +278,7 @@ jobs: -p "$compose_project" \ -f docker/docker-compose.yml \ -f "$compose_override" \ - up -d "$MODULE" --wait --wait-timeout 300 + up -d "$MODULE" --wait --wait-timeout "$WAIT_TIMEOUT_SEC" curl -fsS --connect-timeout 3 --max-time 8 "http://127.0.0.1:$HOST_PORT$PROBE_PATH" >/dev/null echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" From e6f312d28d3a999eda24a247d4727fc745fa853d Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:35:05 +0800 Subject: [PATCH 08/10] chore(workflows): harden compose path and trim cache writes - add explicit docker-compose path validation before compose up in precheck - add the same compose path validation in matrix self-check - remove redundant cache-to from x86 self-check build step --- .../publish_latest_pd_store_server_image.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index d31cc3f..2d97692 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -121,6 +121,12 @@ jobs: - name: Start compose stack with local images run: | + if [ ! -f "docker/docker-compose.yml" ]; then + echo "ERROR: docker/docker-compose.yml not found in $REPOSITORY_URL@$SOURCE_SHA" + echo "Please update the compose file path in this workflow." + exit 1 + fi + cat > /tmp/docker-compose.ci.override.yml < "$compose_override" < Date: Sat, 21 Mar 2026 21:48:23 +0800 Subject: [PATCH 09/10] fix(workflows): skip fragile module self-checks - align matrix host ports with upstream compose port mappings - skip standalone self-check for store and server in module mode - keep pd self-check enabled to retain basic startup validation - move wait timeout validation to the first step in each job chore(workflows): remove unused matrix port field - drop container_port from pd/store/server matrix entries - keep host_port and probe_path as the actual self-check inputs - reduce config ambiguity in publish_matrix --- .../publish_latest_pd_store_server_image.yml | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index 2d97692..fde6e4a 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -51,6 +51,13 @@ jobs: WAIT_TIMEOUT_SEC: ${{ github.event.inputs.wait_timeout_sec || '300' }} steps: + - name: Validate wait timeout + run: | + if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then + echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." + exit 1 + fi + - name: Checkout latest uses: actions/checkout@v4 with: @@ -69,13 +76,6 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Validate wait timeout - run: | - if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then - echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." - exit 1 - fi - - name: Pre-build disk usage run: | df -h @@ -191,21 +191,21 @@ jobs: - module: pd image_url: hugegraph/pd:latest dockerfile: ./hugegraph-pd/Dockerfile - container_port: 8620 - host_port: 18620 + host_port: 8620 probe_path: /v1/health + skip_selfcheck: false - module: store image_url: hugegraph/store:latest dockerfile: ./hugegraph-store/Dockerfile - container_port: 8520 - host_port: 18520 + host_port: 8520 probe_path: /v1/health + skip_selfcheck: true - module: server image_url: hugegraph/server:latest dockerfile: ./hugegraph-server/Dockerfile-hstore - container_port: 8080 - host_port: 18080 + host_port: 8080 probe_path: /versions + skip_selfcheck: true env: REPOSITORY_URL: apache/hugegraph @@ -214,6 +214,13 @@ jobs: WAIT_TIMEOUT_SEC: ${{ github.event.inputs.wait_timeout_sec || '300' }} steps: + - name: Validate wait timeout (${{ matrix.module }}) + run: | + if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then + echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." + exit 1 + fi + - name: Checkout latest uses: actions/checkout@v4 with: @@ -235,13 +242,6 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Validate wait timeout (${{ matrix.module }}) - run: | - if ! [[ "$WAIT_TIMEOUT_SEC" =~ ^[0-9]+$ ]] || [ "$WAIT_TIMEOUT_SEC" -lt 30 ] || [ "$WAIT_TIMEOUT_SEC" -gt 1800 ]; then - echo "Invalid wait_timeout_sec: $WAIT_TIMEOUT_SEC. Expected integer between 30 and 1800." - exit 1 - fi - - name: Pre-build disk usage (${{ matrix.module }}) run: | df -h @@ -263,6 +263,7 @@ jobs: build-args: ${{ env.MVN_ARGS }} - name: Self-check x86 image (${{ matrix.module }}) + if: ${{ !matrix.skip_selfcheck }} env: MODULE: ${{ matrix.module }} IMAGE_URL: ${{ matrix.image_url }} @@ -295,7 +296,7 @@ jobs: echo "Self-check passed: http://127.0.0.1:$HOST_PORT$PROBE_PATH" - name: Dump self-check compose logs on failure (${{ matrix.module }}) - if: ${{ failure() }} + if: ${{ failure() && !matrix.skip_selfcheck }} env: MODULE: ${{ matrix.module }} run: | @@ -305,7 +306,7 @@ jobs: docker compose -p "$compose_project" -f docker/docker-compose.yml -f "$compose_override" logs --no-color --tail=200 || true - name: Stop self-check compose stack (${{ matrix.module }}) - if: ${{ always() }} + if: ${{ always() && !matrix.skip_selfcheck }} env: MODULE: ${{ matrix.module }} run: | From a48f7e25983a0e3c7ed222f6bc54f1adadd1557f Mon Sep 17 00:00:00 2001 From: imbajin Date: Sat, 21 Mar 2026 21:59:23 +0800 Subject: [PATCH 10/10] chore(workflows): skip unused x86 self-check builds - gate x86 self-check build with matrix.skip_selfcheck - avoid building and loading amd64 images for store/server when self-check is disabled - reduce runner disk usage and unnecessary build time --- .github/workflows/publish_latest_pd_store_server_image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish_latest_pd_store_server_image.yml b/.github/workflows/publish_latest_pd_store_server_image.yml index fde6e4a..4442361 100644 --- a/.github/workflows/publish_latest_pd_store_server_image.yml +++ b/.github/workflows/publish_latest_pd_store_server_image.yml @@ -253,6 +253,7 @@ jobs: docker builder prune -af || true - name: Build x86 image for self-check (${{ matrix.module }}) + if: ${{ !matrix.skip_selfcheck }} uses: docker/build-push-action@v7 with: context: .