Skip to content

Commit 4502bd3

Browse files
committed
ci(cli): configure auto bm workflow
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent b386502 commit 4502bd3

5 files changed

Lines changed: 121 additions & 2 deletions

File tree

.github/basic-memory/config.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
project: dev
2+
workspace: basic-memory-7020de4e925843c68c9056c60d101d9e
3+
deploy_workflows:
4+
- Deploy Production
5+
production_environments:
6+
- production
7+
note_folder: project-updates/github/{owner}/{repo}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Memory CI Capture
2+
3+
You turn GitHub delivery context into a concise project update synthesis for
4+
Basic Memory. GitHub records the mechanics. Basic Memory remembers what changed
5+
and why.
6+
7+
## Inputs
8+
9+
- Read `.github/basic-memory/project-update-context.json`.
10+
- Treat GitHub payload fields as immutable facts.
11+
- Do not invent tests, deployment status, issues, or user impact.
12+
13+
## Output
14+
15+
Return only JSON that matches the provided AgentSynthesis schema:
16+
17+
- `summary`: what changed.
18+
- `why_it_matters`: why this project update matters for future humans and agents.
19+
- `user_facing_changes`: visible behavior or product changes.
20+
- `internal_changes`: implementation, infrastructure, or operational changes.
21+
- `verification`: checks, tests, deploy evidence, or explicit unknowns.
22+
- `follow_ups`: concrete remaining work only.
23+
- `decision_candidates`: explicit product or architecture decisions only.
24+
- `task_candidates`: concrete future tasks only.
25+
26+
Prefer source links and grounded phrasing. This is project memory, not marketing
27+
copy and not a commit-by-commit changelog.

.github/workflows/basic-memory.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Basic Memory Project Updates
2+
3+
"on":
4+
pull_request:
5+
types: [closed]
6+
workflow_run:
7+
workflows: ["Deploy Production"]
8+
types: [completed]
9+
10+
jobs:
11+
project-update:
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read
15+
pull-requests: read
16+
issues: read
17+
actions: read
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v6
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v6
24+
with:
25+
python-version: "3.12"
26+
27+
- name: Install Basic Memory
28+
run: |
29+
python -m pip install --upgrade pip
30+
pip install basic-memory
31+
32+
- name: Collect project update context
33+
id: collect
34+
run: |
35+
bm ci collect \
36+
--config .github/basic-memory/config.yml \
37+
--output .github/basic-memory/project-update-context.json
38+
39+
- name: Stop when event is not eligible
40+
if: steps.collect.outputs.eligible != 'true'
41+
run: |
42+
echo "Auto BM skipped: ${{ steps.collect.outputs.skip_reason }}"
43+
44+
- name: Write Codex output schema
45+
if: steps.collect.outputs.eligible == 'true'
46+
run: |
47+
bm ci agent-schema --output "${{ runner.temp }}/agent-synthesis.schema.json"
48+
49+
- name: Synthesize project update with Codex
50+
if: steps.collect.outputs.eligible == 'true'
51+
uses: openai/codex-action@v1
52+
with:
53+
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
54+
prompt-file: .github/basic-memory/memory-ci-capture.md
55+
output-file: ${{ runner.temp }}/agent-synthesis.json
56+
output-schema-file: ${{ runner.temp }}/agent-synthesis.schema.json
57+
sandbox: read-only
58+
safety-strategy: drop-sudo
59+
60+
- name: Publish project update
61+
if: steps.collect.outputs.eligible == 'true'
62+
env:
63+
BASIC_MEMORY_CLOUD_API_KEY: ${{ secrets.BASIC_MEMORY_API_KEY }}
64+
BASIC_MEMORY_CI_CLOUD_HOST: ${{ vars.BASIC_MEMORY_CLOUD_HOST }}
65+
run: |
66+
if [ -n "$BASIC_MEMORY_CI_CLOUD_HOST" ]; then
67+
export BASIC_MEMORY_CLOUD_HOST="$BASIC_MEMORY_CI_CLOUD_HOST"
68+
fi
69+
bm ci publish \
70+
--cloud \
71+
--config .github/basic-memory/config.yml \
72+
--context .github/basic-memory/project-update-context.json \
73+
--synthesis "${{ runner.temp }}/agent-synthesis.json"

src/basic_memory/ci/project_updates.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ def render_workflow(config: ProjectUpdateConfig) -> str:
489489
effort_line = f" effort: {config.codex_effort}\n" if config.codex_effort else ""
490490
return f"""name: Basic Memory Project Updates
491491
492-
on:
492+
"on":
493493
pull_request:
494494
types: [closed]
495495
workflow_run:
@@ -527,7 +527,8 @@ def render_workflow(config: ProjectUpdateConfig) -> str:
527527
528528
- name: Stop when event is not eligible
529529
if: steps.collect.outputs.eligible != 'true'
530-
run: echo "Auto BM skipped: ${{{{ steps.collect.outputs.skip_reason }}}}"
530+
run: |
531+
echo "Auto BM skipped: ${{{{ steps.collect.outputs.skip_reason }}}}"
531532
532533
- name: Write Codex output schema
533534
if: steps.collect.outputs.eligible == 'true'

tests/ci/test_project_updates.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33

44
import pytest
5+
import yaml
56
from pydantic import ValidationError
67

78
from basic_memory.ci.project_updates import (
@@ -399,6 +400,16 @@ def test_render_workflow_invokes_codex_read_only_without_basic_memory_secret() -
399400
assert "BASIC_MEMORY_API_KEY" not in codex_step
400401

401402

403+
def test_render_workflow_outputs_valid_github_actions_yaml() -> None:
404+
workflow = render_workflow(ProjectUpdateConfig(project="team-memory"))
405+
406+
parsed = yaml.safe_load(workflow)
407+
408+
assert isinstance(parsed, dict)
409+
assert parsed["on"]["pull_request"]["types"] == ["closed"]
410+
assert parsed["on"]["workflow_run"]["types"] == ["completed"]
411+
412+
402413
def test_render_capture_prompt_uses_workspace_context_path() -> None:
403414
prompt = render_capture_prompt()
404415

0 commit comments

Comments
 (0)