Skip to content

Releases

brevis-sql v0.8.0

Choose a tag to compare

@github-actions github-actions released this 06 Nov 20:08
98956ae

Added: max_in_flight_per_tenant

  • How many requests one tenant may have waiting on the warehouse, set in
    the file's limits. It was fixed at 4 in code. Four is right for one
    customer per key, and wrong for a key that serves many people, such as
    a gateway in front of a whole product: there a dashboard that fires its
    charts at once gets a 429 for every chart past the fourth.
  • Default 4, so a file that does not set it behaves as before. File-wide
    only, like max_in_flight, and refused over it.

Engine v0.44.0

Choose a tag to compare

@github-actions github-actions released this 05 Nov 23:32
c18be8d

Changed: the live volume finds its sources by pod annotation, and is collected by the scheduler

  • BREVIS_GATEWAY_METRICS_URLS and BREVIS_ENDPOINTS_METRICS_URLS are gone.
    A process that still sees them logs one warning each and ignores them; nothing
    fails to start. The gateways and SQL APIs announce themselves instead (below),
    so replicas under an HPA are followed and nobody types an address.
  • Discovery by annotation. The scheduler lists the pods of its own namespace
    every 15 s and scrapes every pod that is Running, Ready and carries
    brevis.sh/metrics-kind (gateway or endpoints) and brevis.sh/metrics-name
    (the gateway's name:, or the API's name as the console lists it), with
    optional brevis.sh/metrics-port (default 9090) and brevis.sh/metrics-path
    (default /metrics). One pod is one replica; a pod scaled down leaves at once
    and does not stay as a silent replica. The address is the pod IP from the API
    server's answer, never from a request; a pod on the host network is refused
    and the port must be one the pod declares as a containerPort, so a pod
    that announces itself needs its metrics port declared. Outside Kubernetes
    discovery is off and the console says no pod announced itself (the compose
    demo has no live volume).
  • One collector, in the scheduler. It runs under a Postgres advisory lock
    (two schedulers never both collect; the second takes over when the first dies)
    and writes one transaction per scrape round. The API processes no longer
    scrape: they read the tables, so every API pod answers the same, and the
    metrics:streams and metrics:endpoints topics on the one /api/events
    stream follow the rows. A deployment without a running scheduler shows no
    metrics.
  • Migration 00034 adds two tables (metric_minutes, metric_sources).
    Nothing is renamed, so, unlike 00033, it is safe in a rolling update.
  • RBAC: nothing new. The scheduler's role already lists pods in its namespace
    and is what discovery uses; the API's service account still has no pod access.
  • BREVIS_RETENTION_METRICS_HOURS (default 3, the window the console reads;
    allowed 3 to 720; out of range refuses to start) is how long per-minute rows
    are kept. The collector prunes every minute in bounded batches, so lowering it
    on a large backlog does not lock the table.

Upgrade note: annotate the gateway and SQL API pods. On the pod template (not
the Deployment) of each. For a gateway named zarv_ingestion whose metrics
listener is on port 9090:

template:
  metadata:
    annotations:
      brevis.sh/metrics-kind: gateway
      brevis.sh/metrics-name: zarv_ingestion
      brevis.sh/metrics-port: "9090"

A brevis-sql-api uses brevis.sh/metrics-kind: endpoints and its name as in
the console. Until then the Streams and Endpoints screens say no pod announced
itself.

Engine v0.43.0

Choose a tag to compare

@github-actions github-actions released this 05 Nov 21:12
6004f25

Changed: the server has no language

  • Every API failure answers {"error": "<code>", ...data} (a code from a
    fixed list in internal/api/apierror.go), never a sentence; detail carries
    only text that came from a downstream system. The sign-in gate answers
    sign_in_required. Trigger validation answers 422 invalid_params with a
    fields map of codes and data. A script that matched on the old English or
    Portuguese error text must match the code.
  • Everything a screen says is a message key plus data, said by the console in
    the reader's language (11 catalogs, reviewed file by file). Durations carry
    their units in that language too.

Fixed

  • The Overview's failing-workflows list is read once per 3 s however many tabs
    are open, instead of once per tab.
  • Step cancel no longer breaks on a host with a day-first locale (the
    start time of ps is read in the C locale).
  • The old drawer links #publicar and #novo still open their drawers.

Changed: every identifier is English, and the schema moves (migration 00033)

Upgrade note: stop the old replicas before this release migrates. Migration
00033_english_schema.sql renames the table alertas to alerts and the
Portuguese columns, indexes, constraint and sequence that came with it
(criado_em -> created_at, iniciado_em -> started_at, terminado_em ->
finished_at, erro -> error, definicao -> definition, etapas ->
stages, saida -> output, sdk_versao -> sdk_version, ativo -> active,
ultimo_slot -> last_slot, max_ativos -> max_active, grupo_concorrencia
-> concurrency_group, the claim columns of queue_items and alerts, the
load_metrics counters, and six indexes). Each statement is a catalog change
with no data moved, but a pod still running the previous release asks for the
old names, so this one is not a rolling update. brevis migrate down reverses
it. A SQL view, dashboard or script of yours that reads the engine's tables
needs the new names.

  • The column comments that were Portuguese are English now, on existing
    databases too (the migration restates them), and the migration files
    00005, 00006, 00007, 00008, 00009, 00012, 00022, 00023 and
    00024 have English names. goose records only the version, so an existing
    database sees nothing.
  • Keys the engine writes are English, and every one is still READ in both
    spellings, so rows and documents written by an older release keep working:
    the phases in task_runs.stages (index, name, state, at, numbers,
    were indice, nome, estado, em, numeros) and a workflow param in
    workflows.definition / runs.definition (Name, Type, Description,
    were Nome, Tipo, Descricao). Nothing rewrites the old rows.
  • The console's graph payload (/api/workflows/{slug}/graph,
    /api/runs/{id}/graph) uses English keys (action, label, group,
    name, state, numbers, error, attempt, duration_ms, instances,
    instances_ok; node types phase and group). It is the console's own
    payload and ships in the same binary, so nothing in this repository still
    reads the old keys; a script that scraped it must follow.
  • The session cookie is brevis_session (it was brevis_sessao). A session
    signed in under the old name stays valid until it expires and signing out
    clears both, so upgrading signs nobody out; the old name is only read, and
    goes one session lifetime after this release.
  • brevis marca is still accepted as a deprecated alias of brevis brand; it
    goes in v1.
  • Internal Go identifiers (methods, fields, helpers) are English; they are not
    an API.

Fixed: everything the backend says is American English

  • Run-log lines and errors that were still Portuguese now read in English:
    pod aguardando: (now pod waiting:), pod ... terminou em, the
    Kubernetes client and Go-task errors, slack respondeu (now slack answered), the scheduler's slots truncados warning (its log keys
    limite and obs are now limit and note, and primeiro_slot_apos is
    first_slot_after), the Postgres, queue and alert-outbox errors, and the
    run state machine's transicao invalida.
  • Spelling is American: canceled (agent logs, the SQL API's timeout message),
    color in the brand validation errors and brand.example.yaml.
  • The Slack alert and the weekly report show dates as 2006-01-02 instead of
    dd/mm/yyyy.
  • Existing rows written in Portuguese by older versions (events, run errors,
    alert rows, the column comments of the early migrations) are not rewritten.
  • repo-language-check.sh now judges every string literal in non-test Go and
    in the Python library, and the messages of t.Error/t.Fatal in tests.

Added: a stream's health, from what the gateway measured

  • The Streams list and a stream's page say healthy, quiet, degraded or
    failing (and unknown with the reason: no source, an unreachable one, the
    first scrape, a stream the gateway never reported) instead of "no data" for
    every stream. The rule is one pure function over the collector's minute
    buckets, with each threshold named and explained in
    internal/metrics/health.go and summarized in docs/OBSERVABILITY.md.
  • health on /api/ingest/streams and its detail gains since,
    windowMinutes, the window's counts and the ratios behind the state;
    healthCounts counts every state. Both screens refetch on the
    metrics:streams topic, and the list puts failing and degraded streams first.
  • The collector also keeps retried and buried batches, refused-because-full
    requests and requests that never decoded.
  • A stream whose health is failing is listed under "Needs your attention" on
    the Overview, with a link to its page, and counts in the section's total.
    /api/overview/attention gains streams and streamsMore (up to five are
    listed); the Overview follows the metrics:streams topic while it is open.

Changed: the console lives at /, and the old server-rendered one is gone

  • The React console is served at the root: /, /runs, /workflows,
    /ingest/streams, /data, /sql, /login... Any GET no engine route claims
    is a client route and gets the app's shell. The app's own files moved from
    /app/assets/ to /static/, so they no longer share a name with the engine's
    /assets/ (stylesheet, fonts, logo).
  • /app and /app/... answer 308 to the same path without the prefix, query
    kept, so bookmarks keep working. A signed-out visit to a page goes to
    /login?next=...; /api/* still answers 401 JSON, and an unknown /api/*
    path a JSON 404.
  • Removed: the templ pages and their handlers (the HTML /runs, /workflows,
    /ingest/..., /data..., /sql, /projects, the form login at POST /login
    and POST /logout, /nav/runs, /overview/attention, /lang-style fragments
    and the workbench's HTML tree), the old scripts under /assets/ (ui.js,
    dag.js, sql.js, jsx-shim.js, vendor/) and the templ dependency. The
    JSON under /api/* is unchanged, as are POST /workflows/{slug}/trigger,
    GET /runs/{id}/log.txt and POST /preferences/lang. /api/sql/objects,
    /api/sql/columns and /api/sql/estimate (HTML for the old workbench) are gone.
  • make generate now builds the stylesheet and the React app only.

Engine v0.42.0

Choose a tag to compare

@github-actions github-actions released this 03 Nov 00:52
2d3be4f

Added: an Iceberg table is a landing target

  • iceberg://{catalog}/{namespace}/{table} is accepted by the engine's
    validators (three segments, a dotted namespace stays one), and the console
    shows an Iceberg landing as a table on /data and in a stream's summary, with
    iceberg in the kind filter. The destination itself ships as the SDK module
    sdk/iceberg.

Changed: the console follows the brand's accent

  • The label on the accent is derived from the accent itself: near-white on a
    dark brand color, near-black on a light one. The open sidebar item and the
    primary buttons no longer render black on a dark accent.
  • The folded sidebar shows the mark as a centered 32px square, and the expand
    button only on hover. Runs shows just the in-flight badge there, pinned to
    the icon's corner; expanded, the failing and in-flight counts read as one
    joined, opaque pill.
  • The corner radius scale is softer: 6px on cards and controls, 8px on panels.

Fixed

  • make warehouse no longer collides with a dev server on localhost:9000
    (the S3 mock moved to 59000, BREVIS_S3_PORT).

Engine v0.41.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 18:10
2104d50

Changed: the Go modules are brevis.sh/brevis/...

  • The engine's module path moves from github.com/AreteAcademy/brevis to
    brevis.sh/brevis, like every other module in the repository: a path
    on the project's own domain, which brevis.sh serves with go-import
    pages pointing at github.com/brevis-sh/brevis. go install brevis.sh/brevis/cmd/brevis@latest installs the CLI from this release on;
    versions up to 0.40.0 stay under the old path.
  • The update check reads api.github.com/repos/brevis-sh/brevis/releases
    (the old address redirected).

Changed: the images are published as brevissh/* on Docker Hub

  • The engine's images (brevis, with -worker and -agent) and the
    gateway's and brevis-sql's now publish to docker.io/brevissh/*, the
    project's own Docker Hub account, and no longer to areteacademy/*. The
    current versions were copied there with the same digests, so every pin in
    the chart, the manifests, the examples and the documentation -- all moved
    to brevissh/* -- names an image that exists.
  • areteacademy/* keeps every version published so far and gets no new
    ones: change areteacademy/ to brevissh/ to keep upgrading.
  • make image-push publishes to brevissh unless NAMESPACE= says
    otherwise.

Fixed: the images name the repository they were built from

  • Every image's org.opencontainers.image.source label -- the link Docker
    Hub, GitHub and scanners follow back to the code -- said
    https://github.com/AreteAcademy/brevis, written by hand seven times. The
    repository moved to brevis-sh on 2026-11-01. The label is now the
    SOURCE build argument, which the release workflows set to the repository
    that ran them, defaulting to https://github.com/brevis-sh/brevis for a
    local build.
  • image-labels-check.sh refuses a source written into a label, and a
    release build that passes VERSION without SOURCE.
  • The images already published keep the old link, which GitHub redirects.

Fixed: the site's ten translations were never published

  • brevis.sh/pt/, /es/, /fr/, /de/, /zh/, /ja/, /ru/, /ko/,
    /hi/ and /id/ answered 404, though the home page and every page's
    language picker link to them. site/build.py lists what goes into the
    dist/ Cloudflare publishes, and the list named docs and en (which has
    no folder: English is the root) and none of the ten added with the eleven
    languages. The folders now come from the language list itself.
  • build.py --check, which CI runs, now also assembles the dist/ and fails
    when a page it generated is not in it, so a page left out fails the pull
    request rather than production.

Changed: the SQL console, its tree

  • The connection is a picker at the top of the tree, with its logo,
    instead of one root per connection; choosing one opens its tables. With no
    script it is a form (/sql?connection=). Redshift and MySQL destinations,
    which brevis-sql serve has no dialect for, are offered disabled with the
    reason, and the console no longer opens on one.
  • A table is its first look: clicking it opens its columns and puts
    SELECT * … LIMIT 100 in the editor -- in the open tab when it is empty, in
    a new one when somebody has written there. /sql?target= (what the Catalog,
    Loads, Streams and Endpoints link to) does the same for its table, and runs
    nothing; the statement is built from a destination the catalog knows, so a
    statement still never travels in a link.
  • "Filter tables" over the chosen connection's listing. The tree is in every
    language the console speaks.
  • The editor and its bar speak the reader's language: the tabs ("Query
    N", stored as their number, so a tab saved before reads in today's
    language), Run with ⌘↵, the connection with its logo and a link to the
    connections (the Catalog, until there is a Connections screen), Copy, and
    "Reads only" with the way to Workflows, where writes run.
  • The estimate says "Will process 273.9 MB" in the reader's number
    format. A refusal is titled "Will be refused: the SQL service does not run
    this statement", with the service's own sentence after it -- the service
    does not say why it refused, so the console does not guess. A warehouse
    that does not price says so in the reader's words.
  • The answer is three tabs: Results, JSON and History N. History is what
    was the Recent rail beside the grid -- the same list, still kept only in
    this browser, now a tab. The figures over the grid ("100 rows · 91.9 MB
    read · 523 ms — there are more"), the pager, Running and Cancel, the empty
    answer and the console's own failures are in the reader's language. A
    statement the service refuses at Run is titled "Refused by the SQL
    service", with its sentence and the way to Workflows.
  • The whole SQL screen is in every language the console speaks.

Changed: an unset BREVIS_ENV is production (breaking)

  • A console that forgets BREVIS_ENV now refuses to start without a
    credential
    , instead of serving an open console on every interface. Local
    development sets BREVIS_ENV=local (make up and the Compose file already
    do). brevis-sql-api and the gateway keep local as their default; the
    three binaries do not yet agree on what "unset" means.

Fixed: what the audit found in the engine

  • A scheduled slot is no longer lost when the process dies between
    creating a run and queueing it: the next cycle finds the run still created
    or queued with no queue item and finishes the job (RunRepo.Stranded).
    Manual runs too.
  • Two processes can no longer exceed a concurrency limit: Claim takes
    a transaction-scoped advisory lock, so claims take turns across processes.
  • A step timeout on an agent kills the whole process group (as the local
    executor already did), so a grandchild holding the output pipes no longer
    hangs the step until the lease expires.
  • A failed outcome write keeps the queue item and fail() is idempotent:
    a run is no longer left failed with no retry, or queued for ever with no
    item, or released in a 200 ms loop.
  • The sidebar's counts and the Runs queries stay off a full table scan:
    the in-flight count is cached for 5 s and counts only the states the partial
    index covers, the overview chart has a range predicate and explicit UTC
    buckets, and migration 00032 adds runs (criado_em DESC, id DESC),
    built concurrently like 00027: on a large runs table it takes a while.
  • Cross-site requests are refused (Sec-Fetch-Site/Origin) for every
    write and for the "Try it" call, and every response carries
    X-Frame-Options: DENY, Referrer-Policy: same-origin and
    X-Content-Type-Options: nosniff. No CSP yet: the layout's inline script and
    style need nonces first.
  • Login is throttled: two password hashes at once, a per-source lockout
    that doubles up to 15 min, and the typed username is no longer logged.
    Behind a proxy set BREVIS_AUTH_CLIENT_IP_HEADER (see the configuration
    page) so each client has its own key.
  • CI runs only what a change touches (What changed job): a docs or site
    change skips the Go jobs, a change in sdk/ runs everything that builds
    against it.

Security: the scan's findings, and the vulnerable dependencies

  • gosec reads #nosec, not //nolint:gosec. Twenty-seven findings were
    intentional (a CLI that reads the files an operator names, an agent that
    runs the command it is sent, UUID v5's SHA-1) and already carried a
    //nolint the scan does not honour. Each now says #nosec Gxxx and why;
    gosec reports none in the four modules.
  • govulncheck is clean in every module. golang.org/x/net (four
    advisories), google.golang.org/grpc and protobuf, the AWS SDK's S3 and
    event-stream packages, pgx and OpenTelemetry's SDK are on fixed versions,
    with google.golang.org/api and the Google Cloud clients moved to match. The
    SDK's bigquery and pubsub package ceilings (pruning-check.sh) were raised
    once for it, 540 -> 760 and 460 -> 530: that gRPC does not compile against the
    old api, so the whole Google stack moves with it.

Changed: the account menu, a folding sidebar, release notes, GitHub's dark

  • The account button fills the sidebar's foot, and its menu holds the
    language (the eleven, the current one beside it), the theme, Sign out, and
    -- under a separator -- Documentation (in the selected language) and the
    keyboard shortcuts, with the Brevis version last.
  • Theme is auto, light or dark, three icons with the chosen one lit; auto
    (the default) follows the system live. Theme, language and the sidebar's
    state are kept in localStorage and read before the first paint. The
    language is still drawn by the server from its cookie: when the two
    disagree the cookie is mended and the page loads again, once per session.
  • The sidebar folds to an icon rail (full / short) and names each item in a
    hint while folded.
  • The version opens the newest release's notes, drawn from GitHub, with a
    Download button. The console reads the repository's releases every 6 hours
    (a plain GET, nothing sent) and, when one is newer, shows an update icon on
    the account button and a toast once per version. BREVIS_UPDATE_CHECK=off
    turns the check off; a development build never checks.
  • The dark theme follows GitHub's dark palette; the light theme and the
    lime accent are unchanged. Dialogs blur what is behind them.
  • Runs' Live switch is green while it is on, and its dot has a halo that spreads and fades behind it.
  • Every page has the same header height: the title sits on the same line
    whatever the page has beside it (actions, an eyebrow, an intro line), and the
    content begins the same distance below.

Fixed: one colour in brand.yaml no longer repaints the console on parchment (#142)

  • A colour the file leaves out is the product's own. `brand.Default().T...
Read more

brevis-sql v0.7.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 18:33
c73f0d4

Changed: the module is brevis.sh/brevis/sql

  • go install brevis.sh/brevis/sql/cmd/brevis-sql@latest (and
    brevis-sql-api) from this release on; versions up to 0.6.0 stay under
    github.com/AreteAcademy/brevis/sql. It requires the SDK as
    brevis.sh/brevis/sdk v0.88.0.

Changed: the images are brevissh/brevis-sql and brevissh/brevis-sql-api

  • This release publishes to docker.io/brevissh/*, not
    areteacademy/*, which keeps the versions already there. The current ones
    were copied over with the same digests.

Fixed: a failed table rebuild no longer drops the table

  • On Postgres, the DROP and the CREATE TABLE AS of a table model (and of
    incremental --full-refresh) run in one transaction, so a failing CREATE
    leaves the old table readable. (A follow-up builds the new table aside and
    swaps it in by rename, so readers wait only for the rename.)

Added: lookback for incremental models

  • An incremental model can set lookback: 2h (30m, 1d...): the filter is
    w >= max - lookback instead of w > max, so a row that ties the watermark or
    arrives late is merged instead of lost until a --full-refresh. Without it
    the SQL is byte-identical. The watermark must be a TIMESTAMP column.

SDK v0.88.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 16:43
37fe1f8

Changed: the module is brevis.sh/brevis/sdk

  • The SDK's module path moves from github.com/AreteAcademy/brevis/sdk to
    brevis.sh/brevis/sdk, a path on the project's own domain: the
    repository moved to the brevis-sh organization, and a path on the domain
    does not move with an organization again. brevis.sh serves the go-import
    page that points go get at github.com/brevis-sh/brevis.

  • To upgrade, change the import paths and require the new module:

    go get brevis.sh/brevis/sdk@v0.88.0
    # in your code: "github.com/AreteAcademy/brevis/sdk/..." -> "brevis.sh/brevis/sdk/..."

    For Go, the two are different modules: a program must not import both, and
    every package of the SDK moves at once.

  • Every version up to 0.87.0 stays where it is, under the old path, and keeps
    working; there will be no new one there.

  • The extractor's User-Agent names https://github.com/brevis-sh/brevis.

Fixed: a retried or paged POST sent no body

  • extract reads Source.Body once and rewinds it before every attempt and
    every page: a POST retried after a 503, and page 2 of a paged POST, used to go
    out with an empty body and fetch the wrong window without an error.
  • Retry-After is capped at MaxBackoff (60 s when it is zero), the wait
    honours the context, and a non-2xx body is read through a 4 KiB limit: a
    vendor asking for a day no longer sleeps a step for a day.

Fixed: MySQL's dedup ignored more than duplicates

  • to/mysql uses ON DUPLICATE KEY UPDATE <key> = <key> instead of
    INSERT IGNORE, so a value too long, a NULL in a NOT NULL column or a bad
    date fails the load instead of being truncated or zeroed in silence, and the
    batch is capped at 65535 / columns rows (a wide table used to exceed MySQL's
    placeholder limit). Strict sql_mode, the default since 5.7, is assumed.

Gateway v0.33.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 18:46
330f74f

Changed: the module is brevis.sh/brevis/gateway

  • The gateway's module path moves to brevis.sh/brevis/gateway, and it
    requires brevis.sh/brevis/sdk v0.88.0; versions up to 0.32.0 stay under
    github.com/AreteAcademy/brevis/gateway.

Changed: the image is brevissh/brevis-gateway

  • This release publishes to docker.io/brevissh/brevis-gateway (and its
    -slim), not areteacademy/brevis-gateway, which keeps the versions
    already there. The current one was copied over with the same digest.

Fixed: what the audit found in the ingest path

  • The listener bounds reading the body and writing the response in time
    (max(30 s, max_body / 100 KiB/s)), so a client trickling a body can no
    longer hold a connection and its buffer for ever.
  • The memory ceilings count what is queued: batches in the queue and in a
    worker stay in held/bytes until the worker finishes them, and
    max_bytes defaults to 64 MiB (4x max_body or 2x flush.size when those
    are larger). A stream with a slow sink now answers 503 at the stated
    ceiling, instead of at about four times it
    : an operator who tuned
    max_records against the old behaviour will see 503s they did not see before.
  • A retried multi-table batch no longer rewrites the tables that already
    landed
    (under write: append a failure on a later table used to copy the
    earlier ones up to four times).

Engine v0.40.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 23:28
eef1cbf

Added: canceling a run

A run that should not be running can be stopped, from the console or the CLI.
Until now the only way was to kill the process, and the run ended failed and
was retried.

  • A Cancel button on the run's page while it is waiting or running, with a
    confirmation. After the request the page says "Canceling…" until it stops.
  • brevis cancel <run-id> does the same from the CLI, as cli.
  • A waiting run is canceled at once, and leaves the queue. A running run
    is asked: its dispatcher reads the requests every --cancel-poll (2s by
    default), stops the steps and writes canceled. No attempt is spent, and a
    canceled run is not retried.
  • The events feed says who canceled: the console user, cli, or nobody
    when the console has no login.
  • Migration 00030 adds runs.cancel_requested_at and runs.canceled_by.

Changed: Runs is one screen

The list and the run are one screen now, the first of the UI 2.0 screens.
/runs and /runs/{id} are both it -- old links and alerts still land on
their run -- and each pane scrolls on its own.

  • The list is a column: search a piece of a workflow's name (/), All /
    Failed / Running (in flight: running, queued, retrying), Newer and Older,
    and what each workflow runs in. Opening a run swaps the pane without a
    reload; Back, Forward and the arrow keys walk the runs.
  • Why it failed opens a failed run: the step and how it exited, the
    lines before the cause, how many times in a row, and a button that goes
    to the line in the log.
  • The run's log is one, numbered through every attempt, each line with
    its level: search, Warnings and Errors, Wrap, Copy and Download. A huge
    log shows each attempt's last 2,000 lines and the cause; the download has
    it all. The live refresh keeps the search, the filter and the place.
  • Tabs: Logs, Steps (the graph and what each step ran), Parameters (the
    auto params explained, and the values given), Published context.
  • The page loads no React until the Steps tab is opened.
  • In English, Portuguese and Spanish, every word of it.

Changed: the Overview answers what needs you first

The Overview's first section is what needs you now, and the rest of the
screen follows the UI 2.0 design.

  • Needs your attention lists each workflow whose last run failed. Every
    item has why it failed in one line, read from the log as the run page
    reads it; how many times in a row; "View log"; and "Rerun", which comes
    back to the Overview with a toast that links to the new run.
  • It also lists the destinations whose data stopped coming, as /data
    judges them. A destination whose writer is already failing is left out.
  • The section follows itself every ten seconds: a rerun shows as going,
    and the item leaves once the workflow passes. Eight items are drawn, and
    the rest are counted with a link. With nothing to show, a card says so.
  • Four numbers: the success rate, with the retries under it; the failures,
    with "N workflows still failing"; what runs and waits now; and the next
    trigger.
  • The runs chart stacks success, failed and in flight. Clicking a bar now
    opens that hour's or day's runs: the link used parameter names /runs did
    not read, so it opened every run.
  • The next triggers show what each workflow runs in, its schedule in
    words, and when it fires, in green when about to.
  • Recent runs and the event log are tabs. The recent runs filter by All,
    Failed or Running on the page. The event log is the events feed, on a
    screen for the first time.
  • In English, Portuguese and Spanish, every word of it.

Fixed: stopping a local step stops what its shell started

The local executor (BREVIS_ENV=local, and brevis run) killed only the
sh -c. A child it had started was orphaned holding stdout, and the step --
canceled, timed out or shut down -- did not end until the child did. Each step
now runs in its own process group and the whole group is killed, as the remote
agent already did. brevis run stops its steps on Ctrl-C.

Fixed: a failed run records when it ended

A run that failed for good kept terminado_em empty, so the events feed never
showed a run.failed and the insights' durations left every failure out. The
engine now records it, and a retry clears it again when the run goes back to
the queue.

  • Migration 00029 fills it in for the runs that had already failed: the end
    of their last step, or when they were created if no step ever ran.
  • The insights' durations now count failed runs, measured, like the
    others, from when they were created.

Engine v0.39.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 20:38

Added: the console's UI 2.0 foundation

The shared layer the redesigned screens are built on. No screen is redesigned
yet; every one gets the new frame.

  • A light theme, beside the dark default. The switch is at the sidebar's
    foot, the choice is a cookie, and the server writes it on <html>, so the
    page is never painted in the wrong one first. Every text colour reads at
    4.5:1 or better in both, and a test holds it. brand.yaml gains an optional
    theme_light:; without it, the light theme is the product's.
  • The sidebar is grouped by what you came to do: Monitor (Overview, Runs),
    Orchestrate (Workflows), Ingest (Streams, Loads) and Data (Endpoints, SQL).
    Projects is a switcher under the brand. Each section says what it is for on
    hover and on keyboard focus. The sidebar becomes a drawer below 860px (it was
    960px).
  • Every state is a shape, a word and a colour -- a diamond for failed, a
    triangle for late, a spinning ring for running -- so none depends on telling
    colours apart.
  • Keyboard: g then a letter goes to a section (o Overview, e Runs,
    w Workflows, t Streams, s SQL), ? lists the shortcuts, and the palette
    (⌘K) gains actions, starting with Toggle theme. None fire while typing in a
    field.
  • Drawers, modals and toasts. A dialog opens on its first field and gives
    the focus back on close; a toast says what an action did, and a page can
    hand one to the next across a redirect.
  • Brand marks for 28 connectors and languages, embedded in the binary, with
    their licences.
  • With prefers-reduced-motion, nothing moves; a test checks every animation.

Added: the console in Portuguese and Spanish

The console's frame speaks English, Brazilian Portuguese and Spanish: the
sidebar and its hints, the palette, the shortcuts, the account menu, the
states' words, relative times, dates and numbers, and the sign-in page.

  • The language is the reader's choice (a globe at the sidebar's foot, or the
    palette), remembered in a cookie, and English is the default. The server
    draws the page in it from the first paint, and <html lang> says which.
    The browser's Accept-Language is not used yet: until the screens are
    translated it would open a console half in each language for somebody who
    never asked for one.
  • Choosing works with no script: a form that returns to the same page.
  • The pages' own content is still English; each screen is translated as it is
    redesigned.
  • The Spanish catalog is marked for a native speaker's review.

Added: what failed, and since when

  • Runs counts the workflows failing on every page: those whose last
    finished run failed, paused ones included. A screen reader hears it as a
    sentence. The count is read at most every 15 seconds.
  • A run's whole log downloads as one text file, GET /runs/{id}/log.txt, linked from the run's step output: every attempt of
    every step in the order they ran, each under a header with its state and
    exit code. Behind the same login as every page.
  • Underneath, for the redesigned Runs and Overview screens: the line that
    says why a run failed, the level of every log line, and how many times in
    a row a workflow has failed. All computed when a page asks, so a better
    rule applies to every run already recorded. The Slack alert is unchanged.

Added: the events feed, as data

What happened to an installation, in order, for the redesigned Overview's
"Events" tab. Nothing on today's screens changes.

  • A new events table (migration 00026) records what no other table kept
    a history of, each in the action's own transaction and with who did it:
    • a workflow published or pruned;
    • a schedule paused or resumed;
    • a stream published;
    • a gateway or an API taken down;
    • an API's endpoints published.
  • A publish is recorded only when it changed something, so a CI that
    republishes on every deploy does not fill the feed.
  • Runs are read from runs, as started and as ended. Migration 00027
    indexes them by both times, CONCURRENTLY.
  • Reading: a page of 50 is one query and one index per source, with a
    stable cursor and a filter by source. Measured at 0.3–0.6 ms with a million
    runs and a hundred thousand events.
  • Retention: brevis prune deletes the events past the same
    --purge-after as the runs, and its report counts them.
  • The pause button now passes the signed-in operator to the schedule.
    publish, gateway and endpoints record cli as who did it.

Fixed: a draining agent in a pool no longer fails runs (#146)

A start refused by a draining agent behind a pool's Service name went back to
the same agent, down the kept-alive connection, and every refusal spent one of
the run's attempts. Runs failed while a healthy replica stood beside it.

  • The refused start goes to another replica. The engine resolves the name
    itself and tries an address that refused for draining last, for 30 seconds.
    The agent says Brevis-Refusal: draining and closes the connection; an agent
    from 0.38 is recognised by its message. A bare 503 is still a failure.
  • The engine speaks HTTP/1.1 to agents, so no start waits on a connection
    another step's stream holds.
  • A step nobody started spends nothing. When every replica is draining,
    the step's attempts are kept, and the run goes back to the queue with no
    attempt spent and no alert, for at most --drain-wait (default 1h), tried
    again every --drain-requeue-delay (default 30s). Past the wait the
    attempt is spent as before. --drain-wait 0 spends it at once.
  • Migration 00028 adds runs.draining_since.

Fixed: a step that succeeded no longer hangs in the executor (#147)

Closing a host: step's stream while it was still being read could let that
stray read take the end of the next response on the same connection, and a
step that had already succeeded was waited on forever. Each stream now has a
request of its own, and its reader is stopped before the body is closed.

Changed

  • The accent is spent in four places: the primary action, the open
    section, the mark and the focus ring. The primary button is now the lime
    (it was ink); links are ink, underlined; tabs, chips, bars, charts and the
    DAG's edges are neutral.
  • Small buttons are 26px (were 28px).