ci: build only the images whose source files changed
CI/CD / build-and-push (push) Successful in 7s

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 <noreply@anthropic.com>
This commit is contained in:
chemavx
2026-06-12 08:07:49 +00:00
co-authored by Claude Fable 5
parent 43d9577fb2
commit 4928a3c1e4
+89 -10
View File
@@ -19,15 +19,64 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
ssl-verify: false ssl-verify: false
# Full history: needed to diff against github.event.before
fetch-depth: 0
- name: Set image tag - name: Set image tag
id: tag id: tag
run: echo "TAG=${GITHUB_SHA::8}" >> $GITHUB_OUTPUT 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 - 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 run: echo "${{ secrets.CI_TOKEN }}" | docker login gitea.gitea.svc.cluster.local:3000 -u chemavx --password-stdin
- name: Create buildx builder - name: Create buildx builder
if: steps.changes.outputs.build_any == 'true'
run: | run: |
cat > /tmp/buildkitd.toml << 'EOF' cat > /tmp/buildkitd.toml << 'EOF'
[registry."registry-cache.registry-cache.svc.cluster.local:5000"] [registry."registry-cache.registry-cache.svc.cluster.local:5000"]
@@ -50,6 +99,7 @@ jobs:
docker buildx inspect --bootstrap docker buildx inspect --bootstrap
- name: Build and push bot image - name: Build and push bot image
if: steps.changes.outputs.build_bot == 'true'
run: | run: |
TAG=${{ steps.tag.outputs.TAG }} TAG=${{ steps.tag.outputs.TAG }}
docker buildx build \ docker buildx build \
@@ -61,6 +111,7 @@ jobs:
-f Dockerfile . -f Dockerfile .
- name: Build and push API image - name: Build and push API image
if: steps.changes.outputs.build_api == 'true'
run: | run: |
TAG=${{ steps.tag.outputs.TAG }} TAG=${{ steps.tag.outputs.TAG }}
docker buildx build \ docker buildx build \
@@ -72,6 +123,7 @@ jobs:
-f Dockerfile.api . -f Dockerfile.api .
- name: Build and push dashboard image - name: Build and push dashboard image
if: steps.changes.outputs.build_dashboard == 'true'
run: | run: |
TAG=${{ steps.tag.outputs.TAG }} TAG=${{ steps.tag.outputs.TAG }}
docker buildx build \ docker buildx build \
@@ -84,6 +136,7 @@ jobs:
dashboard dashboard
- name: Verify images in registry - name: Verify images in registry
if: steps.changes.outputs.build_any == 'true'
run: | run: |
TAG=${{ steps.tag.outputs.TAG }} TAG=${{ steps.tag.outputs.TAG }}
check_image() { check_image() {
@@ -98,11 +151,18 @@ jobs:
fi fi
echo "OK: chemavx/${image}:${TAG} verified in registry" echo "OK: chemavx/${image}:${TAG} verified in registry"
} }
check_image polymarket-bot if [ "${{ steps.changes.outputs.build_bot }}" = "true" ]; then
check_image polymarket-bot-api check_image polymarket-bot
check_image polymarket-bot-dashboard 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 - name: Update k8s manifests
if: steps.changes.outputs.build_any == 'true'
run: | run: |
pip3 install pyyaml -q pip3 install pyyaml -q
@@ -114,12 +174,20 @@ jobs:
git clone ${{ env.K8S_MANIFESTS_REPO }} /tmp/k8s-manifests git clone ${{ env.K8S_MANIFESTS_REPO }} /tmp/k8s-manifests
cd /tmp/k8s-manifests cd /tmp/k8s-manifests
sed -i "s|image: .*polymarket-bot[^-].*|image: git.chemavx.xyz/chemavx/polymarket-bot:${TAG}|g" \ # Only bump the tag of images that were actually rebuilt: the others
polymarket-bot/deployment-bot.yaml # keep their current (still existing) tag in the registry.
sed -i "s|image: .*polymarket-bot-api.*|image: git.chemavx.xyz/chemavx/polymarket-bot-api:${TAG}|g" \ if [ "${{ steps.changes.outputs.build_bot }}" = "true" ]; then
polymarket-bot/deployment-api.yaml sed -i "s|image: .*polymarket-bot[^-].*|image: git.chemavx.xyz/chemavx/polymarket-bot:${TAG}|g" \
sed -i "s|image: .*polymarket-bot-dashboard.*|image: git.chemavx.xyz/chemavx/polymarket-bot-dashboard:${TAG}|g" \ polymarket-bot/deployment-bot.yaml
polymarket-bot/deployment-dashboard.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" \ sed -i "s|imagePullPolicy: Never|imagePullPolicy: Always|g" \
polymarket-bot/deployment-bot.yaml \ polymarket-bot/deployment-bot.yaml \
polymarket-bot/deployment-api.yaml \ polymarket-bot/deployment-api.yaml \
@@ -154,10 +222,21 @@ jobs:
TAG: ${{ steps.tag.outputs.TAG }} TAG: ${{ steps.tag.outputs.TAG }}
JOB_STATUS: ${{ job.status }} JOB_STATUS: ${{ job.status }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} 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: | run: |
TAG="${TAG:-${GITHUB_SHA:0:8}}" 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 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 else
MSG="❌ Deploy polymarket-bot:${TAG} fallido (status: ${JOB_STATUS})" MSG="❌ Deploy polymarket-bot:${TAG} fallido (status: ${JOB_STATUS})"
fi fi