github-actions[bot]
Sync: publish Space API fix
5e0b58b
Raw History Blame Contribute Delete
15.7 kB
# ============================================================================
# Brain-5D — Continuous Integration
# ============================================================================
# Runs on push/PR to main/develop, and weekly on Monday 06:00 UTC.
#
# Pipeline stages:
# 1. lint-format — code style, linting, pre-commit
# 2. type-check — static type analysis (mypy + pyright)
# 3. security — SAST / dependency scanning
# 4. tests — full test suite across Python versions (matrix)
# 5. build — wheel build + install verification
# 6. docker — Docker image build test
# 7. docs — documentation structure check
# ============================================================================
name: Continuous Integration
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:
permissions:
contents: read
checks: write
pull-requests: write
env:
PYTHONUNBUFFERED: "1"
PIP_NO_WARN_SCRIPT_LOCATION: "1"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
FORCE_COLOR: "1"
defaults:
run:
shell: bash
jobs:
lint-format:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Install project and development tools
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,docs]"
python -m pip install pre-commit bandit
- name: Black (src + tests + scripts)
run: python -m black --check src tests scripts
- name: Ruff (fast linter + isort)
run: python -m ruff check src/ tests/ scripts/
- name: Pylint quality threshold
run: python -m pylint --fail-under=9.0 src
- name: Pre-commit hooks (all files)
run: python -m pre_commit run --all-files --show-diff-on-failure
- name: Whitespace & merge-conflict check
run: |
git diff --check
! grep -rP '^(<<<<<<< |>>>>>>> )|^=======$' src/ tests/ scripts/ --include='*.py' --include='*.md' --include='*.yaml' --include='*.yml'
- name: Summary
if: always()
run: echo "### Lint & Format passed" >> $GITHUB_STEP_SUMMARY
type-check:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Install project and development tools
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,docs]"
- name: Mypy (full src/)
run: python -m mypy src/
- name: Pyright (pyrightconfig.json scope)
run: python -m pyright
- name: Pyright (integration scope)
run: |
python -m pyright \
src/storage/structural_journal.py \
src/storage/structural_recovery.py \
src/storage/core_restore.py \
src/self_organization/approval.py \
src/self_organization/undo.py \
src/self_organization/plasticity.py \
src/self_organization/coordinator.py \
src/dashboard/structural_api.py \
src/dashboard/operator_bridge.py \
src/dashboard/server.py \
src/runtime/control.py \
src/controller/runtime.py \
src/visualization/structural_heatmap.py
- name: Summary
if: always()
run: echo "### Type Check passed" >> $GITHUB_STEP_SUMMARY
security:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
- name: Install tools
run: |
python -m pip install --upgrade pip
python -m pip install bandit pip-audit
- name: Bandit SAST (src/)
run: python -m bandit -c pyproject.toml -r src/ -ll -f json -o bandit-results.json
- name: Upload Bandit report
if: always()
uses: actions/upload-artifact@v7
with:
name: bandit-results
path: bandit-results.json
- name: pip-audit
run: python -m pip_audit
- name: Summary
if: always()
run: echo "### Security scan completed" >> $GITHUB_STEP_SUMMARY
tests:
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Install project and dev dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,docs]"
- name: Smoke tests
run: python -m pytest -m "smoke" -v --tb=short --junit-xml=test-results-smoke.xml
- name: Full test suite (excluding slow)
run: python -m pytest -m "not slow" -v --tb=short --junit-xml=test-results-fast.xml --cov=src --cov-report=xml:coverage.xml --cov-report=term-missing:skip-covered
- name: Slow tests
run: python -m pytest -m "slow" -v --tb=short --junit-xml=test-results-slow.xml || echo "Some slow tests failed (non-blocking)"
continue-on-error: true
- name: Upload test results
if: always()
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.python-version }}
path: |
test-results-*.xml
coverage.xml
- name: Publish test report
if: always()
uses: dorny/test-reporter@v3
with:
name: pytest-report-${{ matrix.python-version }}
path: test-results-*.xml
reporter: java-junit
fail-on-error: false
only-summary: true
- name: Summary
if: always()
run: |
echo "### Tests (${{ matrix.python-version }})" >> $GITHUB_STEP_SUMMARY
python -m pytest --collect-only -q 2>&1 | tail -1 >> $GITHUB_STEP_SUMMARY || true
browser:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install browser check dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[browser]"
python -m playwright install --with-deps chromium
- name: Run Chromium dashboard smoke check
run: python scripts/browser_check.py
- name: Set up Node.js 22
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Install dashboard E2E dependencies
run: npm ci
- name: Run dashboard Chromium E2E suite
run: npx playwright install --with-deps chromium && npm run test:e2e
large-storage:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Install project and development tools
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"
- name: Run opt-in large storage tests
env:
BRAIN5D_RUN_LARGE_STORAGE_TESTS: "1"
BRAIN5D_RUN_LARGE_STORAGE_TEST: "1"
run: |
python -m pytest -v --tb=short \
tests/test_b5d_storage.py::test_large_storage_50k_neurons \
tests/test_delta_journal.py::test_large_journal_100k_entries_opt_in \
--junit-xml=large-storage-results.xml
- name: Upload large storage results
if: always()
uses: actions/upload-artifact@v7
with:
name: large-storage-results
path: large-storage-results.xml
- name: Summary
if: always()
run: echo "### Large storage tests completed" >> $GITHUB_STEP_SUMMARY
scientific-integrity:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
pyproject.toml
requirements.txt
- name: Install project and development tools
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,docs]"
- name: Scientific Integrity Gate
run: >-
python -m pytest -q
tests/test_canonical_state.py
tests/test_restore_determinism_abc.py
tests/test_engine_restore.py
tests/test_production_restore.py
tests/test_golden_chain.py
tests/test_research_registry.py
tests/test_ai_boundaries.py
tests/test_ai_governance.py
tests/test_experiment_validity.py
- name: Summary
if: always()
run: echo "### Scientific Integrity Gate completed" >> $GITHUB_STEP_SUMMARY
catalog-audit:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install project
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"
- name: Generate repository catalog audit report
run: python scripts/generate_catalog_audit_report.py
- name: Upload catalog audit reports
if: always()
uses: actions/upload-artifact@v7
with:
name: catalog-audit-report
path: |
research/generated/CATALOG_AUDIT_REPORT.md
research/generated/CATALOG_AUDIT_REPORT.json
- name: Add catalog audit to job summary
if: always()
run: cat research/generated/CATALOG_AUDIT_REPORT.md >> "$GITHUB_STEP_SUMMARY" || true
build:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [lint-format, type-check, security, tests]
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
- name: Build wheel
run: |
python -m pip install --upgrade pip build
python -m build
- name: Verify wheel installs cleanly
run: |
python -m pip install dist/*.whl
python -c "from src.version import BRAIN5D_VERSION; print(BRAIN5D_VERSION)"
- name: Upload wheel artifact
uses: actions/upload-artifact@v7
with:
name: wheel
path: dist/*.whl
- name: Summary
run: |
echo "### Build successful" >> $GITHUB_STEP_SUMMARY
echo "Wheel: $(ls dist/*.whl)" >> $GITHUB_STEP_SUMMARY
docker:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
steps:
- uses: actions/checkout@v7
- name: Download wheel artifact
uses: actions/download-artifact@v8
with:
name: wheel
path: dist/
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build Docker image
uses: docker/build-push-action@v7
with:
context: .
load: true
tags: brain5d:ci
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Verify Docker image runs
run: |
docker run --rm brain5d:ci python -c "
from src.core.neuron import Neuron;
from src.core.network import NeuralNetwork;
from src.storage.b5d import B5DReader;
from src.homeostasis.engine import HomeostasisEngine;
print('Docker image OK');
"
- name: Summary
run: |
echo "### Docker build passed" >> $GITHUB_STEP_SUMMARY
echo "Image: brain5d:ci" >> $GITHUB_STEP_SUMMARY
docs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Set up Python 3.13
uses: actions/setup-python@v7
with:
python-version: "3.13"
- name: Install documentation check dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev]"
- name: Check documentation links and consistency
run: |
python scripts/check_doc_consistency.py --check-tests
echo "### Documentation structure" >> $GITHUB_STEP_SUMMARY
find docs/ -name "*.md" -type f | sort | head -50 >> $GITHUB_STEP_SUMMARY || true
ci-status:
if: always()
runs-on: ubuntu-latest
needs: [lint-format, type-check, security, tests, large-storage, scientific-integrity, catalog-audit, build, docker, docs]
steps:
- name: CI Pipeline Summary
run: |
echo "## CI Pipeline Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
declare -A RESULTS
RESULTS["lint-format"]="${{ needs.lint-format.result }}"
RESULTS["type-check"]="${{ needs.type-check.result }}"
RESULTS["security"]="${{ needs.security.result }}"
RESULTS["tests"]="${{ needs.tests.result }}"
RESULTS["large-storage"]="${{ needs.large-storage.result }}"
RESULTS["scientific-integrity"]="${{ needs.scientific-integrity.result }}"
RESULTS["catalog-audit"]="${{ needs.catalog-audit.result }}"
RESULTS["build"]="${{ needs.build.result }}"
RESULTS["docker"]="${{ needs.docker.result }}"
RESULTS["docs"]="${{ needs.docs.result }}"
ALL_PASSED=true
for JOB in "${!RESULTS[@]}"; do
STATUS="${RESULTS[$JOB]}"
if [ "$STATUS" = "success" ]; then
echo "- **$JOB** — passed" >> $GITHUB_STEP_SUMMARY
elif [ "$STATUS" = "skipped" ]; then
echo "- **$JOB** — skipped" >> $GITHUB_STEP_SUMMARY
else
echo "- **$JOB** — $STATUS" >> $GITHUB_STEP_SUMMARY
ALL_PASSED=false
fi
done
echo "" >> $GITHUB_STEP_SUMMARY
if [ "$ALL_PASSED" = true ]; then
echo "**All CI checks passed!**" >> $GITHUB_STEP_SUMMARY
else
echo "**Some checks did not pass — review logs above.**" >> $GITHUB_STEP_SUMMARY
exit 1
fi