Skip to content

Optimize integration test runtime#689

Merged
davidgamero merged 1 commit intoAzure:mainfrom
davidgamero:chore/optimize-integration-tests
Feb 11, 2026
Merged

Optimize integration test runtime#689
davidgamero merged 1 commit intoAzure:mainfrom
davidgamero:chore/optimize-integration-tests

Conversation

@davidgamero
Copy link
Collaborator

@davidgamero davidgamero commented Feb 10, 2026

  • add Buildx + GHA cache for docker builds in integration jobs
  • replace fixed 120s sleep with service IP polling and curl retries
  • keep behavior the same while reducing idle waits

@davidgamero davidgamero enabled auto-merge (squash) February 10, 2026 22:24
@davidgamero davidgamero merged commit bf92271 into Azure:main Feb 11, 2026
149 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the per-language integration workflow to reduce idle wait time and speed up Docker builds by introducing Buildx with GitHub Actions cache and replacing fixed sleeps with polling/retries.

Changes:

  • Add docker buildx setup and switch Docker builds to docker buildx build with type=gha caching.
  • Replace fixed sleep 120 waits with polling for the service external IP and retrying curl until the service responds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to 113
- name: Set up buildx
run: |
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap
- name: Build and Push image
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker buildx create --use is executed before eval $(minikube ... docker-env), so the builder may be created against the runner’s default Docker daemon instead of the Minikube daemon. That can cause the subsequent docker buildx build (after switching DOCKER_HOST) to fail to find the builder or to build/push from the wrong daemon. Consider moving buildx setup into the same step after the Minikube docker-env call (or explicitly creating/using the builder after switching to Minikube’s Docker endpoint).

Suggested change
- name: Set up buildx
run: |
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap
- name: Build and Push image
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
- name: Build and Push image
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap

Copilot uses AI. Check for mistakes.
trap 'kill $tunnelPID' EXIT
echo 'Waiting for service IP'
for i in {1..30}; do
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polling the service IP via kubectl get svc ... .items[1]... is brittle because it depends on list ordering and the presence of at least two services. Prefer selecting the specific Service by name (e.g., the release service) or by label selector, then JSONPath into that object.

Suggested change
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
SERVICEIP=$(kubectl get svc test-release-testapp -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

Copilot uses AI. Check for mistakes.
Comment on lines +306 to 314
- name: Set up buildx
run: |
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap
- name: Build and Push Image
continue-on-error: true
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as earlier: buildx is set up before eval $(minikube ... docker-env), which risks creating/using the builder against the wrong Docker daemon. Move buildx setup to after switching to Minikube’s Docker endpoint (or re-create/use the builder after switching).

Suggested change
- name: Set up buildx
run: |
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap
- name: Build and Push Image
continue-on-error: true
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
- name: Build and Push Image
continue-on-error: true
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
docker buildx create --use --name draft-builder || docker buildx use draft-builder
docker buildx inspect --bootstrap

Copilot uses AI. Check for mistakes.
echo 'Starting minikube tunnel'
minikube tunnel > /dev/null 2>&1 & tunnelPID=$!
sleep 120
trap 'kill $tunnelPID' EXIT
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same teardown concern: trap 'kill $tunnelPID' EXIT can fail the step if kill returns non-zero (PID already exited). Make the kill non-fatal so it can’t override the curl loop’s success.

Suggested change
trap 'kill $tunnelPID' EXIT
trap 'kill $tunnelPID 2>/dev/null || true' EXIT

Copilot uses AI. Check for mistakes.
trap 'kill $tunnelPID' EXIT
echo 'Waiting for service IP'
for i in {1..30}; do
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSONPath .items[1]... approach for finding the Service IP is non-deterministic and may break if Service ordering changes. Prefer querying the exact Service (name/selector) before extracting .status.loadBalancer.ingress[0].ip.

Suggested change
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
SERVICEIP=$(kubectl get svc -l app=testapp -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

Copilot uses AI. Check for mistakes.
id: minikube
uses: medyagh/setup-minikube@master
- name: Set up buildx
run: |
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In manifest-update, buildx is configured before switching to the Minikube Docker daemon (eval $(minikube ... docker-env) happens later). With --load, building against the wrong daemon would leave the image unavailable to the cluster. Move buildx setup after switching to Minikube’s Docker env (or re-create/use the builder after the switch).

Suggested change
run: |
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)

Copilot uses AI. Check for mistakes.
echo 'Starting minikube tunnel'
minikube tunnel > /dev/null 2>&1 & tunnelPID=$!
sleep 120
trap 'kill $tunnelPID' EXIT
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trap 'kill $tunnelPID' EXIT can make the step fail if minikube tunnel exits early or the PID is already gone, because kill will return non-zero under the default bash -e runner shell. Make the cleanup non-fatal (e.g., ignore errors / redirect stderr) so a successful curl doesn’t get marked as failed during teardown.

Suggested change
trap 'kill $tunnelPID' EXIT
trap 'kill "$tunnelPID" >/dev/null 2>&1 || true' EXIT

Copilot uses AI. Check for mistakes.
trap 'kill $tunnelPID' EXIT
echo 'Waiting for service IP'
for i in {1..30}; do
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Service IP polling is still using .items[1] which is order-dependent. Use kubectl get svc <expected-service-name> -o jsonpath=... (or a label selector) to make this deterministic.

Suggested change
SERVICEIP=$(kubectl get svc -o jsonpath={'.items[1].status.loadBalancer.ingress[0].ip'})
SERVICEIP=$(kubectl get svc -l app=testapp -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

Copilot uses AI. Check for mistakes.
with:
insecure-registry: "host.minikube.internal:5001,10.0.0.0/24"
- name: Set up buildx
run: |
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buildx setup occurs before switching Docker to Minikube (eval $(minikube ... docker-env) in the next step). This can lead to the builder being created on the wrong daemon. Recommend setting up (or re-selecting) the buildx builder after switching to Minikube’s Docker environment.

Suggested change
run: |
run: |
eval $(minikube -p minikube docker-env)

Copilot uses AI. Check for mistakes.
echo 'Starting minikube tunnel'
minikube tunnel > /dev/null 2>&1 & tunnelPID=$!
sleep 120
trap 'kill $tunnelPID' EXIT
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trap 'kill $tunnelPID' EXIT should ignore errors; if minikube tunnel exits early, kill may fail and cause the step to be marked failed under bash -e. Make tunnel cleanup best-effort.

Suggested change
trap 'kill $tunnelPID' EXIT
trap 'kill "$tunnelPID" >/dev/null 2>&1 || true' EXIT

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants