diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 56330d6..f9e39ac 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -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 }} diff --git a/build-stage.sh b/build-stage.sh index f78ecc0..fb2a6fd 100755 --- a/build-stage.sh +++ b/build-stage.sh @@ -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}" \ .