This commit changes the way Sidekiq is restarted when memory limit is
exceeded. The HUP signal was replaced with TERM, as mentioned in the
official documentation. The stopping timeout has been set to 10 seconds
to account for the Sidekiq timeout (5 seconds) and another for it
shutdown cleanly (5 more seconds).
See https://github.com/sidekiq/sidekiq/wiki/Deployment.
When hard deleting a first post by passing force_destroy: true as an option to PostDestroyer, the post/topic is correctly deleted, and the staff record is created, but the app then errors out.
This only happens on sites with a topic_destroyed webhook setup.
After deleting the record, we pass the topic's ID to TopicView, which then raises an error because it can not load it from the DB.
TopicView supports being initialized with either an ID or an already instantiated record. Since we still have the record in memory after deleting, we can pass that to TopicView.
We currently limit the number of characters in the bar-separated list of auto-membership e-mail domains. We want to make this configurable through site settings.
After this change, we limit the length of each individual domain, and enable the number of domains to be configured through a hidden site setting.
The original limit is there to prevent DoS, since a TEXT column can take up to 1Gb. With this new limit we're still at a maximum of around 10kb.
We have this rule in
https://meta.discourse.org/t/formatting-text-in-discourse-documentation-and-uis/324637:
> Do not use a period for the following:
>
> Tooltips, image captions, or other UI elements with only one sentence
However, this looks strange on some admin pages because we also show
a "Learn more..." link after the header description, which kind of
runs on into the link.
This commit adds a separator after the link to address this issue.
The change made in #31854 introduced a regression when editing groups, preventing saving when no auto membership e-mail domains are entered.
This change fixes that and adds a system test.
Avoids autocompleting or applying mention/emoji/hashtag/any input rules on
rich editor inline code.
There's also a refactor on how the params are passed to input rules – we
now use the same params from plugins, keeping it more consistent.
The string introduced in
https://github.com/discourse/discourse/pull/31854 included a count but
was not pluralized. Even though the singular form may not be used in
English, proper pluralization is necessary for other languages. Some
languages have different plural forms depending on the number, so
explicitly defining pluralization ensures accurate translations.
Before this commit,
`PageObjects::Components::SelectKit#expanded_component` might not expand
the component if `is_collapsed?` returns true which can return true if
the method was called before the select-kit component appears on the
screen. When that happens, we end up not expanding the `select-kit`
because we think it is collapsed when in fact the select-kit component
is not rendered yet. This lead to system test failures with errors like:
```
Capybara::ElementNotFound:
Unable to find css "#add-synonyms.is-expanded"
```
This commit updates `PageObjects::Components::SelectKit#is_collapsed?`
to check that the select-kit component has rendered first before
checking if the component is not expanded.
### Reviewer notes
Instances of test flakiness due to this bug:
1.
https://github.com/discourse/discourse/actions/runs/13905226478/job/38906569777
2.
https://github.com/discourse/discourse/actions/runs/13848357836/job/38751122333
Follow up to e4401e587e98ac4020c2c4fd965e227146cf33d4.
In the previous change, when serialising a Reviewable post, we were appending the title to the post content whilst checking for watched word matches. This append action was acting upon the object itself, rather than just a copy of the string, causing the UI to display the title appended twice to the content.
Fortunately, since it was only happening in the serialiser, the incorrect data was never stored in the database, it was only happening when viewing the review queue.
When performing an action in the review queue, this change makes two improvements:
- The buttons on the reviewable item are disabled, so you can't accidentally multi-click.
- A toast is displayed when the action is complete, as a success indication.
Fixes the custom homepage crawler output to include links to the site's
top menu.

This also provides a way to override that content via a plugin. Example
usage in a `plugin.rb` file:
```
register_html_builder("server:custom-homepage-crawler-view") do |c|
"<div>override</div>"
end
```
This reduces some duplicate color assignment to tags and rolls them up
under a common css var
```css
:root {
--tag-text-color: var(--primary-high);
}
.extra-info-wrapper {
--tag-text-color: var(--header_primary-high);
}
```
This also makes the tag separator color consistent with the tag color,
by setting it to `--tag-text-color`
Ultimately we have 3 tag text color states (this appeared to be
consistent across all tag styles):
* Default: primary-high
* Header: header__primary-high
* Visited topic in the topic list: primary-medium
Previously we were showing a loading spinner, but the old user list
persisted so the spinner was often off the bottom of the screen. This
commit updates the `users` list to be a getter, so it's always perfectly
in-sync with the `_results` set. That means no users will be shown while
a new list is being loaded, so the spinner is more visible.
https://meta.discourse.org/t/load-spinner-missing-from-dynamic-pages/357525/4
This reverts commit 992bdf173ad8ad25764c0a89132bc35df4c81f12.
This change was causing issues in a [third party
plugin](https://meta.discourse.org/t/events-plugin):
https://meta.discourse.org/t/events-plugin/69776/869
```
Uncaught Error: Could not find module `discourse/mixins/singleton` imported from `discourse/plugins/discourse-events/discourse/models/provider`
at loader.js:247:1
at h (loader.js:258:1)
at u.findDeps (loader.js:168:1)
at h (loader.js:262:1)
at u.findDeps (loader.js:168:1)
at h (loader.js:262:1)
at requireModule (loader.js:24:1)
at y (app.js:170:18)
at b (app.js:193:19)
at app.js:156:29
at g.start (app.js:167:1)
at HTMLDocument.<anonymous> (start-app.js:5:7)
at discourse-boot.js:13:12
at discourse-boot.js:1:1
```
Currently we allow for 2 theme screenshots to be specified,
with a lightweight spec to allow both a light and dark
version of the screenshot. However, we were not storing this
screenshot name anywhere, so we would not be able to use it
for light/dark switching.
This commit fixes that issue, and also does some general refactoring
around theme screenshots, and adds more tests.
Test is flaking in CI with:
```
Failure/Error: expect(theme_translations_settings_editor.get_input_value).to have_content("Bonjour!")
expected to find text "Bonjour!" in "Hello there!"
[Screenshot Image]: /__w/discourse/discourse/tmp/capybara/failures_r_spec_example_groups_admin_customize_themes_when_editing_theme_translations_should_allow_admin_to_edit_and_save_the_theme_translations_from_other_languages_797.png
~~~~~~~ JS LOGS ~~~~~~~
(no logs)
~~~~~ END JS LOGS ~~~~~
./spec/system/admin_customize_themes_spec.rb:158:in `block (3 levels) in <main>'
```