Skip to content

Releases: FreshLabDev/branchy

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 13:09

Stable Telegram Bot API 10.2 release. Promoted from v1.1.0-alpha.3 after a
40-hour error-free production soak and live release-notification tests covering
mixed media, the 50-media boundary, unsafe input sanitizing, and rejected-media
fallback.

Added

  • Private group /start. The group-scoped command is ephemeral: Branchy's
    DM prompt is visible only to the invoking user. Registration retries after
    transient Telegram failures without delaying HTTP startup or long polling.

Changed

  • GitHub PR and release bodies are rendered as sanitized Bot API Rich HTML.
    GFM headings, lists, tables, quotes, links, code, task lists, and safe inline
    HTML remain available.
  • Up to 50 valid HTTP(S) images, videos, or audio items remain visible as Rich
    Message blocks. Overflow media remains reachable as links.
  • New outbox jobs retain both preferred Rich HTML and bounded classic HTML, so
    content failures and rollback paths do not lose the notification.

Fixed

  • Rich output is structurally bounded by message size, block count, nesting
    depth, media count, and table width, with balanced HTML after truncation.
  • Telegram content or method errors fall back through Rich HTML without media,
    classic HTML, and plain text. Temporary transport, server, and rate-limit
    failures keep normal retry behavior without risking duplicate fallback sends.
  • Notification headers preserve the visual line break between repository name
    and event details.
  • Ephemeral group replies are sent before the best-effort core.touch, so a
    slow database cannot consume Telegram's reply window or cause duplicates.

Security

  • Unsafe tags, Telegram-specific tags, event attributes, mentions, malformed
    structures, and non-HTTP(S) URL schemes are removed before delivery.
  • Build and CI toolchains require Go 1.26.5, including the standard-library fix
    for GO-2026-5856 in crypto/tls.

Migrations

  • 008_notification_job_payload_format.sql adds rich_text and versioned
    payload metadata. Existing alpha jobs remain identifiable and are sanitized
    before delivery; rollback-era workers continue using classic text.

Operations

  • No new environment variables, OAuth scopes, or webhook-event requirements.
  • AUTO_MIGRATE=true applies migration 008 during upgrade from v1.0.3.
  • WS04 production Compose no longer declares the retired standalone
    branchy-postgres service; shared core-postgres remains the only durable
    store. Historical volume data was preserved for rollback.

v1.1.0-alpha.3

v1.1.0-alpha.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Jul 20:43

Added

  • Private group /start. The group-scoped command now uses Bot API 10.2
    ephemeral commands and replies only to the invoking user with the DM prompt.
    Branchy no longer posts a public group fallback for /start. Command scope
    registration and bot username discovery retry after transient Telegram
    failures without delaying HTTP startup or long polling.

Changed

  • GitHub bodies are rendered to safe Rich HTML inside Branchy. GFM
    headings, lists, tables, quotes, links, code, task lists, and media remain
    available. Safe inline GFM HTML such as underline, superscript, and subscript
    is retained, while unsafe or Telegram-specific tags, attributes, and URL
    schemes are removed before Telegram sees the payload.
  • Up to 50 valid HTTP(S) images, videos, or audio items remain visible as Rich
    Message blocks, including linked Markdown images and supported raw
    <img>/<video>/<audio> media. Media beyond the Telegram limit remains
    available as links.

Fixed

  • Rich content is truncated structurally with balanced HTML and explicit caps
    for message size, block count, nesting depth, media, and table columns.
  • A final HTML5 bounds pass no longer leaks implicit <tbody>, <thead>, or
    <tfoot> tags that Telegram Rich HTML does not support.
  • Telegram content or method errors now fall back through Rich HTML without
    media, bounded classic HTML, and plain text. Every stage receives a fresh
    timeout; rate limits and temporary transport/server failures still retry
    without risking duplicate fallback sends.
  • Ephemeral group /start replies are sent before the best-effort core.touch,
    so a slow or unavailable database cannot consume Telegram's 15-second reply
    window or trigger duplicate private replies.

Security

  • PR authors and release body contributors can no longer inject
    Telegram-specific rich tags, unsafe links, mentions, or malformed structures
    through webhook body Markdown.
  • Build and CI toolchains now require Go 1.26.5, which includes the standard
    library fix for GO-2026-5856 in crypto/tls.

Migrations

  • 008_notification_job_payload_format.sql adds versioned payload metadata and
    rich_text. Existing v1.1.0-alpha.1/alpha.2 rows remain identifiable as
    Rich Markdown but are converted through the safe Rich HTML sanitizer before
    delivery. New jobs keep classic HTML in text for fallback and rollback.

v1.1.0-alpha.2

v1.1.0-alpha.2 Pre-release
Pre-release

Choose a tag to compare

@amtiYo amtiYo released this 16 Jul 09:11

Fixed

  • Notification headers keep a line break under the repo name. Rich Markdown
    collapses a single \n, so the event line (Release · …, commit summary,
    PR action) sat on the same visual row as 📦 repo. Headers now use a blank
    line between the title row and the event row.

v1.1.0-alpha.1

v1.1.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@amtiYo amtiYo released this 16 Jul 09:04

Changed

  • GitHub notifications use Telegram Rich Messages. Delivery switched from
    classic HTML sendMessage to Bot API sendRichMessage (Rich Markdown).
    Headers still use escaped HTML tags; PR and release bodies are passed as
    GitHub Flavored Markdown so Telegram natively renders headings, lists, tables,
    quotes, code, and media (![](url)).
  • Long bodies use <details>. Short notes stay Markdown blockquotes; long
    or truncated notes collapse under a collapsible details summary instead of
    classic <blockquote expandable>.
  • Soft body caps raised for the rich-message limit (PR ~2500 runes, release
    ~10000 runes) while keeping group notifications scannable.
  • Bot UI (/start, settings, OAuth replies) is unchanged and still uses HTML
    parse mode.

Breaking

  • Hard cutover for the outbox payload format. notification_jobs.text is
    now Rich Markdown. Pending jobs enqueued as classic HTML before this deploy
    can fail permanently; drain or fail pending rows before upgrading.

Operations

  • No database migration.
  • Ensure the bot can send media in destination groups if release notes include
    remote images (Telegram may embed media blocks from Markdown).

v1.0.3

Choose a tag to compare

@amtiYo amtiYo released this 01 Jul 20:36

Fixed

  • Local docker-compose stack could not boot after the core consolidation.
    Migration 001 now references the shared core.person/core.chat, but the
    bundled dev Postgres had no core schema, so docker-compose up crash-looped
    (schema "core" does not exist). Added deploy/core-init.sql (a minimal local
    core schema + core.touch) mounted via docker-entrypoint-initdb.d, and set
    search_path=branchy on the compose DATABASE_URL. Production is unaffected
    (it uses the real shared core-postgres); this only fixes local development.

v1.0.2

Choose a tag to compare

@amtiYo amtiYo released this 01 Jul 19:18

Changed

  • Shared core database. Branchy's data now lives in the shared
    core-postgres under a branchy schema, and identity/presence (Telegram
    users and chats) are delegated to the central core hub (core.person /
    core.chat), keyed on the global Telegram id. Domain tables reference
    core.person(telegram_user_id) directly; the local telegram_users and
    telegram_chats tables are dropped. Chat-specific state (bot status, active,
    added-by) moves to a small chat_state table that FKs into core.chat.
    Identity/presence is upserted via the shared core.touch before any dependent
    insert. The bot connects to core-postgres with search_path=branchy; its
    dedicated branchy-postgres is retired.

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 28 Jun 15:08

Fixed

  • In a group, branchy no longer answers a /start that was addressed to a
    different bot (/start@otherbot, which Telegram delivers to every bot in the
    group). It now responds only to the bare /start or its own
    /start@<botname>.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 26 Jun 09:22

First stable release. Branchy watches your GitHub repositories and delivers
push, pull-request and release notifications to Telegram — set up and managed
entirely through the bot, with GitHub OAuth, per-event and branch filters, and
reliable at-least-once delivery through a Postgres outbox.

Promoted from v1.0.0-rc.1 unchanged, after a clean production soak (no errors,
a real release notification delivered end-to-end). This tag marks the 1.0
milestone after a hardening program across the alpha series and two independent
review passes.

v1.0.0-rc.1

v1.0.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 25 Jun 13:45

Release candidate. A second independent review pass closed the last two
lost-notification gaps in the delivery path; everything else was clean.

Reliability

  • Release and pull-request notification bodies are now budgeted by their
    visible rendered length, not the raw Markdown slice. Rendering can expand
    the visible text (a Markdown image becomes an Image: prefix), so an
    image-heavy body could previously exceed Telegram's 4096-character limit and
    be rejected outright — silently losing the notification with no retry. The
    body is re-rendered to fit, and titles are bounded.
  • Subscriptions are matched to incoming webhooks by the stable
    github_repo_id instead of the repository's full name. A GitHub repo
    rename no longer silently drops every notification for that repo (the hook
    keeps firing under the same id with a new name); the cached name is refreshed.

Fixed

  • /start@botname — the form Telegram delivers in groups — is now recognized,
    so the "open me in a DM" prompt fires there.
  • A fatal startup error (e.g. the HTTP port already in use) is no longer masked
    as a clean exit when a shutdown signal arrives at the same instant.
  • A notification job that exhausts its attempts purely through worker
    lease-expiry is now logged instead of being a silent terminal drop.

v1.0.0-alpha.4

v1.0.0-alpha.4 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 25 Jun 12:05

A multi-dimension review pass: two delivery-path correctness blockers closed
plus a cluster of latent outbox/idempotency hardening, and a round of
notification and UX polish.

Security

  • The webhook rate limiter now runs after signature verification, so an
    unsigned flood can no longer drain the shared token bucket and return 429 to
    real GitHub deliveries. Unauthenticated traffic is rejected as 401 without
    touching the limiter.

Reliability

  • Recording a delivery and enqueuing its notification jobs is now a single
    atomic transaction. Previously a crash between the two could leave an
    idempotency marker with no jobs, so a GitHub retry was ignored as a duplicate
    and the notification was lost.
  • Notification job terminal/retry updates are fenced on status = 'processing';
    a stale write from a re-leased job is a safe no-op instead of overwriting a
    job another worker already finalized.
  • A successful send is recorded under an uncancelable context, so a graceful
    shutdown immediately after delivery no longer leaves the job processing and
    re-sends it (a duplicate) on restart.
  • A group→supergroup upgrade now auto-pauses the subscription instead of
    enqueuing jobs to the dead chat id forever (migrate_to_chat_id is detected).
  • A failed Telegram update is re-delivered (the poll offset is not advanced)
    with a short backoff instead of being silently dropped; a persistently failing
    update is given up on after a few attempts so it cannot stall the poll loop.
  • Migrations take a session-level advisory lock, so two instances starting
    together cannot double-run a non-idempotent migration.
  • PUBLIC_BASE_URL is validated as an absolute http(s) URL at startup instead of
    failing far downstream on a malformed value.

Changed

  • Push notifications show as many commits as fit a text budget instead of a
    fixed cap of 10; since GitHub caps a push payload at ~20 commits, real pushes
    now list every commit, with "+N more" only for a pathologically long list.
  • PR and release bodies collapse into an expandable quote only when long
    (over ~600 visible characters or ~10 lines, or truncated); short and medium
    notes render in full in a plain quote.
  • Re-subscribing to a previously auto-paused configuration clears the stale
    pause_reason, so the subscription is no longer shown active with a pause
    warning.

Fixed

  • Deleting a subscription now asks for confirmation first, so a single mistaken
    tap can no longer destroy a subscription and its webhook.
  • The bot registers its command menu (setMyCommands) and replies to
    unrecognized private-chat input with a hint, instead of staying silent and
    reading as a dead bot.
  • A failed test notification keeps the subscription screen (surfaced as a toast)
    instead of ejecting the user to the home menu.
  • Markdown inside a GitHub blockquote (links, emphasis, inline code) renders as
    formatted text instead of raw source.
  • A declined GitHub OAuth consent surfaces the real reason instead of a
    misleading "missing code or state".