Skip to content

Releases: teylabs/mod

v0.12.5

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 23:54
8146506

Fixed

  • A rolled-back apply leaves no maintenance file behind (a regression in 0.12.4). The append-only progress log (journal-<hash>.progress) outlived a failed or interrupted apply, so a caller that rolls back by restoring the files and removing the journal, as tey/kit does, left the log behind and the checkout differed from before.
    • Closing the claim now removes the log, so it survives only a real process death, the crash it exists for. A resume is still exact without it: files already at their target bytes reconcile.
    • A log whose journal is gone is stale. It's swept on the next prepare and never resumed from.

What's Changed

  • Release 0.12.5: remove the progress log when the claim closes; sweep stale logs by @jaspertey in #235

Full Changelog: v0.12.4...v0.12.5

v0.12.4

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 23:18
49f5f15

Fixed

  • Applying a maintenance plan is about 5× faster. Each file used to run the full checkout inspection twice: the claim check, then again when its completion was recorded. So an apply re-read every declared file about twice per file, and rewrote the whole journal, with fsync, once per file. A 154-file lineage spent about 1–3 minutes in that loop.
    • The full freshness check now runs once before the file loop and again before finalization.
    • Per file, only cheap checks run: the exclusive claim is held, the owner and the journal are unchanged, and the file still matches its planned bytes right before it's written. A drifted file aborts with the journal resumable.
    • Completed files go to an append-only progress log beside the journal (journal-<hash>.progress). Each line is fsynced before the next file is written, so a crash resumes exactly, and a torn last line is ignored. The log is removed once the lineage is recorded.
    • Files already at the target bytes are reconciled without being recorded.
    • Measured on two real apps' core lineage (154 files): about 56–99s down to 12–16s wall-clock, and about 37s down to 8s user CPU.

What's Changed

Full Changelog: v0.12.3...v0.12.4

v0.12.3

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 07:05
f65f63c

Fixed

  • The case-collision refusal names both paths: Case alias or collision at declared path resources/js/pages/Auth: the checkout already has resources/js/pages/auth., so the app knows what to rename (#225).

What's Changed

Full Changelog: v0.12.2...v0.12.3

v0.11.6

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 23:50
650a42f

Fixed

  • A rolled-back apply leaves no maintenance file behind (a regression in 0.11.5). The append-only progress log (journal-<hash>.progress) outlived a failed or interrupted apply, so a caller that rolls back by restoring the files and removing the journal, as tey/kit does, left the log behind and the checkout differed from before.
    • Closing the claim now removes the log, so it survives only a real process death, the crash it exists for. A resume is still exact without it: files already at their target bytes reconcile.
    • A log whose journal is gone is stale. It's swept on the next prepare and never resumed from.

What's Changed

  • Remove the progress log when the claim closes; sweep logs whose journal is gone (0.11.x) by @jaspertey in #234

Full Changelog: v0.11.5...v0.11.6

v0.11.5

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 23:15
9338d33

Fixed

  • Applying a maintenance plan is about 5× faster. Each file used to run the full checkout inspection twice: the claim check, then again when its completion was recorded. So an apply re-read every declared file about twice per file, and rewrote the whole journal, with fsync, once per file. A 154-file lineage spent about 1–3 minutes in that loop.
    • The full freshness check now runs once before the file loop and again before finalization.
    • Per file, only cheap checks run: the exclusive claim is held, the owner and the journal are unchanged, and the file still matches its planned bytes right before it's written. A drifted file aborts with the journal resumable.
    • Completed files go to an append-only progress log beside the journal (journal-<hash>.progress). Each line is fsynced before the next file is written, so a crash resumes exactly, and a torn last line is ignored. The log is removed once the lineage is recorded.
    • Files already at the target bytes are reconciled without being recorded.
    • Measured on two real apps' core lineage (154 files): about 56–99s down to 12–16s wall-clock, and about 37s down to 8s user CPU.

What's Changed

  • Check freshness once per apply, not per file; record progress append-only (0.11.x) by @jaspertey in #230
  • Release 0.11.5 by @jaspertey in #231

Full Changelog: v0.11.4...v0.11.5

v0.11.4

Choose a tag to compare

@jaspertey jaspertey released this 29 Oct 06:46
a8e1af9

Fixed

  • The case-collision refusal names both paths: Case alias or collision at declared path resources/js/pages/Auth: the checkout already has resources/js/pages/auth., so the app knows what to rename (#225).

What's Changed

Full Changelog: v0.11.3...v0.11.4

v0.12.2

Choose a tag to compare

@jaspertey jaspertey released this 28 Oct 05:12
adc1c27

Headline

Installed records are portable: no absolute checkout path, and a fresh clone (CI, another worktree, a teammate) can plan and apply.

Fixed

  • Committed installed records work in any checkout of the app. A record stores its root as . instead of the absolute path of the checkout that wrote it, so a clone, CI or another worktree no longer fails with Unknown, foreign or mismatched installed artifact., and no local path is committed. A record written before 0.12.2 is read anywhere and rewritten on the next update. The app id, lineage and artifact fingerprint still refuse a foreign record (#207).
  • The first update in a fresh clone no longer fails with Maintenance data requires an unlinked regular file. When .mod-maintenance/ holds only committed installed records, Mod creates the git-ignored owner.json and lock itself. A linked owner.json is still refused, and unknown content is still reported (#207).

Same fix as 0.11.3 on the 0.11 line. Fresh-install check from a real git clone: plan, apply, upgrade plan, apply; owner.json and lock created; root "." with no local path.


What's Changed

Full Changelog: v0.12.1...v0.12.2

v0.12.1

Choose a tag to compare

@jaspertey jaspertey released this 28 Oct 01:14
99d5dec

Headline

A file the host already brought to the new release is unchanged, not a conflict, so claim followed by an update no longer blocks.

Fixed

  • An owned file whose bytes already equal the new target is unchanged, not a conflict, even when it differs from its recorded original (the host applied the change itself, or took the release's bytes after claiming the file). Nothing is written, the update isn't blocked, and the installed record takes the target, so the original advances. A file that differs from both the original and the target is still a conflict (#216).

Also: tests compare real paths for Laravel 13.39's FileViewFinder realpath change. Fresh-install check: a new Laravel 13.39 app on PHP 8.5 passes mod:install and mod:list, and the install-A, host-writes-B, upgrade script plans unchanged with nothing written (it plans conflict on 0.12.0).


What's Changed

Full Changelog: v0.12.0...v0.12.1

v0.11.3

Choose a tag to compare

@jaspertey jaspertey released this 28 Oct 04:53
a375e78

Headline

Installed records are portable: they no longer store an absolute checkout path, and a fresh clone (CI, another worktree, a teammate) can plan and apply.

Fixed

  • Committed installed records work in any checkout of the app. A record stores its root as . instead of the absolute path of the checkout that wrote it, so a clone, CI or another worktree no longer fails with Unknown, foreign or mismatched installed artifact., and no local path is committed. A record written before 0.11.3 (0.12.2 on the main line) is read anywhere and rewritten on the next update. The app id, lineage and artifact fingerprint still refuse a foreign record (#207).
  • The first update in a fresh clone no longer fails with Maintenance data requires an unlinked regular file. When .mod-maintenance/ holds only committed installed records, Mod creates the git-ignored owner.json and lock itself. A linked owner.json is still refused, and unknown content is still reported (#207).

Fresh-install check from a real git clone + composer install: plan creates, apply completes, an upgrade plan replaces, apply completes; owner.json and lock are created; the record has root "." with no local path. Foreign records are still refused by app id, lineage-hash filename and artifact fingerprint.


What's Changed

Full Changelog: v0.11.2...v0.11.3

v0.11.2

Choose a tag to compare

@jaspertey jaspertey released this 28 Oct 00:54
0d45d3d

Headline

A file the host already brought to the new release is unchanged, not a conflict, so claim followed by an update no longer blocks.

Fixed

  • An owned file whose bytes already equal the new target is unchanged, not a conflict, even when it differs from its recorded original (the host applied the change itself, or took the release's bytes after claiming the file). Nothing is written, the update isn't blocked, and the installed record takes the target, so the original advances. A file that differs from both the original and the target is still a conflict (#216).

Maintenance release on the 0.11 line: the same fix as 0.12.1, for hosts on tey/mod ^0.11 (tey/kit). Fresh-install check: a new Laravel 13.39 app on PHP 8.5 requiring this branch passes mod:install and mod:list, and the install-A, host-writes-B, upgrade script plans unchanged with nothing written (it plans conflict on 0.11.1).


What's Changed

  • Plan an owned file already at the target as unchanged (0.11.x) by @jaspertey in #219

Full Changelog: v0.11.1...v0.11.2