Skip to content

Commit f338333

Browse files
vpeterssonclaude
andcommitted
fix: CI failures — remove JS lint, fix static files, format code
- Remove obsolete javascript-lint.yaml (no package.json after React removal) - Remove TypeScript test job from docker-test.yaml (no npm in container) - Simplify test-runner.yml to Python-only, add migrate + collectstatic before integration tests to fix missing staticfiles manifest - Fix settings.py to create config directory before writing screenly.conf - Apply ruff formatting to all Python files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cff0119 commit f338333

File tree

21 files changed

+86
-226
lines changed

21 files changed

+86
-226
lines changed

.github/workflows/docker-test.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,7 @@ on:
3636
workflow_call:
3737

3838
jobs:
39-
run-typescript-tests:
40-
uses: ./.github/workflows/test-runner.yml
41-
with:
42-
test-type: 'typescript'
43-
python-version: '3.11'
44-
4539
run-python-tests:
4640
uses: ./.github/workflows/test-runner.yml
4741
with:
48-
test-type: 'python'
4942
python-version: '3.11'

.github/workflows/javascript-lint.yaml

Lines changed: 0 additions & 42 deletions
This file was deleted.

.github/workflows/test-runner.yml

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ name: Test Runner
33
on:
44
workflow_call:
55
inputs:
6-
test-type:
7-
description: 'Type of tests to run (typescript or python)'
8-
required: true
9-
type: string
106
python-version:
117
description: 'Python version to use'
128
required: false
@@ -15,7 +11,7 @@ on:
1511

1612
jobs:
1713
run-tests:
18-
name: Run ${{ inputs.test-type }} tests
14+
name: Run python tests
1915
runs-on: ubuntu-24.04
2016
env:
2117
COMPOSE_FILE: docker-compose.test.yml
@@ -49,34 +45,26 @@ jobs:
4945
run: |
5046
docker compose up -d --build
5147
52-
- name: Run TypeScript tests
53-
if: inputs.test-type == 'typescript'
54-
run: |
55-
docker compose exec anthias-test \
56-
npm install
57-
docker compose exec anthias-test \
58-
npm run test
59-
6048
- name: Run Python unit tests
61-
if: inputs.test-type == 'python'
6249
run: |
6350
docker compose exec anthias-test \
6451
python -m pytest tests/ -m "not integration" --ignore=tests/test_scheduler.py --ignore=tests/test_viewer.py -x
6552
6653
- name: Setup integration test environment
67-
if: inputs.test-type == 'python'
6854
run: |
6955
docker compose exec anthias-test \
7056
bash ./bin/prepare_test_environment.sh
57+
docker compose exec anthias-test \
58+
python -m django migrate --run-syncdb
59+
docker compose exec anthias-test \
60+
python -m django collectstatic --noinput --clear
7161
7262
- name: Run Python integration tests
73-
if: inputs.test-type == 'python'
7463
run: |
7564
docker compose exec anthias-test \
7665
python -m pytest tests/test_app.py -m integration -v
7766
7867
- name: Upload coverage reports to Codecov
79-
if: inputs.test-type == 'python'
8068
uses: codecov/codecov-action@v5
8169
env:
8270
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

anthias_app/consumers.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ def connect(self) -> None:
1515
if channel_layer is not None:
1616
from asgiref.sync import async_to_sync
1717

18-
async_to_sync(channel_layer.group_add)(
19-
'viewer', self.channel_name
20-
)
18+
async_to_sync(channel_layer.group_add)('viewer', self.channel_name)
2119
logger.info('Viewer WebSocket connected')
2220

2321
def disconnect(self, close_code: int) -> None:
@@ -33,10 +31,14 @@ def disconnect(self, close_code: int) -> None:
3331
logger.info('Viewer WebSocket disconnected')
3432

3533
def viewer_command(self, event: dict) -> None:
36-
self.send(text_data=json.dumps({
37-
'command': event['command'],
38-
'data': event.get('data'),
39-
}))
34+
self.send(
35+
text_data=json.dumps(
36+
{
37+
'command': event['command'],
38+
'data': event.get('data'),
39+
}
40+
)
41+
)
4042

4143

4244
class UIConsumer(WebsocketConsumer):
@@ -48,9 +50,7 @@ def connect(self) -> None:
4850
if channel_layer is not None:
4951
from asgiref.sync import async_to_sync
5052

51-
async_to_sync(channel_layer.group_add)(
52-
'ui', self.channel_name
53-
)
53+
async_to_sync(channel_layer.group_add)('ui', self.channel_name)
5454

5555
def disconnect(self, close_code: int) -> None:
5656
from channels.layers import get_channel_layer
@@ -59,9 +59,7 @@ def disconnect(self, close_code: int) -> None:
5959
if channel_layer is not None:
6060
from asgiref.sync import async_to_sync
6161

62-
async_to_sync(channel_layer.group_discard)(
63-
'ui', self.channel_name
64-
)
62+
async_to_sync(channel_layer.group_discard)('ui', self.channel_name)
6563

6664
def ui_update(self, event: dict) -> None:
6765
self.send(text_data=json.dumps(event.get('data', {})))

anthias_app/messaging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55

66
def send_to_viewer(
7-
command: str, data: str | None = None,
7+
command: str,
8+
data: str | None = None,
89
) -> None:
910
try:
1011
from asgiref.sync import async_to_sync

anthias_app/tasks.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ def shutdown_anthias() -> None:
6969

7070

7171
def _run_periodic(
72-
func, interval_seconds: int, name: str,
72+
func,
73+
interval_seconds: int,
74+
name: str,
7375
) -> threading.Thread:
7476
def loop():
7577
while True:

anthias_app/views_ui.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ def schedule(request):
2424
@authorized
2525
def asset_tables(request):
2626
context = _get_asset_context()
27-
return render(
28-
request, 'anthias_app/assets/tables.html', context
29-
)
27+
return render(request, 'anthias_app/assets/tables.html', context)
3028

3129

3230
@authorized

anthias_django/asgi.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
from anthias_django.routing import websocket_urlpatterns # noqa: E402
1111

12-
application = ProtocolTypeRouter({
13-
'http': django_asgi_app,
14-
'websocket': URLRouter(websocket_urlpatterns),
15-
})
12+
application = ProtocolTypeRouter(
13+
{
14+
'http': django_asgi_app,
15+
'websocket': URLRouter(websocket_urlpatterns),
16+
}
17+
)

api/tests/test_assets.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ def api_client():
2222

2323

2424
def _create_asset(api_client, data):
25-
return api_client.post(
26-
ASSET_LIST_V2_URL, data=data, format='json'
27-
).data
25+
return api_client.post(ASSET_LIST_V2_URL, data=data, format='json').data
2826

2927

3028
@pytest.mark.django_db
@@ -69,14 +67,8 @@ def test_create_video_asset_with_non_zero_duration_fails(
6967
response = api_client.post(
7068
ASSET_LIST_V2_URL, data=test_data, format='json'
7169
)
72-
assert (
73-
response.status_code
74-
== status.HTTP_500_INTERNAL_SERVER_ERROR
75-
)
76-
assert (
77-
'Duration must be zero for video assets'
78-
in str(response.data)
79-
)
70+
assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
71+
assert 'Duration must be zero for video assets' in str(response.data)
8072
assert mock_rename.call_count == 1
8173
assert mock_validate_uri.call_count == 1
8274

api/tests/test_v2_endpoints.py

Lines changed: 17 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ def test_patch_invalid_auth_backend(
8989
)
9090
assert response.status_code == status.HTTP_400_BAD_REQUEST
9191
assert 'auth_backend' in response.data
92-
assert 'is not a valid choice' in str(
93-
response.data['auth_backend']
94-
)
92+
assert 'is not a valid choice' in str(response.data['auth_backend'])
9593
settings_mock.load.assert_not_called()
9694
settings_mock.save.assert_not_called()
9795

@@ -133,10 +131,7 @@ def test_patch_success(
133131
device_settings_url, data=data, format='json'
134132
)
135133
assert response.status_code == status.HTTP_200_OK
136-
assert (
137-
response.data['message']
138-
== 'Settings were successfully saved.'
139-
)
134+
assert response.data['message'] == 'Settings were successfully saved.'
140135
settings_mock.load.assert_called_once()
141136
settings_mock.save.assert_called_once()
142137
assert settings_mock.__setitem__.call_count == 5
@@ -214,21 +209,12 @@ def test_enable_basic_auth(
214209
device_settings_url, data=data, format='json'
215210
)
216211
assert response.status_code == status.HTTP_200_OK
217-
assert (
218-
response.data['message']
219-
== 'Settings were successfully saved.'
220-
)
212+
assert response.data['message'] == 'Settings were successfully saved.'
221213
settings_mock.load.assert_called_once()
222214
settings_mock.save.assert_called_once()
223-
settings_mock.__setitem__.assert_any_call(
224-
'auth_backend', 'auth_basic'
225-
)
226-
settings_mock.__setitem__.assert_any_call(
227-
'user', 'testuser'
228-
)
229-
settings_mock.__setitem__.assert_any_call(
230-
'password', expected_hashed
231-
)
215+
settings_mock.__setitem__.assert_any_call('auth_backend', 'auth_basic')
216+
settings_mock.__setitem__.assert_any_call('user', 'testuser')
217+
settings_mock.__setitem__.assert_any_call('password', expected_hashed)
232218
send_to_viewer_mock.assert_called_once_with('reload')
233219

234220
@patch('api.views.v2.settings')
@@ -273,15 +259,10 @@ def test_disable_basic_auth(
273259
device_settings_url, data=data, format='json'
274260
)
275261
assert response.status_code == status.HTTP_200_OK
276-
assert (
277-
response.data['message']
278-
== 'Settings were successfully saved.'
279-
)
262+
assert response.data['message'] == 'Settings were successfully saved.'
280263
settings_mock.load.assert_called_once()
281264
settings_mock.save.assert_called_once()
282-
settings_mock.__setitem__.assert_any_call(
283-
'auth_backend', ''
284-
)
265+
settings_mock.__setitem__.assert_any_call('auth_backend', '')
285266
send_to_viewer_mock.assert_called_once_with('reload')
286267

287268
response = api_client.get(device_settings_url)
@@ -324,15 +305,10 @@ def test_patch_default_assets(
324305
format='json',
325306
)
326307
assert response.status_code == status.HTTP_200_OK
327-
assert (
328-
response.data['message']
329-
== 'Settings were successfully saved.'
330-
)
308+
assert response.data['message'] == 'Settings were successfully saved.'
331309
settings_mock.load.assert_called_once()
332310
settings_mock.save.assert_called_once()
333-
settings_mock.__setitem__.assert_any_call(
334-
'default_assets', True
335-
)
311+
settings_mock.__setitem__.assert_any_call('default_assets', True)
336312
add_default_assets_mock.assert_called_once()
337313
remove_default_assets_mock.assert_not_called()
338314
send_to_viewer_mock.assert_called_once_with('reload')
@@ -367,15 +343,10 @@ def test_patch_default_assets(
367343
format='json',
368344
)
369345
assert response.status_code == status.HTTP_200_OK
370-
assert (
371-
response.data['message']
372-
== 'Settings were successfully saved.'
373-
)
346+
assert response.data['message'] == 'Settings were successfully saved.'
374347
settings_mock.load.assert_called_once()
375348
settings_mock.save.assert_called_once()
376-
settings_mock.__setitem__.assert_any_call(
377-
'default_assets', False
378-
)
349+
settings_mock.__setitem__.assert_any_call('default_assets', False)
379350
remove_default_assets_mock.assert_called_once()
380351
add_default_assets_mock.assert_not_called()
381352
send_to_viewer_mock.assert_called_once_with('reload')
@@ -390,20 +361,14 @@ def setup(self):
390361

391362
@patch('api.views.v2.is_balena_app')
392363
@patch('api.views.v2.getenv')
393-
def test_balena_environment(
394-
self, mock_getenv, mock_is_balena
395-
):
364+
def test_balena_environment(self, mock_getenv, mock_is_balena):
396365
mock_is_balena.side_effect = lambda: True
397366
mock_getenv.side_effect = lambda x: {
398367
'BALENA_DEVICE_UUID': 'test-device-uuid',
399368
'BALENA_APP_ID': 'test-app-id',
400369
'BALENA_APP_NAME': 'test-app-name',
401-
'BALENA_SUPERVISOR_VERSION': (
402-
'test-supervisor-version'
403-
),
404-
'BALENA_HOST_OS_VERSION': (
405-
'test-host-os-version'
406-
),
370+
'BALENA_SUPERVISOR_VERSION': ('test-supervisor-version'),
371+
'BALENA_HOST_OS_VERSION': ('test-host-os-version'),
407372
'BALENA_DEVICE_NAME_AT_INIT': 'test-device-name',
408373
}.get(x)
409374

@@ -414,12 +379,8 @@ def test_balena_environment(
414379
'balena_device_id': 'test-device-uuid',
415380
'balena_app_id': 'test-app-id',
416381
'balena_app_name': 'test-app-name',
417-
'balena_supervisor_version': (
418-
'test-supervisor-version'
419-
),
420-
'balena_host_os_version': (
421-
'test-host-os-version'
422-
),
382+
'balena_supervisor_version': ('test-supervisor-version'),
383+
'balena_host_os_version': ('test-host-os-version'),
423384
'balena_device_name_at_init': 'test-device-name',
424385
}
425386

0 commit comments

Comments
 (0)