Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
202 commits
Select commit Hold shift + click to select a range
9d5fd9e
Add the 0.1.6 plan and the two 0.1.5 audits it draws on
afit21 Oct 17, 2026
6fd0cc7
Turn off the Actions cache in the release Flatpak build (SUP-1)
afit21 Oct 17, 2026
37e1053
Add a 0.1.5 state fixture and pin the released schema steps (TS2, ND5)
afit21 Oct 17, 2026
cd3313b
Add wire known-answer vectors from 0.1.3 and 0.1.4 (TS3)
afit21 Oct 17, 2026
1ede316
Run every RNFS_E2E test module in CI (TS1)
afit21 Oct 17, 2026
cf171ff
Lint broad excepts, late imports and stale noqa comments (TS10)
afit21 Oct 17, 2026
00bb67b
Measure test coverage in CI, report only (TS4)
afit21 Oct 17, 2026
69476e0
Mark the phase 0 items done in the 0.1.6 plan
afit21 Oct 17, 2026
6d707fa
Merge phase 0 of 0.1.6: safety nets (SUP-1, TS1, TS2, TS3, TS10, TS4)
afit21 Oct 17, 2026
258afae
Document which thread or lock owns each Response field (NW2 step 1)
afit21 Oct 17, 2026
64ab89a
Don't fall back to a name link's sent CID silently (FEAT-5)
afit21 Oct 17, 2026
5c92e5a
Merge FEAT-5: don't fall back to a name link's sent CID silently
afit21 Oct 17, 2026
fbc4716
Extract the keeper query into _KeeperQuery (FT2)
afit21 Oct 17, 2026
f4708d7
CHANGELOG and plan: FEAT-5
afit21 Oct 17, 2026
0ec517b
Cool down /blocks responses cancelled before real progress (NET-1)
afit21 Oct 17, 2026
5454d5d
Bound the deny-list file-hash check (CONT-1)
afit21 Oct 17, 2026
bcc8c2f
Merge NW2 step 1 and NET-1: cool down /blocks responses cancelled bef…
afit21 Oct 17, 2026
776c501
CHANGELOG and plan: NET-1, NW2 step 1
afit21 Oct 17, 2026
cb5c93f
Answer 451 to a HEAD of a stored denied file (API-5)
afit21 Oct 17, 2026
73c8295
Give keeper /name queries their own budget, and bound lookups (DHT-1)
afit21 Oct 17, 2026
a60ea56
Merge CONT-1 and API-5: bound the deny-list file-hash check; 451 for …
afit21 Oct 17, 2026
df6bcc9
Merge FT2 extraction and DHT-1: keeper /name queries get their own bu…
afit21 Oct 17, 2026
06d4064
CHANGELOG and plan: CONT-1, API-5, FT2, DHT-1
afit21 Oct 17, 2026
04b3e2e
Make get's directory write-out immune to directory swaps (CONT-2)
afit21 Oct 17, 2026
7a868b5
Merge CONT-2: make get's directory write-out immune to directory swaps
afit21 Oct 17, 2026
620da85
CHANGELOG and plan: CONT-2
afit21 Oct 17, 2026
939ecae
Check rnfs.toml and existing subdirectories on POSIX (API-1)
afit21 Oct 17, 2026
d2aac1d
Merge API-1 (with ND6): check rnfs.toml and existing subdirectories o…
afit21 Oct 17, 2026
950bb57
CHANGELOG and plan: API-1, ND6
afit21 Oct 17, 2026
9b9ef61
Merge phase 1 of 0.1.6: medium security fixes (CONT-1, API-5, API-1, …
afit21 Oct 17, 2026
63a0157
Limit what a followed name may pin with follow_quota (DHT-3)
afit21 Oct 17, 2026
b758369
Set every LXMF feature attribute before its start-up steps run (FT1)
afit21 Oct 17, 2026
0c97eb7
Add fsutil.printable_label for labels other people choose (FEAT-6)
afit21 Oct 17, 2026
67bfafe
Tie the installed release to the requested tag (SUP-2)
afit21 Oct 17, 2026
81afb98
Drop request packets on rnfs.dht links this node opened (NET-3)
afit21 Oct 17, 2026
c64ebf5
Require provenance when gh can check it (SUP-3)
afit21 Oct 17, 2026
3fb49ae
Refuse a shared folder that resolves into the rnfs dir (CONT-3)
afit21 Oct 17, 2026
4ac4b89
Say plainly that pip installs resolve dependencies unpinned (SUP-4)
afit21 Oct 17, 2026
58fe37a
Refuse queued auto-fetches from senders taken off the list (FEAT-4)
afit21 Oct 17, 2026
4b72ea7
Never evict the node's own provider record (DHT-5)
afit21 Oct 17, 2026
c61a324
Suggest denying the CID when a file is refused by its hash (CONT-4)
afit21 Oct 17, 2026
021c7c2
Narrow the Flatpak sandbox (SUP-5)
afit21 Oct 17, 2026
c0ec333
Pace single-packet /blocks responses under an explicit upload cap (NE…
afit21 Oct 17, 2026
c00f8d7
Packaging hardening: unit drop-in, isolated postinst, http warning (S…
afit21 Oct 17, 2026
509c056
Warn that name announces reach outsiders in private mode (DHT-4)
afit21 Oct 17, 2026
81dc3a1
Give each auto-fetch sender a share of the inbox (FEAT-1)
afit21 Oct 17, 2026
4441878
Document the cost of grinding node IDs near a key (DHT-6)
afit21 Oct 17, 2026
71d7cb2
Escape names in the example and in rnfs.Client's log (FEAT-7)
afit21 Oct 17, 2026
6738659
Count untrusted LXMF messages the rate limits drop; document the limi…
afit21 Oct 17, 2026
be571fc
Cache the file-index-node page and render it under a lock (FEAT-8)
afit21 Oct 17, 2026
dda4603
Check the daemon's proof before mapping any status (API-2)
afit21 Oct 17, 2026
b565ee8
Reconnect after the proof only for daemons before 0.1.5 (API-4)
afit21 Oct 17, 2026
0d010b1
Count a browser's request without Sec-Fetch-Site as a web page's (API-7)
afit21 Oct 17, 2026
feba0f0
Document that the proof keep-open doubles how long a slot is held (AP…
afit21 Oct 17, 2026
db27b8b
Cap and sanitise the server's only use of link.rtt (NET-5)
afit21 Oct 17, 2026
8d30c61
Release the folder pins of a refused shared folder (CONT-3)
afit21 Oct 17, 2026
e6519b0
Merge CONT-3 and CONT-4: refuse a shared folder inside the rnfs dir; …
afit21 Oct 17, 2026
c1f44cf
CHANGELOG and plan: CONT-3, CONT-4
afit21 Oct 17, 2026
46fa08c
Merge NET-3, NET-2 and NET-5: drop requests on outgoing dht links; pa…
afit21 Oct 17, 2026
43c1c23
Merge SUP-2 to SUP-6, FEAT-7 and FEAT-8: install, packaging and compa…
afit21 Oct 17, 2026
1362f50
CHANGELOG and plan: NET-2, NET-3, NET-5, SUP-2 to SUP-6, FEAT-7, FEAT-8
afit21 Oct 17, 2026
3707a08
Show the sender's address and trust first in rnfs inbox (FEAT-2)
afit21 Oct 17, 2026
3193819
Merge API-2, API-4, API-7 and API-3: proof before status; version-gat…
afit21 Oct 17, 2026
6b2cd03
Merge DHT-3, DHT-5, DHT-4 and DHT-6: follow_quota; own provider recor…
afit21 Oct 17, 2026
d44198d
Raise the private-mode publish warning in rnfs.Node and rnfs.Client (…
afit21 Oct 17, 2026
6e71325
CHANGELOG and plan: API-2, API-3, API-4, API-7, DHT-3 to DHT-6
afit21 Oct 17, 2026
2db7e76
Merge FT1, FEAT-6, FEAT-4, FEAT-1, FEAT-3 and FEAT-2: LXMF inbox hard…
afit21 Oct 17, 2026
0c49aa1
CHANGELOG and plan: FT1, FEAT-1 to FEAT-4, FEAT-6
afit21 Oct 17, 2026
d970da8
Merge phase 2 of 0.1.6: low and info security fixes
afit21 Oct 17, 2026
05710e1
Prune job rate samples as they are added, not only when polled (S1)
afit21 Oct 17, 2026
e54837a
Keep a set alongside the fetcher's pending queue (A3)
afit21 Oct 17, 2026
8afce50
Check an auto-fetch's existing pin with storage.has_pin (S6)
afit21 Oct 17, 2026
e7f5626
Check block names cheaply when scanning the block store (S2)
afit21 Oct 17, 2026
d35ccfe
Read ahead in rnfs.Client/Node open() while reads are sequential (S9)
afit21 Oct 17, 2026
357f10a
Tests: drop a redundant wall-clock bound, end a hung fake request (XC6)
afit21 Oct 17, 2026
c7f05e5
Prune the routing table's bans and drops from the front (S4)
afit21 Oct 17, 2026
0f38807
Cache a shared instance's next-hop interface answers in RnsPaths (C1)
afit21 Oct 17, 2026
913cb7c
Tests: check the API route table against ROUTES and the features (ND4)
afit21 Oct 17, 2026
ebf54fb
Name what the publisher provides: ProvidedItem = Cid | DhtKey (DH3)
afit21 Oct 17, 2026
f8d000c
Correct the comment on how many lookup queries run at once (DH4)
afit21 Oct 17, 2026
33aeb1d
Rename chunker.MAX_SIZE to FASTCDC_MAX, and use walker's type constan…
afit21 Oct 17, 2026
cf19230
Test archive_size against export at msgpack header boundaries (CT5)
afit21 Oct 17, 2026
bc39bdb
Don't mark destinations used on read-only identity checks (C2)
afit21 Oct 17, 2026
fcd55d8
Count announces for the peers listing in the node's rnfs.dht handler …
afit21 Oct 17, 2026
cb944c4
Sleep the idle LXMF loop and daemon main thread instead of waking eac…
afit21 Oct 17, 2026
12727fa
Merge A3, S9, XC6 (tests) and ND4 (tests)
afit21 Oct 17, 2026
e00ff4e
CHANGELOG and plan: A3, S9, XC6, ND4
afit21 Oct 17, 2026
afb5e10
Merge S2, S4, DH3, DH4, XC8 (chunker, walker) and CT5
afit21 Oct 17, 2026
f3a059a
Merge C1, C2 and S8: fewer Reticulum daemon calls; one rnfs.dht annou…
afit21 Oct 17, 2026
f5355c6
Merge S1, S6 and S7: bounded job rate samples; has_pin; no idle 1 Hz …
afit21 Oct 17, 2026
59f0cb4
List the RNS internals C1 and C2 rely on in test_rns_compat
afit21 Oct 17, 2026
57cb0f3
Look up the open links' paths together at the start of a fetch (C1)
afit21 Oct 17, 2026
0cd296a
Compare walker.kind_of results with walker's type constants (XC8)
afit21 Oct 17, 2026
b4e92dd
CHANGELOG and plan: C1, C2, S1, S2, S4, S6, S7, S8 and the small row
afit21 Oct 17, 2026
bd2b585
Take and free a request slot in one place, RequestServer._in_slot (NW4)
afit21 Oct 17, 2026
832cd6e
Check features' responses with protocol.body_refusal; drop take and s…
afit21 Oct 17, 2026
13f432f
Log unexpected exceptions at WARNING inside the except; rnfs.log.Thro…
afit21 Oct 17, 2026
055a81d
Merge NW4, NW6 and XC4 step 3: one place for request slots; body_refu…
afit21 Oct 17, 2026
01c701b
CHANGELOG and plan: NW4, NW6, XC4 step 3
afit21 Oct 17, 2026
25cc40d
Merge phase 3 of 0.1.6: quick wins (A3, C1, C2, S1, S2, S4, S6-S9) an…
afit21 Oct 17, 2026
88427f1
Share one block validity check, blockstore.matches (XC8)
afit21 Oct 17, 2026
8e8d77d
Merge XC8 blockstore.matches: one block validity check
afit21 Oct 17, 2026
b458067
Plan: XC8 matches done
afit21 Oct 17, 2026
c08ec37
List the node's stores in one place (XC5)
afit21 Oct 17, 2026
d928762
Make stop() exception-safe and bound every thread by its budget (XC5)
afit21 Oct 17, 2026
63c404b
Merge XC5: the node's stores in one list; an exception-safe stop with…
afit21 Oct 17, 2026
5921441
Have follow, deny and keepers wait for their threads when they stop (…
afit21 Oct 17, 2026
6b71533
CHANGELOG and plan: XC5
afit21 Oct 17, 2026
07c0d38
Add statedb.RowStore, open_store, delete_rows and reconcile_pins (XC2)
afit21 Oct 17, 2026
1f414bc
Move pin_names onto RowStore; write a pin's name non-durably (XC2, S3)
afit21 Oct 17, 2026
8218829
Move contacts onto RowStore (XC2)
afit21 Oct 17, 2026
d3846e8
Move jobs onto RowStore (XC2)
afit21 Oct 17, 2026
a21781e
Move the publisher's state onto RowStore (XC2)
afit21 Oct 17, 2026
1dcb7e0
Add the block write durability benchmark for plan B's decision gate (B)
afit21 Oct 17, 2026
2c1ecbb
Merge XC2 (part) and S3: statedb.RowStore for pin names, contacts, jo…
afit21 Oct 17, 2026
88d9382
CHANGELOG and plan: XC2 (part), S3
afit21 Oct 17, 2026
807d05d
Merge the block write durability benchmark for plan B's decision gate
afit21 Oct 17, 2026
d618515
Plan: B's benchmark harness done, NVMe numbers; the gate waits for th…
afit21 Oct 17, 2026
1383421
Merge phase 4 of 0.1.6: lifecycle and state (XC5, XC2, S3), blockstor…
afit21 Oct 17, 2026
a92edf6
Pass builder.BuildOptions(chunker, check) explicitly instead of Conte…
afit21 Oct 17, 2026
60941cc
Shared folder: re-read only the files that changed inside a changed e…
afit21 Oct 17, 2026
f3fc39d
Share DAG child listing, the index step and the path walk between wal…
afit21 Oct 17, 2026
a8b918b
Give cache records and "what stopped being complete" one implementati…
afit21 Oct 17, 2026
d677df6
Persist the shared folder's per-file cache in the state database (D1)
afit21 Oct 17, 2026
f109d25
Remember subtree heights across dir set / dir rm edits (D2)
afit21 Oct 17, 2026
9e760b5
Merge CT2 and D1: explicit BuildOptions; the shared folder re-reads o…
afit21 Oct 17, 2026
ef53bba
CHANGELOG and plan: CT2, D1
afit21 Oct 17, 2026
34f72e8
Stop re-walking complete DAGs under the storage lock (D3)
afit21 Oct 17, 2026
484f05b
Merge CT1, CT4, D2 and D3: shared DAG walking in storage; memoised he…
afit21 Oct 17, 2026
edc5eff
CHANGELOG and plan: CT1, CT4, D2, D3
afit21 Oct 17, 2026
daff3ef
Merge phase 5 of 0.1.6: storage (CT1, CT4, CT2, D1, D2, D3)
afit21 Oct 17, 2026
beebbf9
Share one FakeClient and a quiet-log fixture; check fakes against Pee…
afit21 Oct 17, 2026
25e7cb8
Check the Flatpak sources in the tests workflow, and build release ar…
afit21 Oct 17, 2026
24329b9
Add provider records through one _insert, and check the store's index…
afit21 Oct 17, 2026
ed86aaa
Remember files found not sealed; read_file opens a sealed file once (E2)
afit21 Oct 17, 2026
b2c0111
Pure _DagBudget passed to ensure, typed fetch events, progress writes…
afit21 Oct 17, 2026
d094d19
Add CONTRIBUTING.md, check CHANGELOG's version, and take release note…
afit21 Oct 17, 2026
faa62a4
Check the supported-Python lists agree with the tests matrix (TS7)
afit21 Oct 17, 2026
80a8ce4
Share the /blocks size rules in rates: response_capacity and default_…
afit21 Oct 17, 2026
628ae2d
Remember complete pins' type, name and sealed status in pin ls (E2)
afit21 Oct 17, 2026
e0df4e3
Add a Dependabot configuration for the workflows' actions, and pip re…
afit21 Oct 17, 2026
4252b6c
Update the roadmap, and give the specification a version and compatib…
afit21 Oct 17, 2026
208176a
Skip local debris in the Flatpak's source copy, ship no CIDs in the i…
afit21 Oct 17, 2026
7bc4648
Give names a _refresh_name and a _NameFloor class (DH1)
afit21 Oct 17, 2026
171503f
Inject the wait of a name refresh (XC6, names)
afit21 Oct 17, 2026
19ae2bc
Cheaper publisher refresh after an add: cached pinned CIDs, one pass …
afit21 Oct 17, 2026
4da7918
Merge TS5, TS6, TS7, TS8, TS11 and TS12: docs and CI
afit21 Oct 17, 2026
43c4314
CHANGELOG and plan: TS5 to TS8, TS11, TS12
afit21 Oct 17, 2026
9e495a4
Clamp provider times only after the clock went backwards (S5)
afit21 Oct 17, 2026
cbbbe3f
Merge DH2 and S5: one insert path for provider records; clamp only af…
afit21 Oct 17, 2026
fc0e2c9
CHANGELOG and plan: DH2, S5
afit21 Oct 17, 2026
c31372b
Detect a replayed announce by its own emission time (DHT-2)
afit21 Oct 17, 2026
491f33f
Merge E2 and E3: not-sealed and pin ls memos; a cheaper publisher ref…
afit21 Oct 17, 2026
ea4b046
CHANGELOG and plan: E2, E3
afit21 Oct 17, 2026
07c11d1
Reuse and share a name resolve's network refresh (E1)
afit21 Oct 17, 2026
ae0279f
Merge XC7, NW1 and NW5: one FakeClient; _DagBudget and typed events; …
afit21 Oct 17, 2026
2240be0
Merge DH1, XC6, DHT-2 and E1: name floor and refresh; replayed announ…
afit21 Oct 17, 2026
fe0bfe6
CHANGELOG and plan: DH1, XC6, DHT-2, E1
afit21 Oct 17, 2026
a724ed8
Call the request server's backend methods directly (XC7)
afit21 Oct 17, 2026
cf6b78e
Plan: XC7, NW1, NW5 done
afit21 Oct 17, 2026
f14ecd5
Merge phase 7 of 0.1.6: names, DHT and node (DH1, XC6, DHT-2, E1, DH2…
afit21 Oct 17, 2026
e16a958
Merge dev (phases 5 and 7) into phase 8
afit21 Oct 17, 2026
d68bf4a
Give block mismatches and sealed-file errors their own classes, from …
afit21 Oct 17, 2026
d53b0d8
Check dir rm's target in the node, before fetching (ND3)
afit21 Oct 17, 2026
0789612
Ask for read_range's next window before handing the reader this one (A1)
afit21 Oct 17, 2026
a3830f2
Give ApiConnection a typed method for every core route (ND4 client)
afit21 Oct 17, 2026
188229d
Index the security tests by audit ID, module and fix commit (TS9)
afit21 Oct 17, 2026
b776ac0
Merge TS9: index the security tests by audit ID, module and fix commit
afit21 Oct 17, 2026
4a095f8
CHANGELOG and plan: TS9
afit21 Oct 17, 2026
d7406a9
Merge XC4 steps 1-2, ND3 and ND4 (client): one error table; dir rm ch…
afit21 Oct 17, 2026
7ef8296
CHANGELOG and plan: XC4 steps 1-2, ND3, ND4 (client)
afit21 Oct 17, 2026
a4eb2e7
Queue a block's children as soon as it is met in fetch_dag and fetch_…
afit21 Oct 17, 2026
3a83b64
Declare the features each feature uses, and type the contacts accesso…
afit21 Oct 17, 2026
afa3820
Ask an idle provider for a batch dripping in past deadline_slack (NET-4)
afit21 Oct 17, 2026
eb5a2a2
Check feature routes and paths at load; lifecycle and escaping tests;…
afit21 Oct 17, 2026
11e92ab
Merge FT4 and FT5: declared feature dependencies; feature routes and …
afit21 Oct 17, 2026
a309012
CHANGELOG and plan: FT4, FT5
afit21 Oct 17, 2026
ac9ed4f
Don't close a link another fetch has a request on (A1, NET-4)
afit21 Oct 17, 2026
fce12b8
Merge A1, A4 and NET-4: read-ahead across windows, per-block tree wal…
afit21 Oct 17, 2026
62e2646
CHANGELOG and plan: A1, A4, NET-4; A2 deferred until Q1
afit21 Oct 17, 2026
4685346
Merge phase 6 of 0.1.6: fetcher (XC7, NW1, NW5, A1, A4, NET-4)
afit21 Oct 17, 2026
ecbd474
Merge dev (phases 6 and 7) into phase 8
afit21 Oct 17, 2026
30578c0
Index NET-4's regression test (TS9)
afit21 Oct 17, 2026
d042534
Parse 32-hex IDs in one place, rnfs/ids.py (XC3)
afit21 Oct 17, 2026
dc15914
One constant for two missed announces; KIND_NAMES in dag.py (XC8)
afit21 Oct 17, 2026
fb21ead
Describe the fetcher's read-ahead, per-block walk and end game in des…
afit21 Oct 17, 2026
0c9685d
Merge XC3 and the rest of XC8: rnfs/ids.py; one constant for two miss…
afit21 Oct 17, 2026
49a62d1
CHANGELOG and plan: XC3, the rest of XC8
afit21 Oct 17, 2026
9d45868
CHANGELOG: gather 0.1.6's upgrade notes at the top of its entry
afit21 Oct 17, 2026
65c11f6
Add a cross-version interop harness: this tree's daemons against old …
afit21 Oct 17, 2026
ef48e45
Merge phase 8 of 0.1.6: shared helpers, tests, CI and docs
afit21 Oct 17, 2026
1db0e4f
Merge the cross-version interop harness (tests/interop.py)
afit21 Oct 17, 2026
cdf2d19
CONTRIBUTING: how to run the cross-version interop harness
afit21 Oct 17, 2026
1312b9c
Close links before waiting for the node's threads at stop (XC5)
afit21 Oct 17, 2026
c1a5b16
Plan: tick the release checklist items that hold, and say why the res…
afit21 Oct 17, 2026
ace8ac7
Plan: Q1 answered, B and A2 deferred to 0.1.7
afit21 Oct 18, 2026
1a6377d
Roadmap: B and A2 in 0.1.7
afit21 Oct 18, 2026
470538a
Version 0.1.6
afit21 Oct 18, 2026
0a3cabc
Fix three tests that assumed Linux (macOS and Windows CI)
afit21 Oct 18, 2026
9dfb3a4
Merge main (README updates) into dev
afit21 Oct 18, 2026
0e9daa8
Expect CONT-2's documented Windows behaviour in its node-level swap test
afit21 Oct 18, 2026
a62f915
Make two real-RNS security tests work on Windows CI (TS1)
afit21 Oct 18, 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
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Dependabot (TS8). Turning on Dependabot alerts and security updates is a repository setting; this file only
# configures version updates.
version: 2
updates:
# The workflows pin every action to a commit SHA with its tag in a comment; Dependabot updates both together.
# One grouped pull request a week. The Flatpak and Debian container digests in release.yml aren't covered:
# update those by hand
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns: ["*"]

# Report only: open-pull-requests-limit 0 turns off version-update pull requests for pyproject.toml's
# dependencies, while a vulnerable one is still reported (Dependabot alerts and security updates, once turned on
# in the repository's settings). rnfs relies on RNS and LXMF internals, so a new version is taken deliberately:
# packaging/update-lock.py, packaging/flatpak/generate-sources.py and tests/test_rns_compat.py (CONTRIBUTING.md)
- package-ecosystem: pip
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 0
82 changes: 47 additions & 35 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ name: release

# Push a tag vX.Y.Z (matching rnfs.__version__) to build every package and publish a GitHub Release with them,
# SHA256SUMS and signed build provenance. Run it by hand (workflow_dispatch, on any branch or tag) to build the
# same artifacts without releasing.
# same artifacts without releasing. It also builds them, without releasing, for a pull request that changes the
# packaging or the workflows and once a week, so a build that only a release runs (the Flatpak, the Windows exe,
# the arm64 .deb, the Debian 12 smoke test) is known to work before a tag is pushed.
on:
push:
tags: ["v*"]
pull_request:
paths: ["packaging/**", "pyproject.toml", ".github/**"]
schedule:
- cron: "23 5 * * 1" # Mondays, 05:23 UTC
workflow_dispatch:

permissions:
Expand All @@ -17,9 +23,10 @@ permissions:
# --require-hashes, and builds run without build isolation, so nothing unpinned is fetched for a build.
jobs:
# The whole tests workflow (unit and end-to-end tests on every OS and Python, lint, packaging smoke tests);
# the release waits for it
# the release waits for it. A pull request runs tests.yml itself, so it isn't run twice
tests:
uses: ./.github/workflows/tests.yml
if: github.event_name != 'pull_request'

version:
runs-on: ubuntu-latest
Expand All @@ -39,6 +46,28 @@ jobs:
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
# The release notes are CHANGELOG.md's section for this version (`## X.Y.Z`, ended by the next `## `). A tag
# needs it to be the first section and no longer marked "(unreleased)"; any other run takes the version's
# section as it stands
- name: Release notes from CHANGELOG.md (and check the version's section is released)
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
first=$(grep -m1 '^## ' CHANGELOG.md)
if [ "${GITHUB_REF_TYPE}" = tag ] && [ "$first" != "## $VERSION" ]; then
echo "::error::CHANGELOG.md's first section is \"$first\", not \"## $VERSION\" (still unreleased?)"
exit 1
fi
awk -v heading="## $VERSION" '
/^## / { if (on) exit; on = ($0 == heading || index($0, heading " (") == 1); next }
on' CHANGELOG.md > release-notes.md
grep -q . release-notes.md || { echo "::error::CHANGELOG.md has no section for $VERSION"; exit 1; }
cat release-notes.md
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: notes # not release-*: it isn't one of the release's files
path: release-notes.md
if-no-files-found: error

python:
name: wheel and sdist
Expand Down Expand Up @@ -118,32 +147,10 @@ jobs:
path: dist/*.deb
if-no-files-found: error

flatpak-sources:
name: flatpak sources
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false # no token left in .git/config for the build code that runs next
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
# The Flatpak's wheels must be the ones packaging/requirements.lock pins (what every other package
# installs): regenerate them from the lock and fail if that changes the committed files
- name: Check the pinned Flatpak wheels match packaging/requirements.lock
run: |
python -I packaging/flatpak/generate-sources.py
git diff --exit-code -- packaging/flatpak || {
echo "::error::packaging/flatpak/*.json is out of date: run python3 packaging/flatpak/generate-sources.py and commit"
exit 1
}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: flatpak-sources
path: packaging/flatpak/*.json

# The committed packaging/flatpak/*.json are built: the tests workflow (tests.yml's flatpak-sources job, which
# the release waits for) checks they match packaging/requirements.lock
flatpak:
needs: [version, flatpak-sources]
needs: version
runs-on: ubuntu-latest
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08@sha256:c91a88269eee8fcdd73ecf43064232fbebe27411f926f63f38bdf70c51f2ceae
Expand All @@ -152,16 +159,14 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false # no token left in .git/config for the build code that runs next
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: flatpak-sources
path: packaging/flatpak
- uses: flatpak/flatpak-github-actions/flatpak-builder@79327416609af08178ad73b352877e51450790b3 # v6
with:
manifest-path: packaging/flatpak/io.github.afit21.rnfs.yml
bundle: rnfs.flatpak
arch: x86_64
cache-key: flatpak-builder-${{ github.sha }}
# No Actions cache: any default-branch workflow can write one, and a restored cache would go into the
# attested bundle
cache: false
upload-artifact: false
- name: Install and smoke test the bundle
# Best effort: running sandboxed apps inside the CI container depends on the runner's kernel settings
Expand All @@ -171,6 +176,8 @@ jobs:
flatpak run io.github.afit21.rnfs --version
if command -v python3 >/dev/null; then
mkdir -p "$HOME/smoke-tmp"
# The sandbox reaches only ~/.rnfs, ~/.reticulum and Downloads unless granted more
flatpak override --user --filesystem="$HOME/smoke-tmp" io.github.afit21.rnfs
TMPDIR="$HOME/smoke-tmp" python3 packaging/smoke_test.py flatpak run io.github.afit21.rnfs
fi
- name: Name it for the release
Expand Down Expand Up @@ -237,6 +244,10 @@ jobs:
pattern: release-*
path: artifacts
merge-multiple: true
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: notes
path: notes
- name: Checksums
working-directory: artifacts
run: |
Expand All @@ -252,15 +263,16 @@ jobs:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ needs.version.outputs.version }}
# A release already made for this tag on GitHub's release page gets the files attached rather than
# failing; otherwise the release is created here. Files already attached are never replaced (no
# --clobber): users may have downloaded and checked them, so a re-run with the same names fails instead
# failing (its notes are left as they are); otherwise the release is created here, with the version's
# CHANGELOG.md section as its notes. Files already attached are never replaced (no --clobber): users may
# have downloaded and checked them, so a re-run with the same names fails instead
run: |
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release upload "$GITHUB_REF_NAME" artifacts/* --repo "$GITHUB_REPOSITORY"
else
gh release create "$GITHUB_REF_NAME" artifacts/* \
--repo "$GITHUB_REPOSITORY" \
--title "rnfs $VERSION" \
--generate-notes \
--notes-file notes/release-notes.md \
--verify-tag
fi
60 changes: 55 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,46 @@ jobs:
python -m pip check
- name: Unit tests
run: python -m unittest discover tests
# On Windows the daemons are started in their own process groups and stopped with CTRL_BREAK_EVENT
# On Windows the daemons are started in their own process groups and stopped with CTRL_BREAK_EVENT. Every
# module gated on RNFS_E2E is listed here (test_packaging checks it): the embedded node and the security
# regressions that need real RNS included
- name: End-to-end tests (real daemons over local TCP)
env:
RNFS_E2E: "1"
run: python -m unittest tests.test_e2e tests.test_client
timeout-minutes: 10
run: >-
python -m unittest tests.test_e2e tests.test_client tests.test_embedded tests.security.test_h1_real_rns
tests.security.test_m1_real_rns tests.security.test_h2_display_page_pins
timeout-minutes: 20
- name: Command works
run: rnfs --version

# ruff with the rules in pyproject.toml (pyflakes, syntax errors, a few bugbear checks), and no merge-conflict
# markers left in any file
# Line coverage of the whole suite, the real-RNS tests included: a report only, with no threshold. The daemons
# the end-to-end tests start run in their own processes, which aren't measured
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- name: Install (and coverage, from packaging/build-tools.lock)
run: |
python -m pip install --require-hashes --only-binary=:all: -r packaging/requirements.lock
python -m pip install --require-hashes --only-binary=:all: -r packaging/build-tools.lock
python -m pip install --no-deps --no-build-isolation .
python -m pip check
- name: Tests under coverage
env:
RNFS_E2E: "1"
run: python -m coverage run --source=rnfs -m unittest discover tests
timeout-minutes: 30
- name: Report
run: python -m coverage report --sort=cover

# ruff with the rules in pyproject.toml (pyflakes, syntax errors, a few bugbear checks, broad excepts, late
# imports, stale noqa comments), and no merge-conflict markers left in any file
lint:
runs-on: ubuntu-latest
steps:
Expand All @@ -65,6 +94,27 @@ jobs:
- name: No merge-conflict markers
run: "! git grep -nE '^(<<<<<<<|>>>>>>>)( |$)|^=======$' -- . ':!*.lock'"

# The Flatpak's wheels must be the ones packaging/requirements.lock pins (what every other package installs):
# regenerate them from the lock and fail if that changes the committed files. Run here, not only at release, so
# a lock bump that forgets them fails before a vX.Y.Z tag is pushed; the release builds the committed files
flatpak-sources:
name: flatpak sources
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false # no token left in .git/config for the build code that runs next
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- name: Check the pinned Flatpak wheels match packaging/requirements.lock
run: |
python -I packaging/flatpak/generate-sources.py
git diff --exit-code -- packaging/flatpak || {
echo "::error::packaging/flatpak/*.json is out of date: run python3 packaging/flatpak/generate-sources.py and commit"
exit 1
}

# The packages the release workflow builds, smoke-tested: wheel/sdist, .deb, install.sh, PyInstaller binary
packaging:
runs-on: ubuntu-latest
Expand Down
Loading
Loading