name: CI/CD on: push: branches: - main env: REGISTRY: gitea.gitea.svc.cluster.local:3000 K8S_MANIFESTS_REPO: http://chemavx:${{ secrets.CI_TOKEN }}@gitea.gitea.svc.cluster.local:3000/chemavx/k8s-manifests.git GIT_SSL_NO_VERIFY: "true" TELEGRAM_CHAT_ID: "5138407666" jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Checkout 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"] http = true insecure = true [registry."gitea.gitea.svc.cluster.local:3000"] http = true insecure = true [registry."docker.io"] mirrors = ["registry-cache.registry-cache.svc.cluster.local:5000"] EOF docker buildx create \ --name ci-builder \ --driver docker-container \ --driver-opt network=host \ --config /tmp/buildkitd.toml \ --use 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 \ --builder ci-builder \ --cache-from type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot:buildcache \ --cache-to type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot:buildcache,mode=max \ -t gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot:${TAG} \ --push \ -f Dockerfile . - name: Build and push API image if: steps.changes.outputs.build_api == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} docker buildx build \ --builder ci-builder \ --cache-from type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-api:buildcache \ --cache-to type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-api:buildcache,mode=max \ -t gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-api:${TAG} \ --push \ -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 \ --builder ci-builder \ --cache-from type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-dashboard:buildcache \ --cache-to type=registry,ref=gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-dashboard:buildcache,mode=max \ -t gitea.gitea.svc.cluster.local:3000/chemavx/polymarket-bot-dashboard:${TAG} \ --push \ -f dashboard/Dockerfile \ dashboard - name: Verify images in registry if: steps.changes.outputs.build_any == 'true' run: | TAG=${{ steps.tag.outputs.TAG }} check_image() { local image=$1 HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ -u "chemavx:${{ secrets.CI_TOKEN }}" \ -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \ "http://gitea.gitea.svc.cluster.local:3000/v2/chemavx/${image}/manifests/${TAG}") if [ "$HTTP_CODE" != "200" ]; then echo "ERROR: chemavx/${image}:${TAG} not found in registry (HTTP $HTTP_CODE)" exit 1 fi echo "OK: chemavx/${image}:${TAG} verified in registry" } 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 TAG=${{ steps.tag.outputs.TAG }} git config --global user.email "ci@git.chemavx.xyz" git config --global user.name "Gitea CI" git clone ${{ env.K8S_MANIFESTS_REPO }} /tmp/k8s-manifests cd /tmp/k8s-manifests # 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 \ polymarket-bot/deployment-dashboard.yaml python3 -c " import yaml, sys files = [ 'polymarket-bot/deployment-bot.yaml', 'polymarket-bot/deployment-api.yaml', 'polymarket-bot/deployment-dashboard.yaml', ] errors = [] for f in files: try: yaml.safe_load(open(f)) print('OK: ' + f) except yaml.YAMLError as e: errors.append('FAIL: ' + f + ': ' + str(e)) if errors: for e in errors: print(e, file=sys.stderr) sys.exit(1) " git add polymarket-bot/deployment-bot.yaml polymarket-bot/deployment-api.yaml polymarket-bot/deployment-dashboard.yaml git diff --cached --quiet || git commit -m "ci: update polymarket-bot images to ${TAG} [skip ci]" git push - name: Notify Telegram if: always() env: 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 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 curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \ -d "chat_id=${{ env.TELEGRAM_CHAT_ID }}" \ --data-urlencode "text=${MSG}"