Close Unreleased for retry-policy panel, persistent queue, and self-contained backups; pin compose and docs to 1.3.1. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,6 +5,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.3.1] - 2026-08-17
|
||||||
|
|
||||||
|
Retry policy in the panel, persistent Postfix queue, and self-contained
|
||||||
|
full backups. Mail queue and delivery history show this Postfix's first
|
||||||
|
retry, backoff cap, and queue lifetime. Deferred mail survives container
|
||||||
|
recreate. Full backups now archive `data/`, compose, `.env`, and `certs/`;
|
||||||
|
the archive layout breaks 1.3.0 flat backups (unpack those with
|
||||||
|
`tar xzf backup.tar.gz -C ./data` as before). Upgrading from 1.3.0 is a
|
||||||
|
tag bump; no schema migration.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Mail queue and a delivery's history show this Postfix's retry policy
|
- Mail queue and a delivery's history show this Postfix's retry policy
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ docker run --rm -d --name selfpost-try \
|
|||||||
-e SELFPOST_HOSTNAME=mail.local.test \
|
-e SELFPOST_HOSTNAME=mail.local.test \
|
||||||
-e PANEL_COOKIE_SECURE=false \
|
-e PANEL_COOKIE_SECURE=false \
|
||||||
-v selfpost-try-data:/data \
|
-v selfpost-try-data:/data \
|
||||||
ghcr.io/mixeme/selfpost:1.3.0
|
ghcr.io/mixeme/selfpost:1.3.1
|
||||||
```
|
```
|
||||||
|
|
||||||
**Get the setup URL** (pick one):
|
**Get the setup URL** (pick one):
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
selfpost:
|
selfpost:
|
||||||
image: ghcr.io/mixeme/selfpost:1.3.0
|
image: ghcr.io/mixeme/selfpost:1.3.1
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}"
|
SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}"
|
||||||
|
|||||||
+2
-2
@@ -102,7 +102,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
|||||||
2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
|
2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
|
||||||
[§ Release image](#release-image)).
|
[§ Release image](#release-image)).
|
||||||
|
|
||||||
**Planned version cuts** (from pin `1.3.0`; adjust if semver changes mid-track):
|
**Planned version cuts** (from pin `1.3.1`; adjust if semver changes mid-track):
|
||||||
|
|
||||||
| Stage | ID | Cut |
|
| Stage | ID | Cut |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -114,7 +114,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
|||||||
| 6 | panel-docs | `1.8.0` |
|
| 6 | panel-docs | `1.8.0` |
|
||||||
|
|
||||||
Docs-only prep (checklists in plans, no product code) uses the same per-step
|
Docs-only prep (checklists in plans, no product code) uses the same per-step
|
||||||
commit rule but **no** version cut until stage 1 ships.
|
commit rule but **no** version cut until the next product stage ships.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -165,7 +165,7 @@ cat ./data/setup-token
|
|||||||
#### Fixed image tag
|
#### Fixed image tag
|
||||||
|
|
||||||
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`),
|
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`),
|
||||||
deliberately never `:latest`. The current pin is `1.3.0`. Intermediate
|
deliberately never `:latest`. The current pin is `1.3.1`. Intermediate
|
||||||
CHANGELOG sections (`0.2.0`…`0.6.0`) record development cuts from before that
|
CHANGELOG sections (`0.2.0`…`0.6.0`) record development cuts from before that
|
||||||
image was published. Pinning matters because of the backup version check (see
|
image was published. Pinning matters because of the backup version check (see
|
||||||
[Full backup and restore](#full-backup-and-restore)): the panel binary's
|
[Full backup and restore](#full-backup-and-restore)): the panel binary's
|
||||||
@@ -477,7 +477,7 @@ A version mismatch at step 5 refuses to start and leaves `/data` untouched —
|
|||||||
the panel exits with a message naming the tag to use, e.g.:
|
the panel exits with a message naming the tag to use, e.g.:
|
||||||
|
|
||||||
```
|
```
|
||||||
backup: this backup was created by SelfPost 1.2.3 but this image is 1.3.0 — restore into the matching image (selfpost:1.2.3)
|
backup: this backup was created by SelfPost 1.2.3 but this image is 1.3.1 — restore into the matching image (selfpost:1.2.3)
|
||||||
```
|
```
|
||||||
|
|
||||||
Fix the tag in `docker-compose.yml`, `docker compose pull && docker compose up
|
Fix the tag in `docker-compose.yml`, `docker compose pull && docker compose up
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
**Status:** agreed
|
**Status:** agreed
|
||||||
**Version:** target bump **1.x** MINOR; **`2.x` possible** — to be settled once
|
**Version:** target bump **1.x** MINOR; **`2.x` possible** — to be settled once
|
||||||
the implementation lands (do not fix a major in advance).
|
the implementation lands (do not fix a major in advance).
|
||||||
**Order:** the 2026-08-13 full-tree review follow-ups are closed (CHANGELOG
|
**Order:** queue-retries shipped in `[1.3.1]`; this is next as the largest
|
||||||
`[Unreleased]`), so this is next up as the largest remaining 1.x+ **feature**.
|
remaining 1.x+ **feature**. The 2026-08-13 full-tree review follow-ups closed
|
||||||
The domain-admin role
|
in `[1.3.0]`. The domain-admin role and `internal/web` split have shipped —
|
||||||
and `internal/web` split have shipped — see [CHANGELOG](../../CHANGELOG.md)
|
see [CHANGELOG](../../CHANGELOG.md) `[1.2.0]`.
|
||||||
`[1.2.0]`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Plan: queue-retries (Postfix retry policy in the panel)
|
# Plan: queue-retries (Postfix retry policy in the panel)
|
||||||
|
|
||||||
**Status:** implemented (2026-08-17); version cut `1.3.1` pending
|
**Status:** done — shipped in `[1.3.1]` (2026-08-17)
|
||||||
**Date:** 2026-08-13
|
**Date:** 2026-08-13
|
||||||
**Version:** patch; no schema, no configuration surface.
|
**Version:** patch; no schema, no configuration surface.
|
||||||
**Order:** small panel item; does not wait on inbound-relay.
|
**Order:** small panel item; does not wait on inbound-relay.
|
||||||
|
|||||||
+5
-32
@@ -28,7 +28,6 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
|||||||
|
|
||||||
| ID | Topic | Status | Progress | Plan |
|
| ID | Topic | Status | Progress | Plan |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| queue-retries | Postfix retry policy in the panel (queue lifetime, backoff) | **agreed** | 9/9 | [plans/queue-retries.md](plans/queue-retries.md) |
|
|
||||||
| inbound-relay | Inbound relay (backup-MX / forwarding) | **agreed** | 0/15 | [plans/inbound-relay.md](plans/inbound-relay.md) |
|
| inbound-relay | Inbound relay (backup-MX / forwarding) | **agreed** | 0/15 | [plans/inbound-relay.md](plans/inbound-relay.md) |
|
||||||
| send-log-retention | Send-log retention days in panel Settings | candidate | 0/8 | [plans/send-log-retention.md](plans/send-log-retention.md) |
|
| send-log-retention | Send-log retention days in panel Settings | candidate | 0/8 | [plans/send-log-retention.md](plans/send-log-retention.md) |
|
||||||
| domain-stats-auto-ratelimit | 30-day send stats + auto level-2 rate limit | candidate | 0/11 | [plans/domain-stats-auto-ratelimit.md](plans/domain-stats-auto-ratelimit.md) |
|
| domain-stats-auto-ratelimit | 30-day send stats + auto level-2 rate limit | candidate | 0/11 | [plans/domain-stats-auto-ratelimit.md](plans/domain-stats-auto-ratelimit.md) |
|
||||||
@@ -37,14 +36,12 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
|||||||
| panel-docs | In-panel operator documentation | candidate | 0/6 | [plans/panel-docs.md](plans/panel-docs.md) |
|
| panel-docs | In-panel operator documentation | candidate | 0/6 | [plans/panel-docs.md](plans/panel-docs.md) |
|
||||||
| schema-squash | Squash SQLite migrations into a 2.x baseline | **2.x** | — | — |
|
| schema-squash | Squash SQLite migrations into a 2.x baseline | **2.x** | — | — |
|
||||||
|
|
||||||
**Recommended order** (not binding): **queue-retries** is a small panel item
|
**Recommended order** (not binding): the next feature is **inbound-relay**.
|
||||||
that can land first or in parallel; the next feature is **inbound-relay**.
|
|
||||||
**send-log-retention** can land before or beside **domain-stats-auto-ratelimit**
|
**send-log-retention** can land before or beside **domain-stats-auto-ratelimit**
|
||||||
(panel retention ≥ 30 days helps the stats window). The 2026-08-13 full-tree
|
(panel retention ≥ 30 days helps the stats window). queue-retries shipped in
|
||||||
review follow-ups (send-log authorization,
|
[CHANGELOG.md](../CHANGELOG.md) `[1.3.1]`; the 2026-08-13 full-tree review
|
||||||
fail-closed paths, docs, GUI, tests, licence) are closed — history in
|
follow-ups are in `[1.3.0]`. Candidates need explicit agreement before they
|
||||||
[CHANGELOG.md](../CHANGELOG.md) `[Unreleased]` and git. Candidates need
|
join the queue.
|
||||||
explicit agreement before they join the queue.
|
|
||||||
|
|
||||||
After a context reset, pick an item marked `agreed` or `in progress`, then work
|
After a context reset, pick an item marked `agreed` or `in progress`, then work
|
||||||
the **Implementation checklist** in its linked plan. The `Progress` column above
|
the **Implementation checklist** in its linked plan. The `Progress` column above
|
||||||
@@ -53,30 +50,6 @@ is `done/total` checklist steps in that plan ([development.md](development.md)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## queue-retries
|
|
||||||
|
|
||||||
**Goal:** show on Mail queue and on a delivery's history how this Postfix
|
|
||||||
retries deferred mail — first delay, backoff cap, queue lifetime — reading
|
|
||||||
the effective config (`postconf -h`) once at panel start so a manual
|
|
||||||
override is visible.
|
|
||||||
|
|
||||||
**Boundary:** explanation only. Postfix stays as-is; no attempt counter, no
|
|
||||||
panel knobs for queue lifetime, no schema change. Domain administrators see
|
|
||||||
the intervals on `/deliveries/{id}` (they cannot open Mail queue).
|
|
||||||
|
|
||||||
**Done when:** see the criteria in
|
|
||||||
[plans/queue-retries.md](plans/queue-retries.md). Implementation is on
|
|
||||||
`main` (checklist 9/9); the `1.3.1` version cut is still pending because
|
|
||||||
`[Unreleased]` also holds unrelated work (including a breaking backup-layout
|
|
||||||
change).
|
|
||||||
|
|
||||||
**Dependencies / risks:** `postconf` unavailable outside the container
|
|
||||||
(fallback + muted note). Copy must stay time-based — Postfix has no max
|
|
||||||
attempt count.
|
|
||||||
**Version:** patch.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## inbound-relay
|
## inbound-relay
|
||||||
|
|
||||||
**Goal:** optional acceptance of mail on port 25 for explicitly configured
|
**Goal:** optional acceptance of mail on port 25 for explicitly configured
|
||||||
|
|||||||
Reference in New Issue
Block a user