Skip to content

Commit d60713b

Browse files
committed
ci: add Python package tests across 3.10-3.12 and PyPI publish on release
CI: schema validation + Python adapter round-trips + CLI tests on every push/PR CD: trusted publisher to PyPI on GitHub release (no API tokens needed)
1 parent eaf4c2c commit d60713b

2 files changed

Lines changed: 134 additions & 5 deletions

File tree

.github/workflows/publish.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
id-token: write
9+
10+
jobs:
11+
publish:
12+
name: Build & Publish
13+
runs-on: ubuntu-latest
14+
environment:
15+
name: pypi
16+
url: https://pypi.org/p/mif-tools
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: actions/setup-python@v5
21+
with:
22+
python-version: "3.12"
23+
24+
- name: Install build tools
25+
run: pip install build
26+
27+
- name: Build package
28+
working-directory: python
29+
run: python -m build
30+
31+
- name: Publish to PyPI
32+
uses: pypa/gh-action-pypi-publish@release/v1
33+
with:
34+
packages-dir: python/dist/

.github/workflows/validate.yml

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Validate MIF Examples
1+
name: CI
22

33
on:
44
push:
@@ -7,7 +7,8 @@ on:
77
branches: [main]
88

99
jobs:
10-
validate:
10+
schema:
11+
name: Schema & Examples
1112
runs-on: ubuntu-latest
1213
steps:
1314
- uses: actions/checkout@v4
@@ -19,11 +20,105 @@ jobs:
1920
- name: Install dependencies
2021
run: pip install -r requirements.txt
2122

22-
- name: Validate examples against schema
23-
run: python validate.py examples/*.mif.json
24-
2523
- name: Validate schema is valid JSON
2624
run: python -c "import json; json.load(open('schema/mif-v2.schema.json'))"
2725

26+
- name: Validate examples against schema
27+
run: python validate.py examples/*.mif.json
28+
2829
- name: Round-trip test
2930
run: python tests/round_trip.py examples/*.mif.json
31+
32+
python:
33+
name: Python Package
34+
runs-on: ubuntu-latest
35+
strategy:
36+
matrix:
37+
python-version: ["3.10", "3.11", "3.12"]
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- uses: actions/setup-python@v5
42+
with:
43+
python-version: ${{ matrix.python-version }}
44+
45+
- name: Install mif-tools
46+
run: pip install -e "./python[validate]"
47+
48+
- name: Test adapters (MIF v2 round-trip)
49+
run: |
50+
python -c "
51+
from mif import load, dump
52+
data = open('examples/full.mif.json').read()
53+
doc = load(data)
54+
assert len(doc.memories) == 3
55+
assert doc.knowledge_graph is not None
56+
rt = load(dump(doc))
57+
assert len(rt.memories) == 3
58+
print('MIF v2 round-trip: PASS')
59+
"
60+
61+
- name: Test adapters (mem0 round-trip)
62+
run: |
63+
python -c "
64+
from mif import load, dump
65+
data = open('examples/full.mif.json').read()
66+
doc = load(data)
67+
mem0 = dump(doc, format='mem0')
68+
doc2 = load(mem0, format='mem0')
69+
assert len(doc2.memories) == len(doc.memories)
70+
print('mem0 round-trip: PASS')
71+
"
72+
73+
- name: Test adapters (markdown round-trip)
74+
run: |
75+
python -c "
76+
from mif import load, dump
77+
data = open('examples/full.mif.json').read()
78+
doc = load(data)
79+
md = dump(doc, format='markdown')
80+
doc2 = load(md, format='markdown')
81+
assert len(doc2.memories) == len(doc.memories)
82+
print('markdown round-trip: PASS')
83+
"
84+
85+
- name: Test adapters (generic JSON round-trip)
86+
run: |
87+
python -c "
88+
from mif import load, dump
89+
data = open('examples/full.mif.json').read()
90+
doc = load(data)
91+
gen = dump(doc, format='generic')
92+
doc2 = load(gen, format='generic')
93+
assert len(doc2.memories) == len(doc.memories)
94+
print('generic JSON round-trip: PASS')
95+
"
96+
97+
- name: Test auto-detection
98+
run: |
99+
python -c "
100+
from mif import load
101+
# mem0 auto-detect
102+
doc = load('[{\"memory\": \"test\", \"created_at\": \"2026-01-01T00:00:00Z\"}]')
103+
assert doc.memories[0].content == 'test'
104+
# generic auto-detect
105+
doc = load('[{\"content\": \"test2\", \"timestamp\": \"2026-01-01T00:00:00Z\"}]')
106+
assert doc.memories[0].content == 'test2'
107+
print('auto-detection: PASS')
108+
"
109+
110+
- name: Test CLI
111+
run: |
112+
mif formats
113+
mif inspect examples/full.mif.json
114+
mif validate examples/minimal.mif.json examples/full.mif.json
115+
116+
- name: Test schema validation
117+
run: |
118+
python -c "
119+
from mif import validate
120+
data = open('examples/full.mif.json').read()
121+
ok, errors = validate(data)
122+
assert ok, f'Validation failed: {errors}'
123+
print('schema validation: PASS')
124+
"

0 commit comments

Comments
 (0)