From 4928a3c1e44cac0ad311debcb968557ecd24b879 Mon Sep 17 00:00:00 2001 From: chemavx Date: Fri, 12 Jun 2026 08:07:49 +0000 Subject: [PATCH] ci: build only the images whose source files changed Path-based build selection diffed against github.event.before: - bot/, api/, requirements.txt -> bot + api images (both COPY the same python sources; only the CMD differs) - Dockerfile -> bot only; Dockerfile.api -> api only - dashboard/ -> dashboard only - .gitea/workflows/ci.yml, first push or force push -> all (safe fallback) - anything else (tests/, docs) -> no builds, no manifest update The k8s-manifests sed only bumps tags of rebuilt images, so unchanged deployments keep their current tag and don't restart. Registry login, buildx, verification and manifest update are all skipped when nothing needs building. Telegram message now lists what was built. Co-Authored-By: Claude Fable 5 --- .gitea/workflows/ci.yml | 99 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 99bf420..566101f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -19,15 +19,64 @@ jobs: uses: actions/checkout@v4 with: ssl-verify: false + # Full history: needed to diff against github.event.before + fetch-depth: 0 - name: Set image tag id: tag run: echo "TAG=${GITHUB_SHA::8}" >> $GITHUB_OUTPUT + - name: Detect changed components + id: changes + run: | + BEFORE="${{ github.event.before }}" + CHANGED="" + case "$BEFORE" in + ""|0000000000000000000000000000000000000000) + echo "First push or unknown base — building all images" + CHANGED="__all__" + ;; + *) + if git cat-file -e "$BEFORE" 2>/dev/null; then + CHANGED=$(git diff --name-only "$BEFORE" "$GITHUB_SHA") + else + echo "Base commit $BEFORE not in history (force push?) — building all images" + CHANGED="__all__" + fi + ;; + esac + echo "Changed files:" + echo "$CHANGED" + + if [ "$CHANGED" = "__all__" ]; then + BOT=true; API=true; DASH=true + else + BOT=false; API=false; DASH=false + matches() { echo "$CHANGED" | grep -qE "$1"; } + # The workflow itself affects every image build + if matches '^\.gitea/workflows/ci\.yml$'; then BOT=true; API=true; DASH=true; fi + # bot and api images both COPY bot/, api/ and requirements.txt + if matches '^(bot/|api/|requirements\.txt$)'; then BOT=true; API=true; fi + if matches '^Dockerfile$'; then BOT=true; fi + if matches '^Dockerfile\.api$'; then API=true; fi + # dashboard image builds from the dashboard/ context only + if matches '^dashboard/'; then DASH=true; fi + fi + + ANY=false + if [ "$BOT" = "true" ] || [ "$API" = "true" ] || [ "$DASH" = "true" ]; then ANY=true; fi + echo "build_bot=$BOT" >> $GITHUB_OUTPUT + echo "build_api=$API" >> $GITHUB_OUTPUT + echo "build_dashboard=$DASH" >> $GITHUB_OUTPUT + echo "build_any=$ANY" >> $GITHUB_OUTPUT + echo "Will build: bot=$BOT api=$API dashboard=$DASH" + - name: Log in to registry + if: steps.changes.outputs.build_any == 'true' run: echo "${{ secrets.CI_TOKEN }}" | docker login gitea.gitea.svc.cluster.local:3000 -u chemavx --password-stdin - name: Create buildx builder + if: steps.changes.outputs.build_any == 'true' run: | cat > /tmp/buildkitd.toml << 'EOF' [registry."registry-cache.registry-cache.svc.cluster.local:5000"] @@ -50,6 +99,7 @@ jobs: docker buildx inspect --bootstrap - name: Build and push bot image + if: steps.changes.outputs.build_bot == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} docker buildx build \ @@ -61,6 +111,7 @@ jobs: -f Dockerfile . - name: Build and push API image + if: steps.changes.outputs.build_api == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} docker buildx build \ @@ -72,6 +123,7 @@ jobs: -f Dockerfile.api . - name: Build and push dashboard image + if: steps.changes.outputs.build_dashboard == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} docker buildx build \ @@ -84,6 +136,7 @@ jobs: dashboard - name: Verify images in registry + if: steps.changes.outputs.build_any == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} check_image() { @@ -98,11 +151,18 @@ jobs: fi echo "OK: chemavx/${image}:${TAG} verified in registry" } - check_image polymarket-bot - check_image polymarket-bot-api - check_image polymarket-bot-dashboard + if [ "${{ steps.changes.outputs.build_bot }}" = "true" ]; then + check_image polymarket-bot + fi + if [ "${{ steps.changes.outputs.build_api }}" = "true" ]; then + check_image polymarket-bot-api + fi + if [ "${{ steps.changes.outputs.build_dashboard }}" = "true" ]; then + check_image polymarket-bot-dashboard + fi - name: Update k8s manifests + if: steps.changes.outputs.build_any == 'true' run: | pip3 install pyyaml -q @@ -114,12 +174,20 @@ jobs: git clone ${{ env.K8S_MANIFESTS_REPO }} /tmp/k8s-manifests cd /tmp/k8s-manifests - sed -i "s|image: .*polymarket-bot[^-].*|image: git.chemavx.xyz/chemavx/polymarket-bot:${TAG}|g" \ - polymarket-bot/deployment-bot.yaml - sed -i "s|image: .*polymarket-bot-api.*|image: git.chemavx.xyz/chemavx/polymarket-bot-api:${TAG}|g" \ - polymarket-bot/deployment-api.yaml - sed -i "s|image: .*polymarket-bot-dashboard.*|image: git.chemavx.xyz/chemavx/polymarket-bot-dashboard:${TAG}|g" \ - polymarket-bot/deployment-dashboard.yaml + # Only bump the tag of images that were actually rebuilt: the others + # keep their current (still existing) tag in the registry. + if [ "${{ steps.changes.outputs.build_bot }}" = "true" ]; then + sed -i "s|image: .*polymarket-bot[^-].*|image: git.chemavx.xyz/chemavx/polymarket-bot:${TAG}|g" \ + polymarket-bot/deployment-bot.yaml + fi + if [ "${{ steps.changes.outputs.build_api }}" = "true" ]; then + sed -i "s|image: .*polymarket-bot-api.*|image: git.chemavx.xyz/chemavx/polymarket-bot-api:${TAG}|g" \ + polymarket-bot/deployment-api.yaml + fi + if [ "${{ steps.changes.outputs.build_dashboard }}" = "true" ]; then + sed -i "s|image: .*polymarket-bot-dashboard.*|image: git.chemavx.xyz/chemavx/polymarket-bot-dashboard:${TAG}|g" \ + polymarket-bot/deployment-dashboard.yaml + fi sed -i "s|imagePullPolicy: Never|imagePullPolicy: Always|g" \ polymarket-bot/deployment-bot.yaml \ polymarket-bot/deployment-api.yaml \ @@ -154,10 +222,21 @@ jobs: TAG: ${{ steps.tag.outputs.TAG }} JOB_STATUS: ${{ job.status }} TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} + BUILD_BOT: ${{ steps.changes.outputs.build_bot }} + BUILD_API: ${{ steps.changes.outputs.build_api }} + BUILD_DASH: ${{ steps.changes.outputs.build_dashboard }} run: | TAG="${TAG:-${GITHUB_SHA:0:8}}" + BUILT="" + [ "$BUILD_BOT" = "true" ] && BUILT="${BUILT}bot " + [ "$BUILD_API" = "true" ] && BUILT="${BUILT}api " + [ "$BUILD_DASH" = "true" ] && BUILT="${BUILT}dashboard " if [ "$JOB_STATUS" = "success" ]; then - MSG="✅ Deploy polymarket-bot:${TAG} completado" + if [ -n "$BUILT" ]; then + MSG="✅ Deploy polymarket-bot:${TAG} completado (imágenes: ${BUILT% })" + else + MSG="✅ CI polymarket-bot:${TAG} OK — sin cambios de imagen, nada que desplegar" + fi else MSG="❌ Deploy polymarket-bot:${TAG} fallido (status: ${JOB_STATUS})" fi