mirror of
https://github.com/suitenumerique/docs.git
synced 2026-05-07 15:43:01 +02:00
Compare commits
2 Commits
build/arm6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d340c8f1f1 | ||
|
|
67773ef2d9 |
@@ -17,6 +17,7 @@ and this project adheres to
|
||||
|
||||
### Fixed
|
||||
|
||||
- 🩺(project) reload app if front and back unsync #2276
|
||||
- 🐛(frontend) fix patch and comments #2273
|
||||
- 🐛(frontend) interlinking are exported correctly in print mode #2269
|
||||
- 💬(frontend) add missing link in onboarding description #2233
|
||||
|
||||
@@ -6,8 +6,9 @@ FROM python:3.13.13-alpine AS base
|
||||
# Upgrade system packages to install security updates
|
||||
RUN apk update && apk upgrade --no-cache
|
||||
|
||||
# We must do that to avoid having an outdated pip version with security issues
|
||||
RUN python -m pip install --upgrade pip
|
||||
|
||||
# Remove pip. We don't use it.
|
||||
RUN python -m pip uninstall -y pip
|
||||
|
||||
# ---- Back-end builder image ----
|
||||
FROM base AS back-builder
|
||||
@@ -113,7 +114,7 @@ RUN mkdir /cert && \
|
||||
|
||||
# Generate compiled translation messages
|
||||
RUN DJANGO_CONFIGURATION=Build \
|
||||
python manage.py compilemessages --ignore=".venv/**/*"
|
||||
python manage.py compilemessages
|
||||
|
||||
|
||||
# We wrap commands run in this container by the following entrypoint that
|
||||
|
||||
@@ -2841,6 +2841,7 @@ class ConfigView(drf.views.APIView):
|
||||
dict_settings[setting] = getattr(settings, setting)
|
||||
|
||||
dict_settings["theme_customization"] = self._load_theme_customization()
|
||||
dict_settings["RELEASE_VERSION"] = settings.RELEASE
|
||||
|
||||
return drf.response.Response(dict_settings)
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ pytestmark = pytest.mark.django_db
|
||||
FRONTEND_THEME="test-theme",
|
||||
MEDIA_BASE_URL="http://testserver/",
|
||||
POSTHOG_KEY={"id": "132456", "host": "https://eu.i.posthog-test.com"},
|
||||
RELEASE="1.0.0",
|
||||
SENTRY_DSN="https://sentry.test/123",
|
||||
THEME_CUSTOMIZATION_FILE_PATH="",
|
||||
)
|
||||
@@ -77,6 +78,7 @@ def test_api_config(is_authenticated):
|
||||
"LANGUAGE_CODE": "en-us",
|
||||
"MEDIA_BASE_URL": "http://testserver/",
|
||||
"POSTHOG_KEY": {"id": "132456", "host": "https://eu.i.posthog-test.com"},
|
||||
"RELEASE_VERSION": "1.0.0",
|
||||
"SENTRY_DSN": "https://sentry.test/123",
|
||||
"TRASHBIN_CUTOFF_DAYS": 30,
|
||||
"theme_customization": {},
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { createDoc, getCurrentConfig, verifyDocName } from './utils-common';
|
||||
import {
|
||||
createDoc,
|
||||
getCurrentConfig,
|
||||
overrideConfig,
|
||||
verifyDocName,
|
||||
} from './utils-common';
|
||||
import { writeInEditor } from './utils-editor';
|
||||
import { SignIn, expectLoginPage } from './utils-signin';
|
||||
import { createRootSubPage } from './utils-sub-pages';
|
||||
@@ -145,6 +150,29 @@ test.describe('Doc Routing', () => {
|
||||
);
|
||||
await expect(page).toHaveTitle(/401 Unauthorized - Docs/);
|
||||
});
|
||||
|
||||
test('checks redirect if unsync version', async ({ page }) => {
|
||||
await overrideConfig(page, {
|
||||
RELEASE_VERSION: '0.0.0',
|
||||
});
|
||||
|
||||
let counterReload = 0;
|
||||
await page.route(/.*\/users\/me\/$/, async (route) => {
|
||||
counterReload += 1;
|
||||
await route.continue();
|
||||
});
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// The sessionStorage guard should be set to the mismatched backend version.
|
||||
const reloadVersion = await page.evaluate(() =>
|
||||
sessionStorage.getItem('reload-version'),
|
||||
);
|
||||
expect(reloadVersion).toBe('0.0.0');
|
||||
|
||||
// The page should have reloaded once
|
||||
expect(counterReload).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Doc Routing: Not logged', () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from 'path';
|
||||
import { Locator, Page, TestInfo, expect } from '@playwright/test';
|
||||
|
||||
import theme_customization from '../../../../../backend/impress/configuration/theme/default.json';
|
||||
import { version as packageJsonVersion } from '../../package.json';
|
||||
|
||||
export type BrowserName = 'chromium' | 'firefox' | 'webkit';
|
||||
export const BROWSERS: BrowserName[] = ['chromium', 'webkit', 'firefox'];
|
||||
@@ -40,6 +41,7 @@ export const CONFIG = {
|
||||
],
|
||||
LANGUAGE_CODE: 'en-us',
|
||||
POSTHOG_KEY: {},
|
||||
RELEASE_VERSION: packageJsonVersion,
|
||||
SENTRY_DSN: null,
|
||||
TRASHBIN_CUTOFF_DAYS: 30,
|
||||
theme_customization,
|
||||
|
||||
@@ -2,6 +2,8 @@ const crypto = require('crypto');
|
||||
|
||||
const { InjectManifest } = require('workbox-webpack-plugin');
|
||||
|
||||
const { version } = require('./package.json');
|
||||
|
||||
const buildId = crypto.randomBytes(256).toString('hex').slice(0, 8);
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
@@ -25,6 +27,7 @@ const nextConfig = {
|
||||
generateBuildId: () => buildId,
|
||||
env: {
|
||||
NEXT_PUBLIC_BUILD_ID: buildId,
|
||||
NEXT_PUBLIC_APP_VERSION: version,
|
||||
},
|
||||
/**
|
||||
* In dev mode, Next.js doesn't use Webpack, but Turbopack.
|
||||
|
||||
@@ -85,6 +85,32 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => {
|
||||
});
|
||||
}, [conf?.CRISP_WEBSITE_ID]);
|
||||
|
||||
useEffect(() => {
|
||||
const frontendVersion = process.env.NEXT_PUBLIC_APP_VERSION;
|
||||
|
||||
if (
|
||||
!conf?.RELEASE_VERSION ||
|
||||
!frontendVersion ||
|
||||
conf.RELEASE_VERSION === frontendVersion
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid infinite reload loops: only reload once per backend version
|
||||
const RELOAD_VERSION_KEY = 'reload-version';
|
||||
try {
|
||||
const reloadedForVersion = sessionStorage.getItem(RELOAD_VERSION_KEY);
|
||||
if (reloadedForVersion === conf.RELEASE_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
sessionStorage.setItem(RELOAD_VERSION_KEY, conf.RELEASE_VERSION);
|
||||
window.location.reload();
|
||||
} catch {
|
||||
console.warn('Failed to access sessionStorage for version reload logic');
|
||||
}
|
||||
}, [conf?.RELEASE_VERSION]);
|
||||
|
||||
if (!conf) {
|
||||
return (
|
||||
<Box $height="100vh" $width="100vw" $align="center" $justify="center">
|
||||
|
||||
@@ -57,6 +57,7 @@ export interface ConfigResponse {
|
||||
LANGUAGE_CODE: string;
|
||||
MEDIA_BASE_URL?: string;
|
||||
POSTHOG_KEY?: PostHogConf;
|
||||
RELEASE_VERSION: string;
|
||||
SENTRY_DSN?: string;
|
||||
TRASHBIN_CUTOFF_DAYS?: number;
|
||||
theme_customization?: ThemeCustomization;
|
||||
@@ -94,13 +95,13 @@ export const KEY_CONFIG = 'config';
|
||||
|
||||
export function useConfig() {
|
||||
const cachedData = getCachedTranslation();
|
||||
const oneHour = 1000 * 60 * 60;
|
||||
const staleTime = 1000 * 60 * 5;
|
||||
|
||||
return useQuery<ConfigResponse, APIError, ConfigResponse>({
|
||||
queryKey: [KEY_CONFIG],
|
||||
queryFn: () => getConfig(),
|
||||
initialData: cachedData,
|
||||
staleTime: oneHour,
|
||||
initialDataUpdatedAt: Date.now() - oneHour, // Force initial data to be considered stale
|
||||
staleTime,
|
||||
initialDataUpdatedAt: Date.now() - staleTime, // Force initial data to be considered stale
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,6 +60,12 @@ export function PostHogProvider({
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
posthogInstance.debug();
|
||||
}
|
||||
|
||||
if (process.env.NEXT_PUBLIC_APP_VERSION) {
|
||||
posthogInstance.register({
|
||||
app_version: process.env.NEXT_PUBLIC_APP_VERSION,
|
||||
});
|
||||
}
|
||||
},
|
||||
capture_pageview: false,
|
||||
capture_pageleave: true,
|
||||
|
||||
Reference in New Issue
Block a user