Skip to content

Merge pull request #3 from SatyKrish/feature/demo-target-bootstrap-fixes #8

Merge pull request #3 from SatyKrish/feature/demo-target-bootstrap-fixes

Merge pull request #3 from SatyKrish/feature/demo-target-bootstrap-fixes #8

Workflow file for this run

name: deploy
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Databricks CLI
run: curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sh
- name: Validate bundle (demo)
env:
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
DOCINTEL_WAREHOUSE_ID: ${{ vars.DOCINTEL_WAREHOUSE_ID }}
run: databricks bundle validate --strict -t demo --var "warehouse_id=$DOCINTEL_WAREHOUSE_ID"
deploy-demo:
# CI assumes steady-state: the first-ever bring-up of a workspace must be
# done locally via `./scripts/bootstrap-demo.sh`, which handles the
# foundation/consumers staging and waits for Lakebase AVAILABLE. After
# that initial bring-up, every push to main runs a full bundle deploy
# against the now-existing resources — no temp-rename trick (DAB would
# plan to DELETE any resource that disappears from config).
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: validate
runs-on: ubuntu-latest
env:
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
DOCINTEL_CATALOG: ${{ vars.DOCINTEL_CATALOG }}
DOCINTEL_SCHEMA: ${{ vars.DOCINTEL_SCHEMA }}
DOCINTEL_WAREHOUSE_ID: ${{ vars.DOCINTEL_WAREHOUSE_ID }}
PYTHONPATH: ${{ github.workspace }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Databricks CLI
run: curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sh
- name: Install Python deps
run: pip install -r agent/requirements.txt -r evals/requirements.txt
- name: Deploy bundle (full — consumers already exist in steady-state)
# Pin warehouse_id so the dashboard + serving env match what
# wait_for_kpis / log_and_register use. Without --var, the bundle
# falls back to its `lookup: warehouse: Serverless Starter Warehouse`
# default and silently picks a different ID.
run: databricks bundle deploy -t demo --var "warehouse_id=$DOCINTEL_WAREHOUSE_ID"
- name: Wait for Lakebase instance to be AVAILABLE
# Lakebase already exists in steady-state but a config change can
# transition it back through provisioning; the catalog/app bindings
# need it AVAILABLE before the next bundle run touches them.
run: |
python -c "
import json, os, sys, time, subprocess

Check failure on line 63 in .github/workflows/deploy.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/deploy.yml

Invalid workflow file

You have an error in your yaml syntax on line 63
name = os.environ.get('LAKEBASE_NAME') or 'docintel-demo-state-v1'
deadline = time.time() + 600
while True:
out = subprocess.run(['databricks','api','get','/api/2.0/database/instances','--output','json'],
capture_output=True, text=True)
try:
d = json.loads(out.stdout)
except Exception:
d = {}
state = next((i.get('state') for i in d.get('database_instances',[]) if i.get('name')==name), 'UNKNOWN')
print(f'lakebase state: {state}')
if state == 'AVAILABLE':
sys.exit(0)
if time.time() >= deadline:
sys.exit(f'Lakebase {name} did not reach AVAILABLE within 600s (state={state})')
time.sleep(15)
"
env:
LAKEBASE_NAME: ${{ vars.DOCINTEL_LAKEBASE_NAME || 'docintel-demo-state-v1' }}
- name: Refresh data — upload samples, run pipeline, register new model version
run: |
for f in samples/*_10K_*.pdf; do
databricks fs cp "$f" \
"dbfs:/Volumes/${DOCINTEL_CATALOG}/${DOCINTEL_SCHEMA}/raw_filings/" \
--overwrite
done
databricks bundle run -t demo --var "warehouse_id=$DOCINTEL_WAREHOUSE_ID" doc_intel_pipeline
python scripts/wait_for_kpis.py --min-rows 3 --timeout 900
# --serving-endpoint repoints the existing endpoint to the new
# model version in-place (steady-state idempotent operation).
python agent/log_and_register.py --target demo --serving-endpoint analyst-agent-demo
- name: Apply UC grants (catalog + schema; not DAB-supported)
# UC requires the full chain: USE_CATALOG → USE_SCHEMA → SELECT/EXECUTE.
# Defaults to "account users" so CI does not silently skip when the
# GitHub variable is unset.
env:
ANALYST_GROUP: ${{ vars.DOCINTEL_ANALYST_GROUP || 'account users' }}
run: |
databricks api patch \
"/api/2.1/unity-catalog/permissions/CATALOG/${DOCINTEL_CATALOG}" \
--json "{\"changes\":[{\"principal\":\"${ANALYST_GROUP}\",\"add\":[\"USE_CATALOG\"]}]}" || true
databricks api patch \
"/api/2.1/unity-catalog/permissions/SCHEMA/${DOCINTEL_CATALOG}.${DOCINTEL_SCHEMA}" \
--json "{\"changes\":[{\"principal\":\"${ANALYST_GROUP}\",\"add\":[\"USE_SCHEMA\",\"SELECT\",\"EXECUTE\"]}]}" || true
- name: Apply app config + restart
# Databricks Apps deploy docs:
# https://docs.databricks.com/aws/en/dev-tools/databricks-apps/deploy
# `bundle deploy` alone uploads code but doesn't apply config/restart.
run: databricks bundle run -t demo --var "warehouse_id=$DOCINTEL_WAREHOUSE_ID" analyst_app
- name: Verify OBO scopes survived deploy
# `bundle run` may wipe user_api_scopes (documented destructive-update
# behavior). Fail loudly so we re-apply. Skipped when user_api_scopes
# are not declared (workspace feature off).
run: |
if grep -q '^ user_api_scopes:' resources/consumers/analyst.app.yml; then
databricks apps get doc-intel-analyst-demo --output json > /tmp/app.json
python -c "
import json
app = json.load(open('/tmp/app.json'))
scopes = set(app.get('user_api_scopes') or [])
required = {'serving.serving-endpoints', 'sql'}
missing = required - scopes
assert not missing, f'OBO scopes missing: {sorted(missing)} (got {sorted(scopes)})'
"
else
echo "user_api_scopes not declared (workspace feature off); skipping OBO scope check"
fi
- name: CLEARS evaluation gate
run: python evals/clears_eval.py --endpoint analyst-agent-demo --dataset evals/dataset.jsonl