Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
After auto-resolving (or interactively resolving) conflicts, the
tool used to leave the renames as uncommitted changes for the user
to fold back into the right commits by hand. With more than a
trivial branch, that's tedious and error-prone.
For each `(old, new)` rename, find the most recent commit between
`@{u}` and `HEAD` that added `old`, build a `fixup!` commit
targeting it via `git commit --only` (so any unrelated already-
staged changes the user had don't get folded in), and then run `git
rebase --autosquash --autostash @{u}` so the renames land in the
commits that introduced each local migration. Skip the squash for
any renamed file with no in-branch add (untracked or already
committed elsewhere); leave that change in the working tree.
Refuse upfront if `@{u}..HEAD` contains any merge commit, since
`git rebase -i --autosquash` would silently linearize them and
`--autostash` would make recovery awkward.
`--no-rebase` skips the squash for users who want to handle commit
placement themselves.
The interactive prompt previously asked the user to order every
conflicting migration, and the renumberer bumped each loser by one
position at a time. A branch with a single new migration that
collides several positions behind the upstream tip therefore had to
walk through one prompt per intervening commit.
Use `git ls-tree @{u}` to detect which conflicting migrations are
branch-local. When `@{u}` resolves and every conflict group has
exactly one local file, renumber all local migrations at-or-past
the first conflict contiguously past the upstream tip, in NNNN
order: the new NNNNs fill in from `upstream_tip + 1` and increment
by 1, with each file's in-app dep rewritten to the previous file
in the new chain. Non-conflicting local migrations between the
first conflict and the new tip are renumbered too, so the chain
stays intact and there's no NNNN gap.
When `@{u}` can't be resolved, fall back to the existing interactive
prompt per group. If `@{u}` is available but a conflict has 0 or
2+ local files (backport or order-ambiguous), error out and let
the user resolve manually.
Pull the conflict-detection scan into a `find_conflict_groups`
helper that returns one list per colliding NNNN prefix, sorted by
prefix. Have `main()` operate on the lowest-numbered group, re-glob
after each pass, and stop when no group is left. Sets up the
follow-up commit's per-group decision (auto-resolve vs. interactive
prompt).
Interactive callers now get one prompt per conflict group rather
than a single combined prompt for every conflicting file at once,
which is also a smaller blast radius if the user gives a wrong
order.
* Move the body of the `if __name__ == "__main__":` block into a
`main()` function and lift `MIGRATIONS_TO_SKIP` to module scope
near the other module-level definitions at the top of the file.
* Replace the misnamed `stack: list[str]` with a `seen_prefixes:
set[str]`, and de-indent the rename branch by `continue`-ing on
the "first occurrence" path.
* Use `removesuffix(".py")` instead of `replace(".py", "")`.
* Rewrite `validate_order` as a single permutation check, with an
error message that says what was expected and what was received.
* Drop the unused `files_list` parameter from `resolve_conflicts`
and replace its `range(len(...))` with `enumerate`.
The previous regex `[\d]+(_[a-z0-9]+)+` matched any digit run
followed by `_word` segments, anywhere in the file. That includes
unrelated tokens like the Python integer literal `1_000` and
cross-app dependency tuples such as `("auth", "0001_initial")`,
both of which were silently rewritten to the renumbered migration's
new predecessor name.
Match only tuples whose app label matches the app being renumbered,
and rewrite just the migration-name string. Refuse outright to
renumber a file with multiple in-app dependency tuples (a migration
merge), since rewriting all of them to the same predecessor would
produce a self-referential migration; those need to be renumbered
by hand.
3% of generated messages now include a text markdown
file attachment, created via the upload API.
Fixes part of #14991.
Co-authored-by: Andrew Wang
<73965466+wandrew0@users.noreply.github.com>
A pure mechanical rename: classes that subclassed BaseEvent
moved their "Event" prefix to a suffix, e.g. EventAlertWords
-> AlertWordsEvent. This puts the type name first, which
reads more naturally and matches how we've been naming things
in newer code.
Helper classes whose names embed an event class (e.g.
AttachmentFieldForEventAttachmentRemove) follow the rename
through to AttachmentFieldForAttachmentRemoveEvent.
tools/check-schemas is updated to construct names with the
new suffix, and a comment in that file is updated likewise.
Co-authored-by: Steve Howell <showell30@yahoo.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub Actions runners we target are linux/amd64, but
images on Apple Silicon (arm64) hosts produces an arm64
image and `docker push` publishes a manifest CI cannot run.
Pinning at the FROM line forces qemu emulation on arm64 hosts,
trading build time for a reproducible amd64 artifact regardless
of where the build happens.
When trying to backport a pull request that hasn't yet been merged on
GitHub, we'd get an unhelpful error due to the empty `$merge_commit`
value:
```
gh: ` 0` does not appear to be a valid cursor.
```
This commit introduces an explicit check and a clear error.
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
webpack-dev-server's `--allowed-hosts` CLI flag is repeatable
(documented as `<value...>` in webpack-cli's SERVE-OPTIONS-v5.md,
declared as `multiple: true` with `path: "allowedHosts[]"` in
webpack-dev-server's `bin/cli-flags.js`) and does not split on
commas. The previous comma-joined form caused the entire string
`"127.0.0.1,.zulipdev.com,.zulipdev.org"` to be stored as a
single literal entry in `allowedHosts`, which matched no real
host and never triggered the leading-dot wildcard branch.
The practical symptom was webpack-dev-server rejecting the
WebSocket handshake with "Invalid Host/Origin header" when the
dev server was accessed via the default `zulipdev.com:9991`
EXTERNAL_HOST: only the hardcoded fallbacks for localhost, IP
literals, and `options.host` (= 127.0.0.1) still passed.
Running with `--interface=` masked the bug because that path
takes the `--disable-host-check` branch (which becomes
`--allowed-hosts=all`).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Switch the topic summarization integration from the litellm wrapper
library to the OpenAI Python SDK directly. The SDK can be pointed at
any OpenAI-compatible endpoint via a new TOPIC_SUMMARIZATION_API_BASE
setting, so provider/model strings like "groq/llama-3.3-70b-versatile"
become a plain model name plus a base URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Fedora 44 ships Postgres 17 in PGDG and shares Fedora 43's package
list, so support is just a matter of accepting the new version in
the provision check.
This automates backend provisioning, fixes RabbitMQ hostname resolution,
grants PostgreSQL passwordless sudo, and explicitly forwards only the
required web port (9991).
Fedora 38 reached end of life upstream; replace it with Fedora 43,
which ships dnf5 and a recent enough groonga to skip the source
build. Concretely, to make `tools/provision` run cleanly on
Fedora 43:
* dnf5 (Fedora 41+) dropped the `groupinstall` alias and no longer
resolves the "Development Tools" display name, so switch the
Fedora branch of `setup-yum-repo` to
`dnf group install development-tools` (by group ID). Move the
existing CentOS/RHEL `groupinstall` calls into their own branches
so they keep working on yum/dnf4.
* Map Fedora 43 to PostgreSQL 17, and add `groonga-devel`,
`xxhash-devel`, `meson`, and `redhat-rpm-config` to the Fedora
package list. PGroonga 4.0.6 switched its build system to meson;
on Fedora, PostgreSQL's `pg_config` exports CFLAGS containing
`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1` and
`-specs=.../redhat-annobin-cc1`, and without `redhat-rpm-config`
the PGroonga build fails with "cannot read spec file".
`xxhash-devel` is required because `xxhash-libs` is often pulled
in transitively (by blosc2, pyarrow, etc.) without its headers,
in which case meson detects libxxhash via pkg-config and skips
the vendored fallback that would otherwise build it from source.
* Use the packaged groonga from Fedora's main repo (15.0.4 on
Fedora 43, satisfying PGroonga 4.0.6's >= 14.1.0 requirement)
instead of compiling groonga from source. This removes the only
remaining caller of `scripts/lib/build-groonga` and the
BUILD_GROONGA_FROM_SOURCE plumbing in provision.py, which the
prior Fedora 38 path was the only user of.
Verified end-to-end on a Fedora 43 host and in a fresh fedora:43
podman container: setup-yum-repo, the package install, and the
PGroonga source build against the system groonga all complete
cleanly.
Because of how the test runner varies settings.LOCAL_UPLOADS_DIR,
we reset the realm uploaded emoji for the realm export tests for
both the python and curl examples. Previously, the realm export
was failing after the success response with the export ID was
sent.
When a user Tabs to a sidebar element and presses arrow keys,
sync the ListCursor to the focused element's row and navigate
from there, then move focus to the new row. This makes switching
between Tab and arrow key navigation preserve position.
When Tab is pressed from a search input after arrow key
navigation, focus moves to the highlighted row rather than the
next element in DOM order. Pressing Tab also clears the cursor
highlight so it doesn't persist alongside focus styling.
For the right sidebar, arrow keys from section headers, "view
all" links, and the "invite" link navigate to the nearest
visible user row in the appropriate direction.
The new logic in activity_ui.ts is jQuery/DOM traversal glue
(closest/nextAll/addBack, document.activeElement, focus()) that
is better verified end-to-end than with mocked node tests, and
buddy_list.ts and essentially every other *_ui.ts sidebar file
are already in EXEMPT_FILES. Add activity_ui.ts there for
consistency rather than writing low-value mock-heavy tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Its behavior is the default now; asyncio.DefaultEventLoopPolicy and
asyncio.set_event_loop_policy are deprecated.
https://docs.python.org/3.14/whatsnew/3.14.html#id10
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
Recent frontend dependency changes removed global jQuery
exposure in the webpack build.
The screenshot scripts were still using $ inside
page.evaluate callbacks, which caused ReferenceError
at runtime.
Replace those jQuery calls with equivalent DOM
operations using querySelectorAll, remove,
classList.remove, and style updates.