Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into chore/rtk-identity-traits
Browse files Browse the repository at this point in the history
# Conflicts:
#	frontend/web/components/pages/UserPage.tsx
  • Loading branch information
kyle-ssg committed Feb 25, 2025
2 parents 1ed98d7 + 65058e3 commit 2810457
Show file tree
Hide file tree
Showing 260 changed files with 2,316 additions and 843 deletions.
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
# Linting fixes for frontend
# https://github.com/Flagsmith/flagsmith/pull/5123
1f7083636d3b163588fe9a8b45af289bd40b1a8d
# Migrate to ruff
# https://github.com/Flagsmith/flagsmith/pull/5150
f7487ac5278d60e62067e2f4d5976ceb755f4980
9 changes: 1 addition & 8 deletions .github/workflows/platform-docker-build-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ jobs:
with:
file_path: './chart/charts/flagsmith/Chart.yaml'

- uses: us-ignite/action-bump-semver@main
id: bump-semver
with:
current_version: ${{ steps.yaml-output.outputs.version }}
level: minor

- name: Update flagsmith-charts values.yaml with latest docker version
uses: fjogeleit/yaml-update-action@main
with:
Expand All @@ -185,6 +179,5 @@ jobs:
valueFile: 'charts/flagsmith/Chart.yaml'
changes: |
{
"appVersion": "${{ steps.version-trim.outputs.version }}",
"version": "${{ steps.bump-semver.outputs.new_version }}"
"appVersion": "${{ steps.version-trim.outputs.version }}"
}
29 changes: 10 additions & 19 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
repos:
- repo: https://github.com/PyCQA/isort
rev: 6.0.0
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.9.7
hooks:
- id: isort
name: isort (python)

- repo: https://github.com/psf/black
rev: 25.1.0
hooks:
- id: black
language_version: python3
exclude: migrations

- repo: https://github.com/pycqa/flake8
rev: 7.1.2
hooks:
- id: flake8
name: flake8
args: [--config, api/.flake8]
# Run the linter.
- id: ruff
args: [--config, api/pyproject.toml, --config, "src = ['api']", --fix]
# Run the formatter.
- id: ruff-format
args: [--config, api/pyproject.toml, --config, "src = ['api']"]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
Expand Down Expand Up @@ -52,5 +43,5 @@ repos:
args: ["-C", "api"]

ci:
skip: [python-typecheck, isort]
skip: [python-typecheck]
autoupdate_commit_msg: "ci: pre-commit autoupdate"
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.162.0"
".": "2.163.0"
}
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## [2.163.0](https://github.com/Flagsmith/flagsmith/compare/v2.162.0...v2.163.0) (2025-02-21)


### Features

* Adds support for quickly navigating to recently created or existing requested changes ([#5109](https://github.com/Flagsmith/flagsmith/issues/5109)) ([e7b1adc](https://github.com/Flagsmith/flagsmith/commit/e7b1adccd0507d730a5362a8c520e7f2493b5233))
* Grafana feature health provider ([#5098](https://github.com/Flagsmith/flagsmith/issues/5098)) ([210519e](https://github.com/Flagsmith/flagsmith/commit/210519e44364b4eece64465f0c9e6c1741aaf36c))


### Bug Fixes

* Audit Log integrations are triggered when integration config is soft deleted ([#5128](https://github.com/Flagsmith/flagsmith/issues/5128)) ([a81d22e](https://github.com/Flagsmith/flagsmith/commit/a81d22e4bf5e2c5c2b0b4fac37aeb7944e98bb35))
* Consistent hover styles for tabs & improved dark mode side menu UX ([#5133](https://github.com/Flagsmith/flagsmith/issues/5133)) ([145bf1f](https://github.com/Flagsmith/flagsmith/commit/145bf1f3e5d598feeba9a69e4cc0288f803bcd76))
* **edge-identities:** prevent unauthorised identity access ([#5135](https://github.com/Flagsmith/flagsmith/issues/5135)) ([690f87c](https://github.com/Flagsmith/flagsmith/commit/690f87c0a96b5566ec7768ccf7705ee8ea760fc3))
* feature specific segment creation ([#5148](https://github.com/Flagsmith/flagsmith/issues/5148)) ([789e394](https://github.com/Flagsmith/flagsmith/commit/789e39486102992474edf156291d3d255e4977d3))
* Fix StaleFlagWarning Display & Migrate FeatureRow to TypeScript ([#5129](https://github.com/Flagsmith/flagsmith/issues/5129)) ([a1dcdb8](https://github.com/Flagsmith/flagsmith/commit/a1dcdb8110935fa06ea9a13c2c5d72c9a67db286))
* identity overrides only called once ([#5145](https://github.com/Flagsmith/flagsmith/issues/5145)) ([8621b26](https://github.com/Flagsmith/flagsmith/commit/8621b261f8fe6d01186f5268442e53021354e190))
* Segment override permissions ([#5134](https://github.com/Flagsmith/flagsmith/issues/5134)) ([66629e4](https://github.com/Flagsmith/flagsmith/commit/66629e4fba95e3dc948d2584ad86e9639e3c4484))
* Show "Clear all" to the left of feature filters to prevent layout shift ([#5143](https://github.com/Flagsmith/flagsmith/issues/5143)) ([cff5c96](https://github.com/Flagsmith/flagsmith/commit/cff5c96d820f56e541d57dd498f36d665779bcc1))
* **typing:** Add missing type stubs for dependencies ([#5126](https://github.com/Flagsmith/flagsmith/issues/5126)) ([4e1ba8b](https://github.com/Flagsmith/flagsmith/commit/4e1ba8b63cd0c4f1b44808eb3c956acdca98e9e8))

## [2.162.0](https://github.com/Flagsmith/flagsmith/compare/v2.161.0...v2.162.0) (2025-02-18)


Expand Down
10 changes: 0 additions & 10 deletions api/.flake8

This file was deleted.

25 changes: 24 additions & 1 deletion api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,21 @@ django-make-migrations:
poetry run python manage.py waitfordb
poetry run python manage.py makemigrations $(opts)

.PHONY: django-squash-migrations
django-squash-migrations:
poetry run python manage.py waitfordb
poetry run python manage.py squashmigrations $(opts)

.PHONY: django-migrate
django-migrate:
poetry run python manage.py waitfordb
poetry run python manage.py migrate
poetry run python manage.py createcachetable

.PHONY: django-shell
django-shell:
poetry run python manage.py shell

.PHONY: django-collect-static
django-collect-static:
poetry run python manage.py collectstatic --noinput
Expand All @@ -98,7 +107,7 @@ serve:
generate-ld-client-types:
curl -sSL https://app.launchdarkly.com/api/v2/openapi.json | \
npx openapi-format /dev/fd/0 \
--filterFile ld-openapi-filter.yaml | \
--filterFile openapi-filter-launchdarkly.yaml | \
datamodel-codegen \
--output integrations/launch_darkly/types.py \
--output-model-type typing.TypedDict \
Expand All @@ -108,6 +117,20 @@ generate-ld-client-types:
--wrap-string-literal \
--special-field-name-prefix=

.PHONY: generate-grafana-client-types
generate-grafana-client-types:
curl -sSL https://raw.githubusercontent.com/grafana/grafana/refs/heads/main/public/openapi3.json | \
npx openapi-format /dev/fd/0 \
--filterFile openapi-filter-grafana.yaml | \
datamodel-codegen \
--output integrations/grafana/types.py \
--output-model-type typing.TypedDict \
--target-python-version 3.10 \
--use-double-quotes \
--use-standard-collections \
--wrap-string-literal \
--special-field-name-prefix=

.PHONY: integrate-private-tests
integrate-private-tests:
$(eval WORKFLOW_REVISION := $(shell grep -A 1 "\[tool.poetry.group.workflows.dependencies\]" pyproject.toml | awk -F '"' '{printf $$4}'))
Expand Down
6 changes: 5 additions & 1 deletion api/api/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
from typing import Any

from drf_yasg.inspectors import SwaggerAutoSchema # type: ignore[import-untyped]
from drf_yasg.openapi import SCHEMA_DEFINITIONS, Response, Schema # type: ignore[import-untyped]
from drf_yasg.openapi import ( # type: ignore[import-untyped]
SCHEMA_DEFINITIONS,
Response,
Schema,
)
from pydantic import BaseModel
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
from pydantic_core import core_schema
Expand Down
2 changes: 1 addition & 1 deletion api/api/urls/v1.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from app_analytics.views import SDKAnalyticsFlags, SelfHostedTelemetryAPIView
from django.conf import settings
from django.urls import include, path, re_path
from drf_yasg import openapi # type: ignore[import-untyped]
from drf_yasg.views import get_schema_view # type: ignore[import-untyped]
from rest_framework import authentication, permissions, routers

from app_analytics.views import SDKAnalyticsFlags, SelfHostedTelemetryAPIView
from environments.identities.traits.views import SDKTraits
from environments.identities.views import SDKIdentities
from environments.sdk.views import SDKEnvironmentAPIView
Expand Down
3 changes: 2 additions & 1 deletion api/api/urls/v2.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from app_analytics.views import SDKAnalyticsFlagsV2
from django.urls import re_path

from app_analytics.views import SDKAnalyticsFlagsV2

app_name = "v2"

urlpatterns = [
Expand Down
11 changes: 9 additions & 2 deletions api/api_keys/models.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from django.conf import settings
from django.db import models
from django_lifecycle import BEFORE_UPDATE, LifecycleModelMixin, hook # type: ignore[import-untyped]
from django_lifecycle import ( # type: ignore[import-untyped]
BEFORE_UPDATE,
LifecycleModelMixin,
hook,
)
from rest_framework_api_key.models import AbstractAPIKey, APIKeyManager
from softdelete.models import SoftDeleteManager, SoftDeleteObject # type: ignore[import-untyped]
from softdelete.models import ( # type: ignore[import-untyped]
SoftDeleteManager,
SoftDeleteObject,
)

from organisations.models import Organisation

Expand Down
9 changes: 7 additions & 2 deletions api/api_keys/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ def is_group_admin(self, group_id: int) -> bool:
return False

def has_project_permission(
self, permission: str, project: "Project", tag_ids: typing.List[int] = None # type: ignore[assignment]
self,
permission: str,
project: "Project",
tag_ids: typing.List[int] = None, # type: ignore[assignment]
) -> bool:
return project in self.get_permitted_projects(permission, tag_ids)

Expand All @@ -95,7 +98,9 @@ def has_organisation_permission(
)

def get_permitted_projects(
self, permission_key: str, tag_ids: typing.List[int] = None # type: ignore[assignment]
self,
permission_key: str,
tag_ids: typing.List[int] = None, # type: ignore[assignment]
) -> QuerySet["Project"]:
return get_permitted_projects_for_master_api_key(
self.key, permission_key, tag_ids
Expand Down
2 changes: 1 addition & 1 deletion api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from importlib import reload

import dj_database_url # type: ignore[import-untyped]
import pytz # type: ignore[import-untyped]
import pytz
from corsheaders.defaults import default_headers # type: ignore[import-untyped]
from django.core.exceptions import ImproperlyConfigured
from django.core.management.utils import get_random_secret_key
Expand Down
2 changes: 2 additions & 0 deletions api/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
re_path(r"^api/v1/", include("api.urls.v1", namespace="api-v1")),
re_path(r"^api/v2/", include("api.urls.v2", namespace="api-v2")),
re_path(r"^admin/", admin.site.urls),
re_path(r"^health/liveness/?", views.version_info),
re_path(r"^health/readiness/?", include("health_check.urls")),
re_path(r"^health", include("health_check.urls", namespace="health")),
# Aptible health checks must be on /healthcheck and cannot redirect
# see https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks
Expand Down
18 changes: 10 additions & 8 deletions api/app_analytics/analytics_db_service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from datetime import date, datetime, timedelta
from typing import List

from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.db.models import Sum
from django.utils import timezone

from app_analytics.dataclasses import FeatureEvaluationData, UsageData
from app_analytics.influxdb_wrapper import get_events_for_organisation
from app_analytics.influxdb_wrapper import (
get_events_for_organisation,
)
from app_analytics.influxdb_wrapper import (
get_feature_evaluation_data as get_feature_evaluation_data_from_influxdb,
)
Expand All @@ -14,11 +21,6 @@
FeatureEvaluationBucket,
Resource,
)
from dateutil.relativedelta import relativedelta # type: ignore[import-untyped]
from django.conf import settings
from django.db.models import Sum
from django.utils import timezone

from environments.models import Environment
from features.models import Feature
from organisations.models import Organisation
Expand Down Expand Up @@ -76,7 +78,7 @@ def get_usage_data(

if date_start:
assert date_stop
kwargs["date_start"] = date_start
kwargs["date_start"] = date_start # type: ignore[assignment]
kwargs["date_stop"] = date_stop # type: ignore[assignment]

return get_usage_data_from_local_db(**kwargs) # type: ignore[arg-type]
Expand All @@ -89,7 +91,7 @@ def get_usage_data(

if date_start:
assert date_stop
kwargs["date_start"] = date_start
kwargs["date_start"] = date_start # type: ignore[assignment]
kwargs["date_stop"] = date_stop # type: ignore[assignment]

return get_usage_data_from_influxdb(**kwargs) # type: ignore[arg-type]
Expand Down
5 changes: 3 additions & 2 deletions api/app_analytics/cache.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from collections import defaultdict
from threading import Lock

from app_analytics.tasks import track_feature_evaluation, track_request
from app_analytics.track import track_feature_evaluation_influxdb
from django.conf import settings
from django.utils import timezone

from app_analytics.tasks import track_feature_evaluation, track_request
from app_analytics.track import track_feature_evaluation_influxdb


class APIUsageCache:
def __init__(self): # type: ignore[no-untyped-def]
Expand Down
6 changes: 3 additions & 3 deletions api/app_analytics/influxdb_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

from django.conf import settings
from django.utils import timezone
from influxdb_client import InfluxDBClient, Point # type: ignore[import-untyped]
from influxdb_client.client.exceptions import InfluxDBError # type: ignore[import-untyped]
from influxdb_client.client.write_api import SYNCHRONOUS # type: ignore[import-untyped]
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.exceptions import InfluxDBError
from influxdb_client.client.write_api import SYNCHRONOUS
from sentry_sdk import capture_exception
from urllib3 import Retry
from urllib3.exceptions import HTTPError
Expand Down
3 changes: 2 additions & 1 deletion api/app_analytics/management/commands/migrate_analytics.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import argparse
from typing import Any

from app_analytics.migrate_to_pg import migrate_feature_evaluations
from django.core.management import BaseCommand

from app_analytics.migrate_to_pg import migrate_feature_evaluations


class Command(BaseCommand):
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
Expand Down
5 changes: 3 additions & 2 deletions api/app_analytics/management/commands/populate_buckets.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import argparse
from typing import Any

from django.conf import settings
from django.core.management import BaseCommand

from app_analytics.constants import ANALYTICS_READ_BUCKET_SIZE
from app_analytics.tasks import (
populate_api_usage_bucket,
populate_feature_evaluation_bucket,
)
from django.conf import settings
from django.core.management import BaseCommand

MINUTES_IN_DAY: int = 1440

Expand Down
4 changes: 2 additions & 2 deletions api/app_analytics/management/commands/sendapiusagetoinflux.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from django.conf import settings
from django.core.management import BaseCommand
from influxdb_client import InfluxDBClient, Point # type: ignore[import-untyped]
from influxdb_client.client.write_api import SYNCHRONOUS # type: ignore[import-untyped]
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS


class Command(BaseCommand):
Expand Down
3 changes: 2 additions & 1 deletion api/app_analytics/middleware.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.conf import settings

from app_analytics.cache import APIUsageCache
from app_analytics.tasks import track_request
from django.conf import settings

from .models import Resource
from .track import (
Expand Down
2 changes: 1 addition & 1 deletion api/app_analytics/migrate_to_pg.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def migrate_feature_evaluations(migrate_till: int = 30) -> None:
query_api = influxdb_client.query_api()

for i in range(migrate_till):
range_start = f"-{i+1}d"
range_start = f"-{i + 1}d"
range_stop = f"-{i}d"
query = (
f'from (bucket: "{read_bucket}") '
Expand Down
Loading

0 comments on commit 2810457

Please sign in to comment.