Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c7ab7d8
fix(jmap): correctness fixes + dedup from June 2026 review
tobixen Jun 19, 2026
f6283c6
chore: server compatibility matrix
tobixen Jun 15, 2026
b14ba43
test: server-compatibility test suite
tobixen Jun 16, 2026
a055e52
fix: compatibility: comp-type-less search
tobixen Jun 16, 2026
851d26b
docs(tests): correcting some misinformation
tobixen Jun 4, 2026
e7b51ef
fix: compatibility: set calendar canonical URL on create
tobixen Jun 16, 2026
2c1dc8e
fix: config-section handling for get_davclient
tobixen Jun 10, 2026
9fe3d19
fix: some icalendar handling was incorrect
tobixen Jun 11, 2026
a8146f5
fix: eight crash/wrong-result bugs from code review
tobixen Jun 11, 2026
55f441b
fix: URL.canonical() __eq__-problems
tobixen Jun 11, 2026
6cdc334
fix: search.py code-review bugs
tobixen Jun 11, 2026
7aaf803
fix: Several silent wrong-result bugs
tobixen Jun 11, 2026
31d61c6
fix: require_tls=True not enforced on well-known URI redirect
tobixen Jun 11, 2026
e907f45
fix: XML parser in response.py lacked entity hardening
tobixen Jun 11, 2026
d6e66cf
fix: three more crash bugs from code review
tobixen Jun 11, 2026
1fec2a9
fix: let PYTHON_CALDAV_COMMDUMP yield warnings
tobixen Jun 18, 2026
e756ca3
fix: code-review edge-case bugs (§1.2–1.5, §2.14, §2.15)
tobixen Jun 11, 2026
37d1b69
docs: SECURITY notes + code review cleanup
tobixen Jun 13, 2026
d05e6e6
fix: replace empty except-blocks with warn/skip logic
tobixen Jun 14, 2026
da340ad
perf: use calendar-multiget on unloaded search results
tobixen Jun 14, 2026
349b213
refactor: unify search.py sync/async driver protocol
tobixen Jun 14, 2026
ce01348
refactor: dedup rate-limit + get_calendars logic between sync/async c…
tobixen Jun 14, 2026
5ae5c94
refactor: dedup calendarobjectresource (a)sync twins
tobixen Jun 14, 2026
20f9ccf
refactor: dedup sync/async multistatus/multiget twins (§5.7)
tobixen Jun 14, 2026
215807a
refactor: collapse sync/async get_objects_by_sync_token twins
tobixen Jun 14, 2026
8cde9ab
refactor: accept generic <error>/<responsedescription> without server…
tobixen Jun 14, 2026
aa6f7ab
docs: CHANGELOG for v3.3.0, and rewrite the http-libraries background
tobixen Jun 15, 2026
ed54c87
fix: async Principal.calendar() raised TypeError instead of returning…
tobixen Jun 16, 2026
7131d7b
chore(pre-commit): bump hook versions to current latest
tobixen Jun 28, 2026
247a008
refactor(pre-commit): migrate deprecated ruff hook id to ruff-check
tobixen Jun 28, 2026
644deca
docs: replace dead www.open-xchange.com link with ox.io
tobixen Jul 26, 2026
8155c9c
ci: let the link checker reuse and close a single report issue
tobixen Jul 26, 2026
6fc8600
ci: add pip-audit dependency audit as a tox env and a scheduled workflow
tobixen Aug 11, 2026
cfbb321
ci: gate the link checker issue steps on master, not main
tobixen Aug 11, 2026
4a3571f
ci: key the pip cache on pyproject.toml instead of the removed setup.py
tobixen Aug 11, 2026
cf88f5e
ci: drop the bogus y39 entry from the tox envlist
tobixen Aug 11, 2026
8737f8e
chore: drop dead setuptools configuration from pyproject.toml
tobixen Aug 11, 2026
992e088
ci: rename [tox:tox] to [tox] so the envlist takes effect
tobixen Aug 11, 2026
78e340b
style: reformat test_caldav_unit.py for ruff-format v0.15.20
tobixen Aug 16, 2026
0a54d34
chore: ignore docs/design/tmp-* scratch files
tobixen Aug 16, 2026
2bbfe0e
docs: use a reserved example domain in the require_tls docstring
tobixen Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: audit

# Dependency vulnerability audit (pip-audit, see the `audit` env in tox.ini).
#
# This is deliberately *not* wired into the `tests` workflow: a new advisory
# can be published against an unchanged dependency tree, so the audit is
# time-triggered rather than change-triggered. The pull_request trigger is
# narrowed to the files that can change the dependency tree.
on:
pull_request:
paths:
- pyproject.toml
- tox.ini
- .github/workflows/audit.yml
workflow_dispatch:
schedule:
# Mondays 04:17 UTC, well clear of the nightly link check (22:03).
- cron: "17 4 * * 1"

concurrency:
group: audit-${{ github.ref }}
cancel-in-progress: false

jobs:
pip-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
# hatch-vcs derives the version from git tags; without them the
# project metadata pip-audit reads cannot be built.
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip|${{ hashFiles('pyproject.toml') }}|${{ hashFiles('tox.ini') }}
- run: pip install tox
- name: Audit dependencies for known vulnerabilities
run: tox -e audit
Comment on lines +27 to +43
46 changes: 37 additions & 9 deletions .github/workflows/linkcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,57 @@ on:
schedule:
- cron: "03 22 * * *"

concurrency:
group: linkcheck-${{ github.ref }}
cancel-in-progress: false

jobs:
linkcheck:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/checkout@v5
- name: Restore lychee cache
uses: actions/cache@v4
with:
path: .lycheecache
key: cache-lychee-${{ github.run_id }}
restore-keys: cache-lychee-
- name: Check links with Lychee
id: lychee
uses: lycheeverse/lychee-action@v2
with:
fail: false
args: >-
--root-dir "$(pwd)"
--timeout 20
--max-retries 3
--timeout 30
--max-retries 6
--retry-wait-time 2
--cache
--max-cache-age 14d
.
- name: Create Issue From File
if: steps.lychee.outputs.exit_code != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: Link Checker Report
content-filepath: ./lychee/out.md
labels: report, automated issue
- name: Create or update Link Checker issue
if: steps.lychee.outputs.exit_code != 0 && github.ref == 'refs/heads/master'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Keep the oldest open report issue as canonical, fold duplicates in.
ISSUES=$(gh issue list --label "report" --state open --json number --jq '.[].number' | sort -n)
CANON=$(printf '%s\n' "$ISSUES" | head -1)
for n in $(printf '%s\n' "$ISSUES" | tail -n +2); do
gh issue close "$n" --comment "Duplicate of #${CANON} - auto-closed by the link checker."
done
if [ -n "$CANON" ]; then
gh issue edit "$CANON" --body-file ./lychee/out.md
else
gh issue create --title "Link Checker Report" --body-file ./lychee/out.md --label "report" --label "automated issue"
fi
- name: Close Link Checker issue if all links are healthy
if: steps.lychee.outputs.exit_code == 0 && github.ref == 'refs/heads/master'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for n in $(gh issue list --label "report" --state open --json number --jq '.[].number'); do
gh issue close "$n" --comment "All links are now healthy."
done
8 changes: 4 additions & 4 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }}
key: pip|${{ hashFiles('pyproject.toml') }}|${{ hashFiles('tox.ini') }}
- run: pip install tox
- name: Configure Baikal with pre-seeded database
run: |
Expand Down Expand Up @@ -326,7 +326,7 @@ jobs:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }}
key: pip|${{ hashFiles('pyproject.toml') }}|${{ hashFiles('tox.ini') }}
- run: pip install tox
- run: tox -e docs
style:
Expand All @@ -339,7 +339,7 @@ jobs:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }}
key: pip|${{ hashFiles('pyproject.toml') }}|${{ hashFiles('tox.ini') }}
- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
Expand All @@ -356,7 +356,7 @@ jobs:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip|${{ hashFiles('setup.py') }}|${{ hashFiles('tox.ini') }}
key: pip|${{ hashFiles('pyproject.toml') }}|${{ hashFiles('tox.ini') }}
- run: pip install tox
- run: tox -e deptry
# The three async-* jobs below exist to test the async backend *selection* logic,
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ tests/docker-test-servers/*/baikal-backup/
!tests/docker-test-servers/baikal/Specific/
# Local test server configuration (may contain credentials)
tests/caldav_test_servers.yaml
# Lychee link checker cache
.lycheecache
# Scratch files from AI sessions (review notes, draft commit messages)
docs/design/tmp-*
2 changes: 2 additions & 0 deletions .lycheeignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
https?://your\.server\.example\.com/.*
https?://.*\.example\.com(:\d+)?(/.*)?$
https?://domain/.*
https?://evil.attacker.com/caldav/

# Localhost URLs for test servers (not accessible in CI)
http://localhost:\d+/.*
Expand All @@ -17,6 +18,7 @@ https://caldav\.gmx\.net/.*
https://caldav\.icloud\.com/.*
https://p\d+-caldav\.icloud\.com/.*
https://posteo\.de:\d+/.*
https://sync\.infomaniak\.com/.*
https://purelymail\.com/.*
https://webmail\.all-inkl\.com/.*
https://www\.google\.com/calendar/dav/.*
Expand Down
14 changes: 7 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
---
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.4
rev: v0.15.20
hooks:
- id: ruff
- id: ruff-check
args: [--fix]
- id: ruff-format

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: check-byte-order-marker
- id: fix-byte-order-marker
- id: trailing-whitespace
- id: end-of-file-fixer

- repo: https://github.com/pycalendar/ai-prompt-auto-commit
rev: v0.0.5
rev: v0.0.8
hooks:
- id: unstage-ai-prompts
- id: append-ai-prompts
Expand All @@ -26,13 +26,13 @@ repos:
stages: [manual]

- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.4.0
rev: v4.4.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]

- repo: https://github.com/lycheeverse/lychee
rev: lychee-v0.24.1
rev: lychee-v0.24.2
hooks:
- id: lychee
args: ["--no-progress", "--timeout", "10", "--exclude-path", ".lycheeignore", "--max-cache-age=30d", "--cache"]
Expand Down
Loading
Loading