name: Promote to Production on: push: tags: - 'v*' jobs: promote: name: Deploy to Production runs-on: ubuntu-latest steps: - name: Checkout code at tag uses: actions/checkout@v4 - name: Install kubectl run: | curl -sLO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl - name: Get image info id: image run: | # Use the commit SHA instead of "latest" to avoid a race condition: # The tag event can fire before the staging build (deploy.yml) finishes # pushing the new "latest" image. By referencing the exact SHA that # deploy.yml tags images with (${{ github.sha }}), we ensure we # promote the correct build — and wait for it if it's still running. echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - name: Login to Forgejo Registry uses: docker/login-action@v3 with: registry: git.cloonar.com username: openclawd password: ${{ secrets.REGISTRY_TOKEN }} - name: Wait for staging image and retag for production run: | SHA_IMAGE="git.cloonar.com/openclawd/docfast:${{ steps.image.outputs.sha }}" PROD_IMAGE="git.cloonar.com/openclawd/docfast:${{ steps.image.outputs.tag }}" # Wait for the SHA-tagged image (built by staging) to be available for i in $(seq 1 20); do echo "Attempt $i/20: pulling $SHA_IMAGE ..." if docker pull --platform linux/arm64 "$SHA_IMAGE" 2>/dev/null; then echo "✅ Image found!" break fi if [ "$i" -eq 20 ]; then echo "❌ Image not available after 10 minutes. Aborting." exit 1 fi echo "Image not ready yet, waiting 30s..." sleep 30 done docker tag "$SHA_IMAGE" "$PROD_IMAGE" docker push "$PROD_IMAGE" - name: Deploy to Production run: | echo "${{ secrets.KUBECONFIG }}" | base64 -d > /tmp/kubeconfig.yaml ./kubectl set image deployment/docfast \ docfast=git.cloonar.com/openclawd/docfast:${{ steps.image.outputs.tag }} \ -n docfast --kubeconfig=/tmp/kubeconfig.yaml ./kubectl rollout status deployment/docfast \ -n docfast --kubeconfig=/tmp/kubeconfig.yaml --timeout=180s echo "✅ Production deploy complete! Version: ${{ steps.image.outputs.tag }}"