Skip to content

Commit

Permalink
Fix conflicts and merge branch 'main' into feat/add_mypy_type_checking
Browse files Browse the repository at this point in the history
  • Loading branch information
zachaysan committed Dec 3, 2024
2 parents 91e79f3 + 679acdd commit dbe12f9
Show file tree
Hide file tree
Showing 53 changed files with 1,365 additions and 684 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/manual-e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 'Manual E2E tests'

on:
workflow_dispatch:
inputs:
e2e-token:
description: 'The authentication token used by the E2E process'
required: true
e2e-concurrency:
description: 'The concurrency value to use when running the E2E process'
default: 3
type: number
api-url:
description: 'Which database service to use to run the API against'
default: 'https://api.flagsmith.com/api/v1/'

jobs:
run-e2e-tests:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: npm
node-version-file: frontend/.nvmrc
cache-dependency-path: frontend/package-lock.json

- name: Run tests
working-directory: frontend
env:
E2E_TEST_AUTH_TOKEN: ${{ inputs.e2e-token }}
FLAGSMITH_API_URL: ${{ inputs.api-url }}
E2E_CONCURRENCY: ${{ inputs.e2e-concurrency }}
run: |
npm ci
npm run env
npm run test
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ repos:
- id: check-json
- id: check-toml

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
- repo: local
hooks:
- id: prettier
name: prettier
exclude: ^(frontend/|CHANGELOG.md|.github/docker_build_comment_template.md)
additional_dependencies:
- prettier@3.3.3 # SEE: https://github.com/pre-commit/pre-commit/issues/3133
language: system
entry: npx prettier --check

- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
Expand Down
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.154.0"
".": "2.155.0"
}
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [2.155.0](https://github.com/Flagsmith/flagsmith/compare/v2.154.0...v2.155.0) (2024-12-03)


### Features

* Create change requests for segments ([#4265](https://github.com/Flagsmith/flagsmith/issues/4265)) ([355f4e2](https://github.com/Flagsmith/flagsmith/commit/355f4e2827dc0a0cba169a320c7a0db8b522089e))
* **environment/views:** Add get-by-uuid action ([#4875](https://github.com/Flagsmith/flagsmith/issues/4875)) ([db8433b](https://github.com/Flagsmith/flagsmith/commit/db8433ba0a307b3e27f078aadf94d6ef4e717391))
* **org/view:** Add api to get organisation by uuid ([#4878](https://github.com/Flagsmith/flagsmith/issues/4878)) ([06ed466](https://github.com/Flagsmith/flagsmith/commit/06ed466864d723ac43bad9ec8fa738a8e9d0812d))


### Bug Fixes

* Environment Ready Checker ([#4865](https://github.com/Flagsmith/flagsmith/issues/4865)) ([2392222](https://github.com/Flagsmith/flagsmith/commit/23922223d4367792b196d798cb2571dc8f589ee1))
* prevent enabling versioning from affecting scheduled change requests ([#4872](https://github.com/Flagsmith/flagsmith/issues/4872)) ([c7aa30b](https://github.com/Flagsmith/flagsmith/commit/c7aa30bb217deca7ea6a0b0657d1a08076f2ab44))

## [2.154.0](https://github.com/Flagsmith/flagsmith/compare/v2.153.0...v2.154.0) (2024-11-21)


Expand Down
2 changes: 1 addition & 1 deletion api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ POETRY_VERSION ?= 1.8.3
GUNICORN_LOGGER_CLASS ?= util.logging.GunicornJsonCapableLogger

SAML_REVISION ?= v1.6.4
RBAC_REVISION ?= v0.11.0
RBAC_REVISION ?= v0.11.1

-include .env-local
-include $(DOTENV_OVERRIDE_FILE)
Expand Down
24 changes: 24 additions & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1274,3 +1274,27 @@
# subscriptions created before this date full audit log and versioning
# history.
VERSIONING_RELEASE_DATE = env.date("VERSIONING_RELEASE_DATE", default=None)

SUBSCRIPTION_LICENCE_PUBLIC_KEY = env.str(
"SUBSCRIPTION_LICENCE_PUBLIC_KEY",
"""
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs1H23Xv1IlhyTbUP9Z4e
zN3t6oa97ybLufhqSRCoPxHWAY/pqqjdwiC00AnRbL/guDi1FLPEkLza2gAKfU+f
04SsNTfYL5MTPnaFtf+B+hlYmlrT1C6n05t+uQW2OQm6mWoqBssmoyR8T5FXfBls
FrT8dsZg5XG7JaWAyGbbVscHrXHXqVcLbFGO8CcO2BG2whl+7hzm4edNCsxLJqmN
uASR9KtntdulkRar0A9x+hAQUlrDKv77nMMdljNIqkcCcWrbhiDoTVCDbE99mhMq
LeC/+C54/ZiCb3r9woq/kpsbRj0Ys2b4czfjWioXooSxA0w3BE6/lV0+hVltjRO6
5QIDAQAB
-----END PUBLIC KEY-----
""",
)

# For the matching private key to the public key added above
# search for "Flagsmith licence private key" in Bitwarden.
SUBSCRIPTION_LICENCE_PRIVATE_KEY = env.str("SUBSCRIPTION_LICENCE_PRIVATE_KEY", None)

LICENSING_INSTALLED = importlib.util.find_spec("licensing") is not None

if LICENSING_INSTALLED: # pragma: no cover
INSTALLED_APPS.append("licensing")
43 changes: 43 additions & 0 deletions api/app/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,46 @@
RETRY_WEBHOOKS = True

INFLUXDB_BUCKET = "test_bucket"

SUBSCRIPTION_LICENCE_PRIVATE_KEY = """
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0o6Q+J6ArJZ2x
RyZQ5e9ue6dB4bgH7I7DYYb9t9eIb55z0vZZWVLLmIr+ngCfCxIePqCclrAen9gr
rCRhyAXD+XZYjRP0w2wlqA367HJXbti1adXnQnM4QXITNJhRnGoqiRVx7vQ/Klup
+yMBJOU4IkkSsQaAgp0eTdPlGlA+KAfCH39rsqIHNXuS1qfspI2RyaR6130NvR6D
4p07XJls1AYOs8xphdWl8b4hzbJTvC0IqRhvX+z4kEyQjprdcfwOG4qrqtIb4asm
21imOtE8CGRvHUl/cV+1l/hgv1fdbeCFzM89q16Z/KXIAWJMYfkWuOWGVEmf7yjB
9aMrfM3fAgMBAAECggEAKqGwQocBkw1GoS8kiNUrY8zFFZRa5Wvb6ZqbzEdWE7oc
EEPKph2hn7E5pIvPo7luJjsrlqktmZyp3Oy8jWMykSTP3Gg3PH3eiSiXXA/vkFj1
xiLbO8AAB1fSv1ubUy9yEuXVbNUzSbEKfxxpD30Qp+XXjxS+bxfkUuGVT62dIH3V
j251CEsCIZzwOriGP52OKK5HR24Y9/c+uGLu1CLY6qdrMgWAXTYqEoUw7ku8Sm8B
o6fuu9i0mAEJUl6qcVz3yH0QYe9pM6jDQ9oZeSkVYyspCwysTVs2jsCTMYUpK/kD
WU9sniHRgly3C9Ge3PrE4qUeMRTNk0Vd4RETtznwqQKBgQD3UiJ11FUd3g1FXL9N
iLOIayACrX37cBuc8M5iAzasNDjSVNoCrQun1091xzYK6/F7As4PtH1YUaDgXdBp
efHHl3DPTFkeztPMOKOd8tCpLai/23sbCBNc51x0LCuWWnNaAuidId1rpvFq7AMJ
jE4HPJkoL6udOzlKUHebp02ILQKBgQC6+nT2A+AZeheUiw2wBl0BRitQCxA+TN+L
vkAwLa0u/OqeNc8W50lybzHCS9nEVZ0Lp3Qk9Cl++X/k5o6k2byqJxtmMvLGqjjw
UNuZWHSoUzfdzs8yBjroLM4HsBgbEaG9E2e2zuqKBvwLqZ3fv/fXvmJDIu+aCWXC
ADtlrAvJuwKBgQDq+CW1PJ4BWk3RcGRwDUhEe0JWSO5ATCpv2Hi7tcHjqVmyutrF
YBKKy4y6oSE/DxrFe8y6LwhHOIZXo8m17B1BOyf6StcA5g9jHwyTq3WCxdZlMOis
red3hHfaB30Bw72D7u+BGgN7m4gRxVi9YYdgaLo569Bn+TRc3kZEo5aNoQKBgH7z
aJBU50ZFCFeZ5iw61dD0pJnPOTMjnLBT917+1FRP8riCzl29obep2b4TJANTIbL0
+j3Q7Y/BtV1kUTuKfreEn+zO8NmEX+6C5+cBEQvsnMTkEvfjFQHo0eaUYHmYihlH
YKbVbJdU0LLWclOmEpAQOsVcphQPB2EmKS4KF2LbAoGAOqVsQg61S1u7s4NF4JCN
EiJvBDjjwTycNCmhY7bV1R7LX+Qk/Mq9fgK3yccKV/Bl69C9Fmeopivbu20urNhn
q/sgOPDK0zJUSVh76gFon1gx7OfaHV31TrvIl0T7WnyfDvAv20F+dmmXkjnPBNNm
dXzo4kXwDOlWCJI8VhYfH/0=
-----END PRIVATE KEY-----
"""

SUBSCRIPTION_LICENCE_PUBLIC_KEY = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtKOkPiegKyWdsUcmUOXv
bnunQeG4B+yOw2GG/bfXiG+ec9L2WVlSy5iK/p4AnwsSHj6gnJawHp/YK6wkYcgF
w/l2WI0T9MNsJagN+uxyV27YtWnV50JzOEFyEzSYUZxqKokVce70PypbqfsjASTl
OCJJErEGgIKdHk3T5RpQPigHwh9/a7KiBzV7ktan7KSNkcmketd9Db0eg+KdO1yZ
bNQGDrPMaYXVpfG+Ic2yU7wtCKkYb1/s+JBMkI6a3XH8DhuKq6rSG+GrJttYpjrR
PAhkbx1Jf3FftZf4YL9X3W3ghczPPatemfylyAFiTGH5FrjlhlRJn+8owfWjK3zN
3wIDAQAB
-----END PUBLIC KEY-----
"""
29 changes: 29 additions & 0 deletions api/environments/migrations/0037_add_uuid_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.23 on 2024-11-27 08:46

from django.db import migrations, models
import uuid

from core.migration_helpers import AddDefaultUUIDs


class Migration(migrations.Migration):
dependencies = [
("environments", "0036_add_is_creating_field"),
]

operations = [
migrations.AddField(
model_name="environment",
name="uuid",
field=models.UUIDField(editable=False, null=True),
),
migrations.RunPython(
AddDefaultUUIDs("environments", "environment"),
reverse_code=migrations.RunPython.noop,
),
migrations.AlterField(
model_name="environment",
name="uuid",
field=models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
),
]
6 changes: 5 additions & 1 deletion api/environments/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import typing
import uuid
from copy import deepcopy

from core.models import abstract_base_auditable_model_factory
Expand Down Expand Up @@ -63,14 +64,16 @@
class Environment(
LifecycleModel,
abstract_base_auditable_model_factory(
change_details_excluded_fields=["updated_at"]
change_details_excluded_fields=["updated_at"],
historical_records_excluded_fields=["uuid"],
),
SoftDeleteObject,
):
history_record_class_path = "environments.models.HistoricalEnvironment"
related_object_type = RelatedObjectType.ENVIRONMENT

name = models.CharField(max_length=2000)
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
created_date = models.DateTimeField("DateCreated", auto_now_add=True)
description = models.TextField(null=True, blank=True, max_length=20000)
project = models.ForeignKey(
Expand Down Expand Up @@ -178,6 +181,7 @@ def clone(
"""
clone = deepcopy(self)
clone.id = None
clone.uuid = uuid.uuid4()
clone.name = name
clone.api_key = api_key if api_key else create_hash()
clone.is_creating = True
Expand Down
1 change: 1 addition & 0 deletions api/environments/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Meta:
model = Environment
fields = (
"id",
"uuid",
"name",
"api_key",
"description",
Expand Down
22 changes: 20 additions & 2 deletions api/environments/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import logging

from common.environments.permissions import TAG_SUPPORTED_PERMISSIONS
from common.environments.permissions import (
TAG_SUPPORTED_PERMISSIONS,
VIEW_ENVIRONMENT,
)
from django.db.models import Count, Q
from django.utils.decorators import method_decorator
from drf_yasg import openapi
from drf_yasg.utils import no_body, swagger_auto_schema
from rest_framework import mixins, status, viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import ValidationError
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.generics import get_object_or_404
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
Expand Down Expand Up @@ -142,6 +146,20 @@ def perform_create(self, serializer):
user=self.request.user, environment=environment, admin=True
)

@action(
detail=False,
url_path=r"get-by-uuid/(?P<uuid>[0-9a-f-]+)",
methods=["get"],
)
def get_by_uuid(self, request, uuid):
qs = self.get_queryset()
environment = get_object_or_404(qs, uuid=uuid)
if not request.user.has_environment_permission(VIEW_ENVIRONMENT, environment):
raise PermissionDenied()

serializer = self.get_serializer(environment)
return Response(serializer.data)

@action(detail=True, methods=["GET"], url_path="trait-keys")
def trait_keys(self, request, *args, **kwargs):
keys = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Generated by Django 4.2.16 on 2024-11-28 13:45
from django.apps.registry import Apps
from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.models import F


def fix_corrupted_feature_states(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
feature_state_model_class = apps.get_model("features", "FeatureState")
environment_feature_version_model_class = apps.get_model(
"feature_versioning", "EnvironmentFeatureVersion"
)

feature_states_to_update = []
environment_feature_versions_to_update = []

for feature_state in feature_state_model_class.objects.filter(
# We're looking for feature states that live in environments
# that don't have versioning enabled, but have an environment
# feature version associated to them. Moreover, those environment
# feature versions should have a change request associated with
# them. See this PR for further details of the bug we're looking
# to clean up after: https://github.com/Flagsmith/flagsmith/pull/4872
environment__use_v2_feature_versioning=False,
environment_feature_version__isnull=False,
environment_feature_version__change_request__isnull=False,
).exclude(
# Just to be safe, we exclude feature states for which the version
# belongs to the same feature and environment. This will prevent us
# from accidentally modifying any feature states that belong to
# legitimate environment feature versions but perhaps versioning
# has been switched off for the environment.
environment_feature_version__feature=F("feature"),
environment_feature_version__environment=F("environment")
).select_related("environment_feature_version"):
environment_feature_version = feature_state.environment_feature_version

# 1. move the change request back to the feature state
feature_state.change_request = environment_feature_version.change_request

# 2. remove the change request from the EnvironmentFeatureVersion
environment_feature_version.change_request = None

# 3. remove the environment feature version from the feature state
feature_state.environment_feature_version = None

feature_states_to_update.append(feature_state)
environment_feature_versions_to_update.append(environment_feature_version)

feature_state_model_class.objects.bulk_update(
feature_states_to_update,
["environment_feature_version", "change_request"],
)
environment_feature_version_model_class.objects.bulk_update(
environment_feature_versions_to_update,
["change_request"],
)


class Migration(migrations.Migration):

dependencies = [
("feature_versioning", "0004_add_version_change_set"),
]

operations = [
migrations.RunPython(
fix_corrupted_feature_states,
reverse_code=migrations.RunPython.noop
),
]
2 changes: 2 additions & 0 deletions api/features/versioning/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ def _create_initial_feature_versions(environment: "Environment"):
change_request__isnull=False,
change_request__committed_at__isnull=False,
change_request__deleted_at__isnull=True,
environment=environment,
).select_related("change_request")

for feature_state in scheduled_feature_states:
ef_version = EnvironmentFeatureVersion.objects.create(
feature=feature,
Expand Down
8 changes: 4 additions & 4 deletions api/integrations/flagsmith/data/environment.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"multivariate_feature_state_values": []
},
{
"django_id": 627339,
"django_id": 638869,
"enabled": true,
"feature": {
"id": 96656,
Expand All @@ -24,11 +24,11 @@
},
"feature_segment": null,
"feature_state_value": null,
"featurestate_uuid": "566228a6-78b0-4696-a023-feb149b61fd2",
"featurestate_uuid": "768e6102-7a0c-49f6-9d9f-097e376ed76c",
"multivariate_feature_state_values": []
},
{
"django_id": 627341,
"django_id": 638871,
"enabled": true,
"feature": {
"id": 96657,
Expand All @@ -37,7 +37,7 @@
},
"feature_segment": null,
"feature_state_value": null,
"featurestate_uuid": "4f7cae64-afed-416c-ada8-e6b034dff436",
"featurestate_uuid": "346cc272-dabe-4993-9cfa-76afd0d848f1",
"multivariate_feature_state_values": []
},
{
Expand Down
Loading

0 comments on commit dbe12f9

Please sign in to comment.