feat: Add node-specific tools for token optimization #668
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .github/workflows/docker-build.yml | |
| name: Build and Push Docker Images | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - '**.md' | |
| - '**.txt' | |
| - 'docs/**' | |
| - 'examples/**' | |
| - '.github/FUNDING.yml' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - '.github/pull_request_template.md' | |
| - '.gitignore' | |
| - 'LICENSE*' | |
| - 'ATTRIBUTION.md' | |
| - 'SECURITY.md' | |
| - 'CODE_OF_CONDUCT.md' | |
| pull_request: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - '**.md' | |
| - '**.txt' | |
| - 'docs/**' | |
| - 'examples/**' | |
| - '.github/FUNDING.yml' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - '.github/pull_request_template.md' | |
| - '.gitignore' | |
| - 'LICENSE*' | |
| - 'ATTRIBUTION.md' | |
| - 'SECURITY.md' | |
| - 'CODE_OF_CONDUCT.md' | |
| workflow_dispatch: | |
| # Prevent concurrent Docker pushes across all workflows (shared with release.yml) | |
| # This ensures docker-build.yml and release.yml never push to 'latest' simultaneously | |
| concurrency: | |
| group: docker-push-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build: | |
| name: Build Docker Image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| id: buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=sha,format=short | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| no-cache: false | |
| platforms: linux/amd64,linux/arm64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| - name: Verify multi-arch manifest for latest tag | |
| if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' | |
| run: | | |
| echo "Verifying multi-arch manifest for latest tag..." | |
| # Retry with exponential backoff (registry propagation can take time) | |
| MAX_ATTEMPTS=5 | |
| ATTEMPT=1 | |
| WAIT_TIME=2 | |
| while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do | |
| echo "Attempt $ATTEMPT of $MAX_ATTEMPTS..." | |
| MANIFEST=$(docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest 2>&1 || true) | |
| # Check for both platforms | |
| if echo "$MANIFEST" | grep -q "linux/amd64" && echo "$MANIFEST" | grep -q "linux/arm64"; then | |
| echo "✅ Multi-arch manifest verified: both amd64 and arm64 present" | |
| echo "$MANIFEST" | |
| exit 0 | |
| fi | |
| if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then | |
| echo "⏳ Registry still propagating, waiting ${WAIT_TIME}s before retry..." | |
| sleep $WAIT_TIME | |
| WAIT_TIME=$((WAIT_TIME * 2)) # Exponential backoff: 2s, 4s, 8s, 16s | |
| fi | |
| ATTEMPT=$((ATTEMPT + 1)) | |
| done | |
| echo "❌ ERROR: Multi-arch manifest incomplete after $MAX_ATTEMPTS attempts!" | |
| echo "$MANIFEST" | |
| exit 1 | |
| build-railway: | |
| name: Build Railway Docker Image | |
| runs-on: ubuntu-latest | |
| needs: build | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| id: buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for Railway | |
| id: meta-railway | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-railway | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=sha,format=short | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push Railway Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.railway | |
| no-cache: false | |
| platforms: linux/amd64 | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta-railway.outputs.tags }} | |
| labels: ${{ steps.meta-railway.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: false | |
| # Nginx build commented out until Phase 2 | |
| # build-nginx: | |
| # name: Build nginx-enhanced Docker Image | |
| # runs-on: ubuntu-latest | |
| # permissions: | |
| # contents: read | |
| # packages: write |