Skip to content

Commit 925c924

Browse files
committed
Merge branch 'main' into fix/autox-configure-extend-empty-state
2 parents c6d3b2f + f77c5fa commit 925c924

85 files changed

Lines changed: 1129 additions & 401 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/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,17 @@ jobs:
314314
**/node_modules
315315
key: ${{ needs.Setup.outputs.modules-cache-key }}
316316
- name: Restore Cypress build cache
317+
id: cypress-build-cache
317318
uses: actions/cache/restore@v4
318319
with:
319320
path: |
320321
**/public-cypress
321322
key: ${{ needs.Cypress-Setup.outputs.cypress-cache-key }}
323+
- name: Rebuild on cache miss
324+
if: steps.cypress-build-cache.outputs.cache-hit != 'true'
325+
run: |
326+
echo "::warning::Cypress build cache miss — rebuilding (key: ${{ needs.Cypress-Setup.outputs.cypress-cache-key }})"
327+
npm run cypress:server:build:coverage -- --concurrency=4
322328
- name: Run Cypress Mock tests
323329
run: |
324330
npm run test:cypress-ci:coverage:nobuild -- --spec "../packages/${{ matrix.test-group.spec }}"

frontend/src/app/App.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ const App: React.FC = () => {
6161
dashboardConfig: dashboardConfigFromServer,
6262
loaded: configLoaded,
6363
loadError: fetchConfigError,
64+
refresh,
6465
} = useApplicationSettings();
6566

66-
const { dashboardConfig, ...devFeatureFlagsProps } =
67-
useDevFeatureFlags(dashboardConfigFromServer);
67+
const { dashboardConfig, ...devFeatureFlagsProps } = useDevFeatureFlags(
68+
dashboardConfigFromServer,
69+
refresh,
70+
);
6871

6972
const [storageClasses] = useStorageClasses();
7073

frontend/src/app/featureFlags/useDevFeatureFlags.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const useDevFlags: () => string[] = () => {
4646
*/
4747
const useDevFeatureFlags = (
4848
dashboardConfig?: DashboardConfigKind | null,
49+
refreshConfig?: () => Promise<void>,
4950
): {
5051
dashboardConfig: DashboardConfigKind | null;
5152
} & DevFeatureFlags => {
@@ -197,8 +198,17 @@ const useDevFeatureFlags = (
197198
(turnOff: boolean) => {
198199
setSessionFlags(turnOff ? null : {});
199200
setBannerVisible(false);
201+
202+
// Clear the axios header immediately so the next config fetch
203+
// from the server returns clean (un-overridden) values.
204+
if (turnOff) {
205+
delete axios.defaults.headers.common[HEADER_NAME];
206+
} else {
207+
axios.defaults.headers.common[HEADER_NAME] = JSON.stringify({});
208+
}
209+
refreshConfig?.();
200210
},
201-
[setSessionFlags, setBannerVisible],
211+
[setSessionFlags, setBannerVisible, refreshConfig],
202212
);
203213

204214
const setDevFeatureFlag = React.useCallback(

frontend/src/concepts/areas/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { DashboardCommonConfig } from '#~/k8sTypes';
22
import { SupportedArea, SupportedAreasState, DataScienceStackComponent } from './types';
33

44
export const techPreviewFlags = {
5-
disableModelRegistry: true,
65
genAiStudio: false,
76
automl: false,
87
autorag: false,
@@ -67,6 +66,7 @@ export const advancedAIMLFlags = {
6766
disablePipelines: false,
6867
disableDistributedWorkloads: false,
6968
disableModelCatalog: false,
69+
disableModelRegistry: false,
7070
disableModelRegistrySecureDB: false,
7171
disableFeatureStore: false,
7272
disableFineTuning: true,

frontend/src/pages/distributedWorkloads/components/WorkloadStatusLabel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const WorkloadStatusLabel: React.FC<{ workload: WorkloadKind }> = ({ work
1111
color={statusInfo.color}
1212
status={statusInfo.labelStatus}
1313
icon={<statusInfo.icon />}
14+
style={{ width: 'fit-content' }}
1415
>
1516
{statusInfo.status}
1617
</Label>

frontend/src/pages/projects/screens/spawner/SpawnerPage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ const SpawnerPage: React.FC<SpawnerPageProps> = ({ existingNotebook }) => {
310310
dataTestId="workbench"
311311
{...k8sNameDescriptionData}
312312
autoFocusName
313+
maxLength={250}
314+
maxLengthDesc={5500}
313315
/>
314316
</FormSection>
315317
<FormSection

frontend/src/pages/projects/screens/spawner/storage/CreateNewStorageSection.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ const CreateNewStorageSection = <D extends StorageData>({
8484
onDataChange={setClusterNameDesc}
8585
dataTestId="create-new-storage"
8686
autoFocusName={autoFocusName}
87+
maxLength={250}
88+
maxLengthDesc={5500}
8789
nameHelperText={
8890
hasDuplicateName ? (
8991
<HelperTextItem icon={<ExclamationCircleIcon />} variant="error">

packages/automl/api/openapi/automl.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ paths:
373373
374374
Only CSV uploads are allowed: Content-Type `text/csv`, or `application/octet-stream` (or empty)
375375
when the part filename ends with `.csv`. The body is size-limited (declared Content-Length
376-
and total multipart size caps; file part max 1 GiB). Rejects with 413 when limits are exceeded.
376+
and total multipart size caps; file part max 32 MiB). Rejects with 413 when limits are exceeded.
377377
378378
On success, returns JSON with `uploaded: true` and the resolved `key` (which may differ
379379
from the requested key if a collision was avoided by probing existing keys).
@@ -1723,7 +1723,7 @@ components:
17231723
example: "413"
17241724
message:
17251725
type: string
1726-
example: "request body exceeds maximum upload size (1 GiB plus allowance for multipart framing)"
1726+
example: "request body exceeds maximum upload size (32 MiB plus allowance for multipart framing)"
17271727

17281728
Unauthorized:
17291729
description: Unauthorized

packages/automl/bff/internal/api/s3_handler.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func (app *App) PostS3FileHandler(w http.ResponseWriter, r *http.Request, _ http
273273
mr, err := r.MultipartReader()
274274
if err != nil {
275275
if isS3PostRequestBodyTooLarge(err) {
276-
app.payloadTooLargeResponse(w, r, "request body exceeds maximum upload size (1 GiB plus allowance for multipart framing)")
276+
app.payloadTooLargeResponse(w, r, s3PayloadTooLargeMsg)
277277
return
278278
}
279279
app.badRequestResponse(w, r, fmt.Errorf("failed to parse multipart request: %w", err))
@@ -292,7 +292,7 @@ func (app *App) PostS3FileHandler(w http.ResponseWriter, r *http.Request, _ http
292292
}
293293
if nextErr != nil {
294294
if isS3PostRequestBodyTooLarge(nextErr) {
295-
app.payloadTooLargeResponse(w, r, "request body exceeds maximum upload size (1 GiB plus allowance for multipart framing)")
295+
app.payloadTooLargeResponse(w, r, s3PayloadTooLargeMsg)
296296
return
297297
}
298298
app.badRequestResponse(w, r, fmt.Errorf("reading multipart: %w", nextErr))
@@ -305,7 +305,7 @@ func (app *App) PostS3FileHandler(w http.ResponseWriter, r *http.Request, _ http
305305
_, copyErr := io.Copy(io.Discard, part)
306306
if copyErr != nil {
307307
if isS3PostRequestBodyTooLarge(copyErr) {
308-
app.payloadTooLargeResponse(w, r, "request body exceeds maximum upload size (1 GiB plus allowance for multipart framing)")
308+
app.payloadTooLargeResponse(w, r, s3PayloadTooLargeMsg)
309309
return
310310
}
311311
app.badRequestResponse(w, r, fmt.Errorf("reading multipart: %w", copyErr))
@@ -333,7 +333,7 @@ func (app *App) PostS3FileHandler(w http.ResponseWriter, r *http.Request, _ http
333333
if err := s3.client.UploadObject(ctx, bucket, resolvedKey, limitedFile, contentType); err != nil {
334334
var maxBytesErr *http.MaxBytesError
335335
if errors.As(err, &maxBytesErr) {
336-
app.payloadTooLargeResponse(w, r, "file exceeds maximum size of 1 GiB")
336+
app.payloadTooLargeResponse(w, r, s3FilePartTooLargeMsg)
337337
return
338338
}
339339
if errors.Is(err, s3int.ErrObjectAlreadyExists) {
@@ -432,7 +432,7 @@ func splitStemAndNextIndex(stem string) (base string, nextIndex int) {
432432
func (app *App) rejectDeclaredOversizedS3Post(next httprouter.Handle) httprouter.Handle {
433433
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
434434
if app.s3PostDeclaredBodyExceedsLimit(r) {
435-
app.payloadTooLargeResponse(w, r, "request body exceeds maximum upload size (1 GiB plus allowance for multipart framing)")
435+
app.payloadTooLargeResponse(w, r, s3PayloadTooLargeMsg)
436436
return
437437
}
438438
next(w, r, ps)

packages/automl/bff/internal/api/s3_upload_limit.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ package api
22

33
import "net/http"
44

5-
// s3MaxUploadFileBytes is the maximum allowed size for the uploaded file (1 GiB).
6-
const s3MaxUploadFileBytes int64 = 1 << 30
5+
// s3MaxUploadFileBytes is the maximum allowed size for the uploaded file (32 MiB).
6+
const s3MaxUploadFileBytes int64 = 32 << 20
77

88
// s3MultipartMaxEnvelopeBytes is headroom for multipart boundaries and non-file form fields.
99
const s3MultipartMaxEnvelopeBytes int64 = 64 << 20 // 64 MiB
1010

11+
// s3PayloadTooLargeMsg is the error message when the total request body exceeds the maximum allowed size.
12+
const s3PayloadTooLargeMsg = "request body exceeds maximum upload size (32 MiB plus allowance for multipart framing)"
13+
14+
// s3FilePartTooLargeMsg is the error message when the file part exceeds the maximum allowed size.
15+
const s3FilePartTooLargeMsg = "file exceeds maximum size of 32 MiB"
16+
1117
// s3PostMaxTotalBodyBytes is the maximum allowed size of the entire POST body (multipart framing
1218
// plus all parts). Matches rejectDeclaredOversizedS3Post and the MaxBytesReader wrapping r.Body
1319
// before MultipartReader so chunked uploads cannot stream unbounded while skipping non-file parts.

0 commit comments

Comments
 (0)