Skip to content

Commit

Permalink
Merge branch 'main' into feat/feature-health-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
khvn26 authored Jan 29, 2025
2 parents f04d459 + b0d0a80 commit 278fc1b
Show file tree
Hide file tree
Showing 114 changed files with 2,420 additions and 705 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/.reusable-docker-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ on:
required: false
default: ubuntu-latest
secrets:
gcr-token:
GCR_TOKEN:
description: A token to use for logging into Github Container Registry. If not provided, login does not occur.
required: false
SLACK_TOKEN:
description: A token to use uploading test failures to slack.
required: false

jobs:
run-e2e:
Expand All @@ -43,7 +46,7 @@ jobs:
id-token: write

env:
GCR_TOKEN: ${{ secrets.gcr-token }}
GCR_TOKEN: ${{ secrets.GCR_TOKEN }}

steps:
- name: Cloning repo
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/platform-docker-build-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ jobs:
concurrency: 2
- tests: versioning
concurrency: 1
- tests: organisation-permission environment-permission project-permission roles
concurrency: 1

docker-publish-api:
needs: [docker-build-api, run-e2e-tests]
Expand Down
24 changes: 23 additions & 1 deletion .github/workflows/platform-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ jobs:
concurrency: ${{ matrix.args.concurrency }}
tests: ${{ matrix.args.tests }}
secrets:
gcr-token: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.GITHUB_TOKEN || '' }}
GCR_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.GITHUB_TOKEN || '' }}
SLACK_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.SLACK_TOKEN || '' }}

strategy:
matrix:
Expand All @@ -154,3 +155,24 @@ jobs:
concurrency: 2
- tests: versioning
concurrency: 1

run-e2e-tests-private-cloud:
if: needs.permissions-check.outputs.can-write == 'true' && !cancelled()
needs: [permissions-check, docker-build-private-cloud, docker-build-e2e]
uses: ./.github/workflows/.reusable-docker-e2e-tests.yml
with:
runs-on: ${{ matrix.runs-on }}
e2e-image: ${{ needs.docker-build-e2e.outputs.image }}
api-image: ${{ needs.docker-build-private-cloud.outputs.image }}
concurrency: ${{ matrix.args.concurrency }}
tests: ${{ matrix.args.tests }}
secrets:
GCR_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.GITHUB_TOKEN || '' }}
SLACK_TOKEN: ${{ needs.permissions-check.outputs.can-write == 'true' && secrets.SLACK_TOKEN || '' }}

strategy:
matrix:
runs-on: [ubuntu-latest, ARM64-2c]
args:
- tests: organisation-permission environment-permission project-permission roles
concurrency: 1
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ repos:
types: [javascript,jsx,ts,tsx,markdown,mdx,html,css,json,yaml]

- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
rev: 2.0.1
hooks:
- id: poetry-check
args: ['-C', 'api']
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.159.0"
".": "2.160.2"
}
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
# Changelog

## [2.160.2](https://github.com/Flagsmith/flagsmith/compare/v2.160.1...v2.160.2) (2025-01-28)


### Bug Fixes

* **5044:** handle deleted feature state ([#5045](https://github.com/Flagsmith/flagsmith/issues/5045)) ([ecd409b](https://github.com/Flagsmith/flagsmith/commit/ecd409bdc5806fdcbda0df834ec06214e58126e7))
* cast boolean on length environment ([#5017](https://github.com/Flagsmith/flagsmith/issues/5017)) ([c0e8b81](https://github.com/Flagsmith/flagsmith/commit/c0e8b8106471748f557187d006602bae01b9ca58))
* Disable invite button when email config is not set ([#5022](https://github.com/Flagsmith/flagsmith/issues/5022)) ([2faca89](https://github.com/Flagsmith/flagsmith/commit/2faca89f180c36cb687b5af8ce1e21fa944e376d))
* ensure project names are unique ([#5039](https://github.com/Flagsmith/flagsmith/issues/5039)) ([aa665c0](https://github.com/Flagsmith/flagsmith/commit/aa665c0e7347cada2a234921fae1b87990a5a84a))
* Raise if `environment_feature_version` is `None` ([#5028](https://github.com/Flagsmith/flagsmith/issues/5028)) ([edd7141](https://github.com/Flagsmith/flagsmith/commit/edd71412200333ed2f0bb268a14f9045b2372f28))
* Set Hubspot id to newest value ([#5040](https://github.com/Flagsmith/flagsmith/issues/5040)) ([2bcb0bd](https://github.com/Flagsmith/flagsmith/commit/2bcb0bd9c7d6def29df610b49b307f40c81304a3))
* **webhook/signal:** Optimise historical record writes ([#5041](https://github.com/Flagsmith/flagsmith/issues/5041)) ([fe69d55](https://github.com/Flagsmith/flagsmith/commit/fe69d55b37e1d4fdcdcca41aa1d508c89cafae66))

## [2.160.1](https://github.com/Flagsmith/flagsmith/compare/v2.160.0...v2.160.1) (2025-01-22)


### Bug Fixes

* **ci:** Fix Dockerfile casing warnings ([#5031](https://github.com/Flagsmith/flagsmith/issues/5031)) ([29b7a90](https://github.com/Flagsmith/flagsmith/commit/29b7a9002367c18c74270baa6b226dfcc18b4549))
* **migration-test:** add decorator to skip if not enabled ([#5024](https://github.com/Flagsmith/flagsmith/issues/5024)) ([33cabfc](https://github.com/Flagsmith/flagsmith/commit/33cabfc5a68f541cb999559951c0c4a0b2561c07))


### Dependency Updates

* Bump flagsmith-workflows to 2.7.6 ([#5027](https://github.com/Flagsmith/flagsmith/issues/5027)) ([638e97d](https://github.com/Flagsmith/flagsmith/commit/638e97d49469058d9b6d365853948ce47c8ff421))
* update poetry ([#5019](https://github.com/Flagsmith/flagsmith/issues/5019)) ([9cbf058](https://github.com/Flagsmith/flagsmith/commit/9cbf058cb1d3da474b1a61fb1ef4b853c27bacd9))

## [2.160.0](https://github.com/Flagsmith/flagsmith/compare/v2.159.0...v2.160.0) (2025-01-20)


### Features

* Adds Licensing upload tab ([#4934](https://github.com/Flagsmith/flagsmith/issues/4934)) ([5e1c1be](https://github.com/Flagsmith/flagsmith/commit/5e1c1be60304385f578dc538c31ad0877cf3ff1c))
* Improves segment rule value validation and feedback ([#4975](https://github.com/Flagsmith/flagsmith/issues/4975)) ([8db1a3d](https://github.com/Flagsmith/flagsmith/commit/8db1a3d98908c65267cf44081a4e9df5a8a0c2e1))


### Bug Fixes

* `POST /identities` incorrectly applies segment overrides when using null or empty identifier, only in Core API ([#5018](https://github.com/Flagsmith/flagsmith/issues/5018)) ([3557e14](https://github.com/Flagsmith/flagsmith/commit/3557e1480ae8cbc7f4e60492fba87b4328a39fd1))
* Action dropdown not properly overflowing ([#5000](https://github.com/Flagsmith/flagsmith/issues/5000)) ([5fc9fef](https://github.com/Flagsmith/flagsmith/commit/5fc9fefbcb84f1227b80cd890c974a0669af1774))
* Adds force-2fa to startup plan ([#4994](https://github.com/Flagsmith/flagsmith/issues/4994)) ([d0e2f76](https://github.com/Flagsmith/flagsmith/commit/d0e2f760cd47f70512f7ba73e15167aef411dcc4))
* Don't display password managers on irrelevant input fields ([#5004](https://github.com/Flagsmith/flagsmith/issues/5004)) ([c04eb95](https://github.com/Flagsmith/flagsmith/commit/c04eb95101c8baf366e3a39cad6404e9fbacc3a0))
* Remove AWS IMDS endpoint request on API startup ([#5008](https://github.com/Flagsmith/flagsmith/issues/5008)) ([2e79ff4](https://github.com/Flagsmith/flagsmith/commit/2e79ff4b5f26a5537758011e2cbda8af2cfc4d97))
* role permissions ([#4996](https://github.com/Flagsmith/flagsmith/issues/4996)) ([4a90cf6](https://github.com/Flagsmith/flagsmith/commit/4a90cf6b576962e6d6b66326e86aa5f1a3c3cb91))
* Set logger for skipping API usage ([#5003](https://github.com/Flagsmith/flagsmith/issues/5003)) ([3c49ae0](https://github.com/Flagsmith/flagsmith/commit/3c49ae06c3fcb151d920cb3222cd3a4de6b5cdc7))
* Use "Flagsmith" as default TOTP issuer ([#4992](https://github.com/Flagsmith/flagsmith/issues/4992)) ([0681988](https://github.com/Flagsmith/flagsmith/commit/0681988d33a38c885a63eb1eaca1bd4ddcff567f))


### Dependency Updates

* bump django from 4.2.17 to 4.2.18 in /api ([#5012](https://github.com/Flagsmith/flagsmith/issues/5012)) ([3ac455d](https://github.com/Flagsmith/flagsmith/commit/3ac455d5cab524a09083b8126379f6cc868b535d))
* bump katex from 0.16.11 to 0.16.21 in /docs ([#5015](https://github.com/Flagsmith/flagsmith/issues/5015)) ([fc437d5](https://github.com/Flagsmith/flagsmith/commit/fc437d5905db87d12fd500e63d01f84309adac57))
* bump task-processor ([#4995](https://github.com/Flagsmith/flagsmith/issues/4995)) ([a122146](https://github.com/Flagsmith/flagsmith/commit/a1221468f9debd103e8d9039b32d2dd0acafdc05))

## [2.159.0](https://github.com/Flagsmith/flagsmith/compare/v2.158.0...v2.159.0) (2025-01-13)


Expand Down
24 changes: 12 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ ARG CI_COMMIT_SHA=dev
ARG NODE_VERSION=16
ARG PYTHON_VERSION=3.11

FROM public.ecr.aws/docker/library/node:${NODE_VERSION}-bookworm as node
FROM cgr.dev/chainguard/wolfi-base:latest as wolfi-base
FROM public.ecr.aws/docker/library/node:${NODE_VERSION}-bookworm AS node
FROM cgr.dev/chainguard/wolfi-base:latest AS wolfi-base

# - Intermediary stages
# * build-node
Expand All @@ -73,17 +73,17 @@ RUN cd frontend && ENV=${ENV} npm ci --quiet --production
COPY frontend /build/frontend

# * build-node-django [build-node]
FROM build-node as build-node-django
FROM build-node AS build-node-django

RUN mkdir /build/api && cd frontend && npm run bundledjango

# * build-node-selfhosted [build-node]
FROM build-node as build-node-selfhosted
FROM build-node AS build-node-selfhosted

RUN cd frontend && npm run bundle

# * build-python
FROM wolfi-base as build-python
FROM wolfi-base AS build-python
WORKDIR /build

ARG PYTHON_VERSION
Expand Down Expand Up @@ -115,7 +115,7 @@ RUN --mount=type=secret,id=github_private_cloud_token \
make install-private-modules

# * api-runtime
FROM wolfi-base as api-runtime
FROM wolfi-base AS api-runtime

# Install Python and make it available to venv entrypoints
ARG PYTHON_VERSION
Expand All @@ -140,7 +140,7 @@ ENTRYPOINT ["/app/scripts/run-docker.sh"]
CMD ["migrate-and-serve"]

# * api-runtime-private [api-runtime]
FROM api-runtime as api-runtime-private
FROM api-runtime AS api-runtime-private

# Install SAML binary dependency
RUN apk add xmlsec
Expand All @@ -159,7 +159,7 @@ CMD ["make test"]

# - Target (shippable) stages
# * private-cloud-api [api-runtime-private, build-python-private]
FROM api-runtime-private as private-cloud-api
FROM api-runtime-private AS private-cloud-api

COPY --from=build-python-private /build/.venv/ /usr/local/

Expand All @@ -169,7 +169,7 @@ RUN touch ./ENTERPRISE_VERSION
USER nobody

# * private-cloud-unified [api-runtime-private, build-python-private, build-node-django]
FROM api-runtime-private as private-cloud-unified
FROM api-runtime-private AS private-cloud-unified

COPY --from=build-python-private /build/.venv/ /usr/local/
COPY --from=build-node-django /build/api/ /app/
Expand All @@ -180,7 +180,7 @@ RUN touch ./ENTERPRISE_VERSION
USER nobody

# * saas-api [api-runtime-private, build-python-private]
FROM api-runtime-private as saas-api
FROM api-runtime-private AS saas-api

# Install GnuPG and import private key
RUN --mount=type=secret,id=sse_pgp_pkey \
Expand All @@ -197,7 +197,7 @@ RUN touch ./SAAS_DEPLOYMENT
USER nobody

# * oss-api [api-runtime, build-python]
FROM api-runtime as oss-api
FROM api-runtime AS oss-api

COPY --from=build-python /build/.venv/ /usr/local/

Expand Down Expand Up @@ -228,7 +228,7 @@ CMD ["node", "./api/index.js"]
USER nobody

# * oss-unified [api-runtime, build-python, build-node-django]
FROM api-runtime as oss-unified
FROM api-runtime AS oss-unified

COPY --from=build-python /build/.venv/ /usr/local/
COPY --from=build-node-django /build/api/ /app/
Expand Down
2 changes: 1 addition & 1 deletion api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ COMPOSE_PROJECT_NAME ?= flagsmith

DOTENV_OVERRIDE_FILE ?= .env

POETRY_VERSION ?= 1.8.3
POETRY_VERSION ?= 2.0.1

GUNICORN_LOGGER_CLASS ?= util.logging.GunicornJsonCapableLogger

Expand Down
15 changes: 15 additions & 0 deletions api/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import TypedDict

import shortuuid
from django.conf import settings

UNKNOWN = "unknown"
VERSIONS_INFO_FILE_LOCATION = ".versions.json"
Expand All @@ -12,6 +13,7 @@
class VersionInfo(TypedDict):
ci_commit_sha: str
image_tag: str
has_email_provider: bool
is_enterprise: bool
is_saas: bool

Expand All @@ -29,6 +31,18 @@ def is_saas() -> bool:
return pathlib.Path("./SAAS_DEPLOYMENT").exists()


def has_email_provider() -> bool:
match settings.EMAIL_BACKEND:
case "django.core.mail.backends.smtp.EmailBackend":
return settings.EMAIL_HOST_USER is not None
case "sgbackend.SendGridBackend":
return settings.SENDGRID_API_KEY is not None
case "django_ses.SESBackend":
return settings.AWS_SES_REGION_ENDPOINT is not None
case _:
return False


@lru_cache
def get_version_info() -> VersionInfo:
"""Reads the version info baked into src folder of the docker container"""
Expand All @@ -45,6 +59,7 @@ def get_version_info() -> VersionInfo:
version_json = version_json | {
"ci_commit_sha": _get_file_contents("./CI_COMMIT_SHA"),
"image_tag": image_tag,
"has_email_provider": has_email_provider(),
"is_enterprise": is_enterprise(),
"is_saas": is_saas(),
}
Expand Down
30 changes: 15 additions & 15 deletions api/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
from segments.models import Condition, Segment, SegmentRule
from tests.test_helpers import fix_issue_3869
from tests.types import (
AdminClientAuthType,
WithEnvironmentPermissionsCallable,
WithOrganisationPermissionsCallable,
WithProjectPermissionsCallable,
Expand Down Expand Up @@ -471,14 +472,14 @@ def _with_project_permissions(


@pytest.fixture()
def environment_v2_versioning(environment):
def environment_v2_versioning(environment: Environment) -> Environment:
enable_v2_versioning(environment.id)
environment.refresh_from_db()
return environment


@pytest.fixture()
def identity(environment):
def identity(environment: Environment) -> Identity:
return Identity.objects.create(identifier="test_identity", environment=environment)


Expand Down Expand Up @@ -1177,23 +1178,22 @@ def github_repository(
)


@pytest.fixture(
params=[
"admin_client_original",
"admin_master_api_key_client",
]
)
def admin_client_new(
@pytest.fixture(params=AdminClientAuthType.__args__)
def admin_client_auth_type(
request: pytest.FixtureRequest,
) -> AdminClientAuthType:
return request.param


@pytest.fixture
def admin_client_new(
admin_client_auth_type: AdminClientAuthType,
admin_client_original: APIClient,
admin_master_api_key_client: APIClient,
) -> APIClient:
if request.param == "admin_client_original":
yield admin_client_original
elif request.param == "admin_master_api_key_client":
yield admin_master_api_key_client
else:
assert False, "Request param mismatch"
if admin_client_auth_type == "master_api_key":
return admin_master_api_key_client
return admin_client_original


@pytest.fixture()
Expand Down
12 changes: 11 additions & 1 deletion api/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ def natural_key(self):
return (str(self.uuid),)


class SoftDeleteAwareHistoricalRecords(HistoricalRecords):
def create_historical_record(
self, instance: models.Model, history_type: str, using: str = None
) -> None:
if getattr(instance, "deleted_at", None) is not None and history_type == "~":
# Don't create `update` historical record for soft-deleted objects
return
super().create_historical_record(instance, history_type, using)


class SoftDeleteExportableManager(UUIDNaturalKeyManagerMixin, SoftDeleteManager):
pass

Expand Down Expand Up @@ -198,7 +208,7 @@ def abstract_base_auditable_model_factory(
show_change_details_for_create: bool = False,
) -> typing.Type[AbstractBaseAuditableModel]:
class Base(AbstractBaseAuditableModel):
history = HistoricalRecords(
history = SoftDeleteAwareHistoricalRecords(
bases=[
base_historical_model_factory(
change_details_excluded_fields or [],
Expand Down
2 changes: 2 additions & 0 deletions api/core/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def create_audit_log_from_historical_record(
if settings.TASK_RUN_METHOD == TaskRunMethod.TASK_PROCESSOR
else None
)
if instance.get_skip_create_audit_log():
return

try:
environment, project = instance.get_environment_and_project()
Expand Down
Loading

0 comments on commit 278fc1b

Please sign in to comment.