Skip to content

Commit 058ff61

Browse files
committed
Merge remote-tracking branch 'github/main' into feat/add-version-to-response-headers
2 parents b39bbcf + d4b5d6a commit 058ff61

30 files changed

+146
-73
lines changed

.release-please-manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "2.174.0"
2+
".": "2.175.0"
33
}

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## [2.175.0](https://github.com/Flagsmith/flagsmith/compare/v2.174.0...v2.175.0) (2025-04-23)
4+
5+
6+
### Features
7+
8+
* MetadataModelRequirement uses organisation ID as objectID (✅ relies on [#5325](https://github.com/Flagsmith/flagsmith/issues/5325) - deployed) ([#5326](https://github.com/Flagsmith/flagsmith/issues/5326)) ([8dc92c3](https://github.com/Flagsmith/flagsmith/commit/8dc92c3ef9ede001377a3c8ee9a6d10794f08824))
9+
* unsaved warning modal in environment settings ([#5337](https://github.com/Flagsmith/flagsmith/issues/5337)) ([dbf8d6c](https://github.com/Flagsmith/flagsmith/commit/dbf8d6c568ad67164e3e708a0fa82c40a97591f9))
10+
11+
12+
### Bug Fixes
13+
14+
* order of onboarding requests ([#5376](https://github.com/Flagsmith/flagsmith/issues/5376)) ([2650e1d](https://github.com/Flagsmith/flagsmith/commit/2650e1d08441370ccc1d644b7e9f61aa5fd9770f))
15+
* public urls ([#5319](https://github.com/Flagsmith/flagsmith/issues/5319)) ([4c5043d](https://github.com/Flagsmith/flagsmith/commit/4c5043dd3b7b1b0a5524ed452a577af84b100046))
16+
317
## [2.174.0](https://github.com/Flagsmith/flagsmith/compare/v2.173.1...v2.174.0) (2025-04-22)
418

519

Dockerfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ FROM wolfi-base AS api-runtime
119119

120120
# Install Python and make it available to venv entrypoints
121121
ARG PYTHON_VERSION
122-
RUN apk add curl python-${PYTHON_VERSION} && \
122+
RUN apk add python-${PYTHON_VERSION} && \
123123
mkdir /build/ && ln -s /usr/local/ /build/.venv
124124

125125
WORKDIR /app
@@ -140,7 +140,7 @@ ENTRYPOINT ["/app/scripts/run-docker.sh"]
140140
CMD ["migrate-and-serve"]
141141

142142
HEALTHCHECK --interval=2s --timeout=2s --retries=3 --start-period=20s \
143-
CMD curl -f http://localhost:8000/health/liveness || exit 1
143+
CMD flagsmith healthcheck tcp
144144

145145
# * api-runtime-private [api-runtime]
146146
FROM api-runtime AS api-runtime-private

api/manage.py

-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
#!/usr/bin/env python
22
import os
3-
import sys
43

54
from common.core.main import main
65

76
if __name__ == "__main__":
8-
# Backwards compatibility for task-processor health checks
9-
# See https://github.com/Flagsmith/flagsmith-task-processor/issues/24
10-
if "checktaskprocessorthreadhealth" in sys.argv:
11-
import scripts.healthcheck
12-
13-
scripts.healthcheck.main()
14-
157
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings.local")
168

179
main()

api/poetry.lock

+10-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ pygithub = "2.1.1"
154154
hubspot-api-client = "^8.2.1"
155155
djangorestframework-dataclasses = "^1.3.1"
156156
pyotp = "^2.9.0"
157-
flagsmith-common = "^1.10.0"
157+
flagsmith-common = "^1.11.0"
158158
django-stubs = "^5.1.3"
159159
tzdata = "^2024.1"
160160
djangorestframework-simplejwt = "^5.3.1"

api/sales_dashboard/templates/sales_dashboard/home.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ <h1 class="h2">Organisations</h1>
2929

3030
<div class="sort-form">
3131
<form action="{% url 'sales_dashboard:index' %}" method="get" class="form-inline float-right">
32+
<label for="include-deleted" class="mr-1">Include deleted:</label>
33+
<input type="checkbox" name="include_deleted" id="include-deleted" class="mr-1" {% if include_deleted %}checked{% endif %}>
3234
<label for="filter-plan">Filter: </label>
3335
<select name="filter_plan" id="filter-plan" class="custom-select m-1">
3436
<option value="" {% if not filter_plan %}selected{% endif %}>Filter Plan</option>
@@ -82,7 +84,7 @@ <h1 class="h2">Organisations</h1>
8284
{% endif %}"
8385
>
8486
<td>{{org.id}}</td>
85-
<td><a href="/sales-dashboard/organisations/{{org.id}}">{{org.name}}</a></td>
87+
<td><a href="/sales-dashboard/organisations/{{org.id}}">{{org.name}} {% if org.deleted_at %}<span class="badge badge-danger">Deleted</span>{% endif %}</a></td>
8688
<td>{{ org.subscription.plan|default:"Free" }}{% if org.subscription.payment_method %} - {{ org.subscription.payment_method|capfirst }}{% endif %}</td>
8789
<td><span class="{% if org.num_users > org.subscription_information_cache.allowed_seats %}badge badge-danger{% endif %}">{{org.num_users}}</span></td>
8890
<td>{{org.subscription_information_cache.allowed_seats|default:1}}</td>

api/sales_dashboard/templates/sales_dashboard/organisation.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
<h1 class="h2 float-left">
1717
Organisation: <strong>{{organisation.name}}</strong>
1818
- Plan: <strong>{{ organisation.subscription.plan|default:"Free"}}</strong>
19-
{% if organisation.has_paid_subscription and not organisation.is_paid %}<span class="badge badge-danger">Subscription Cancelled</button>{% endif %}
19+
{% if organisation.deleted_at %}<span class="badge badge-danger">Deleted</span>{% endif %}
20+
{% if organisation.has_paid_subscription and not organisation.is_paid %}<span class="badge badge-danger">Subscription Cancelled</span>{% endif %}
2021
</h1>
2122
<div class="float-right"><a href="/admin/organisations/organisation/{{organisation.id}}/change">Django Admin</a></div>
2223
<div class="float-right">

api/sales_dashboard/views.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ class OrganisationList(ListView): # type: ignore[type-arg]
6767
template_name = "sales_dashboard/home.html"
6868

6969
def get_queryset(self): # type: ignore[no-untyped-def]
70-
queryset = Organisation.objects.annotate(
70+
if self.request.GET.get("include_deleted") == "on" or self.request.GET.get(
71+
"search"
72+
):
73+
queryset = Organisation.objects.all_with_deleted()
74+
else:
75+
queryset = Organisation.objects.all()
76+
77+
queryset = queryset.annotate(
7178
num_projects=Count("projects", distinct=True),
7279
num_users=Count("users", distinct=True),
7380
num_features=Count("projects__features", distinct=True),
@@ -105,6 +112,7 @@ def get_context_data(self, **kwargs): # type: ignore[no-untyped-def]
105112
data["filter_plan"] = self.request.GET.get("filter_plan")
106113
data["sort_field"] = self.request.GET.get("sort_field")
107114
data["sort_direction"] = self.request.GET.get("sort_direction")
115+
data["include_deleted"] = self.request.GET.get("include_deleted", "off") == "on"
108116

109117
# Use the most recent "influx_updated_at" in
110118
# OrganisationSubscriptionInformationCache object to determine
@@ -155,7 +163,8 @@ def _build_search_query(self, search_term: str) -> Q:
155163
@staff_member_required
156164
def organisation_info(request: HttpRequest, organisation_id: int) -> HttpResponse:
157165
organisation = get_object_or_404(
158-
Organisation.objects.select_related("subscription"), pk=organisation_id
166+
Organisation.objects.all_with_deleted().select_related("subscription"),
167+
pk=organisation_id,
159168
)
160169
template = loader.get_template("sales_dashboard/organisation.html")
161170
subscription_metadata = organisation.subscription.get_subscription_metadata()

api/scripts/__init__.py

Whitespace-only changes.

api/scripts/healthcheck.py

+6-21
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
import logging
22
import sys
33

4-
import requests
5-
6-
HEALTH_LIVENESS_URL = "http://localhost:8000/health/liveness"
7-
8-
9-
logger = logging.getLogger(__name__)
10-
11-
12-
def main() -> None:
13-
logger.warning(
14-
f"This healthcheck, invoked by {' '.join(sys.argv)}, is deprecated. "
15-
f"Use the `{HEALTH_LIVENESS_URL}` endpoint instead."
16-
)
17-
status_code = requests.get(HEALTH_LIVENESS_URL).status_code
18-
19-
if status_code != 200:
20-
logger.error(f"Health check failed with status {status_code}")
21-
22-
sys.exit(0 if 200 >= status_code < 300 else 1)
23-
4+
from common.core.main import main
245

256
if __name__ == "__main__":
26-
main()
7+
logging.getLogger(__name__).warning(
8+
f"This healthcheck, invoked by `{' '.join(sys.argv)}``, is deprecated. "
9+
"Please use one of the `flagsmith healthcheck` commands instead."
10+
)
11+
main(["flagsmith", "healthcheck", "http"])

docs/docs/deployment/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ We recommend running Flagsmith with [Docker](/deployment/hosting/docker). We hav
7272
The Flagsmith architecture is based around a REST API that is accessed by both SDK clients and the Flagsmith Dashboard
7373
Front End Web App.
7474

75-
![Application Architecture](/img/self-hosted-architecture.svg)
75+
![Application Architecture](/img/architecture.svg)
7676

7777
## Dependencies
7878

docs/docs/system-administration/architecture.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Architecture
44

55
## Self Hosted / On Prem
66

7-
![Image](/img/self-hosted-architecture.svg)
7+
![Image](/img/architecture.svg)
88

99
## SaaS
1010

0 commit comments

Comments
 (0)