Skip to content

v1.36.0

Latest

Choose a tag to compare

@rdeavila rdeavila released this 30 Aug 21:11
ab19727

Warning

Review CRON_RETENTION_DAYS before upgrading.

The retention job has never actually deleted anything — INTERVAL $1 day is
a syntax error in PostgreSQL and the error was being discarded — so whatever
value you have configured has been inert since the feature shipped.

This release fixes it. On the first run after the upgrade, at the time set in
CRON_RETENTION_EXPRESSION (0 2 * * * in the documented examples), every
execution older than the retention period is deleted for good. An
installation that has accumulated months of history while the job was broken
loses all of it in one pass.

The default is 7 days, and the sample .env in the README uses 1. Raise
CRON_RETENTION_DAYS if that history matters to you.

Note that you cannot disable the job by clearing CRON_RETENTION_EXPRESSION:
an empty value fails to parse and the server panics on startup. To postpone
the cleanup, schedule it far out instead.

This release is mostly about things that were quietly broken. The test suite
skips itself when PostgreSQL is unreachable, and nothing ever applied the
migrations to the test database, so it had been passing green for a long time
without running. Once it could actually run, it exposed four defects that had
been in production the whole time.

Fixed

  • Retention cleanup never deleted anything. INTERVAL $1 day is a syntax
    error in PostgreSQL — an interval literal cannot take a placeholder — and the
    statement discarded its error, so every run failed silently and executions
    accumulated no matter what CRON_RETENTION_DAYS was set to. See the warning
    above before upgrading.
  • /assets/{machine_id} returned 500 whenever one of the asset's
    executions had a NULL details. The column is nullable and the handler read
    it into a plain string.
  • POST /v1/executions returned 500 and dropped the execution when the
    agent omitted executed_at. The column is NOT NULL; an omitted timestamp
    now means "now".
  • GET /v1/transactions/ids answered 400 for a request carrying neither
    query parameters nor a body. No parameters is an empty result.
  • A failure to bind the listening port no longer exits silently with status
    0.
    r.Run() now logs the error and exits non-zero, so an orchestrator can
    see the failure. A failure to register /health is logged instead of
    discarded.
  • A failed cron lock release is now logged. When the cron_lock delete
    failed silently the row stayed behind, making the next runs of the
    statistics, retention, materialized view and OSV jobs log "Another instance
    is running this job" and skip, until the stale lock was reaped twelve hours
    later.
  • DnfUser no longer panics on a dnf user string where > precedes <,
    such as a>b<c.
  • Migrations: added the missing 202603020002_add_ecosystem.down.sql, the
    only migration without a down counterpart.
  • Documentation: the "Run Database Migrations" how-to said the server does
    not apply migrations on startup and that they had to be triggered by hand.
    It always has applied them, before serving traffic.

Changed

  • The test suite runs against PostgreSQL again. It applies the migrations
    itself from a TestMain in each package with database-backed tests, and its
    fixtures were realigned with the current schema — they had drifted unnoticed.
    make test runs everything against a throwaway PostgreSQL container managed
    with Podman.
  • CI now checks the code. A new Check workflow runs gofmt, vet,
    golangci-lint and the tests, with a PostgreSQL service, on every push and
    pull request. Both make test and CI set TXLOG_TEST_REQUIRE_DB, so a
    database that fails to start is a failure rather than a silent skip.
  • Modern Go idioms throughout, for the go 1.26 toolchain: errors.Is for
    sql.ErrNoRows, any, builtin min/max, for i := range n,
    slices/maps iterator helpers, strings.Cut, strings.SplitSeq,
    cmp.Or, wg.Go and t.Context() in tests.
  • LDAP connections use ldap.DialURL instead of the deprecated
    ldap.Dial and ldap.DialTLS. LDAP_HOST, LDAP_PORT and LDAP_USE_TLS
    keep their current meaning and default ports.
  • New migrations must use a full 14-digit YYYYMMDDHHMMSS prefix.
    golang-migrate reads the prefix as an integer version, so a shorter prefix
    would sort before migrations already applied and be skipped in silence.
  • Added a .golangci.yml and cleared every finding it reports.
  • Bump github.com/tavsec/gin-healthcheck from 1.7.16 to 1.7.18.

Docker Image

docker pull ghcr.io/txlog/server:v1.36.0

Full Changelog: v1.35.1...v1.36.0