diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bc305a18156b193e47309f3e2d65c79491d49bc1..0ef5d8305488090ed82992a1990379018119eb26 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,7 @@ stages:
   - build-images
   - fixtures
   - lint
+  - test-frontend
   - test
   - post-test
   - review
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 2c644195222b0fc7ff698e54e840c74eba384ffa..8db7912d589a6b1cb747b8fecf995c7738893299 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -92,7 +92,6 @@ update-assets-compile-production-cache:
     - .update-cache-base
     - .assets-compile-cache-push
     - .shared:rules:update-cache
-  stage: prepare
   artifacts: {}  # This job's purpose is only to update the cache.
 
 update-assets-compile-test-cache:
@@ -101,7 +100,6 @@ update-assets-compile-test-cache:
     - .update-cache-base
     - .assets-compile-cache-push
     - .shared:rules:update-cache
-  stage: prepare
   artifacts: {}  # This job's purpose is only to update the cache.
 
 update-storybook-yarn-cache:
@@ -240,7 +238,7 @@ graphql-schema-dump:
   before_script:
     - !reference [.default-before_script, before_script]
     - yarn_install_script
-  stage: test
+  stage: test-frontend
 
 jest-build-cache:
   extends:
@@ -440,7 +438,7 @@ webpack-dev-server:
     - .yarn-cache
     - .repo-from-artifacts
     - .frontend:rules:default-frontend-jobs
-  stage: test
+  stage: test-frontend
   variables:
     WEBPACK_MEMORY_TEST: "true"
     WEBPACK_VENDOR_DLL: "true"
@@ -454,32 +452,12 @@ webpack-dev-server:
     paths:
       - webpack-dev-server.json
 
-bundle-size-review:
-  extends:
-    - .default-retry
-    - .default-utils-before_script
-    - .assets-compile-cache
-    - .repo-from-artifacts
-    - .frontend:rules:bundle-size-review
-  image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:danger
-  stage: test
-  needs:
-    - !reference [.repo-from-artifacts, needs]
-  script:
-    - yarn_install_script
-    - scripts/bundle_size_review
-  artifacts:
-    when: always
-    name: bundle-size-review
-    expire_in: 31d
-    paths:
-      - bundle-size-review/
-
 compile-storybook:
   extends:
     - .frontend-test-base
     - .storybook-yarn-cache
     - .frontend:rules:compile-storybook
+  stage: pages
   needs:
     - !reference [.repo-from-artifacts, needs]
     - !reference [.with-fixtures-needs, needs]
diff --git a/.gitlab/ci/includes/gitlab-com/danger-review.gitlab-ci.yml b/.gitlab/ci/includes/gitlab-com/danger-review.gitlab-ci.yml
index 6453936b6cbdb2c8593a5100afa69ff5d14adef5..15d50bb88c907c9535685caa9341f1a752368bb7 100644
--- a/.gitlab/ci/includes/gitlab-com/danger-review.gitlab-ci.yml
+++ b/.gitlab/ci/includes/gitlab-com/danger-review.gitlab-ci.yml
@@ -2,6 +2,7 @@ include:
   - component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.4.1
     inputs:
       job_image: "${DEFAULT_CI_IMAGE}"
+      job_stage: "preflight"
       # By default DANGER_DANGERFILE_PREFIX is not defined but allows JiHu to
       # use a different prefix.
       # See https://jihulab.com/gitlab-cn/gitlab/-/blob/main-jh/jh/.gitlab-ci.yml
diff --git a/.gitlab/ci/preflight.gitlab-ci.yml b/.gitlab/ci/preflight.gitlab-ci.yml
index ad8c3047396a11c07a205485489919ae892db4dd..e2132d3eeecb5f750a7575b107993c4df1051479 100644
--- a/.gitlab/ci/preflight.gitlab-ci.yml
+++ b/.gitlab/ci/preflight.gitlab-ci.yml
@@ -115,3 +115,21 @@ pipeline-tier-3:
   extends:
     - .pipeline-tier-base
     - .preflight:rules:pipeline-tier-3
+
+bundle-size-review:
+  extends:
+    - .default-retry
+    - .default-utils-before_script
+    - .assets-compile-cache
+    - .repo-from-artifacts
+    - .frontend:rules:bundle-size-review
+  stage: preflight
+  script:
+    - yarn_install_script
+    - scripts/bundle_size_review
+  artifacts:
+    when: always
+    name: bundle-size-review
+    expire_in: 31d
+    paths:
+      - bundle-size-review/
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index b525c0342ed9d772b721054d1b950f8d56be1ffa..214e35c6df7f0923f1723e063f3a62a5a551f0b7 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -102,6 +102,7 @@ qa:metadata-lint:
   extends:
     - .qa-job-base
     - .qa:rules:metadata-lint
+  stage: lint
   variables:
     QA_EXPORT_TEST_METRICS: "false"
     # Disable warnings in browserslist which can break on backports
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index 0acec43ca31a4003b276935930aadc73e7cdef3d..0ebe3c586193ad94b49028725f3c3ae1cbf68897 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -91,7 +91,7 @@ verify-tests-yml:
   extends:
     - .setup:rules:verify-tests-yml
   image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}ruby:${RUBY_VERSION}-alpine3.20
-  stage: test
+  stage: preflight
   needs: []
   script:
     - source scripts/utils.sh