Skip to content

feat(bridge-auth): send X-Admin-Token on all /xiaozhi/admin/* calls (… #236

feat(bridge-auth): send X-Admin-Token on all /xiaozhi/admin/* calls (…

feat(bridge-auth): send X-Admin-Token on all /xiaozhi/admin/* calls (… #236

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
yaml-lint:
name: YAML Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: pip install yamllint
- name: Lint YAML files
run: |
cat > .yamllint.yml <<'EOF'
extends: relaxed
rules:
line-length: disable
truthy: disable
EOF
yamllint \
.config.yaml.template \
docker-compose.yml.template \
compose.all-in-one.yml \
compose.local.override.yml \
mkdocs.yml
compose-validate:
name: Compose Validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Validate docker-compose.yml.template
# Template still contains <TZ_VALUE> etc. — compose accepts them as
# string values; only schema correctness is checked here.
run: docker compose -f docker-compose.yml.template config > /dev/null
- name: Validate compose.all-in-one.yml
run: docker compose -f compose.all-in-one.yml config > /dev/null
config-parse:
name: Config Parse
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Parse .config.yaml.template
run: python3 -c "import yaml; yaml.safe_load(open('.config.yaml.template'))"
lint:
name: Ruff Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install ruff
- name: ruff check
run: ruff check .
python-tests:
name: Python Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install test dependencies
run: |
pip install pytest pytest-cov
pip install \
'fastapi>=0.115,<1' \
'uvicorn[standard]>=0.34,<1' \
'pydantic>=2.9,<3' \
'jinja2>=3.1,<4' \
'python-multipart>=0.0.9,<1' \
'prometheus-client>=0.20,<1' \
'PyYAML>=6.0,<7' \
'numpy>=1.24,<3' \
'aiohttp>=3.9,<4' \
'requests>=2.31,<3' \
'httpx>=0.27,<1'
- name: Run bridge + pi_voice unit tests
run: |
pytest tests/ custom-providers/pi_voice/tests/ -v --tb=short \
--cov --cov-report=
- name: Run dotty-behaviour unit tests + combined coverage gate
# Separate pytest process on purpose: dotty-behaviour/conftest.py puts
# the package's flat modules (config, consumers, routes, …) on sys.path,
# which would shadow the bridge's modules if both suites were collected
# in one session. --cov-append accumulates onto the step above, and the
# --cov-fail-under floor is evaluated on the combined data (currently
# ~70%). Lower the gate only when intentionally removing tests.
run: |
pytest dotty-behaviour/tests/ -v --tb=short \
--cov --cov-append --cov-report=term --cov-fail-under=56
pi-ext-tests:
name: dotty-pi-ext TS Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "22"
- name: Install dotty-pi-ext deps
working-directory: dotty-pi-ext
run: npm ci
- name: Run dotty-pi-ext tests
working-directory: dotty-pi-ext
run: npm test
frontmatter-check:
name: Frontmatter Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Verify YAML frontmatter in docs
run: |
fail=0
for f in docs/*.md; do
# Skip symlinks — root-level files (README, ROADMAP, SETUP, etc.)
# are symlinked into docs/ for the mkdocs nav but are primarily
# consumed as plain GitHub markdown; YAML frontmatter would clutter
# their on-GitHub rendering.
[ -L "$f" ] && continue
if ! head -1 "$f" | grep -q '^---$'; then
echo "FAIL: $f missing YAML frontmatter"
fail=1
fi
done
exit $fail
docs-links:
name: Docs Link Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Check links
uses: lycheeverse/lychee-action@v2
with:
args: >-
--no-progress
--exclude-private
--offline
--base https://github.com/BrettKinny/dotty-stackchan
docs/*.md
*.md
notify-failure:
name: Notify on Failure
runs-on: ubuntu-latest
needs: [yaml-lint, compose-validate, config-parse, lint, python-tests, pi-ext-tests, frontmatter-check, docs-links]
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
REPO: ${{ github.repository }}
REF: ${{ github.ref_name }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- name: Post Slack notification
if: env.SLACK_WEBHOOK_URL != ''
run: |
payload=$(jq -cn --arg t ":x: *CI failed* · \`${REPO}\` · \`${REF}\` — ${RUN_URL}" '{text: $t}')
curl -fsS -X POST "$SLACK_WEBHOOK_URL" -H 'Content-Type: application/json' -d "$payload"