ci: add asset-only fast path (<5min for PNG changes)
Deploy marketing to Cloud Run / deploy (push) Has been cancelled
Deploy marketing to Cloud Run / deploy (push) Has been cancelled
- Detect asset-only changes (src/assets/, src/shares/, static HTML, llms.txt) and skip El compilation, C build deps, and Docker full build entirely - Fast path pulls :latest as base and rebuilds only the assets layer - Gate clone-el, install-C-deps, elc-cache, build-elc, build-image, push-image behind asset_only != 'true'; deploy steps run unconditionally - Switch build-stage.sh from registry cache driver (requires docker-container buildx driver) to inline cache backed by :latest — compatible with default docker driver on the runner
This commit is contained in:
@@ -31,7 +31,24 @@ jobs:
|
||||
- name: Checkout neuron-web
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Detect change type
|
||||
id: changetype
|
||||
run: |
|
||||
set -euo pipefail
|
||||
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD 2>/dev/null || echo "unknown")
|
||||
echo "Changed files:"
|
||||
echo "$CHANGED"
|
||||
# Asset-only: only src/assets/, src/shares/, src/index.html, src/about.html, src/terms.html, src/enterprise-terms.html, src/llms.txt
|
||||
NON_ASSET=$(echo "$CHANGED" | grep -v '^src/assets/' | grep -v '^src/shares/' | grep -v '^src/index\.html' | grep -v '^src/about\.html' | grep -v '^src/terms\.html' | grep -v '^src/enterprise-terms\.html' | grep -v '^src/llms\.txt' | grep -v '^$' || true)
|
||||
if [ -z "$NON_ASSET" ] && [ "$CHANGED" != "unknown" ]; then
|
||||
echo "asset_only=true" >> "$GITHUB_OUTPUT"
|
||||
echo "=> Asset-only change detected, will use fast path"
|
||||
else
|
||||
echo "asset_only=false" >> "$GITHUB_OUTPUT"
|
||||
echo "=> Full build required"
|
||||
fi
|
||||
|
||||
# foundation/el contains the elc compiler that build-stage.sh shells out
|
||||
# to. We clone el directly with git rather than a second
|
||||
@@ -41,6 +58,7 @@ jobs:
|
||||
# workspace so the path build-stage.sh expects (../../foundation/el)
|
||||
# resolves correctly.
|
||||
- name: Clone el (foundation/el — provides the elc compiler)
|
||||
if: steps.changetype.outputs.asset_only != 'true'
|
||||
env:
|
||||
CHECKOUT_TOKEN: ${{ secrets.CHECKOUT_TOKEN }}
|
||||
run: |
|
||||
@@ -75,11 +93,13 @@ jobs:
|
||||
run: gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
|
||||
|
||||
- name: Install C build deps for elc
|
||||
if: steps.changetype.outputs.asset_only != 'true'
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y --no-install-recommends build-essential libcurl4-openssl-dev libssl-dev
|
||||
|
||||
- name: Restore elc binary from GCS cache
|
||||
if: steps.changetype.outputs.asset_only != 'true'
|
||||
id: elc-cache
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -99,7 +119,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Build elc (cache miss only)
|
||||
if: steps.elc-cache.outputs.cache_hit != 'true'
|
||||
if: steps.changetype.outputs.asset_only != 'true' && steps.elc-cache.outputs.cache_hit != 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# The committed dist/platform/elc is arm64 from Will's mac. We
|
||||
@@ -127,6 +147,7 @@ jobs:
|
||||
echo "Will build and push: ${IMAGE}"
|
||||
|
||||
- name: Build image (build-stage.sh)
|
||||
if: steps.changetype.outputs.asset_only != 'true'
|
||||
env:
|
||||
EXTRACT_JS: '1'
|
||||
run: |
|
||||
@@ -135,10 +156,38 @@ jobs:
|
||||
docker tag "marketing:${{ steps.tag.outputs.tag }}" "us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:latest"
|
||||
|
||||
- name: Push image
|
||||
if: steps.changetype.outputs.asset_only != 'true'
|
||||
run: |
|
||||
docker push "${{ steps.tag.outputs.image }}"
|
||||
docker push "us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:latest"
|
||||
|
||||
- name: Asset-only fast build
|
||||
if: steps.changetype.outputs.asset_only == 'true'
|
||||
env:
|
||||
IMAGE: ${{ steps.tag.outputs.image }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Pull existing image as base - no El compilation needed
|
||||
LATEST="us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:latest"
|
||||
docker pull "$LATEST"
|
||||
# Build tiny patch image: just replace the assets layer
|
||||
cat > /tmp/Dockerfile.assets <<'EOF'
|
||||
ARG BASE
|
||||
FROM ${BASE}
|
||||
COPY src/assets /srv/landing/assets
|
||||
COPY src/shares /srv/landing/shares
|
||||
EOF
|
||||
docker buildx build --platform linux/amd64 --load \
|
||||
--build-arg BASE="$LATEST" \
|
||||
-f /tmp/Dockerfile.assets \
|
||||
-t "marketing:${{ steps.tag.outputs.tag }}" \
|
||||
-t "$IMAGE" \
|
||||
-t "${LATEST%:*}:latest" \
|
||||
.
|
||||
docker push "$IMAGE"
|
||||
docker push "${LATEST%:*}:latest"
|
||||
echo "Fast asset build complete"
|
||||
|
||||
- name: Deploy to all marketing prod regions in parallel
|
||||
env:
|
||||
IMAGE: ${{ steps.tag.outputs.image }}
|
||||
|
||||
+2
-2
@@ -89,8 +89,8 @@ sed "${SED_INPLACE[@]}" \
|
||||
|
||||
echo "==> Building Docker image marketing:${TAG} for linux/amd64"
|
||||
docker buildx build --platform linux/amd64 --load \
|
||||
--cache-from type=registry,ref=us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:cache \
|
||||
--cache-to type=registry,ref=us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:cache,mode=max \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--cache-from us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:latest \
|
||||
-f Dockerfile.stage \
|
||||
-t "marketing:${TAG}" \
|
||||
.
|
||||
|
||||
Reference in New Issue
Block a user