name: Build and Push agentchat Image on: push: branches: [main] jobs: quality: runs-on: ubuntu-latest steps: - name: Checkout repository # Plain git instead of actions/checkout: rootless podman on cirunner-vps # rejects symlinks inside cached actions ("path escapes from parent"). env: GITEA_TOKEN: ${{ gitea.token }} run: | git init -q . git remote add origin "${{ gitea.server_url }}/${{ gitea.repository }}.git" auth="$(printf 'x-access-token:%s' "$GITEA_TOKEN" | base64 -w0)" git -c http.extraHeader="Authorization: basic $auth" \ fetch -q --depth 1 origin "${{ gitea.sha }}" git checkout -q FETCH_HEAD - name: Set up Bun # Install script instead of oven-sh/setup-bun (same podman symlink issue). run: | curl -fsSL https://bun.sh/install | bash -s "bun-v1.3.14" >/dev/null echo "$HOME/.bun/bin" >> "$GITHUB_PATH" - run: bun install --frozen-lockfile - name: Typecheck and test run: | bun run typecheck bun test build-image: needs: [quality] runs-on: ubuntu-latest steps: - name: Checkout repository # Plain git instead of actions/checkout: rootless podman on cirunner-vps # rejects symlinks inside cached actions ("path escapes from parent"). env: GITEA_TOKEN: ${{ gitea.token }} run: | git init -q . git remote add origin "${{ gitea.server_url }}/${{ gitea.repository }}.git" auth="$(printf 'x-access-token:%s' "$GITEA_TOKEN" | base64 -w0)" git -c http.extraHeader="Authorization: basic $auth" \ fetch -q --depth 1 origin "${{ gitea.sha }}" git checkout -q FETCH_HEAD - name: Log in to container registry run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.gbrown.org -u "${{ secrets.REGISTRY_USER }}" --password-stdin # One build-and-push step, fully-qualified tags, --push from the builder. # This is the only form that works across all the runners: unqualified # names resolve to docker.io/library/* on podman-backed daemons, and # buildx docker-container drivers keep plain builds in the build cache # where a separate push step can't see them. - name: Build and push image run: docker build --push -f docker/Dockerfile -t git.gbrown.org/gib/agentchat:${{ gitea.sha }} -t git.gbrown.org/gib/agentchat:latest . # Watchtower was retired 2026-08-17: it recreated containers outside their # podman-compose pod, which took gitea down for three days while reporting # success. Deploys now SSH to the VPS and restart the systemd UNIT, so # podman-compose rebuilds the project properly (pod, networks, ports). # # The key is pinned to a forced command that accepts only a service name, so # it cannot open a shell or reach anything else. 192.168.2.2 is the VPS over # WireGuard: reachable from every runner, never the public internet. # # Non-fatal on purpose: the image is already pushed, and podman-update.timer # sweeps at midnight, so a trigger hiccup delays the deploy by hours rather # than failing a build that otherwise succeeded. - name: Trigger immediate deploy run: | echo "${{ secrets.DEPLOY_SSH_KEY }}" > "$HOME/.deploy_key" chmod 600 "$HOME/.deploy_key" ssh -i "$HOME/.deploy_key" \ -o BatchMode=yes \ -o StrictHostKeyChecking=accept-new \ -o ConnectTimeout=15 \ gib@192.168.2.2 agentchat \ || echo "::warning::deploy trigger failed; nightly sweep will deploy instead" rm -f "$HOME/.deploy_key"