Skip to content

feat(text-embedding): add text embedding function with Ollama #126

feat(text-embedding): add text embedding function with Ollama

feat(text-embedding): add text embedding function with Ollama #126

name: CI Test K8s
on:
pull_request:
branches:
- main
- release/*
paths:
- "k8s/**"
- "tests/e2e/**"
- "functions/**"
- ".github/workflows/test-k8s-deployment.yaml"
push:
branches:
- main
- release/*
paths:
- "k8s/**"
- "tests/e2e/**"
- "functions/**"
- ".github/workflows/test-k8s-deployment.yaml"
workflow_dispatch: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-test-deployment
cancel-in-progress: true
jobs:
discover:
name: Discover functions
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Find functions with e2e tests
id: find
run: |
entries=$(
for f in functions/*/handler.json; do
[ -f "$f" ] || continue
name=$(jq -r .name "$f")
dir=$(basename "$(dirname "$f")")
# Only include functions that have a matching e2e test file
if [ -f "tests/e2e/__tests__/${name}.e2e.test.ts" ]; then
echo "{\"name\":\"$name\",\"dir\":\"$dir\"}"
fi
done | jq -s -c '.'
)
echo "matrix={\"include\":$entries}" >> "$GITHUB_OUTPUT"
echo "Discovered functions with e2e tests: $entries"
e2e:
name: E2E ${{ matrix.name }}
needs: discover
runs-on: ubuntu-latest
if: ${{ needs.discover.outputs.matrix != '{"include":[]}' }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.discover.outputs.matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "22"
cache: "pnpm"
- name: Install project dependencies
run: pnpm install
- name: Generate workspace packages
run: pnpm generate
- name: Setup kind cluster
uses: helm/kind-action@v1
with:
cluster_name: ci-${{ matrix.name }}
wait: 120s
- name: Verify cluster
run: |
kubectl version
kubectl get nodes -o wide
- name: Install Skaffold
run: |
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
chmod +x skaffold
sudo mv skaffold /usr/local/bin/
- name: Create namespace and GHCR pull secret
env:
GHCR_USERNAME: ${{ secrets.GH_USERNAME }}
GHCR_TOKEN: ${{ secrets.GH_PAT_TOKEN }}
GHCR_EMAIL: ${{ secrets.GH_EMAIL }}
run: |
set -e
kubectl create namespace constructive-functions --dry-run=client -o yaml | kubectl apply -f -
if [ -n "${GHCR_USERNAME:-}" ] && [ -n "${GHCR_TOKEN:-}" ]; then
echo "Creating ghcr-pull secret in constructive-functions namespace"
kubectl create secret docker-registry ghcr-pull \
--docker-server=ghcr.io \
--docker-username="${GHCR_USERNAME}" \
--docker-password="${GHCR_TOKEN}" \
--docker-email="${GHCR_EMAIL:-devnull@example.com}" \
--dry-run=client -o yaml | kubectl apply -n constructive-functions -f -
kubectl patch serviceaccount default -n constructive-functions \
-p '{"imagePullSecrets": [{"name": "ghcr-pull"}]}'
else
echo "GHCR_USERNAME/GHCR_TOKEN not set; assuming images are public."
fi
- name: Generate per-run postgres password
# k8s overlay secrets use REPLACE_WITH_POSTGRES_PASSWORD placeholders; substitute
# a fresh per-run value before Skaffold applies them so deploys + e2e share it.
run: |
PG_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=' | cut -c1-24)
echo "PG_PASSWORD=$PG_PASSWORD" >> "$GITHUB_ENV"
echo "::add-mask::$PG_PASSWORD"
# Substitute into all kustomize secret files for the local-simple overlay.
find k8s/overlays/local-simple -type f \( -name '*.yaml' -o -name '*.yml' \) \
-exec sed -i.bak "s|REPLACE_WITH_POSTGRES_PASSWORD|${PG_PASSWORD}|g" {} \;
find k8s/overlays/local-simple -name '*.bak' -delete
- name: Deploy with Skaffold (per-function profile)
run: skaffold run -p ${{ matrix.name }}
- name: Wait for pods to stabilize
run: |
echo "Waiting for deployments..."
for deploy in $(kubectl get deploy -n constructive-functions -o jsonpath='{.items[*].metadata.name}'); do
echo " Waiting for $deploy..."
kubectl rollout status deploy/"$deploy" -n constructive-functions --timeout=180s || true
done
echo "Pod status:"
kubectl get pods -n constructive-functions -o wide
- name: Wait for DB setup job
run: |
kubectl wait --for=condition=complete job/constructive-db \
-n constructive-functions --timeout=180s
- name: Restart job service after DB ready
run: |
kubectl rollout restart deploy/knative-job-service -n constructive-functions
kubectl rollout status deploy/knative-job-service -n constructive-functions --timeout=120s
- name: Port-forward postgres and run e2e tests
env:
PGHOST: localhost
PGPORT: "5432"
PGUSER: postgres
PGPASSWORD: ${{ env.PG_PASSWORD }}
PGDATABASE: constructive
run: |
kubectl port-forward -n constructive-functions svc/postgres 5432:5432 &
sleep 3
pnpm jest tests/e2e/__tests__/job-queue.test.ts tests/e2e/__tests__/${{ matrix.name }}.e2e.test.ts
- name: Dump diagnostics on failure
if: failure()
run: |
NS=constructive-functions
echo "=== Namespaces ==="
kubectl get ns
echo "=== Pods ==="
kubectl get pods -n $NS -o wide || true
echo "=== Events ==="
kubectl get events -n $NS --sort-by=.lastTimestamp || true
echo "=== Deployments ==="
kubectl get deploy -n $NS -o wide || true
echo "=== Logs ==="
for pod in $(kubectl get pods -n $NS -o jsonpath='{.items[*].metadata.name}'); do
echo "--------------------------------------------------"
echo "Logs for $pod"
kubectl describe pod -n $NS "$pod" || true
kubectl logs -n $NS "$pod" --all-containers --tail=200 || true
done