Skip to content

Commit 495e2c2

Browse files
authored
Merge branch 'develop' into dev/claude-pr-review
2 parents 847bb41 + e661684 commit 495e2c2

415 files changed

Lines changed: 16511 additions & 5000 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/combine-results/action.yml

Lines changed: 0 additions & 103 deletions
This file was deleted.

.github/actions/ecr-build-push-pull/action.yml

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ inputs:
3737
description: Tag used for the ECR layer cache image (e.g. "cache-base", "cache-curobo").
3838
required: false
3939
default: 'cache'
40-
overlay-dockerfile-path:
41-
description: 'Thin overlay Dockerfile applied on top of a deps cache hit.'
42-
required: false
43-
default: 'docker/Dockerfile.overlay'
44-
4540
runs:
4641
using: composite
4742
steps:
@@ -67,15 +62,15 @@ runs:
6762
export DOCKER_CONFIG="${DOCKER_CONFIG_DIR}"
6863
6964
if [ -n "${{ env.NGC_API_KEY }}" ]; then
70-
echo "🟢 Logging into nvcr.io..."
65+
echo "🔵 Logging into nvcr.io..."
7166
docker login -u \$oauthtoken -p ${{ env.NGC_API_KEY }} nvcr.io
7267
else
73-
echo "🟠 NGC_API_KEY not set skipping nvcr.io login (normal for fork PRs)"
68+
echo "🟠 NGC_API_KEY not set - skipping nvcr.io login (normal for fork PRs)"
7469
fi
7570
7671
##### 2: Resolve ECR URL #####
7772

78-
# Tries: explicit input ECR_CACHE_URL env var SSM parameter on EC2.
73+
# Tries: explicit input >> ECR_CACHE_URL env var >> SSM parameter on EC2.
7974
# Exports ECR_URL to GITHUB_ENV and sets output `available`.
8075

8176
- name: Resolve ECR URL
@@ -87,13 +82,13 @@ runs:
8782
ECR_URL="${INPUT_ECR_URL:-}"
8883
8984
if [ -z "${ECR_URL}" ]; then
90-
echo "🟢 ecr-url input not set, trying ECR_CACHE_URL env var..."
85+
echo "🔵 ecr-url input not set, trying ECR_CACHE_URL env var..."
9186
ECR_URL="${ECR_CACHE_URL:-}"
9287
[ -n "${ECR_URL}" ] && echo "🟢 Using ECR_CACHE_URL env var: ${ECR_URL}"
9388
fi
9489
9590
if [ -z "${ECR_URL}" ]; then
96-
echo "🟢 ECR_CACHE_URL env var not set, trying SSM..."
91+
echo "🔵 ECR_CACHE_URL env var not set, trying SSM..."
9792
IMDS_TOKEN=$(curl -sf -X PUT "http://169.254.169.254/latest/api/token" \
9893
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600") || true
9994
INSTANCE_ID=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
@@ -109,10 +104,10 @@ runs:
109104
if [ -n "${ECR_URL}" ]; then
110105
echo "🟢 Resolved ECR URL from SSM (/github-runner/${INSTANCE_ID}/ecr-cache-url): ${ECR_URL}"
111106
else
112-
echo "🟢 SSM parameter not found for instance ${INSTANCE_ID}"
107+
echo "🔵 SSM parameter not found for instance ${INSTANCE_ID}"
113108
fi
114109
else
115-
echo "🟢 Not running on EC2 or IMDS unavailable, skipping SSM lookup"
110+
echo "🔵 Not running on EC2 or IMDS unavailable, skipping SSM lookup"
116111
fi
117112
fi
118113
@@ -136,7 +131,7 @@ runs:
136131
AWS_REGION=$(echo "${REGISTRY}" | sed 's/.*\.dkr\.ecr\.\(.*\)\.amazonaws\.com/\1/')
137132
138133
if [ "${AWS_REGION}" = "${REGISTRY}" ]; then
139-
echo "🔴 Invalid ECR URL cannot extract AWS region: ${ECR_URL}"
134+
echo "🔴 Invalid ECR URL - cannot extract AWS region: ${ECR_URL}"
140135
echo "🔴 Expected format: <account-id>.dkr.ecr.<region>.amazonaws.com/<repo>"
141136
exit 1
142137
fi
@@ -148,39 +143,55 @@ runs:
148143
echo "ECR_IMAGE=${ECR_IMAGE}" >> "$GITHUB_ENV"
149144
echo "CACHE_IMAGE=${CACHE_IMAGE}" >> "$GITHUB_ENV"
150145
151-
echo "🟢 Logging into ECR registry..."
146+
echo "🔵 Logging into ECR registry..."
152147
aws ecr get-login-password --region "${AWS_REGION}" | \
153148
docker login --username AWS --password-stdin "${REGISTRY}"
154149
155-
##### 4: Pull exact image from ECR #####
150+
##### 4: Check if exact image exists in ECR #####
156151

157-
# If the exact per-commit image already exists in ECR, pull and tag it locally.
158-
# Sets output `hit: true` to skip all subsequent build/push steps.
152+
# Lightweight manifest check - fetches only the image manifest (~KB),
153+
# not the actual layers. If the exact per-commit image already exists
154+
# in ECR, sets output `hit: true` to skip all subsequent build/push steps.
159155

160-
- name: Pull exact image from ECR
156+
- name: Check exact image in ECR
161157
id: pull-exact
162158
if: steps.resolve-ecr.outputs.available == 'true'
163159
shell: bash
164160
run: |
165-
echo "🟢 Trying to pull commit-tagged ${ECR_IMAGE} from ECR..."
166-
if docker pull "${ECR_IMAGE}" 2>/dev/null; then
167-
docker tag "${ECR_IMAGE}" "${{ inputs.image-tag }}"
168-
echo "🟢 Commit-tagged image pulled, skipping build!"
161+
echo "🔵 Checking if commit-tagged image exists in ECR >> ${ECR_IMAGE}"
162+
if docker manifest inspect "${ECR_IMAGE}" >/dev/null 2>&1; then
163+
echo "🟢 Commit-tagged image found in ECR, skipping build!"
169164
echo "hit=true" >> "$GITHUB_OUTPUT"
170165
else
171166
echo "🟠 Image ${ECR_IMAGE} not found in ECR, will try deps-cache strategy..."
172167
fi
173168
174-
##### 5: Compute deps hash and try overlay #####
169+
# Pull the image when the manifest check succeeded but the image is not
170+
# available locally (test jobs need it for `docker run`). Build jobs
171+
# that only push to ECR will already have the image or don't need it.
172+
- name: Pull exact image from ECR
173+
if: steps.pull-exact.outputs.hit == 'true'
174+
shell: bash
175+
run: |
176+
if docker image inspect "${{ inputs.image-tag }}" >/dev/null 2>&1; then
177+
echo "🟢 Image already available locally, skipping pull"
178+
else
179+
echo "🔵 Pulling ${ECR_IMAGE} from ECR..."
180+
docker pull "${ECR_IMAGE}"
181+
docker tag "${ECR_IMAGE}" "${{ inputs.image-tag }}"
182+
echo "🟢 Image pulled and tagged as ${{ inputs.image-tag }}"
183+
fi
184+
185+
##### 5: Check deps cache #####
175186

176187
# Hashes installation-relevant files + the base image digest to produce a stable
177-
# deps-<hash> ECR tag. If it exists, builds only the thin final-COPY overlay
178-
# (seconds) instead of the full image (40-60 min).
188+
# deps-<hash> ECR tag. If the image exists in ECR, the build job succeeds
189+
# immediately and test jobs pull the deps image with a source volume mount.
179190

180191
# Edit DEPS_FILES or DEPS_MANIFEST_PATTERN when install
181192
# inputs change (new packages, new manifests, etc.).
182193

183-
- name: Compute deps hash and try overlay
194+
- name: Check deps cache
184195
id: deps-cache
185196
if: steps.resolve-ecr.outputs.available == 'true' && steps.pull-exact.outputs.hit != 'true'
186197
shell: bash
@@ -191,7 +202,6 @@ runs:
191202
"${{ inputs.dockerfile-path }}"
192203
isaaclab.sh
193204
environment.yml
194-
tools
195205
source/isaaclab/isaaclab/cli
196206
)
197207
# Manifest files matched repo-wide via git ls-files.
@@ -209,36 +219,26 @@ runs:
209219
BASE_IMAGE_UNIQ_ID="${{ inputs.isaacsim-base-image }}:${{ inputs.isaacsim-version }}"
210220
fi
211221
212-
echo "🟢 Base image ID: ${BASE_IMAGE_UNIQ_ID}"
222+
echo "🔵 Base image ID: ${BASE_IMAGE_UNIQ_ID}"
213223
214224
MANIFEST_FILES=$(git ls-files | grep -E "${DEPS_MANIFEST_PATTERN}" || true)
215225
FILE_HASH=$(git ls-files -s "${DEPS_FILES[@]}" ${MANIFEST_FILES} 2>/dev/null \
216226
| sha256sum | cut -c1-16)
217227
DEPS_HASH=$(printf '%s %s' "${FILE_HASH}" "${BASE_IMAGE_UNIQ_ID}" | sha256sum | cut -c1-16)
218228
DEPS_ECR_IMAGE="${ECR_URL}:deps-${DEPS_HASH}"
219-
echo "🟢 Deps hash: ${DEPS_HASH}"
220-
echo "🟢 Trying to pull deps image ${DEPS_ECR_IMAGE} from ECR..."
221-
222-
if docker pull "${DEPS_ECR_IMAGE}" 2>/dev/null; then
223-
echo "🟢 Deps cache HIT!!! Building thin overlay (final COPY only)..."
224-
OVERLAY_BUILDER="ci-builder-overlay-${{ github.run_id }}-${{ github.job }}"
225-
docker buildx create --use --driver docker-container --name "${OVERLAY_BUILDER}" \
226-
|| docker buildx use "${OVERLAY_BUILDER}"
227-
trap 'docker buildx rm "${OVERLAY_BUILDER}" || true' EXIT
228-
docker buildx build \
229-
--progress=plain \
230-
--platform linux/amd64 \
231-
-f "${{ inputs.overlay-dockerfile-path }}" \
232-
--build-arg "DEPS_IMAGE=${DEPS_ECR_IMAGE}" \
233-
--build-arg "ISAACLAB_PATH_ARG=/workspace/isaaclab" \
234-
-t "${{ inputs.image-tag }}" \
235-
--load \
236-
.
237-
echo "🟢 Overlay build complete!"
238-
docker tag "${{ inputs.image-tag }}" "${ECR_IMAGE}"
239-
echo "🟢 Pushing overlay image ${ECR_IMAGE} to ECR for future reuse..."
240-
docker push "${ECR_IMAGE}"
241-
echo "overlay-built=true" >> "$GITHUB_OUTPUT"
229+
echo "🔵 Deps hash: ${DEPS_HASH}"
230+
echo "🔵 Checking if deps image ${DEPS_ECR_IMAGE} exists in ECR..."
231+
232+
# Lightweight manifest check - fetches only the image manifest (~KB),
233+
# not the actual layers, so this completes in seconds.
234+
if docker manifest inspect "${DEPS_ECR_IMAGE}" >/dev/null 2>&1; then
235+
echo "🟢 Deps cache HIT!!! Image exists in ECR: ${DEPS_ECR_IMAGE}"
236+
# Create a commit-tagged alias pointing to the same manifest (registry-side,
237+
# no layer download). Test jobs will pull this tag normally.
238+
echo "🔵 Tagging as commit image ${ECR_IMAGE}..."
239+
docker buildx imagetools create -t "${ECR_IMAGE}" "${DEPS_ECR_IMAGE}"
240+
echo "🟢 Tagged ${ECR_IMAGE} >> ${DEPS_ECR_IMAGE}"
241+
echo "deps-cache-hit=true" >> "$GITHUB_OUTPUT"
242242
else
243243
echo "🟠 Deps cache MISS 😿😿😿 (${DEPS_HASH}). Will build now. 🐢🐢🐢"
244244
echo "DEPS_ECR_IMAGE=${DEPS_ECR_IMAGE}" >> "$GITHUB_ENV"
@@ -247,11 +247,11 @@ runs:
247247
248248
##### 6: Full build #####
249249

250-
# Runs when neither the exact image nor the deps-overlay was available.
250+
# Runs when neither the exact image nor the deps cache was available.
251251
# Uses ECR layer cache (--cache-from/--cache-to) when ECR is available.
252252

253253
- name: Full build
254-
if: steps.pull-exact.outputs.hit != 'true' && steps.deps-cache.outputs.overlay-built != 'true'
254+
if: steps.pull-exact.outputs.hit != 'true' && steps.deps-cache.outputs.deps-cache-hit != 'true'
255255
shell: bash
256256
run: |
257257
BUILD_ARGS=(
@@ -278,7 +278,7 @@ runs:
278278
|| docker buildx use "${BUILDER_NAME}"
279279
trap 'docker buildx rm "${BUILDER_NAME}" || true' EXIT
280280
281-
echo "🟢 Building ${{ inputs.image-tag }}..."
281+
echo "🔵 Building ${{ inputs.image-tag }}..."
282282
docker buildx build --load "${BUILD_ARGS[@]}" .
283283
284284
##### 7: Push to ECR #####
@@ -290,10 +290,10 @@ runs:
290290
if: >
291291
steps.resolve-ecr.outputs.available == 'true' &&
292292
steps.pull-exact.outputs.hit != 'true' &&
293-
steps.deps-cache.outputs.overlay-built != 'true'
293+
steps.deps-cache.outputs.deps-cache-hit != 'true'
294294
shell: bash
295295
run: |
296-
echo "🟢 Pushing ${ECR_IMAGE} to ECR..."
296+
echo "🔵 Pushing ${ECR_IMAGE} to ECR..."
297297
docker push "${ECR_IMAGE}"
298298
echo "🟢 Pushed ${ECR_IMAGE}"
299299
@@ -306,7 +306,7 @@ runs:
306306
if: env.PUSH_DEPS_IMAGE == 'true'
307307
shell: bash
308308
run: |
309-
echo "🟢 Pushing deps image for future cache hits: ${DEPS_ECR_IMAGE}"
309+
echo "🔵 Pushing deps image for future cache hits: ${DEPS_ECR_IMAGE}"
310310
docker tag "${{ inputs.image-tag }}" "${DEPS_ECR_IMAGE}"
311311
docker push "${DEPS_ECR_IMAGE}"
312312

0 commit comments

Comments
 (0)