diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5162b48279b24ef03741764cf43de811b82e879f..eb47e65060cc1b09ca646b9e200926eb98b6e4a2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,7 +28,6 @@ default:
   tags:
     - "nixos"
     - "shell"
-  stage: "build"
 
 variables:
   # https://docs.gitlab.com/ee/ci/runners/configure_runners.html#job-stages-attempts
@@ -36,6 +35,7 @@ variables:
 
 docs:
   <<: *RUN_ON_MERGE_REQUEST
+  stage: "build"
   script:
     - "nix-build --attr docs --out-link result-docs"
     # GitLab wants to lchown artifacts.  It can't do that to store paths.  Get
@@ -48,14 +48,14 @@ docs:
 
 unit-tests:
   <<: *RUN_ON_MERGE_REQUEST
+  stage: "build"
   script:
     - "nix-build --attr unit-tests && cat result"
 
 .morph-build: &MORPH_BUILD
   <<: *RUN_ON_MERGE_REQUEST
-
   timeout: "3 hours"
-
+  stage: "build"
   script:
     - |
       # GRID is set in one of the "instantiations" of this job template.
@@ -87,6 +87,7 @@ morph-build-production:
 
 vulnerability-scan:
   <<: *RUN_ON_MERGE_REQUEST
+  stage: "build"
   script:
     - "ci-tools/vulnerability-scan security-report.json"
     - "ci-tools/count-vulnerabilities <security-report.json"
@@ -99,11 +100,13 @@ vulnerability-scan:
 system-tests:
   <<: *RUN_ON_MERGE_REQUEST
   timeout: "3 hours"
+  stage: "build"
   script:
     - "nix-build --attr system-tests"
 
 # A template for a job that can update one of the grids.
 .update-grid: &UPDATE_GRID
+  stage: "deploy"
   script: |
     env --ignore-environment - \
       NIX_PATH="$NIX_PATH" \