Skip to content

Commit

Permalink
Merge branch 'master' into hogql-calculation-bis
Browse files Browse the repository at this point in the history
  • Loading branch information
Twixes authored Apr 17, 2024
2 parents 7a8db16 + 3f1dd04 commit aa0de3e
Show file tree
Hide file tree
Showing 81 changed files with 1,614 additions and 339 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci-backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
# Job to decide if we should run backend ci
# See https://github.com/dorny/paths-filter#conditional-execution for more details
changes:
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.repository == 'PostHog/posthog'
name: Determine need to run backend checks
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
timeout-minutes: 30

name: Python code quality checks
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest

steps:
# If this run wasn't initiated by the bot (meaning: snapshot update) and we've determined
Expand Down Expand Up @@ -171,7 +171,7 @@ jobs:
timeout-minutes: 10

name: Validate Django and CH migrations
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -236,7 +236,7 @@ jobs:
timeout-minutes: 30

name: Django tests – ${{ matrix.segment }} (persons-on-events ${{ matrix.person-on-events && 'on' || 'off' }}), Py ${{ matrix.python-version }}, ${{ matrix.clickhouse-server-image }} (${{matrix.group}}/${{ matrix.concurrency }})
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest

strategy:
fail-fast: false
Expand Down Expand Up @@ -319,7 +319,7 @@ jobs:
clickhouse-server-image:
['clickhouse/clickhouse-server:23.11.2.11-alpine', 'clickhouse/clickhouse-server:23.12.5.81-alpine']
if: needs.changes.outputs.backend == 'true'
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
steps:
- name: 'Checkout repo'
uses: actions/checkout@v3
Expand Down Expand Up @@ -373,7 +373,7 @@ jobs:
calculate-running-time:
name: Calculate running time
needs: [django, async-migrations]
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
if: needs.changes.outputs.backend == 'true'
steps:
- name: Calculate running time
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/ci-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ concurrency:

jobs:
changes:
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.repository == 'PostHog/posthog'
name: Determine need to run E2E checks
Expand Down Expand Up @@ -55,11 +55,10 @@ jobs:
chunks:
needs: changes
name: Cypress preparation
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
chunks: ${{ steps.chunk.outputs.chunks }}

steps:
- name: Check out
uses: actions/checkout@v3
Expand All @@ -70,7 +69,7 @@ jobs:

container:
name: Build and cache container image
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 60
needs: [changes]
permissions:
Expand All @@ -94,7 +93,7 @@ jobs:

cypress:
name: Cypress E2E tests (${{ strategy.job-index }})
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 60
needs: [chunks, changes, container]
permissions:
Expand Down Expand Up @@ -279,7 +278,7 @@ jobs:

calculate-running-time:
name: Calculate running time
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
needs: [cypress]
if: needs.changes.outputs.shouldTriggerCypress == 'true'
steps:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci-plugin-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
# Job to decide if we should run plugin server ci
# See https://github.com/dorny/paths-filter#conditional-execution for more details
changes:
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.repository == 'PostHog/posthog'
name: Determine need to run plugin server checks
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
name: Code quality
needs: changes
if: needs.changes.outputs.plugin-server == 'true'
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest
defaults:
run:
working-directory: 'plugin-server'
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:
tests:
name: Plugin Server Tests (${{matrix.shard}})
needs: changes
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest

strategy:
fail-fast: false
Expand Down Expand Up @@ -180,7 +180,7 @@ jobs:
name: Functional tests (POE=${{matrix.POE_EMBRACE_JOIN_FOR_TEAMS}},RDK=${{matrix.KAFKA_CONSUMPTION_USE_RDKAFKA}})
needs: changes
if: needs.changes.outputs.plugin-server == 'true'
runs-on: depot-ubuntu-latest-4
runs-on: ubuntu-latest

strategy:
fail-fast: false
Expand Down
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@
"DATABASE_URL": "postgres://posthog:posthog@localhost:5432/posthog",
"SKIP_SERVICE_VERSION_REQUIREMENTS": "1",
"PRINT_SQL": "1",
"BILLING_SERVICE_URL": "https://billing.dev.posthog.dev",
"RECORDINGS_INGESTER_URL": "http://localhost:6738"
"BILLING_SERVICE_URL": "https://billing.dev.posthog.dev"
},
"console": "integratedTerminal",
"python": "${workspaceFolder}/env/bin/python",
Expand Down
1 change: 0 additions & 1 deletion bin/start
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
export DEBUG=${DEBUG:-1}
export SKIP_SERVICE_VERSION_REQUIREMENTS=1
export BILLING_SERVICE_URL=${BILLING_SERVICE_URL:-https://billing.dev.posthog.dev}
export RECORDINGS_INGESTER_URL=${RECORDINGS_INGESTER_URL:-http://localhost:6738}

service_warning() {
echo -e "\033[0;31m$1 isn't ready. You can run the stack with:\ndocker compose -f docker-compose.dev.yml up\nIf you have already ran that, just make sure that services are starting properly, and sit back.\nWaiting for $1 to start...\033[0m"
Expand Down
8 changes: 6 additions & 2 deletions docker-compose.base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ services:
volumes:
- /var/lib/elasticsearch/data
temporal:
restart: on-failure
environment:
- DB=postgresql
- DB_PORT=5432
Expand All @@ -169,8 +170,11 @@ services:
volumes:
- ./docker/temporal/dynamicconfig:/etc/temporal/config/dynamicconfig
depends_on:
- db
- elasticsearch
db:
condition: service_healthy
elasticsearch:
condition: service_started
temporal-admin-tools:
environment:
- TEMPORAL_CLI_ADDRESS=temporal:7233
Expand Down
1 change: 1 addition & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ services:
extends:
file: docker-compose.base.yml
service: temporal

temporal-admin-tools:
extends:
file: docker-compose.base.yml
Expand Down
1 change: 0 additions & 1 deletion docker-compose.hobby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ services:
SENTRY_DSN: $SENTRY_DSN
SITE_URL: https://$DOMAIN
SECRET_KEY: $POSTHOG_SECRET
RECORDINGS_INGESTER_URL: http://plugins:6738
depends_on:
- db
- redis
Expand Down
89 changes: 89 additions & 0 deletions ee/clickhouse/views/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
ClickhouseTrendExperimentResult,
)
from ee.clickhouse.queries.experiments.utils import requires_flag_warning
from posthog.api.cohort import CohortSerializer
from posthog.api.feature_flag import FeatureFlagSerializer, MinimalFeatureFlagSerializer
from posthog.api.routing import TeamAndOrgViewSetMixin
from posthog.api.shared import UserBasicSerializer
Expand Down Expand Up @@ -150,6 +151,7 @@ class Meta:
"end_date",
"feature_flag_key",
"feature_flag",
"exposure_cohort",
"parameters",
"secondary_metrics",
"filters",
Expand All @@ -164,6 +166,7 @@ class Meta:
"created_at",
"updated_at",
"feature_flag",
"exposure_cohort",
]

def validate_parameters(self, value):
Expand Down Expand Up @@ -353,3 +356,89 @@ def requires_flag_implementation(self, request: Request, *args: Any, **kwargs: A
warning = requires_flag_warning(filter, self.team)

return Response({"result": warning})

@action(methods=["POST"], detail=True)
def create_exposure_cohort_for_experiment(self, request: Request, *args: Any, **kwargs: Any) -> Response:
experiment = self.get_object()
flag = getattr(experiment, "feature_flag", None)
if not flag:
raise ValidationError("Experiment does not have a feature flag")

if not experiment.start_date:
raise ValidationError("Experiment does not have a start date")

if experiment.exposure_cohort:
raise ValidationError("Experiment already has an exposure cohort")

exposure_filter_data = (experiment.parameters or {}).get("custom_exposure_filter")
exposure_filter = None
if exposure_filter_data:
exposure_filter = Filter(data={**exposure_filter_data, "is_simplified": True}, team=experiment.team)

target_entity: int | str = "$feature_flag_called"
target_entity_type = "events"
target_filters = [
{
"key": "$feature_flag",
"value": [flag.key],
"operator": "exact",
"type": "event",
}
]

if exposure_filter:
entity = exposure_filter.entities[0]
if entity.id:
target_entity_type = entity.type if entity.type in ["events", "actions"] else "events"
target_entity = entity.id
if entity.type == "actions":
try:
target_entity = int(target_entity)
except ValueError:
raise ValidationError("Invalid action ID")

target_filters = [
prop.to_dict()
for prop in entity.property_groups.flat
if prop.type in ("event", "feature", "element", "hogql")
]

cohort_serializer = CohortSerializer(
data={
"is_static": False,
"name": f'Users exposed to experiment "{experiment.name}"',
"is_calculating": True,
"filters": {
"properties": {
"type": "OR",
"values": [
{
"type": "OR",
"values": [
{
"type": "behavioral",
"value": "performed_event",
"key": target_entity,
"negation": False,
"event_type": target_entity_type,
"event_filters": target_filters,
"explicit_datetime": experiment.start_date.isoformat(),
}
],
}
],
}
},
},
context={
"request": request,
"team": self.team,
"team_id": self.team_id,
},
)

cohort_serializer.is_valid(raise_exception=True)
cohort = cohort_serializer.save()
experiment.exposure_cohort = cohort
experiment.save(update_fields=["exposure_cohort"])
return Response({"cohort": cohort_serializer.data}, status=201)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# serializer version: 1
# name: ClickhouseTestExperimentSecondaryResults.test_basic_secondary_metric_results
'''
/* user_id:109 celery:posthog.tasks.tasks.sync_insight_caching_state */
/* user_id:106 celery:posthog.tasks.tasks.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
Expand Down
Loading

0 comments on commit aa0de3e

Please sign in to comment.