Skip to content
Closed
23 changes: 23 additions & 0 deletions docs/admin/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2348,6 +2348,29 @@ On by default, as that suits public server setups.

.. _settings-credentials:

.. setting:: WEBSITE_ALERTS_ENABLED

WEBSITE_ALERTS_ENABLED
----------------------

.. versionadded:: 5.16.1

Default: ``True``

Defines whether Weblate should check website availability and show alerts
for broken project or component websites.

When set to ``False``, Weblate will skip website availability checks and
will not generate alerts for unreachable websites. This is useful when:

- Your websites are behind firewalls that block Weblate's requests
- You want to avoid 403/503-type errors from bot protection
- Website availability is not a concern for your installation

.. seealso::

:setting:`WEBSITE_REQUIRED`

Configuring version control credentials
---------------------------------------

Expand Down
3 changes: 3 additions & 0 deletions docs/admin/install/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,9 @@ Generic settings

Allows CORS requests to API from all origins.

.. envvar:: WEBLATE_WEBSITE_ALERTS_ENABLED

Configures :setting:`WEBSITE_ALERTS_ENABLED`.

.. envvar:: CLIENT_MAX_BODY_SIZE

Expand Down
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Weblate 5.16.1

.. rubric:: New features

* Added :setting:`WEBSITE_ALERTS_ENABLED` setting to allow disabling website availability checks and alerts.
* :doc:`/formats/asciidoc` is now a supported file format.

.. rubric:: Improvements
Expand Down
3 changes: 3 additions & 0 deletions weblate/settings_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
# Whether site uses https
ENABLE_HTTPS = get_env_bool("WEBLATE_ENABLE_HTTPS")

# Support for env variable
WEBSITE_ALERTS_ENABLED = get_env_bool("WEBLATE_WEBSITE_ALERTS_ENABLED", True)

# Site URL
SITE_URL = f"{'https' if ENABLE_HTTPS else 'http'}://{SITE_DOMAIN}"

Expand Down
4 changes: 4 additions & 0 deletions weblate/settings_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,10 @@
# PGP commits signing
WEBLATE_GPG_IDENTITY = None

# Website availability checks
# Set to False to disable broken website alerts
WEBSITE_ALERTS_ENABLED = True

# Third party services integration
MATOMO_SITE_ID = None
MATOMO_URL = None
Expand Down
3 changes: 3 additions & 0 deletions weblate/trans/models/_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class WeblateConf(AppConf):
LICENSE_FILTER = None
LICENSE_REQUIRED = False
WEBSITE_REQUIRED = True
# Enable or disable website availability checks and alerts
# Set to False to disable broken website alerts
WEBSITE_ALERTS_ENABLED = True
FONTS_CDN_URL = None
PROJECT_BACKUP_KEEP_DAYS = 30
PROJECT_BACKUP_KEEP_COUNT = 3
Expand Down
3 changes: 3 additions & 0 deletions weblate/trans/models/alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,9 @@ def __init__(self, instance: Alert, error: str | None = None) -> None:

@staticmethod
def check_component(component: Component) -> bool | dict | None:
if not settings.WEBSITE_ALERTS_ENABLED:
return False

if component.project.web:
location_error = get_uri_error(component.project.web)
if location_error is not None:
Expand Down
42 changes: 40 additions & 2 deletions weblate/trans/tests/test_alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,52 @@

"""Test for alerts."""

from django.test.utils import override_settings
from django.test import TestCase, override_settings
from django.urls import reverse

from weblate.lang.models import Language
from weblate.trans.models import Unit
from weblate.trans.models import Component, Project, Unit
from weblate.trans.tests.test_views import ViewTestCase


class WebsiteAlertSettingTest(TestCase):
"""Test WEBSITE_ALERTS_ENABLED setting."""

def setUp(self):
# Create a test project with a broken website URL
self.project = Project.objects.create(
name="Test Project",
slug="test-project",
web="https://this-website-does-not-exist-404.com",
)
self.component = Component.objects.create(

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / macos

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / macos

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, mariadb, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, mariadb, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.13, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.13, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, redis, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, redis, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, valkey, edge deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, postgresql, valkey, edge deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.12, postgresql, valkey, minimal deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.12, postgresql, valkey, minimal deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.12, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.12, postgresql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, mysql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_enabled KeyError: ''

Check failure on line 25 in weblate/trans/tests/test_alert.py

View workflow job for this annotation

GitHub Actions / py3.14, mysql, valkey, latest deps

WebsiteAlertSettingTest.test_website_alerts_disabled KeyError: ''
project=self.project,
name="Test Component",
slug="test-component",
# ... other required fields ...
)
Comment on lines +15 to +30
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Component.objects.create() call is missing required fields. Components in Weblate require several fields including file_format, filemask, repo, and vcs to be valid. This test will fail at runtime. Consider using the existing test infrastructure like ViewTestCase which properly sets up components, or look at how other tests create components (e.g., in test_license which uses self.component that's created by the test infrastructure).

Suggested change
class WebsiteAlertSettingTest(TestCase):
"""Test WEBSITE_ALERTS_ENABLED setting."""
def setUp(self):
# Create a test project with a broken website URL
self.project = Project.objects.create(
name="Test Project",
slug="test-project",
web="https://this-website-does-not-exist-404.com",
)
self.component = Component.objects.create(
project=self.project,
name="Test Component",
slug="test-component",
# ... other required fields ...
)
class WebsiteAlertSettingTest(ViewTestCase):
"""Test WEBSITE_ALERTS_ENABLED setting."""
def create_component(self):
# Use standard test infrastructure to create a valid component
return self.create_po_new_base()
def setUp(self):
super().setUp()
# Ensure the project has a broken website URL
self.project.web = "https://this-website-does-not-exist-404.com"
self.project.save(update_fields=["web"])

Copilot uses AI. Check for mistakes.

@override_settings(WEBSITE_ALERTS_ENABLED=False)
def test_website_alerts_disabled(self):
"""Test that website alerts are not created when setting is False."""
# Run alert check
# ... code to trigger alert check ...

# Assert no broken website alert was created
alerts = self.component.alert_set.filter(name="BrokenProjectWebsite")
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alert name filter should be "BrokenProjectURL" not "BrokenProjectWebsite". Looking at line 64 of this same file, you can see the correct alert name is "BrokenProjectURL". This is also confirmed in alert.py where the class is registered as BrokenProjectURL.

Copilot uses AI. Check for mistakes.
self.assertEqual(alerts.count(), 0)

@override_settings(WEBSITE_ALERTS_ENABLED=True)
def test_website_alerts_enabled(self):
"""Test that website alerts are created when setting is True."""
# Run alert check
# ... code to trigger alert check ...

# Assert broken website alert was created
alerts = self.component.alert_set.filter(name="BrokenProjectWebsite")
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alert name filter should be "BrokenProjectURL" not "BrokenProjectWebsite". This is the same issue as in test_website_alerts_disabled - the correct alert name is "BrokenProjectURL" as seen on line 64 of this file.

Copilot uses AI. Check for mistakes.
self.assertGreater(alerts.count(), 0)
Comment on lines +15 to +50
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is incomplete - it contains placeholder comments instead of actual test implementation. The tests need to call component.update_alerts() to trigger the alert check mechanism, following the pattern used in other tests in this file (see test_license at line 128-161). Without actually triggering the alert check, these tests don't verify the functionality they claim to test.

Copilot uses AI. Check for mistakes.


class AlertTest(ViewTestCase):
def create_component(self):
return self._create_component("po", "po-duplicates/*.dpo", manage_units=True)
Expand Down
Loading