diff --git a/contrib/heptapod-ci.yml b/contrib/heptapod-ci.yml
index 3f7c7a855af022d5ac4f9d26d74f0e5db86635d6_Y29udHJpYi9oZXB0YXBvZC1jaS55bWw=..b65f11f49375e034fe4583837c45c0144a6f080a_Y29udHJpYi9oZXB0YXBvZC1jaS55bWw= 100644
--- a/contrib/heptapod-ci.yml
+++ b/contrib/heptapod-ci.yml
@@ -20,6 +20,7 @@
       when: always
 
 stages:
+  - nightly-trigger
   - build
   - checks
   - tests
@@ -79,6 +80,17 @@
     - .dummy
   when: manual
 
+
+trigger-nightly-build:
+  extends: .trigger
+  stage: nightly-trigger
+  rules:
+    - if: $CI_COMMIT_BRANCH =~ $RE_BRANCH
+      when: manual
+      allow_failure: true
+    - if: $CI_COMMIT_BRANCH =~ $RE_TOPIC
+      when: never
+
 .build-wheel:
   extends: .all
   image: "registry.heptapod.net/mercurial/ci-images/core-wheel-x86_64-c:v3.0"
@@ -100,6 +112,7 @@
       - wheels/
     expire_in: 1 week
 
+
 build-c-wheel:
   extends: .build-wheel
   variables:
@@ -239,7 +252,15 @@
 trigger-pycompat:
   extends: .trigger
   stage: py-version-compat
+  rules:
+  - if: $CI_COMMIT_BRANCH =~ $RE_BRANCH
+    when: on_success
+    needs:
+      - trigger-nightly-build
+  - if: $CI_COMMIT_BRANCH =~ $RE_TOPIC
+    when: manual
+    allow_failure: true
 
 .test-c-pycompat:
     extends: .test-c
     stage: py-version-compat
@@ -242,9 +263,7 @@
 
 .test-c-pycompat:
     extends: .test-c
     stage: py-version-compat
-    needs:
-      - trigger-pycompat
     variables:
         WHEEL_TYPE: "c"
 
@@ -256,6 +275,7 @@
     variables:
         PYTHON: python3.8
     needs:
+      - job: trigger-pycompat
       - job: build-c-wheel
         parallel:
           matrix:
@@ -266,6 +286,7 @@
     variables:
         PYTHON: python3.12
     needs:
+      - job: trigger-pycompat
       - job: build-c-wheel
         parallel:
           matrix:
@@ -284,6 +305,7 @@
     variables:
         PYTHON: python3.13
     needs:
+      - job: trigger-pycompat
       - job: build-c-wheel
         parallel:
           matrix:
@@ -333,6 +355,12 @@
 trigger-wheel-windows:
   extends: .trigger
   stage: build
+  rules:
+  - if: $CI_COMMIT_BRANCH =~ $RE_BRANCH
+    when: never
+  - if: $CI_COMMIT_BRANCH =~ $RE_TOPIC
+    when: manual
+    allow_failure: true
 
 build-c-wheel-windows:
     extends: .windows
@@ -340,7 +368,13 @@
     # wait for someone to click on "trigger-wheel-windows"
     when: on_success
     needs:
-      - "trigger-wheel-windows"
+    rules:
+    - if: $CI_COMMIT_BRANCH =~ $RE_BRANCH
+      needs:
+        - trigger-nightly-build
+    - if: $CI_COMMIT_BRANCH =~ $RE_TOPIC
+      needs:
+        - "trigger-wheel-windows"
     variables:
       MERCURIAL_SETUP_FORCE_TRANSLATIONS: "1"
     script:
@@ -458,7 +492,13 @@
 # The weird directory structure match the one we use for Linux to deal with the
 # multiple jobs. (all this might be unnecessary)
 build-c-wheel-macos:
-    when: manual  # avoid overloading the CI by default
+    rules:
+    - if: $CI_COMMIT_BRANCH =~ $RE_BRANCH
+      needs:
+        - trigger-nightly-build
+    - if: $CI_COMMIT_BRANCH =~ $RE_TOPIC
+      when: manual  # avoid overloading the CI by default
+      allow_failure: true
     stage: build
     tags:
       - macos
@@ -494,9 +534,6 @@
       when: on_success
     - if: '$CI_COMMIT_BRANCH =~ $RE_TOPIC'
       when: never
-      # if you need to test this, make it
-      # when: manual
-      # allow_failure: true
 
 # a dummy job that gather greatly parallel object into one.
 #
@@ -505,6 +542,6 @@
 #
 .sink:
   extends:
-    - .nightly_build_sink
+    - .nightly_build_step
     - .dummy
 
@@ -509,6 +546,6 @@
     - .dummy
 
-linux-test-result:
+test-result-linux:
   extends: .sink
   needs:
     - test-c
@@ -516,8 +553,8 @@
     - test-3.12-c
     - test-3.13-c
 
-macos-test-result:
+test-result-macos:
   extends: .sink
   needs:
     - macos
 
@@ -520,8 +557,8 @@
   extends: .sink
   needs:
     - macos
 
-windows-test-result:
+test-result-windows:
   extends: .sink
   needs:
     - windows
@@ -544,9 +581,9 @@
     - build-c-wheel
     - build-c-wheel-macos
     - build-c-wheel-windows
-    - linux-test-result
-    - macos-test-result
-    - windows-test-result
+    - test-result-linux
+    - test-result-macos
+    - test-result-windows
   # It would be nice to be able to restrict that a bit to protected branch only
   variables:
     TWINE_USERNAME: gitlab-ci-token