- src/server.py: CALDAV_DATA_PATH validation moved from import-time to
_validate_startup_config(), called on __main__ or MCP_ICS_VALIDATE_ON_IMPORT=1.
Module is now importable in tests without env setup.
- tests/: Radicale fixture tree (VCALENDAR/VADDRESSBOOK, hidden dirs, corrupt
props, bad ics), covers discover_calendars, parse_ics_files, component_to_dt,
format_dt, format_component (exclude/birthday filters, VEVENT vs VTODO shape),
get_events_in_range (RRULE expansion, cross-calendar aggregation, sort),
get_agenda (default +7d end, error dict, flag forwarding), /health endpoint,
_validate_startup_config. 31 tests, <2s.
- .gitea/workflows/_ci-common.yaml: new pytest job running the test suite
inside the built CI image (prod requirements).
- pkg/Dockerfile: COPY tests/
Split the monolithic docker-build/release/test workflows into the shared
_ci-common.yaml + trigger-specific files used on web/mydl:
- pr.yaml -> PR checks (hadolint + build smoke test)
- main.yaml -> CI + local build + git semver tag (PAT, triggers tag.yaml)
- tag.yaml -> CI + build/push :vX.Y.Z and :vX.Y.Z-latest (sole Docker push)
- cron.yaml -> nightly rebuild of :vX.Y.Z-latest
- _ci-common.yaml -> hadolint + build-test with docker smoke and GHA cache
Docker pushes to :latest on every merge are replaced by versioned,
tested tags. The tag job uses SA_TOKEN_ACTION_PUSH_TAGS (a PAT) so the
tag push actually triggers tag.yaml - GITHUB_TOKEN would not.