Skip to content

Commit

Permalink
Merge branch 'main' into fix/improve-the-ui-ux-for-github-integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
novakzaballa committed May 16, 2024
2 parents 4cbace3 + c5bd7a2 commit 5e7e6bc
Show file tree
Hide file tree
Showing 101 changed files with 4,536 additions and 1,578 deletions.
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.114.0"
".": "2.115.0"
}
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## [2.115.0](https://github.com/Flagsmith/flagsmith/compare/v2.114.1...v2.115.0) (2024-05-15)


### Features

* Add metadata fields to core entities (API) ([#3315](https://github.com/Flagsmith/flagsmith/issues/3315)) ([06eb8a4](https://github.com/Flagsmith/flagsmith/commit/06eb8a4754bf8afbff29974eb6e075953ca0352d))


### Bug Fixes

* add trailing slash to update group logic ([#3943](https://github.com/Flagsmith/flagsmith/issues/3943)) ([95b14d1](https://github.com/Flagsmith/flagsmith/commit/95b14d121d0a8d2419746ac5112b6ca78670f5d9))
* changed the error message from custom_auth serializer ([#3924](https://github.com/Flagsmith/flagsmith/issues/3924)) ([185bd6a](https://github.com/Flagsmith/flagsmith/commit/185bd6a441af53fefec2426a891df0a1d140af58))
* Create GitHub comment as table ([#3948](https://github.com/Flagsmith/flagsmith/issues/3948)) ([bf67b1d](https://github.com/Flagsmith/flagsmith/commit/bf67b1dc0ad3a34c38f8aabb8a5cfaf5f65863de))
* Organisation ID is an object calling useHasPermission at organisation level ([#3950](https://github.com/Flagsmith/flagsmith/issues/3950)) ([1372917](https://github.com/Flagsmith/flagsmith/commit/13729173d0587c322272f603f1957908874f9375))
* organisation id parsing ([#3954](https://github.com/Flagsmith/flagsmith/issues/3954)) ([aae116b](https://github.com/Flagsmith/flagsmith/commit/aae116bc6fd83837e6ead8bc681155c25149dcdc))
* Scroll to top on path change ([#3926](https://github.com/Flagsmith/flagsmith/issues/3926)) ([1a2e793](https://github.com/Flagsmith/flagsmith/commit/1a2e793e9bb47922ad0c688c445a54d5ff2677db))
* segment override link ([#3945](https://github.com/Flagsmith/flagsmith/issues/3945)) ([fc0cceb](https://github.com/Flagsmith/flagsmith/commit/fc0cceb40b881891878678c1c61cc0cc1148d090))
* Validate and handle URL params ([#3932](https://github.com/Flagsmith/flagsmith/issues/3932)) ([7e1617f](https://github.com/Flagsmith/flagsmith/commit/7e1617f5bd4e754dbc7d17db957f4315c53c3fba))
* **versioning:** prevent task from deleting all unrelated feature states / feature segments ([#3955](https://github.com/Flagsmith/flagsmith/issues/3955)) ([0ed5148](https://github.com/Flagsmith/flagsmith/commit/0ed5148183e21a74ad93aa9e0af47a08941cfed6))

## [2.114.1](https://github.com/Flagsmith/flagsmith/compare/v2.114.0...v2.114.1) (2024-05-14)


### Bug Fixes

* Add multivariate values when cloning identities ([#3894](https://github.com/Flagsmith/flagsmith/issues/3894)) ([92e3e9f](https://github.com/Flagsmith/flagsmith/commit/92e3e9f55c25855cd0d1b7b7333184ab54385846))
* Organisation id not numeric in organisation settings ([#3929](https://github.com/Flagsmith/flagsmith/issues/3929)) ([9e3746b](https://github.com/Flagsmith/flagsmith/commit/9e3746bd7dce9a8d2eac6bf616a73f2dd1f5b54e))
* **versioning:** fix exception getting feature states for edge identity post v2 versioning migration ([#3916](https://github.com/Flagsmith/flagsmith/issues/3916)) ([132ef77](https://github.com/Flagsmith/flagsmith/commit/132ef77ee0d50c618c23431e3ea1b60aec3e5bf4))
* **versioning:** handle mapping of environment to engine post v2 versioning migration ([#3913](https://github.com/Flagsmith/flagsmith/issues/3913)) ([75acd12](https://github.com/Flagsmith/flagsmith/commit/75acd12c632a9fe8b4a5af5a48a33d18a406e9d4))

## [2.114.0](https://github.com/Flagsmith/flagsmith/compare/v2.113.0...v2.114.0) (2024-05-10)


Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ REST calls to the API.
- [Website](https://flagsmith.com/)
- [Documentation](https://docs.flagsmith.com/)
- If you have any questions about our projects you can email [support@flagsmith.com](mailto:support@flagsmith.com)

## Acknowledgements

Thank you to [Uffizzi](https://www.uffizzi.com) for providing ephemeral environments to preview pull requests.
11 changes: 11 additions & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1197,3 +1197,14 @@
INSTALLED_APPS += ("split_testing",)

ENABLE_API_USAGE_ALERTING = env.bool("ENABLE_API_USAGE_ALERTING", default=False)

# See DomainAuthMethods in flagsmith-auth-controller repository with auth_controller.models module
GLOBAL_DOMAIN_AUTH_METHODS = env.dict(
"GLOBAL_DOMAIN_AUTH_METHODS",
{
"EP": True, # Email / Password
"GO": True, # Google
"GH": True, # GitHub
"SAML": True, # Security Assertion Markup Language
},
)
200 changes: 184 additions & 16 deletions api/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,16 @@ def with_environment_permissions(
"""

def _with_environment_permissions(
permission_keys: list[str],
permission_keys: list[str] | None = None,
environment_id: int | None = None,
admin: bool = False,
) -> UserEnvironmentPermission:
environment_id = environment_id or environment.id
uep, __ = UserEnvironmentPermission.objects.get_or_create(
environment_id=environment_id, user=staff_user, defaults={"admin": admin}
)
uep.permissions.add(*permission_keys)
if permission_keys:
uep.permissions.add(*permission_keys)

return uep

Expand Down Expand Up @@ -384,7 +385,7 @@ def with_project_permissions(
"""

def _with_project_permissions(
permission_keys: list[str] = None,
permission_keys: list[str] | None = None,
project_id: typing.Optional[int] = None,
admin: bool = False,
) -> UserProjectPermission:
Expand Down Expand Up @@ -552,6 +553,29 @@ def segment_featurestate(feature_segment, feature, environment):
)


@pytest.fixture()
def feature_with_value_segment(
feature_with_value: Feature, segment: Segment, environment: Environment
) -> FeatureSegment:
return FeatureSegment.objects.create(
feature=feature_with_value, segment=segment, environment=environment
)


@pytest.fixture()
def segment_featurestate_and_feature_with_value(
feature_with_value_segment: FeatureSegment,
feature_with_value: Feature,
environment: Environment,
) -> FeatureState:
return FeatureState.objects.create(
feature_segment=feature_with_value_segment,
feature=feature_with_value,
environment=environment,
updated_at="2024-01-01 00:00:00",
)


@pytest.fixture()
def environment_api_key(environment):
return EnvironmentAPIKey.objects.create(
Expand Down Expand Up @@ -658,23 +682,23 @@ def task_processor_synchronously(settings):


@pytest.fixture()
def a_metadata_field(organisation):
def a_metadata_field(organisation: Organisation) -> MetadataField:
return MetadataField.objects.create(name="a", type="int", organisation=organisation)


@pytest.fixture()
def b_metadata_field(organisation):
def b_metadata_field(organisation: Organisation) -> MetadataField:
return MetadataField.objects.create(name="b", type="str", organisation=organisation)


@pytest.fixture()
def required_a_environment_metadata_field(
organisation,
a_metadata_field,
environment,
project,
project_content_type,
):
organisation: Organisation,
a_metadata_field: MetadataField,
environment: Environment,
project: Project,
project_content_type: ContentType,
) -> MetadataModelField:
environment_type = ContentType.objects.get_for_model(environment)
model_field = MetadataModelField.objects.create(
field=a_metadata_field,
Expand All @@ -688,7 +712,119 @@ def required_a_environment_metadata_field(


@pytest.fixture()
def optional_b_environment_metadata_field(organisation, b_metadata_field, environment):
def required_a_feature_metadata_field(
organisation: Organisation,
a_metadata_field: MetadataField,
feature_content_type: ContentType,
project: Project,
project_content_type: ContentType,
) -> MetadataModelField:
model_field = MetadataModelField.objects.create(
field=a_metadata_field,
content_type=feature_content_type,
)

MetadataModelFieldRequirement.objects.create(
content_type=project_content_type, object_id=project.id, model_field=model_field
)

return model_field


@pytest.fixture()
def required_a_feature_metadata_field_using_organisation_content_type(
organisation: Organisation,
a_metadata_field: MetadataField,
feature_content_type: ContentType,
project: Project,
organisation_content_type: ContentType,
) -> MetadataModelField:
model_field = MetadataModelField.objects.create(
field=a_metadata_field,
content_type=feature_content_type,
)

MetadataModelFieldRequirement.objects.create(
content_type=organisation_content_type,
object_id=organisation.id,
model_field=model_field,
)

return model_field


@pytest.fixture()
def required_a_segment_metadata_field(
organisation: Organisation,
a_metadata_field: MetadataField,
segment_content_type: ContentType,
project: Project,
project_content_type: ContentType,
) -> MetadataModelField:
model_field = MetadataModelField.objects.create(
field=a_metadata_field,
content_type=segment_content_type,
)

MetadataModelFieldRequirement.objects.create(
content_type=project_content_type, object_id=project.id, model_field=model_field
)

return model_field


@pytest.fixture()
def required_a_segment_metadata_field_using_organisation_content_type(
organisation: Organisation,
a_metadata_field: MetadataField,
segment_content_type: ContentType,
project: Project,
organisation_content_type: ContentType,
) -> MetadataModelField:
model_field = MetadataModelField.objects.create(
field=a_metadata_field,
content_type=segment_content_type,
)

MetadataModelFieldRequirement.objects.create(
content_type=organisation_content_type,
object_id=organisation.id,
model_field=model_field,
)

return model_field


@pytest.fixture()
def optional_b_feature_metadata_field(
organisation: Organisation, b_metadata_field: MetadataField, feature: Feature
) -> MetadataModelField:
feature_type = ContentType.objects.get_for_model(feature)

return MetadataModelField.objects.create(
field=b_metadata_field,
content_type=feature_type,
)


@pytest.fixture()
def optional_b_segment_metadata_field(
organisation: Organisation, b_metadata_field: MetadataField, segment: Segment
) -> MetadataModelField:
segment_type = ContentType.objects.get_for_model(segment)

return MetadataModelField.objects.create(
field=b_metadata_field,
content_type=segment_type,
)


@pytest.fixture()
def optional_b_environment_metadata_field(
organisation: Organisation,
b_metadata_field: MetadataField,
environment: Environment,
) -> MetadataModelField:
environment_type = ContentType.objects.get_for_model(environment)

return MetadataModelField.objects.create(
Expand All @@ -698,7 +834,10 @@ def optional_b_environment_metadata_field(organisation, b_metadata_field, enviro


@pytest.fixture()
def environment_metadata_a(environment, required_a_environment_metadata_field):
def environment_metadata_a(
environment: Environment,
required_a_environment_metadata_field: MetadataModelField,
) -> Metadata:
environment_type = ContentType.objects.get_for_model(environment)
return Metadata.objects.create(
object_id=environment.id,
Expand All @@ -709,7 +848,10 @@ def environment_metadata_a(environment, required_a_environment_metadata_field):


@pytest.fixture()
def environment_metadata_b(environment, optional_b_environment_metadata_field):
def environment_metadata_b(
environment: Environment,
optional_b_environment_metadata_field: MetadataModelField,
) -> Metadata:
environment_type = ContentType.objects.get_for_model(environment)
return Metadata.objects.create(
object_id=environment.id,
Expand All @@ -720,15 +862,30 @@ def environment_metadata_b(environment, optional_b_environment_metadata_field):


@pytest.fixture()
def environment_content_type():
def environment_content_type() -> ContentType:
return ContentType.objects.get_for_model(Environment)


@pytest.fixture()
def project_content_type():
def feature_content_type() -> ContentType:
return ContentType.objects.get_for_model(Feature)


@pytest.fixture()
def segment_content_type() -> ContentType:
return ContentType.objects.get_for_model(Segment)


@pytest.fixture()
def project_content_type() -> ContentType:
return ContentType.objects.get_for_model(Project)


@pytest.fixture()
def organisation_content_type() -> ContentType:
return ContentType.objects.get_for_model(Organisation)


@pytest.fixture
def manage_user_group_permission(db):
return OrganisationPermissionModel.objects.get(key=MANAGE_USER_GROUPS)
Expand Down Expand Up @@ -817,6 +974,17 @@ def feature_external_resource(feature: Feature) -> FeatureExternalResource:
)


@pytest.fixture()
def feature_with_value_external_resource(
feature_with_value: Feature,
) -> FeatureExternalResource:
return FeatureExternalResource.objects.create(
url="https://github.com/userexample/example-project-repo/issues/11",
type="GITHUB_ISSUE",
feature=feature_with_value,
)


@pytest.fixture()
def github_configuration(organisation: Organisation) -> GithubConfiguration:
return GithubConfiguration.objects.create(
Expand Down
2 changes: 1 addition & 1 deletion api/custom_auth/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Meta(UserCreateSerializer.Meta):
UniqueValidator(
queryset=FFAdminUser.objects.all(),
lookup="iexact",
message="Invalid email address.",
message="Email already exists. Please log in.",
)
]
}
Expand Down
1 change: 1 addition & 0 deletions api/edge_api/identities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,5 +259,6 @@ def clone_flag_states_from(self, source_identity: "EdgeIdentity") -> None:
feature=feature_in_source.feature,
feature_state_value=feature_in_source.feature_state_value,
enabled=feature_in_source.enabled,
multivariate_feature_state_values=feature_in_source.multivariate_feature_state_values,
)
self.add_feature_override(feature_state_target)
8 changes: 8 additions & 0 deletions api/environments/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
IDENTITY_INTEGRATIONS_RELATION_NAMES = [
"amplitude_config",
"heap_config",
"mixpanel_config",
"rudderstack_config",
"segment_config",
"webhook_config",
]
Loading

0 comments on commit 5e7e6bc

Please sign in to comment.