fix: auto-install node-llama-cpp for local embeddings (memory_search) #139
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
| name: Build and Push Docker Containers | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| jobs: | |
| # ─── Discover Flavors ───────────────────────────────────────────────────────── | |
| # Dynamically builds the matrix from templates/flavors/ directory. | |
| # Each subdirectory name becomes a flavor entry. | |
| # NOTE: Flavor directory names must exactly match the intended image name | |
| # (e.g. templates/flavors/morpheus-agent/ → ghcr.io/everclaw/morpheus-agent). | |
| # Adding a new flavor is zero-config: just create the directory and push. | |
| discover-flavors: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build flavor matrix | |
| id: set-matrix | |
| run: | | |
| # Discover all flavor directories | |
| FLAVORS=$(ls -d templates/flavors/*/ 2>/dev/null | xargs -I{} basename {} | jq -R . | jq -s .) | |
| # Build matrix: generic (no flavor) + all discovered flavors | |
| # Use -c (compact) to keep JSON on a single line for GITHUB_OUTPUT | |
| MATRIX=$(echo "$FLAVORS" | jq -c '[{"flavor": "", "image_name": "everclaw/everclaw"}, (.[] | {"flavor": ., "image_name": ("everclaw/" + .)})]') | |
| echo "matrix={\"include\":$MATRIX}" >> $GITHUB_OUTPUT | |
| echo "Discovered $(echo "$FLAVORS" | jq 'length') flavors + 1 generic" | |
| # ─── Build & Push ────────────────────────────────────────────────────────────── | |
| # Builds one Docker image per matrix entry (generic + all flavors). | |
| # All images share 99%+ of layers — only the final flavor overlay differs. | |
| # Each flavor gets both :latest and :CalVer tags. | |
| build-and-push: | |
| needs: discover-flavors | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.discover-flavors.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Get version from package.json | |
| id: version | |
| run: echo "VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT | |
| - name: Get OpenClaw version from Dockerfile | |
| id: openclaw_version | |
| run: echo "OPENCLAW_VERSION=$(grep -m1 'ARG OPENCLAW_VERSION=' Dockerfile | sed 's/ARG OPENCLAW_VERSION=//')" >> $GITHUB_OUTPUT | |
| - name: Set up QEMU (for multi-arch) | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to 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 Docker | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ matrix.image_name }} | |
| tags: | | |
| # On push to main: tag as "latest" and version from package.json | |
| type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} | |
| type=raw,value=${{ steps.version.outputs.VERSION }},enable=${{ github.ref == 'refs/heads/main' }} | |
| # On tag push: tag as "latest", version from package.json, and the git tag | |
| type=match,pattern=v(.*),group=1,enable=${{ startsWith(github.ref, 'refs/tags/v') }} | |
| type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} | |
| type=raw,value=${{ steps.version.outputs.VERSION }},enable=${{ startsWith(github.ref, 'refs/tags/v') }} | |
| # PR builds: tag with PR number (not pushed) | |
| type=ref,event=pr | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| build-args: | | |
| EVERCLAW_VERSION=${{ steps.version.outputs.VERSION }} | |
| OPENCLAW_VERSION=${{ steps.openclaw_version.outputs.OPENCLAW_VERSION }} | |
| FLAVOR=${{ matrix.flavor }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| no-cache-filters: openclaw-builder | |
| platforms: linux/amd64,linux/arm64 | |
| - name: Output image info | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| FLAVOR="${{ matrix.flavor }}" | |
| LABEL="${FLAVOR:-generic}" | |
| echo "## Docker Image Published 🐳 ($LABEL)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Flavor:** $LABEL" >> $GITHUB_STEP_SUMMARY | |
| echo "**Version:** ${{ steps.version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Tags:**" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Pull:**" >> $GITHUB_STEP_SUMMARY | |
| echo '```bash' >> $GITHUB_STEP_SUMMARY | |
| echo "docker pull ${{ env.REGISTRY }}/${{ matrix.image_name }}:latest" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY |