-
Phandroid v2.0.86-dev Pre-release
released this
2026-10-23 08:03:15 +02:00 | 0 commits to main since this releaseFixed
- The images inside an edit-history snapshot can be opened again. A snapshot is a
StatusEditand carries no status id, so the preview cards in the history sheet
rendered media links pointing at/s/undefined: the thumbnails were there, tapping
them did nothing, and the page's own viewer could not help either — it resolves its
attachments from the store by status id, and a snapshot is never in the store. Tapping
a snapshot's image now opens the real viewer with that snapshot's attachments
(carousel, zoom, alt text, captions, and the back button closes the image before the
sheet). The same links are broken on the web, so the fix is not gated on native.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The images inside an edit-history snapshot can be opened again. A snapshot is a
-
Phandroid v2.0.25 Stable
released this
2026-10-23 06:56:20 +02:00 | 4531 commits to main since this releaseSame fixes as dev 2.0.81 — the upstream-merge model and the release-pipeline fixes of 2026-10-18/19.
Fixed
- The F-Droid "What's New" can no longer be blocked by a changelog entry that mentions
a heading. The converter stripped backticks and bold but left a literal###in the
text, so the release gate's "no Markdown left" assertion failed — and that is exactly
what happened to 2.0.81 on the dev channel: the entry about the duplicate### Changed
heading fed its own heading into the What's New text, the gate refused, and the release
was never signed (dev stayed on 2.0.80). The converter now drops heading hash runs (the
words stay, so the entry still reads correctly), which makes its guarantee hold for any
input. prod was not affected. merge=ourscan no longer silently discard your change. The fork-owned files
(README, CHANGELOG, LICENSE, SECURITY, PRIVACY) must keep our version on an upstream
merge — but git calls that driver for every three-way merge, and on a rebase or
cherry-pick "ours" is the branch being replayed onto while "theirs" is your commit.
The built-intruetherefore threw your change away, silently: it did exactly that
three times on 2026-10-18/19 (both prod cherry-picks and one rebase, each losing a
CHANGELOG entry), with no conflict and nothing in the diffstat to catch the eye.
scripts/phandroid-merge-ours.shreplaces it: it still keeps ours, but writes the
discarded version to.git/phandroid-dropped/<path>and names it on stderr, so the
loss is visible while it happens and recoverable afterwards. It needs the driver once
per clone (git config merge.phandroid-ours.driver …; the workflow declares it for
CI), and a clone without it now gets a visible conflict instead of silence.- The upstream sync no longer re-resolves the lockfile from a stale base — the
outage class that stranded dev at 2.0.79 for two days is closed.
package-lock.jsonis nowmerge=theirs: a merge takes upstream's lock, the
dependency resolution they actually build and test with, and the sync
regenerates it only to re-add the fork's eleven overlay entries. The old model
kept our lock (merge=ours) and re-resolved it from scratch on every merge,
handing each upstream dependency bump to npm's peer resolver as a fresh coin
flip: on 2026-10-16 upstream bumped@linguito ~6.9.1 and npm walked the
unguarded peerOptional chain (@lingui/vite-plugin→
@rolldown/plugin-babel→@babel/plugin-transform-runtime) into Babel 8.x
against the tree's@babel/[email protected]—ERESOLVE, and the sync failed
eleven consecutive runs while dev sat 20 commits behind upstream. Starting from
upstream's lock instead, the identical regeneration touches nothing upstream
owns (measured: 716 entries, 0 changed, 0 removed, 195 added by the overlay;
verified under npm 9.2 and 11.21). A new guard,
scripts/phandroid-lockfile-invariant.mjs, fails the run if the regeneration
changes or drops any upstream-owned entry — the drift can neither crash the
sync nor ship silently again. This branch carries the same model and the same
guard, so the nextupstream/productionmove cannot hit the same wall. - The lockfile guard fails closed. Input it cannot check — a lockfile without a
packagesmap (lockfileVersion 1), an unparsable or missing file — now stops the
run with one line naming the file and the reason (exit 2), instead of comparing
zero entries and reporting a green "0 upstream entries unchanged". A guard that
validates nothing is the failure mode this pipeline keeps hitting: an unmatched
test glob ran zero tests and exited 0, and the awk the changelog bump replaced
exited 0 on a missing[Unreleased]heading. Only exit 0 means the invariant held. - A release section no longer carries two
### Changedheadings. The generated
upstream-merge block was followed by the moved hand-written entries including
their own### Changed, so a release whose entries had one showed that heading
twice — in the release body on both instances (2.0.80 shipped that way) and, for
sections short enough to survive the 500-character limit, twice as "Changed:" in
the F-Droid "What's New" text (measured against the pre-fix script; in 2.0.80 the
truncation dropped the second block, so there only the release body showed it).
Hand-written### Changedbullets now merge into the generated block, which stays
first because the upstream merge is the release's headline; every other
hand-written section keeps its place. A body without a### Changedheading still
produces byte-identical output — verified against the pre-fix script over six
input shapes. A heading spelled with extra whitespace (### Changed) counts as
the same heading, and a body of nothing but headings no longer counts as fork
changes: it used to append a stray empty heading and drop the "no Android-fork
code changes" claim for a release that had none.
Changed
- A failed sync now says why, and for how long it has been failing. The
lockfile step tees its output into the failure report — theERESOLVEthat
killed eleven runs was previously only findable by pulling job logs by hand —
a failed merge lists its conflicted files the same way, and every CI-failure
issue now carries a trend line ("N consecutive failed run(s); last success:
run X on …") computed from the run history. Forgejo notifies nobody about
Actions results, so the issue body is the only alarm channel — and "still
down" reads differently than "another failure". - The sync announces conflict candidates before merging. Files that both
upstream and the fork changed since the last merge — minus the ones the merge
drivers own — are printed up front, so the next real conflict shows up in the
job log and the issue instead of being a surprise mid-merge. - The conflict-candidate list is read from
.gitattributesinstead of a fixed
list of files. Upstream edits its ownCHANGELOG.mdregularly andmerge=ours
resolves that without a human, so the hardcoded version would have announced a
conflict candidate on most runs — the noise that makes a real one invisible.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The F-Droid "What's New" can no longer be blocked by a changelog entry that mentions
-
Phandroid v2.0.85-dev Pre-release
released this
2026-10-22 16:39:04 +02:00 | 2 commits to main since this releaseChanged
- Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see
CHANGELOG.phanpy.mdfor upstream detail):bb2c7ea3I need the total net diff
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see
-
Phandroid v2.0.84-dev Pre-release
released this
2026-10-22 10:34:29 +02:00 | 5 commits to main since this releaseChanged
- Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see
CHANGELOG.phanpy.mdfor upstream detail):33924e31Missed this onecf9b91f5Add "View profile" button in profile sheets27c8bfb9Improve copies
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see
-
Phandroid v2.0.83-dev Pre-release
released this
2026-10-21 10:35:31 +02:00 | 10 commits to main since this releaseChanged
- Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see
CHANGELOG.phanpy.mdfor upstream detail):19ff20feMore lowercases8727c68cLoading indicator for notifications popover27aa49e1Dedupe quotes too in Mentions page
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see
-
Phandroid v2.0.82-dev Pre-release
released this
2026-10-20 16:34:01 +02:00 | 15 commits to main since this releaseChanged
- Merged upstream Phanpy — 5 commit(s) (see
CHANGELOG.phanpy.mdfor upstream detail):2ef1b407Allow emulate boost/like/bookmark53b2b2e7Experiment: lowercase post text78710d8dusername setting for bylines tooe272ba27Add note for quote post count field22cc47ddi18n updates (ar-SA,ca-ES,cs-CZ,de-DE,es-ES,eu-ES,fi-FI,fr-FR,he-IL,kab,pl-PL,zh-CN) (#1620)
Fixed
- The F-Droid "What's New" can no longer be blocked by a changelog entry that mentions
a heading. The converter stripped backticks and bold but left a literal###in the
text, so the release gate's "no Markdown left" assertion failed — and that is exactly
what happened to 2.0.81: the entry about the duplicate### Changedheading fed its
own heading into the What's New text, the gate refused, and the release was never
signed. The converter now drops heading hash runs (the words stay, so the entry still
reads correctly), which makes its guarantee hold for any input. prod was unaffected;
dev stayed on 2.0.80 until the release was re-run.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 5 commit(s) (see
-
Phandroid v2.0.81-dev Pre-release
released this
2026-10-19 20:41:16 +02:00 | 22 commits to main since this releaseChanged
- Merged upstream Phanpy — 2 commit(s) (see
CHANGELOG.phanpy.mdfor upstream detail):63d26fdaUpgrade deps2a801b1eOnly generate used icons
- The conflict-candidate list is read from
.gitattributesinstead of a fixed
list of files. Upstream edits its ownCHANGELOG.mdregularly andmerge=ours
resolves that without a human, so the hardcoded version would have announced a
conflict candidate on most runs — the noise that makes a real one invisible.
Fixed
merge=ourscan no longer silently discard your change. The fork-owned files
(README, CHANGELOG, LICENSE, SECURITY, PRIVACY) must keep our version on an upstream
merge — but git calls that driver for every three-way merge, and on a rebase or
cherry-pick "ours" is the branch being replayed onto while "theirs" is your commit.
The built-intruetherefore threw your change away, silently: it did exactly that
three times on 2026-10-18/19 (both prod cherry-picks and one rebase, each losing a
CHANGELOG entry), with no conflict and nothing in the diffstat to catch the eye.
scripts/phandroid-merge-ours.shreplaces it: it still keeps ours, but writes the
discarded version to.git/phandroid-dropped/<path>and names it on stderr, so the
loss is visible while it happens and recoverable afterwards. It needs the driver once
per clone (git config merge.phandroid-ours.driver …; the workflow declares it for
CI), and a clone without it now gets a visible conflict instead of silence.- The lockfile guard fails closed. Input it cannot check — a lockfile without a
packagesmap (lockfileVersion 1), an unparsable or missing file — now stops the
run with one line naming the file and the reason (exit 2), instead of comparing
zero entries and reporting a green "0 upstream entries unchanged". A guard that
validates nothing is the failure mode this pipeline keeps hitting: an unmatched
test glob ran zero tests and exited 0, and the awk the changelog bump replaced
exited 0 on a missing[Unreleased]heading. Only exit 0 means the invariant held. - A release section no longer carries two
### Changedheadings. The generated
upstream-merge block was followed by the moved hand-written entries including
their own### Changed, so a release whose entries had one showed that heading
twice — in the release body on both instances (2.0.80 shipped that way) and, for
sections short enough to survive the 500-character limit, twice as "Changed:" in
the F-Droid "What's New" text (measured against the pre-fix script; in 2.0.80 the
truncation dropped the second block, so there only the release body showed it).
Hand-written### Changedbullets now merge into the generated block, which stays
first because the upstream merge is the release's headline; every other
hand-written section keeps its place. A body without a### Changedheading still
produces byte-identical output — verified against the pre-fix script over six
input shapes. A heading spelled with extra whitespace (### Changed) counts as
the same heading, and a body of nothing but headings no longer counts as fork
changes: it used to append a stray empty heading and drop the "no Android-fork
code changes" claim for a release that had none.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 2 commit(s) (see
-
Phandroid v2.0.80-dev Pre-release
released this
2026-10-18 23:23:48 +02:00 | 30 commits to main since this releaseChanged
- Merged upstream Phanpy — 20 commit(s) (see
CHANGELOG.phanpy.mdfor upstream detail):78ca68d7new config style for lingui5fbc3a01Upgrade deps651c2421Update lock filee01ebe59Rearrange and hide some visibilities045e3577Restyle mini translation blockf0bb03c4Actually can share the locale stringscf05b2dfi18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1615)5840c0e6Remove this "fix"6a051937Experiment: "Hide post metrics"2dd139cdExperiment: only show usernamesdbe778a4i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1617)f90c2f6eSorry, translators.4eac7b15i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1618)e2d2f1e4Names in filtered posts also need subtle treatmentc3cddcacAdd toggles for hide post metrics and display username285fb248Apply metrics hiding for notifications toode2c88d6Apply display username setting to notifications too8ca38b7aA little bit of "life" in the carousel dotsdc6a27f2i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,es-ES,eu-ES,fi-FI,fr-FR,pl-PL,zh-CN) (#1619)15f73bbfUpdate README.md
Fixed
- The upstream sync no longer re-resolves the lockfile from a stale base — the
outage class that stranded dev at 2.0.79 for two days is closed.
package-lock.jsonis nowmerge=theirs: a merge takes upstream's lock, the
dependency resolution they actually build and test with, and the sync
regenerates it only to re-add the fork's eleven overlay entries. The old model
kept our lock (merge=ours) and re-resolved it from scratch on every merge,
handing each upstream dependency bump to npm's peer resolver as a fresh coin
flip: on 2026-10-16 upstream bumped@linguito ~6.9.1 and npm walked the
unguarded peerOptional chain (@lingui/vite-plugin→
@rolldown/plugin-babel→@babel/plugin-transform-runtime) into Babel 8.x
against the tree's@babel/[email protected]—ERESOLVE, and the sync failed
eleven consecutive runs while dev sat 20 commits behind upstream. Starting from
upstream's lock instead, the identical regeneration touches nothing upstream
owns (measured: 716 entries, 0 changed, 0 removed, 195 added by the overlay;
verified under npm 9.2 and 11.21). A new guard,
scripts/phandroid-lockfile-invariant.mjs, fails the run if the regeneration
changes or drops any upstream-owned entry — the drift can neither crash the
sync nor ship silently again. Ported to theprodbranch as well, so the next
upstream/productionmove cannot hit the same wall.
Changed
- A failed sync now says why, and for how long it has been failing. The
lockfile step tees its output into the failure report — theERESOLVEthat
killed eleven runs was previously only findable by pulling job logs by hand —
a failed merge lists its conflicted files the same way, and every CI-failure
issue now carries a trend line ("N consecutive failed run(s); last success:
run X on …") computed from the run history. Forgejo notifies nobody about
Actions results, so the issue body is the only alarm channel — and "still
down" reads differently than "another failure". - The sync announces conflict candidates before merging. Files that both
upstream and the fork changed since the last merge — minus the ones the merge
drivers own — are printed up front, so the next real conflict shows up in the
job log and the issue instead of being a surprise mid-merge.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 20 commit(s) (see
-
Phandroid v2.0.79-dev Pre-release
released this
2026-10-15 22:31:56 +02:00 | 54 commits to main since this releaseChanged
- Merged upstream Phanpy — 2 commit(s); no Android-fork code changes (see
CHANGELOG.phanpy.mdfor upstream detail):b4804d90Fix notification dot color36f9f259Try remove @babel/plugin-transform-runtime this time
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 2 commit(s); no Android-fork code changes (see
-
Phandroid v2.0.78-dev Pre-release
released this
2026-10-15 04:30:55 +02:00 | 58 commits to main since this releaseChanged
- Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see
CHANGELOG.phanpy.mdfor upstream detail):2fb534dbExperiment: pagination dots for boosts carousel
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see