diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..e82d9cf --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,53 @@ +name: Publish dashboard + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pages-${{ github.event_name == 'pull_request' && github.ref || 'production' }} + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + path: PyAutoBroca + - uses: actions/checkout@v4 + with: + repository: PyAutoLabs/PyAutoBrain + path: PyAutoBrain + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Install renderer + run: pip install ./PyAutoBroca + - name: Validate saved evidence + run: python -m broca --root PyAutoBroca check + - name: Render dashboard without recollecting evidence + run: python -m broca --root PyAutoBroca render --brain PyAutoBrain --output site/index.html + - name: Upload site only + uses: actions/upload-pages-artifact@v3 + with: + path: site + deploy: + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/AGENTS.md b/AGENTS.md index 304e6d4..c378101 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,9 @@ runs, then import summaries; no default paid or scheduled execution. This repository and its tracked dashboard snapshot are public. Review new records and receipts before committing them: keep local paths, raw transcripts, credentials -and private project metadata outside this repository. GitHub Pages is not enabled. +and private project metadata outside this repository. GitHub Pages uses `.github/workflows/pages.yml`: publish only the rendered site +artifact, never the whole checkout. Deployments preserve collection timestamps +and do not collect evidence or execute benchmarks. Board presentation reuses PyAutoBrain's shared components and contracts: https://github.com/PyAutoLabs/PyAutoBrain/blob/main/docs/standards.md diff --git a/README.md b/README.md index caaf2ae..0878dcd 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ python -m broca render --brain /path/to/PyAutoBrain --output dashboard.html python -m pytest -q ``` -Open [dashboard.html](dashboard.html). Brain must include the Broca theme registration. +Open the [live dashboard](https://pyautolabs.github.io/PyAutoBroca/) or the local [dashboard.html](dashboard.html). Brain must include the Broca theme registration. The board uses the shared banner, check-in panel, navigation cards, collapsible sections, responsive sizing, light/dark styling and clipboard behavior. Its Update control is unavailable until an actual collection service is configured. @@ -60,10 +60,12 @@ the public repo. Existing published history is not deleted or rewritten. ## Scope and privacy -The repository and tracked dashboard snapshot are public. No Pages deployment -or scheduled model campaign is enabled. Review imported records and receipts +The repository and dashboard are public. GitHub Actions publishes the saved +evidence at https://pyautolabs.github.io/PyAutoBroca/ on main updates or a manual +`Publish dashboard` dispatch. Publication does not collect new evidence, change +its refresh timestamp or run a model campaign. Review imported records and receipts before committing; retain raw transcripts and private project data elsewhere. [CHECKIN.md](CHECKIN.md) is the board's portable workflow. A broader campaign needs an explicit budget and execution environment. Project -feedback ingestion, full wiki/API drift audits and hosted dashboard publication +feedback ingestion, full wiki/API drift audits and additional publication formats are later extensions; the initial board provides inventory, historical results, provenance, freshness and next-action guidance. diff --git a/tests/test_pages_workflow.py b/tests/test_pages_workflow.py new file mode 100644 index 0000000..01b3262 --- /dev/null +++ b/tests/test_pages_workflow.py @@ -0,0 +1,25 @@ +"""Publication must not expose the checkout or mutate evaluation evidence.""" +from pathlib import Path +import yaml + + +def test_pages_publishes_only_rendered_snapshot_with_guarded_deployment(): + root = Path(__file__).resolve().parents[1] + workflow = yaml.safe_load((root / '.github/workflows/pages.yml').read_text()) + triggers = workflow.get('on', workflow.get(True)) + assert set(triggers) == {'push', 'pull_request', 'workflow_dispatch'} + assert triggers['push']['branches'] == ['main'] + build = workflow['jobs']['build'] + commands = '\n'.join(step.get('run', '') for step in build['steps']) + assert 'broca --root PyAutoBroca check' in commands + assert 'render --brain PyAutoBrain --output site/index.html' in commands + assert 'refresh' not in commands and '--pilot' not in commands + upload = next(step for step in build['steps'] if step.get('uses', '').startswith('actions/upload-pages-artifact@')) + assert upload['with']['path'] == 'site' + deploy = workflow['jobs']['deploy'] + assert deploy['needs'] == 'build' + assert "github.ref == 'refs/heads/main'" in deploy['if'] + assert "github.event_name != 'pull_request'" in deploy['if'] + assert deploy['permissions'] == {'pages': 'write', 'id-token': 'write'} + assert workflow['permissions'] == {'contents': 'read'} + assert deploy['environment']['name'] == 'github-pages'