Skip to content

Commit 49c8185

Browse files
Merge branch 'main' into fix/sdk-get-empty-body
2 parents f4f2737 + 4412567 commit 49c8185

99 files changed

Lines changed: 7039 additions & 2634 deletions

File tree

Some content is hidden

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

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ updates:
99
directory: "/" # Location of package manifests
1010
schedule:
1111
interval: "daily"
12+
cooldown:
13+
default-days: 7
1214
rebase-strategy: "disabled" # use dependabot-rebase-stale
1315
commit-message:
1416
prefix: chore
@@ -26,6 +28,8 @@ updates:
2628
directory: "/"
2729
schedule:
2830
interval: "daily"
31+
cooldown:
32+
default-days: 7
2933
rebase-strategy: "disabled"
3034
commit-message:
3135
prefix: chore

.github/workflows/ci.yml

Lines changed: 151 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,43 @@ on:
1010
branches:
1111
- "*"
1212

13+
permissions: {}
14+
1315
concurrency:
1416
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15-
cancel-in-progress: false
17+
cancel-in-progress: true
1618

1719
jobs:
1820
linting:
19-
runs-on: ubuntu-latest
21+
runs-on: blacksmith-2vcpu-ubuntu-2404
2022
steps:
21-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
23+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
24+
with:
25+
persist-credentials: false
2226
- name: Install uv and set Python version
23-
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
27+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
2428
with:
2529
version: "0.11.2"
2630
python-version: "3.13"
27-
enable-cache: true
31+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
2832
- name: Install dependencies
2933
run: uv sync --locked
3034
- name: Run Ruff
3135
run: uv run --frozen ruff check .
3236

3337
type-checking:
34-
runs-on: ubuntu-latest
38+
runs-on: blacksmith-2vcpu-ubuntu-2404
3539
steps:
36-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
40+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
41+
with:
42+
persist-credentials: false
3743
- name: Install uv and set Python version
38-
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
44+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
3945
with:
4046
version: "0.11.2"
4147
python-version: "3.13"
42-
enable-cache: true
43-
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
48+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
49+
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 # zizmor: ignore[cache-poisoning]
4450
name: Cache mypy cache
4551
with:
4652
path: ./.mypy_cache
@@ -52,17 +58,14 @@ jobs:
5258
- name: Run mypy type checking
5359
run: uv run --frozen mypy langfuse --no-error-summary
5460

55-
ci:
56-
runs-on: ubuntu-latest
61+
unit-tests:
62+
runs-on: blacksmith-4vcpu-ubuntu-2404
5763
timeout-minutes: 30
5864
env:
5965
LANGFUSE_BASE_URL: "http://localhost:3000"
60-
LANGFUSE_PUBLIC_KEY: "pk-lf-1234567890"
61-
LANGFUSE_SECRET_KEY: "sk-lf-1234567890"
62-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
63-
# SERPAPI_API_KEY: ${{ secrets.SERPAPI_API_KEY }}
64-
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
65-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
66+
LANGFUSE_PUBLIC_KEY: "pk-lf-test"
67+
LANGFUSE_SECRET_KEY: "sk-lf-test"
68+
OPENAI_API_KEY: "test-openai-key"
6669
strategy:
6770
fail-fast: false
6871
matrix:
@@ -73,56 +76,99 @@ jobs:
7376
- "3.13"
7477
- "3.14"
7578

76-
name: Test on Python version ${{ matrix.python-version }}
79+
name: Unit tests on Python ${{ matrix.python-version }}
7780
steps:
78-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
79-
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
81+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
82+
with:
83+
persist-credentials: false
84+
- name: Install uv and set Python version
85+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
8086
with:
81-
version: 10.33.0
87+
version: "0.11.2"
88+
python-version: ${{ matrix.python-version }}
89+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
8290

83-
- name: Clone langfuse server
91+
- name: Check Python version
92+
run: python --version
93+
94+
- name: Install the project dependencies
95+
run: uv sync --locked
96+
97+
- name: Run the automated tests
8498
run: |
85-
git clone https://github.com/langfuse/langfuse.git ./langfuse-server && echo $(cd ./langfuse-server && git rev-parse HEAD)
99+
python --version
100+
uv run --frozen pytest -n auto --dist worksteal -s -v --log-cli-level=INFO tests/unit
86101
87-
- name: Setup node (for langfuse server)
88-
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
89-
with:
90-
node-version: 24
102+
e2e-tests:
103+
runs-on: ubuntu-latest
104+
timeout-minutes: 30
105+
strategy:
106+
fail-fast: false
107+
matrix:
108+
include:
109+
- suite: e2e
110+
job_name: E2E shard 1 tests on Python 3.13
111+
shard_name: shard-1
112+
shard_index: 0
113+
shard_count: 2
114+
- suite: e2e
115+
job_name: E2E shard 2 tests on Python 3.13
116+
shard_name: shard-2
117+
shard_index: 1
118+
shard_count: 2
119+
- suite: live_provider
120+
job_name: E2E live-provider tests on Python 3.13
121+
shard_name: live-provider
122+
env:
123+
LANGFUSE_BASE_URL: "http://localhost:3000"
124+
LANGFUSE_PUBLIC_KEY: "pk-lf-1234567890"
125+
LANGFUSE_SECRET_KEY: "sk-lf-1234567890"
126+
LANGFUSE_INIT_ORG_ID: "0c6c96f4-0ca0-4f16-92a8-6dd7d7c6a501"
127+
LANGFUSE_INIT_ORG_NAME: "SDK Test Org"
128+
LANGFUSE_INIT_PROJECT_ID: "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a"
129+
LANGFUSE_INIT_PROJECT_NAME: "SDK Test Project"
130+
LANGFUSE_INIT_PROJECT_PUBLIC_KEY: "pk-lf-1234567890"
131+
LANGFUSE_INIT_PROJECT_SECRET_KEY: "sk-lf-1234567890"
132+
LANGFUSE_INIT_USER_EMAIL: "sdk-tests@langfuse.local"
133+
LANGFUSE_INIT_USER_NAME: "SDK Tests"
134+
LANGFUSE_INIT_USER_PASSWORD: "langfuse-ci-password"
135+
LANGFUSE_E2E_READ_TIMEOUT_SECONDS: "60"
136+
LANGFUSE_E2E_READ_INTERVAL_SECONDS: "0.5"
137+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
138+
# SERPAPI_API_KEY: ${{ secrets.SERPAPI_API_KEY }}
139+
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
140+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
91141

92-
- name: Cache langfuse server dependencies
93-
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
142+
name: ${{ matrix.job_name }}
143+
steps:
144+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
94145
with:
95-
path: ./langfuse-server/node_modules
96-
key: |
97-
langfuse-server-${{ hashFiles('./langfuse-server/package-lock.json') }}
98-
langfuse-server-
146+
persist-credentials: false
147+
- name: Install uv and set Python version
148+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
149+
with:
150+
version: "0.11.2"
151+
python-version: "3.13"
152+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
153+
- name: Install the project dependencies
154+
run: uv sync --locked
155+
- name: Check uv Python version
156+
run: uv run --frozen python --version
157+
- name: Prepare langfuse server compose
158+
run: |
159+
mkdir -p ./langfuse-server
160+
LANGFUSE_SERVER_SHA="$(git ls-remote https://github.com/langfuse/langfuse.git HEAD | cut -f1)"
161+
curl -fsSL "https://raw.githubusercontent.com/langfuse/langfuse/${LANGFUSE_SERVER_SHA}/docker-compose.yml" \
162+
-o ./langfuse-server/docker-compose.yml
163+
echo "${LANGFUSE_SERVER_SHA}"
99164
100165
- name: Run langfuse server
101166
run: |
102167
cd ./langfuse-server
103168
104-
echo "::group::Run langfuse server"
105-
TELEMETRY_ENABLED=false docker compose up -d postgres
106-
echo "::endgroup::"
107-
108-
echo "::group::Logs from langfuse server"
109-
TELEMETRY_ENABLED=false docker compose logs
110-
echo "::endgroup::"
111-
112-
echo "::group::Install dependencies (necessary to run seeder)"
113-
pnpm i
114-
echo "::endgroup::"
115-
116-
echo "::group::Seed db"
117-
cp .env.dev.example .env
118-
pnpm run db:migrate
119-
pnpm run db:seed
120-
echo "::endgroup::"
121-
rm -rf .env
122-
123-
echo "::group::Run server"
124-
169+
echo "::group::Start langfuse server"
125170
TELEMETRY_ENABLED=false \
171+
NEXT_PUBLIC_LANGFUSE_RUN_NEXT_INIT=true \
126172
LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT=http://localhost:9090 \
127173
LANGFUSE_INGESTION_QUEUE_DELAY_MS=10 \
128174
LANGFUSE_INGESTION_CLICKHOUSE_WRITE_INTERVAL_MS=10 \
@@ -131,51 +177,81 @@ jobs:
131177
LANGFUSE_ENABLE_EVENTS_TABLE_V2_APIS=true \
132178
LANGFUSE_ENABLE_EVENTS_TABLE_OBSERVATIONS=true \
133179
docker compose up -d
134-
135180
echo "::endgroup::"
136181
137-
# Add this step to check the health of the container
138182
- name: Health check for langfuse server
139183
run: |
140184
echo "Checking if the langfuse server is up..."
141185
retry_count=0
142-
max_retries=10
143-
until curl --output /dev/null --silent --head --fail http://localhost:3000/api/public/health
186+
max_retries=20
187+
until curl --output /dev/null --silent --head --fail http://localhost:3000/api/public/health && \
188+
uv run --frozen python -c "from langfuse import Langfuse; client = Langfuse(); project_id = client._get_project_id(); assert project_id == '7a88fb47-b4e2-43b8-a06c-a5ce950dc53a', project_id; print(project_id)"
144189
do
145190
retry_count=`expr $retry_count + 1`
146191
echo "Attempt $retry_count of $max_retries..."
147192
if [ $retry_count -ge $max_retries ]; then
148193
echo "Langfuse server did not respond in time. Printing logs..."
149-
docker logs langfuse-server-langfuse-web-1
194+
(cd ./langfuse-server && docker compose ps)
195+
(cd ./langfuse-server && docker compose logs langfuse-web langfuse-worker)
150196
echo "Failing the step..."
151197
exit 1
152198
fi
153199
sleep 5
154200
done
155201
echo "Langfuse server is up and running!"
156202
157-
- name: Install uv and set Python version
158-
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
159-
with:
160-
version: "0.11.2"
161-
python-version: ${{ matrix.python-version }}
162-
enable-cache: true
203+
- name: Select e2e shard files
204+
if: ${{ matrix.suite == 'e2e' }}
205+
run: |
206+
uv run --frozen python scripts/select_e2e_shard.py \
207+
--shard-index ${{ matrix.shard_index }} \
208+
--shard-count ${{ matrix.shard_count }} \
209+
--json
210+
uv run --frozen python scripts/select_e2e_shard.py \
211+
--shard-index ${{ matrix.shard_index }} \
212+
--shard-count ${{ matrix.shard_count }} \
213+
> "$RUNNER_TEMP/e2e-shard-files.txt"
214+
cat "$RUNNER_TEMP/e2e-shard-files.txt"
163215
164-
- name: Check Python version
165-
run: python --version
216+
- name: Run the parallel end-to-end tests
217+
if: ${{ matrix.suite == 'e2e' }}
218+
run: |
219+
uv run --frozen python --version
220+
mapfile -t e2e_files < "$RUNNER_TEMP/e2e-shard-files.txt"
221+
set +e
222+
uv run --frozen pytest -n 4 --dist worksteal -s -v --log-cli-level=INFO "${e2e_files[@]}" -m "not serial_e2e"
223+
status=$?
224+
set -e
225+
if [ "$status" -eq 5 ]; then
226+
echo "No parallel e2e tests selected for this shard."
227+
elif [ "$status" -ne 0 ]; then
228+
exit "$status"
229+
fi
166230
167-
- name: Install the project dependencies
168-
run: uv sync --locked
231+
- name: Run serial end-to-end tests
232+
if: ${{ matrix.suite == 'e2e' }}
233+
run: |
234+
mapfile -t e2e_files < "$RUNNER_TEMP/e2e-shard-files.txt"
235+
set +e
236+
uv run --frozen pytest -s -v --log-cli-level=INFO "${e2e_files[@]}" -m "serial_e2e"
237+
status=$?
238+
set -e
239+
if [ "$status" -eq 5 ]; then
240+
echo "No serial e2e tests selected for this shard."
241+
elif [ "$status" -ne 0 ]; then
242+
exit "$status"
243+
fi
169244
170-
- name: Run the automated tests
245+
- name: Run live-provider tests
246+
if: ${{ matrix.suite == 'live_provider' }}
171247
run: |
172-
python --version
173-
uv run --frozen pytest -n auto --dist loadfile -s -v --log-cli-level=INFO
248+
uv run --frozen python --version
249+
uv run --frozen pytest -n 4 --dist worksteal -s -v --log-cli-level=INFO tests/live_provider -m "live_provider"
174250
175251
all-tests-passed:
176252
# This allows us to have a branch protection rule for tests and deploys with matrix
177-
runs-on: ubuntu-latest
178-
needs: [ci, linting, type-checking]
253+
runs-on: blacksmith-2vcpu-ubuntu-2404
254+
needs: [unit-tests, e2e-tests, linting, type-checking]
179255
if: always()
180256
steps:
181257
- name: Successful deploy

.github/workflows/claude-review-maintainer-prs.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
name: Claude Review on Maintainer PRs
22

33
on:
4-
pull_request_target:
4+
pull_request:
55
types:
66
- opened
77
- ready_for_review
88

99
jobs:
1010
comment:
11-
if: github.event.pull_request.draft == false
11+
# Only run on PRs that are not drafts and are from the same repository (i.e., not from forks)
12+
if: github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.repository
1213
runs-on: ubuntu-latest
1314
permissions:
1415
issues: write
1516
pull-requests: write
1617
steps:
1718
- name: Check author permission and existing review request
1819
id: check
19-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
20+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
2021
with:
2122
script: |
2223
const owner = context.repo.owner;
@@ -57,7 +58,7 @@ jobs:
5758
5859
- name: Add Claude review comment
5960
if: steps.check.outputs.should_comment == 'true'
60-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
61+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
6162
with:
6263
script: |
6364
await github.rest.issues.createComment({

.github/workflows/codeql.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ jobs:
5555
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
5656
steps:
5757
- name: Checkout repository
58-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
58+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
59+
with:
60+
persist-credentials: false
5961

6062
# Initializes the CodeQL tools for scanning.
6163
- name: Initialize CodeQL

.github/workflows/dependabot-merge.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ permissions:
1111
jobs:
1212
dependabot:
1313
runs-on: ubuntu-latest
14-
if: ${{ github.actor == 'dependabot[bot]' }}
14+
if: github.event.pull_request.user.id == 49699333 # dependabot[bot]
1515
steps:
1616
- name: Dependabot metadata
1717
id: metadata
18-
uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 # v3
18+
uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 # v3.0.0
1919
with:
2020
github-token: "${{ secrets.GITHUB_TOKEN }}"
2121
- name: Enable auto-merge for Dependabot PRs

0 commit comments

Comments
 (0)