Skip to content

Commit 58b98bd

Browse files
Merge remote-tracking branch 'upstream/main' into dpf-time-type
2 parents 5208f7c + e65e6d2 commit 58b98bd

56 files changed

Lines changed: 8817 additions & 6367 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.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: e2e recordings
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
e2e_recordings:
14+
# The Sumo shared key secret is only available on the upstream repo, so skip on forks.
15+
if: github.repository == 'equinor/webviz'
16+
runs-on: ubuntu-22.04
17+
18+
env:
19+
COMPOSE_FILE: docker-compose.yml:docker-compose-cosmos-db.yml
20+
WEBVIZ_CLIENT_SECRET: 0
21+
WEBVIZ_SMDA_SUBSCRIPTION_KEY: 0
22+
WEBVIZ_ENTERPRISE_SUBSCRIPTION_KEY: 0
23+
WEBVIZ_VDS_HOST_ADDRESS: 0
24+
WEBVIZ_PSEUDONYM_HMAC_KEY: 0
25+
WEBVIZ_SESSION_STORE_FERNET_KEY: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
26+
WEBVIZ_REDIS_AUTH_STORE_PASSWORD: 0
27+
WEBVIZ_REDIS_CACHE_PASSWORD: 0
28+
WEBVIZ_SUMO_ENV: prod
29+
30+
steps:
31+
- name: 📖 Checkout commit locally
32+
uses: actions/checkout@v4
33+
34+
- uses: actions/setup-node@v4
35+
with:
36+
node-version: 24
37+
cache: npm
38+
cache-dependency-path: frontend/package-lock.json
39+
40+
- name: 📦 Install frontend dependencies
41+
working-directory: ./frontend
42+
run: npm ci --include=dev
43+
44+
- name: 🎭 Install Playwright browser (chromium)
45+
working-directory: ./frontend
46+
run: npx playwright install --with-deps chromium
47+
48+
- name: 🎙️ Ensure ffmpeg is available (for voiceover muxing)
49+
run: ffmpeg -version >/dev/null 2>&1 || (sudo apt-get update && sudo apt-get install -y ffmpeg)
50+
51+
- name: 🧠 Cache the Kokoro TTS model
52+
uses: actions/cache@v4
53+
with:
54+
path: ~/.cache/huggingface
55+
key: huggingface-kokoro-82m-v1.0-onnx
56+
57+
- name: 📦 Cache synthesized narration audio
58+
uses: actions/cache@v4
59+
with:
60+
path: frontend/.narration-cache
61+
key: narration-audio-${{ github.run_id }}
62+
restore-keys: narration-audio-
63+
64+
- name: 🐳 Build and start the full stack
65+
run: docker compose up --build --detach
66+
67+
- name: 🔑 Add Sumo shared key into the backend container
68+
env:
69+
SHARED_KEY_SUMO_PROD: ${{ secrets.SHARED_KEY_DROGON_READ_PROD }}
70+
run: |
71+
if [ ${#SHARED_KEY_SUMO_PROD} -eq 0 ]; then
72+
echo "Error: SHARED_KEY_SUMO_PROD is empty. Stopping the action."
73+
exit 1
74+
fi
75+
printf '%s' "$SHARED_KEY_SUMO_PROD" > shared.key
76+
docker compose exec -T backend-primary mkdir -p /home/appuser/.sumo
77+
docker compose cp shared.key backend-primary:/home/appuser/.sumo/9e5443dd-3431-4690-9617-31eed61cb55a.sharedkey
78+
rm -f shared.key
79+
80+
# `docker compose cp` writes the file as root, but the backend runs as `appuser`. Fix ownership.
81+
docker compose exec -T -u root backend-primary \
82+
chown appuser:appuser /home/appuser/.sumo/9e5443dd-3431-4690-9617-31eed61cb55a.sharedkey
83+
docker compose exec -T -u root backend-primary \
84+
chmod 600 /home/appuser/.sumo/9e5443dd-3431-4690-9617-31eed61cb55a.sharedkey
85+
86+
- name: ⏳ Wait for the stack to become responsive
87+
run: |
88+
curl --retry 90 --retry-delay 5 --retry-connrefused --retry-all-errors -f http://localhost:5000/alive
89+
curl --retry 30 --retry-delay 2 --retry-connrefused --retry-all-errors -f http://localhost:8080
90+
91+
- name: 🎥 Run e2e tests with recording
92+
working-directory: ./frontend
93+
env:
94+
CI: "true"
95+
run: npm run test:e2e:record
96+
97+
- name: 🐳 Dump docker compose logs on failure
98+
if: failure()
99+
run: docker compose logs --no-color
100+
101+
- name: ☁️ Upload recordings to Azure Blob Storage
102+
env:
103+
AZURE_STORAGE_CONNECTION_STRING: ${{ secrets.E2E_RECORDINGS_STORAGE_CONNECTION_STRING }}
104+
run: |
105+
az storage blob upload-batch \
106+
--destination tutorial-videos \
107+
--source frontend/test-results \
108+
--pattern "*.webm" \
109+
--overwrite \
110+
--output none
111+
112+
- name: 🧹 Tear down the stack
113+
if: always()
114+
run: docker compose down --volumes

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,19 @@ storybook-static
116116
!.vscode/launch.json
117117
!backend_py/primary/.vscode/launch.json
118118

119+
frontend/docs/
120+
119121
# playwright results
120122
playwright-report/
121123
test-results/
122124
playwright/.cache/
123125

126+
# Cached narration audio (content-hash keyed)
127+
frontend/.narration-cache/
128+
129+
# Seeded auth state for e2e tests
130+
frontend/tests/e2e/setup/storageState.json
131+
124132
# Ignore Jupyter Notebook files
125133
*.ipynb
126134

backend_go/surface_query/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
3131
github.com/ugorji/go/codec v1.3.0 // indirect
3232
golang.org/x/arch v0.20.0 // indirect
33-
golang.org/x/crypto v0.51.0 // indirect
33+
golang.org/x/crypto v0.52.0 // indirect
3434
golang.org/x/net v0.55.0 // indirect
3535
golang.org/x/sys v0.45.0 // indirect
3636
golang.org/x/text v0.37.0 // indirect

backend_go/surface_query/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
6767
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
6868
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
6969
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
70-
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
71-
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
70+
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
71+
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
7272
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
7373
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
7474
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

backend_py/libs/services/poetry.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend_py/libs/services/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ redis = "7.1.1"
1313
pyarrow = "^24.0.0"
1414
numpy = "^2.2.0"
1515
httpx = "^0.28.1"
16-
sumo-wrapper-python = "^1.6.0"
16+
sumo-wrapper-python = "^1.9.0"
1717
pottery = "^3.0.0"
1818
requests-toolbelt = "^1.0.0"
1919
xtgeo = "^4.18.0"
@@ -33,7 +33,7 @@ pydantic = "~2.12.0"
3333

3434
### Might change model fields in minor updates, so pinned for stability
3535
fmu-datamodels = "0.21.4"
36-
fmu-sumo = "2.14.0"
36+
fmu-sumo = "2.15.1"
3737

3838

3939
[build-system]

backend_py/libs/services/src/webviz_services/sumo_access/sumo_client_factory.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
LOGGER = logging.getLogger(__name__)
1010

11+
SENTINEL_ACCESS_TOKEN_FOR_TESTING = "DUMMY_TOKEN_FOR_TESTING" # nosec B105
12+
1113

1214
class _FakeSyncHttpClient:
1315
"""A fake HTTP client to ensure we use async methods instead of sync ones.
@@ -26,7 +28,7 @@ def create_sumo_client(access_token: str) -> SumoClient:
2628

2729
services_config = get_services_config()
2830

29-
if access_token == "DUMMY_TOKEN_FOR_TESTING": # nosec bandit B105
31+
if access_token == SENTINEL_ACCESS_TOKEN_FOR_TESTING:
3032
sumo_client = SumoClient(env=services_config.sumo_env, interactive=False)
3133
else:
3234
sumo_client = SumoClient(

backend_py/primary/poetry.lock

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend_py/primary/primary/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
SESSION_STORE_FERNET_KEY = os.environ["WEBVIZ_SESSION_STORE_FERNET_KEY"]
3131
REDIS_AUTH_STORE_PASSWORD = os.environ["WEBVIZ_REDIS_AUTH_STORE_PASSWORD"]
3232
REDIS_AUTH_STORE_URL = f"redis://:{REDIS_AUTH_STORE_PASSWORD}@redis-auth-store:6379"
33+
# Redis key prefix for the encrypted auth session store. Shared so the e2e seed script writes to the
34+
# same keys the SessionMiddleware reads (see scripts/seed_e2e_session.py).
35+
AUTH_SESSION_STORE_PREFIX = "auth-sessions:"
3336

3437
REDIS_CACHE_PASSWORD = os.environ["WEBVIZ_REDIS_CACHE_PASSWORD"]
3538
REDIS_CACHE_URL = f"redis://:{REDIS_CACHE_PASSWORD}@redis-cache:6379"

backend_py/primary/primary/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ async def lifespan_handler_async(_fastapi_app: FastAPI) -> AsyncIterator[None]:
196196
)
197197

198198
encrypted_session_store = EncryptedRedisSessionStore(
199-
fernet_key=config.SESSION_STORE_FERNET_KEY, redis_url=config.REDIS_AUTH_STORE_URL, prefix="auth-sessions:"
199+
fernet_key=config.SESSION_STORE_FERNET_KEY,
200+
redis_url=config.REDIS_AUTH_STORE_URL,
201+
prefix=config.AUTH_SESSION_STORE_PREFIX,
200202
)
201203
app.add_middleware(SessionMiddleware, store=encrypted_session_store)
202204

0 commit comments

Comments
 (0)