diff --git a/Jenkinsfile b/Jenkinsfile
index c1a47c5749637b04b213ba4fa07cab0900b9bf77..9212ba6039704c09c1fe0469c1ee737bc21b3288 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -3,6 +3,14 @@
 // Note: To work on this script without having to push a commit each
 // time, use the jenkins-cli command (see:
 // https://wiki.savoirfairelinux.com/wiki/Jenkins.jami.net#Usage_CLI_de_Jenkins).
+//
+// Requirements:
+// 1. gerrit-trigger plugin
+// 2. ws-cleanup plugin
+
+// Configuration globals.
+def SUBMODULES = ['daemon', 'lrc', 'client-gnome', 'client-qt']
+
 pipeline {
     agent {
         label 'guix'
@@ -12,6 +20,12 @@ pipeline {
         string(name: 'GERRIT_REFSPEC',
                defaultValue: 'refs/heads/master',
                description: 'The Gerrit refspec to fetch.')
+        booleanParam(name: 'WITH_MANUAL_SUBMODULES',
+                     defaultValue: false,
+                     description: 'Checkout the ' + SUBMODULES.join(', ') +
+                     ' submodules at their Git-recorded commit.  When left ' +
+                     'unticked (the default), checkout the submodules at ' +
+                     'their latest commit from their main remote branch.')
         booleanParam(name: 'BUILD_OWN_QT',
                      defaultValue: false,
                      description: 'Whether to build our own Qt packages.')
@@ -45,9 +59,11 @@ See https://wiki.savoirfairelinux.com/wiki/Jenkins.jami.net#Configuration"
 
         stage('Fetch submodules') {
             steps {
-                echo 'Updating relevant submodules to their latest commit'
-                sh 'git submodule update --init --recursive --remote ' +
-                   'daemon lrc client-gnome client-qt'
+                echo 'Initializing submodules ' + SUBMODULES.join(', ') +
+                    (params.WITH_MANUAL_SUBMODULES ? '.' : ' to their latest commit.')
+                sh 'git submodule update --init --recursive' +
+                    (params.WITH_MANUAL_SUBMODULES ? ' ' : ' --remote ') +
+                    SUBMODULES.join(' ')
             }
         }
 
@@ -79,21 +95,22 @@ See https://wiki.savoirfairelinux.com/wiki/Jenkins.jami.net#Configuration"
                                          returnStdout: true).trim()
                     }
 
-                    def targets = targetsText.split(/\s/)
+                    TARGETS = targetsText.split(/\s/)
                     if (!params.BUILD_OWN_QT) {
-                        targets = targets.findAll { !it.endsWith('_qt') }
+                        TARGETS = TARGETS.findAll { !it.endsWith('_qt') }
                     }
                     if (!params.BUILD_ARM) {
-                        targets = targets.findAll { !(it =~ /_(armhf|arm64)$/) }
+                        TARGETS = TARGETS.findAll { !(it =~ /_(armhf|arm64)$/) }
                     }
 
+
                     def stages = [:]
 
-                    targets.each { target ->
+                    TARGETS.each { target ->
                         // Note: The stage calls are wrapped in closures, to
                         // delay their execution.
-                        stages["${target}"] =  {
-                            stage("${target}") {
+                        stages[target] =  {
+                            stage(target) {
                                 // Offload builds to different agents.
                                 node('linux-builder') {
                                     cleanWs()