1+ name : Test Cookiecutter
2+
3+ on :
4+ push :
5+ branches : [main, dev, 'feat/*']
6+ pull_request :
7+ branches : [main]
8+ workflow_dispatch :
9+
10+ jobs :
11+ test-generation :
12+ name : Test template generation
13+ runs-on : ${{ matrix.os }}
14+ strategy :
15+ fail-fast : false
16+ matrix :
17+ os : [ubuntu-latest, windows-latest, macos-latest]
18+ python-version : ['3.8', '3.9', '3.10', '3.11']
19+ num-activities : [1, 3, 5]
20+
21+ steps :
22+ - uses : actions/checkout@v4
23+
24+ - name : Set up Python
25+ uses : actions/setup-python@v5
26+ with :
27+ python-version : ${{ matrix.python-version }}
28+
29+ - name : Install dependencies
30+ run : |
31+ python -m pip install --upgrade pip
32+ pip install -r requirements.txt
33+
34+ - name : Test cookiecutter generation
35+ run : |
36+ python -m cookiecutter . --no-input \
37+ protocol_name="Test Protocol ${{ matrix.num-activities }}" \
38+ protocol_description="Testing with ${{ matrix.num-activities }} activities" \
39+ github_org="test-org" \
40+ github_repo="test-repo" \
41+ protocol_slug="test_protocol_${{ matrix.num-activities }}" \
42+ author_name="Test Author" \
43+ author_email="test@example.com" \
44+ license="MIT" \
45+ number_of_activities=${{ matrix.num-activities }}
46+
47+ - name : Validate generated project structure
48+ run : |
49+ cd "Test Protocol ${{ matrix.num-activities }}"
50+ # Check essential files exist
51+ test -f README.md
52+ test -f Makefile
53+ test -f LICENSE
54+ test -f config.env
55+ test -d activities
56+ test -d ui-changes
57+ test -f test_protocol_${{ matrix.num-activities }}/test_protocol_${{ matrix.num-activities }}_schema
58+ shell : bash
59+
60+ - name : Count activities
61+ run : |
62+ cd "Test Protocol ${{ matrix.num-activities }}/activities"
63+ count=$(ls -d */ | wc -l)
64+ echo "Found $count activities"
65+ if [ $count -ne ${{ matrix.num-activities }} ]; then
66+ echo "ERROR: Expected ${{ matrix.num-activities }} activities but found $count"
67+ exit 1
68+ fi
69+ shell : bash
70+
71+ - name : Validate JSON schemas
72+ run : |
73+ cd "Test Protocol ${{ matrix.num-activities }}"
74+ python -c "
75+ import json
76+ import sys
77+ from pathlib import Path
78+
79+ errors = []
80+
81+ # Check all schema files
82+ for schema_file in Path('.').rglob('*_schema') :
83+ try :
84+ with open(schema_file) as f :
85+ json.load(f)
86+ print(f'✓ Valid JSON : {schema_file}')
87+ except json.JSONDecodeError as e :
88+ errors.append(f'✗ Invalid JSON in {schema_file} : {e}')
89+
90+ # Check all item files
91+ for item_file in Path('.').rglob('*_item') :
92+ try :
93+ with open(item_file) as f :
94+ json.load(f)
95+ print(f'✓ Valid JSON : {item_file}')
96+ except json.JSONDecodeError as e :
97+ errors.append(f'✗ Invalid JSON in {item_file} : {e}')
98+
99+ if errors :
100+ print('\nErrors found:')
101+ for error in errors :
102+ print(error)
103+ sys.exit(1)
104+ else :
105+ print('\nAll schemas are valid JSON!')
106+ "
107+
108+ - name: Check protocol schema has correct activities
109+ run: |
110+ cd " Test Protocol ${{ matrix.num-activities }}"
111+ python -c "
112+ import json
113+ import sys
114+
115+ with open('test_protocol_${{ matrix.num-activities }}/test_protocol_${{ matrix.num-activities }}_schema') as f :
116+ schema = json.load(f)
117+
118+ activities = schema['ui']['addProperties']
119+ order = schema['ui']['order']
120+
121+ print(f'Found {len(activities)} activities in addProperties')
122+ print(f'Found {len(order)} activities in order')
123+
124+ if len(activities) != ${{ matrix.num-activities }} :
125+ print(f'ERROR : Expected ${{ matrix.num-activities }} activities but found {len(activities)}')
126+ sys.exit(1)
127+
128+ if len(order) != ${{ matrix.num-activities }} :
129+ print(f'ERROR : Expected ${{ matrix.num-activities }} items in order but found {len(order)}')
130+ sys.exit(1)
131+
132+ print('✓ Protocol schema has correct number of activities')
133+ "
134+
135+ validate-schemas:
136+ name: Validate ReproSchema compliance
137+ runs-on: ubuntu-latest
138+ needs: test-generation
139+
140+ steps:
141+ - uses: actions/checkout@v4
142+
143+ - name: Set up Python
144+ uses: actions/setup-python@v5
145+ with:
146+ python-version: '3.11'
147+
148+ - name: Install dependencies
149+ run: |
150+ python -m pip install --upgrade pip
151+ pip install -r requirements.txt
152+ pip install reproschema
153+
154+ - name: Generate test protocol
155+ run: |
156+ python -m cookiecutter . --no-input \
157+ protocol_name=" Validation Test" \
158+ number_of_activities=3
159+
160+ - name : Validate with reproschema
161+ run : |
162+ cd "Validation Test"
163+ # Note: This will fail until reproschema-py is updated
164+ # For now, we'll do basic schema validation
165+ python -c "
166+ import json
167+ from pathlib import Path
168+
169+ print('Checking schema versions...')
170+ for schema_file in Path('.').rglob('*_schema') :
171+ with open(schema_file) as f :
172+ schema = json.load(f)
173+
174+ context = schema.get('@context', '')
175+ if '1.0.0-rc' in str(context) :
176+ print(f'WARNING : {schema_file} uses release candidate version')
177+ elif '1.0.0' in str(context) :
178+ print(f'✓ {schema_file} uses stable version')
179+ else :
180+ print(f'? {schema_file} has unexpected context : {context}')
181+ "
182+
183+ test-hooks:
184+ name: Test generation hooks
185+ runs-on: ubuntu-latest
186+
187+ steps:
188+ - uses: actions/checkout@v4
189+
190+ - name: Set up Python
191+ uses: actions/setup-python@v5
192+ with:
193+ python-version: '3.11'
194+
195+ - name: Install dependencies
196+ run: |
197+ python -m pip install --upgrade pip
198+ pip install -r requirements.txt
199+
200+ - name: Test pre-generation hook
201+ run: |
202+ cd hooks
203+ python -c "
204+ # Test activity selection
205+ import sys
206+ sys.path.insert(0, '.')
207+
208+ # Mock cookiecutter context
209+ class MockCookiecutter :
210+ number_of_activities = '3'
211+
212+ # Replace the template variable
213+ with open('pre_gen_project.py', 'r') as f :
214+ code = f.read()
215+ code = code.replace('{{ cookiecutter.number_of_activities }}', '3')
216+
217+ # Execute the modified code
218+ exec(code)
219+
220+ # Check if activities were selected
221+ import json
222+ with open('../selected_activities.json') as f :
223+ selected = json.load(f)
224+
225+ print(f'Selected activities : {selected}')
226+ assert len(selected) == 3
227+ assert all(a in ['Activity1', 'Activity2', 'Activity3', 'selectActivity', 'voiceActivity'] for a in selected)
228+ print('✓ Pre-generation hook works correctly')
229+ "
230+
231+ - name: Clean up
232+ run: rm -f selected_activities.json
233+
234+ lint-and-format:
235+ name: Code quality checks
236+ runs-on: ubuntu-latest
237+
238+ steps:
239+ - uses: actions/checkout@v4
240+
241+ - name: Set up Python
242+ uses: actions/setup-python@v5
243+ with:
244+ python-version: '3.11'
245+
246+ - name: Install dependencies
247+ run: |
248+ python -m pip install --upgrade pip
249+ pip install -r requirements.txt
250+
251+ - name: Run black
252+ run: black --check hooks/ update_schema_version.py
253+
254+ - name: Run ruff
255+ run: ruff check hooks/ update_schema_version.py
256+
257+ - name: Run bandit
258+ run: bandit -r hooks/ -ll
259+ continue-on-error: true # Bandit can be overly strict
260+
261+ integration-test:
262+ name: Full integration test
263+ runs-on: ubuntu-latest
264+ needs: [test-generation, validate-schemas, test-hooks]
265+
266+ steps:
267+ - uses: actions/checkout@v4
268+
269+ - name: Set up Python
270+ uses: actions/setup-python@v5
271+ with:
272+ python-version: '3.11'
273+
274+ - name: Install dependencies
275+ run: |
276+ python -m pip install --upgrade pip
277+ pip install -r requirements.txt
278+
279+ - name: Generate and test protocol
280+ run: |
281+ # Generate a protocol
282+ python -m cookiecutter . --no-input \
283+ protocol_name=" Integration Test" \
284+ number_of_activities=3
285+
286+ cd "Integration Test"
287+
288+ # Test that Makefile works
289+ make help
290+
291+ # Check config.env was created
292+ test -f config.env
293+ grep -q "REPROSCHEMA_UI_CHECKSUM" config.env
294+
295+ # Ensure no Activity4 references
296+ if grep -r "Activity4" .; then
297+ echo "ERROR : Found Activity4 references"
298+ exit 1
299+ fi
300+
301+ echo "✓ Integration test passed!"
0 commit comments