Skip to content

Commit dad5625

Browse files
Merge branch 'dev' into dependabot/npm_and_yarn/svgo-2.8.2
2 parents a66a2c1 + f097732 commit dad5625

File tree

607 files changed

+36932
-143025
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

607 files changed

+36932
-143025
lines changed

.github/ISSUE_TEMPLATE/1.bug_report.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ body:
2424
render: shell
2525
- type: input
2626
attributes:
27-
label: Which Umami version are you using? (if relevant)
27+
label: Which Umami version are you using?
2828
description: 'For example: 2.18.0, 2.15.1, 1.39.0, etc'
2929
- type: input
3030
attributes:
31-
label: Which browser are you using? (if relevant)
32-
description: 'For example: Chrome, Edge, Firefox, etc'
31+
label: How are you deploying your application?
32+
description: 'For example: Vercel, Railway, Docker, etc'
3333
- type: input
3434
attributes:
35-
label: How are you deploying your application? (if relevant)
36-
description: 'For example: Vercel, Railway, Docker, etc'
35+
label: Which browser are you using?
36+
description: 'For example: Chrome, Edge, Firefox, etc'

.github/workflows/cd.yml

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ jobs:
2323
permissions:
2424
contents: read
2525
packages: write
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
include:
30+
- type: standard
31+
base_path: ""
32+
suffix: ""
33+
- type: base
34+
base_path: "/umami"
35+
suffix: "-base"
2636

2737
steps:
2838
- uses: actions/checkout@v5
@@ -55,6 +65,7 @@ jobs:
5565
REF_TYPE="${{ github.ref_type }}"
5666
REF_NAME="${{ github.ref_name }}"
5767
INCLUDE_LATEST="${{ github.event.inputs.include_latest }}"
68+
SUFFIX="${{ matrix.suffix }}"
5869
5970
# Determine version source
6071
if [[ -n "$INPUT" ]]; then
@@ -74,30 +85,33 @@ jobs:
7485
7586
if [[ "$VERSION" == *-* ]]; then
7687
# prerelease: only version tag
77-
GHCR_TAGS="ghcr.io/${{ github.repository }}:$VERSION"
78-
DOCKER_TAGS="umamisoftware/umami:$VERSION"
88+
GHCR_TAGS="ghcr.io/${{ github.repository }}:$VERSION$SUFFIX"
89+
DOCKER_TAGS="umamisoftware/umami:$VERSION$SUFFIX"
7990
else
8091
# stable release: version + hierarchy
81-
GHCR_TAGS="ghcr.io/${{ github.repository }}:$VERSION"
82-
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:${MAJOR}.${MINOR}"
83-
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:${MAJOR}"
84-
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:postgresql-latest"
85-
86-
DOCKER_TAGS="umamisoftware/umami:$VERSION"
87-
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:${MAJOR}.${MINOR}"
88-
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:${MAJOR}"
89-
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:postgresql-latest"
92+
GHCR_TAGS="ghcr.io/${{ github.repository }}:$VERSION$SUFFIX"
93+
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:${MAJOR}.${MINOR}$SUFFIX"
94+
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:${MAJOR}$SUFFIX"
95+
96+
DOCKER_TAGS="umamisoftware/umami:$VERSION$SUFFIX"
97+
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:${MAJOR}.${MINOR}$SUFFIX"
98+
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:${MAJOR}$SUFFIX"
99+
100+
if [[ -z "$SUFFIX" ]]; then
101+
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:postgresql-latest"
102+
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:postgresql-latest"
103+
fi
90104
91105
# Add latest tag based on trigger and input
92106
if [[ "$REF_TYPE" == "tag" ]] || [[ "$INCLUDE_LATEST" == "true" ]]; then
93-
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:latest"
94-
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:latest"
107+
GHCR_TAGS="$GHCR_TAGS,ghcr.io/${{ github.repository }}:latest$SUFFIX"
108+
DOCKER_TAGS="$DOCKER_TAGS,umamisoftware/umami:latest$SUFFIX"
95109
fi
96110
fi
97111
else
98112
# Non-tag build (e.g. from main branch)
99-
GHCR_TAGS="ghcr.io/${{ github.repository }}:${REF_NAME}"
100-
DOCKER_TAGS="umamisoftware/umami:${REF_NAME}"
113+
GHCR_TAGS="ghcr.io/${{ github.repository }}:${REF_NAME}$SUFFIX"
114+
DOCKER_TAGS="umamisoftware/umami:${REF_NAME}$SUFFIX"
101115
fi
102116
103117
echo "ghcr_tags=$GHCR_TAGS" >> $GITHUB_OUTPUT
@@ -112,8 +126,10 @@ jobs:
112126
platforms: linux/amd64,linux/arm64
113127
push: true
114128
tags: ${{ steps.compute.outputs.ghcr_tags }}
115-
cache-from: type=gha
116-
cache-to: type=gha,mode=max
129+
build-args: |
130+
BASE_PATH=${{ matrix.base_path }}
131+
cache-from: type=gha,scope=${{ matrix.type }}
132+
cache-to: type=gha,mode=max,scope=${{ matrix.type }}
117133

118134
- name: Build and push to Docker Hub
119135
if: github.repository == 'umami-software/umami'
@@ -123,5 +139,7 @@ jobs:
123139
platforms: linux/amd64,linux/arm64
124140
push: true
125141
tags: ${{ steps.compute.outputs.docker_tags }}
126-
cache-from: type=gha
127-
cache-to: type=gha,mode=max
142+
build-args: |
143+
BASE_PATH=${{ matrix.base_path }}
144+
cache-from: type=gha,scope=${{ matrix.type }}
145+
cache-to: type=gha,mode=max,scope=${{ matrix.type }}

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,19 @@ package-lock.json
1111
/coverage
1212

1313
# next.js
14+
next-env.d.ts
1415
/.next
1516
/out
1617

1718
# production
1819
/build
1920
/public/script.js
21+
/public/recorder.js
2022
/geo
2123
/dist
2224
/generated
2325
/src/generated
26+
pm2.yml
2427

2528
# misc
2629
.DS_Store
@@ -30,6 +33,10 @@ package-lock.json
3033
*.log
3134
.vscode
3235
.tool-versions
36+
.claude
37+
.agents
38+
tmpclaude*
39+
nul
3340

3441
# debug
3542
npm-debug.log*
@@ -42,4 +49,3 @@ yarn-error.log*
4249
*.env.*
4350

4451
*.dev.yml
45-

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ COPY --from=deps /app/node_modules ./node_modules
1616
COPY . .
1717
COPY docker/middleware.ts ./src
1818

19-
ARG BASE_PATH
19+
ARG BASE_PATH=""
2020

2121
ENV BASE_PATH=$BASE_PATH
22+
LABEL org.opencontainers.image.base-path="$BASE_PATH"
2223
ENV NEXT_TELEMETRY_DISABLED=1
2324
ENV DATABASE_URL="postgresql://user:pass@localhost:5432/dummy"
2425

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
-- Create Performance
2+
CREATE TABLE umami.website_performance
3+
(
4+
website_id UUID,
5+
session_id UUID,
6+
visit_id UUID,
7+
url_path String,
8+
lcp Nullable(Decimal(10, 1)),
9+
inp Nullable(Decimal(10, 1)),
10+
cls Nullable(Decimal(10, 4)),
11+
fcp Nullable(Decimal(10, 1)),
12+
ttfb Nullable(Decimal(10, 1)),
13+
created_at DateTime('UTC')
14+
)
15+
ENGINE = MergeTree
16+
PARTITION BY toYYYYMM(created_at)
17+
ORDER BY (website_id, toStartOfHour(created_at), session_id)
18+
SETTINGS index_granularity = 8192;
19+
20+
-- Performance hourly aggregation
21+
CREATE TABLE umami.website_performance_hourly
22+
(
23+
website_id UUID,
24+
url_path String,
25+
lcp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
26+
lcp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
27+
lcp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
28+
inp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
29+
inp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
30+
inp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
31+
cls_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 4))),
32+
cls_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 4))),
33+
cls_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 4))),
34+
fcp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
35+
fcp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
36+
fcp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
37+
ttfb_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
38+
ttfb_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
39+
ttfb_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
40+
sample_count SimpleAggregateFunction(sum, UInt64),
41+
created_at DateTime('UTC')
42+
)
43+
ENGINE = AggregatingMergeTree
44+
PARTITION BY toYYYYMM(created_at)
45+
ORDER BY (website_id, toStartOfHour(created_at), url_path)
46+
SETTINGS index_granularity = 8192;
47+
48+
CREATE MATERIALIZED VIEW umami.website_performance_hourly_mv
49+
TO umami.website_performance_hourly
50+
AS
51+
SELECT
52+
website_id,
53+
url_path,
54+
quantileState(0.5)(lcp) as lcp_p50,
55+
quantileState(0.75)(lcp) as lcp_p75,
56+
quantileState(0.95)(lcp) as lcp_p95,
57+
quantileState(0.5)(inp) as inp_p50,
58+
quantileState(0.75)(inp) as inp_p75,
59+
quantileState(0.95)(inp) as inp_p95,
60+
quantileState(0.5)(cls) as cls_p50,
61+
quantileState(0.75)(cls) as cls_p75,
62+
quantileState(0.95)(cls) as cls_p95,
63+
quantileState(0.5)(fcp) as fcp_p50,
64+
quantileState(0.75)(fcp) as fcp_p75,
65+
quantileState(0.95)(fcp) as fcp_p95,
66+
quantileState(0.5)(ttfb) as ttfb_p50,
67+
quantileState(0.75)(ttfb) as ttfb_p75,
68+
quantileState(0.95)(ttfb) as ttfb_p95,
69+
count() as sample_count,
70+
toStartOfHour(created_at) as created_at
71+
FROM umami.website_performance
72+
GROUP BY website_id, url_path, created_at;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Create session_replay
2+
CREATE TABLE umami.session_replay
3+
(
4+
replay_id UUID,
5+
website_id UUID,
6+
session_id UUID,
7+
visit_id UUID,
8+
chunk_index UInt32,
9+
events String CODEC(ZSTD(3)),
10+
event_count UInt32,
11+
started_at DateTime64(6),
12+
ended_at DateTime64(6),
13+
created_at DateTime64(6) DEFAULT now64(6)
14+
)
15+
ENGINE = MergeTree()
16+
PARTITION BY toYYYYMM(created_at)
17+
ORDER BY (replay_id, website_id, session_id, visit_id, chunk_index)
18+
SETTINGS index_granularity = 8192;

db/clickhouse/schema.sql

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,95 @@ JOIN (SELECT event_id, string_value as currency
281281
WHERE positionCaseInsensitive(data_key, 'currency') > 0) c
282282
ON c.event_id = ed.event_id
283283
WHERE positionCaseInsensitive(data_key, 'revenue') > 0;
284+
285+
-- Create Performance
286+
CREATE TABLE umami.website_performance
287+
(
288+
website_id UUID,
289+
session_id UUID,
290+
visit_id UUID,
291+
url_path String,
292+
lcp Nullable(Decimal(10, 1)),
293+
inp Nullable(Decimal(10, 1)),
294+
cls Nullable(Decimal(10, 4)),
295+
fcp Nullable(Decimal(10, 1)),
296+
ttfb Nullable(Decimal(10, 1)),
297+
created_at DateTime('UTC')
298+
)
299+
ENGINE = MergeTree
300+
PARTITION BY toYYYYMM(created_at)
301+
ORDER BY (website_id, toStartOfHour(created_at), session_id)
302+
SETTINGS index_granularity = 8192;
303+
304+
-- Performance hourly aggregation
305+
CREATE TABLE umami.website_performance_hourly
306+
(
307+
website_id UUID,
308+
url_path String,
309+
lcp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
310+
lcp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
311+
lcp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
312+
inp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
313+
inp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
314+
inp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
315+
cls_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 4))),
316+
cls_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 4))),
317+
cls_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 4))),
318+
fcp_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
319+
fcp_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
320+
fcp_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
321+
ttfb_p50 AggregateFunction(quantile(0.5), Nullable(Decimal(10, 1))),
322+
ttfb_p75 AggregateFunction(quantile(0.75), Nullable(Decimal(10, 1))),
323+
ttfb_p95 AggregateFunction(quantile(0.95), Nullable(Decimal(10, 1))),
324+
sample_count SimpleAggregateFunction(sum, UInt64),
325+
created_at DateTime('UTC')
326+
)
327+
ENGINE = AggregatingMergeTree
328+
PARTITION BY toYYYYMM(created_at)
329+
ORDER BY (website_id, toStartOfHour(created_at), url_path)
330+
SETTINGS index_granularity = 8192;
331+
332+
CREATE MATERIALIZED VIEW umami.website_performance_hourly_mv
333+
TO umami.website_performance_hourly
334+
AS
335+
SELECT
336+
website_id,
337+
url_path,
338+
quantileState(0.5)(lcp) as lcp_p50,
339+
quantileState(0.75)(lcp) as lcp_p75,
340+
quantileState(0.95)(lcp) as lcp_p95,
341+
quantileState(0.5)(inp) as inp_p50,
342+
quantileState(0.75)(inp) as inp_p75,
343+
quantileState(0.95)(inp) as inp_p95,
344+
quantileState(0.5)(cls) as cls_p50,
345+
quantileState(0.75)(cls) as cls_p75,
346+
quantileState(0.95)(cls) as cls_p95,
347+
quantileState(0.5)(fcp) as fcp_p50,
348+
quantileState(0.75)(fcp) as fcp_p75,
349+
quantileState(0.95)(fcp) as fcp_p95,
350+
quantileState(0.5)(ttfb) as ttfb_p50,
351+
quantileState(0.75)(ttfb) as ttfb_p75,
352+
quantileState(0.95)(ttfb) as ttfb_p95,
353+
count() as sample_count,
354+
toStartOfHour(created_at) as created_at
355+
FROM umami.website_performance
356+
GROUP BY website_id, url_path, created_at;
357+
358+
-- Create session_replay
359+
CREATE TABLE umami.session_replay
360+
(
361+
replay_id UUID,
362+
website_id UUID,
363+
session_id UUID,
364+
visit_id UUID,
365+
chunk_index UInt32,
366+
events String CODEC(ZSTD(3)),
367+
event_count UInt32,
368+
started_at DateTime64(6),
369+
ended_at DateTime64(6),
370+
created_at DateTime64(6) DEFAULT now64(6)
371+
)
372+
ENGINE = MergeTree()
373+
PARTITION BY toYYYYMM(created_at)
374+
ORDER BY (replay_id, website_id, session_id, visit_id, chunk_index)
375+
SETTINGS index_granularity = 8192;

next-env.d.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)