diff --git a/gems/gitlab-housekeeper/README.md b/gems/gitlab-housekeeper/README.md
index a4793aea9a62d41ff2ce3faf60de9f1039e4f655..66c3f715787784d0d2ce063fe2faa08ba406ca87 100644
--- a/gems/gitlab-housekeeper/README.md
+++ b/gems/gitlab-housekeeper/README.md
@@ -69,6 +69,9 @@ module Keeps
 
         change.changed_files = [file_name]
 
+        # to push changes without triggering a pipeline.
+        change.push_options.ci_skip = true
+
         yield(change)
       end
     end
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
index 18551a9a2f87541cf6e0cc20e03c9df82f0f5bf4..f61377a841c417206b1a02776d83ee35cb46261a 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require 'gitlab/housekeeper/push_options'
+
 module Gitlab
   module Housekeeper
     class Change
@@ -10,12 +12,14 @@ class Change
         :labels,
         :keep_class,
         :changelog_type,
-        :mr_web_url
+        :mr_web_url,
+        :push_options
       attr_reader :reviewers
 
       def initialize
         @labels = []
         @reviewers = []
+        @push_options = PushOptions.new
       end
 
       def reviewers=(reviewers)
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/git.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/git.rb
index ab9d2555b76e18f6c598e7168f6895370aead819..8970eb9e5b7cb41d51abfe40a05e91b6279313dc 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/git.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/git.rb
@@ -2,6 +2,7 @@
 
 require 'logger'
 require 'gitlab/housekeeper/shell'
+require 'gitlab/housekeeper/push_options'
 
 module Gitlab
   module Housekeeper
@@ -46,8 +47,11 @@ def create_commit(change)
         Shell.execute("git", "commit", "-m", change.commit_message)
       end
 
-      def push(branch_name)
-        Shell.execute('git', 'push', '-f', housekeeper_remote, "#{branch_name}:#{branch_name}")
+      def push(branch_name, push_options = PushOptions.new)
+        push_command = ['git', 'push', '-f', housekeeper_remote, "#{branch_name}:#{branch_name}"]
+        push_command << '-o ci.skip' if push_options.ci_skip
+
+        Shell.execute(*push_command)
       end
 
       private
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/push_options.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/push_options.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad3c3466e6e5594cc7e8d1d8ba53c159a38c2926
--- /dev/null
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/push_options.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module Housekeeper
+    class PushOptions
+      attr_accessor :ci_skip
+
+      def initialize
+        @ci_skip = false
+      end
+    end
+  end
+end
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
index 3ce4da9a278b19cc53353b3f85009b87c53c8e4e..bd3624b56202a644642fa903c16ddebd27e5f8df 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
@@ -105,7 +105,10 @@ def require_keeps
       end
 
       def print_change_details(change, branch_name)
-        puts "Merge request URL: #{change.mr_web_url || '(known after create)'}, on branch #{branch_name}".yellowish
+        base_message = "Merge request URL: #{change.mr_web_url || '(known after create)'}, on branch #{branch_name}."
+        base_message << " CI skipped." if change.push_options.ci_skip
+
+        puts base_message.yellowish
         puts "=> #{change.identifiers.join(': ')}".purple
 
         puts '=> Title:'.purple
@@ -137,7 +140,7 @@ def create(change, branch_name)
           target_project_id: housekeeper_target_project_id
         )
 
-        git.push(branch_name) unless non_housekeeper_changes.include?(:code)
+        git.push(branch_name, change.push_options) unless non_housekeeper_changes.include?(:code)
 
         gitlab_client.create_or_update_merge_request(
           change: change,
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
index a4a2ed678d8a677b732315d0f500768bcf2ee32b..6bd99dde1a2ec72f56bd3da7bd76f4471a44cae7 100644
--- a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
@@ -17,6 +17,7 @@
 
       expect(change.labels).to eq([])
       expect(change.reviewers).to eq([])
+      expect(change.push_options.ci_skip).to eq(false)
     end
   end
 
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/git_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/git_spec.rb
index 3489b002d6e674d8b7da972ba200203a2623e618..38e567468900a0a8432d546b69d77c2247116e69 100644
--- a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/git_spec.rb
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/git_spec.rb
@@ -130,6 +130,8 @@ def setup_and_checkout_another_branch
   end
 
   describe '#push' do
+    let(:push_options) { ::Gitlab::Housekeeper::PushOptions.new }
+
     before do
       # Needed to check if remote exists
       allow(::Gitlab::Housekeeper::Shell).to receive(:execute)
@@ -152,7 +154,7 @@ def setup_and_checkout_another_branch
         expect(::Gitlab::Housekeeper::Shell).to receive(:execute)
           .with('git', 'push', '-f', 'housekeeper', 'the-branch-name:the-branch-name')
 
-        git.push('the-branch-name')
+        git.push('the-branch-name', push_options)
       end
     end
 
@@ -160,7 +162,18 @@ def setup_and_checkout_another_branch
       expect(::Gitlab::Housekeeper::Shell).to receive(:execute)
         .with('git', 'push', '-f', 'origin', 'the-branch-name:the-branch-name')
 
-      git.push('the-branch-name')
+      git.push('the-branch-name', push_options)
+    end
+
+    context 'with push options defined' do
+      it 'pushes with push options set' do
+        expect(::Gitlab::Housekeeper::Shell).to receive(:execute)
+          .with('git', 'push', '-f', 'origin', 'the-branch-name:the-branch-name', '-o ci.skip')
+
+        push_options.ci_skip = true
+
+        git.push('the-branch-name', push_options)
+      end
     end
   end
 end
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/push_options_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/push_options_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6dbb1274b77dab3ac64f4c8638d7824697a0db3c
--- /dev/null
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/push_options_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'gitlab/housekeeper/push_options'
+
+RSpec.describe ::Gitlab::Housekeeper::PushOptions do
+  describe '#initialize' do
+    it 'sets ci_skip to false by default' do
+      push_options = described_class.new
+      expect(push_options.ci_skip).to be false
+    end
+  end
+end
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/runner_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/runner_spec.rb
index 6acbf64a45d83feb06dba601a60d6753ea660f2e..d0b7521879aeecbc086ea45c2fd241e70b93e67f 100644
--- a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/runner_spec.rb
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/runner_spec.rb
@@ -95,12 +95,12 @@
         .with('git', '--no-pager', 'diff', '--color=always', 'master',
           'the-identifier-for-the-first-change', '--', 'change1.txt', 'change2.txt')
       expect(git).to receive(:push)
-        .with('the-identifier-for-the-first-change')
+        .with('the-identifier-for-the-first-change', change1.push_options)
       expect(::Gitlab::Housekeeper::Shell).to receive(:execute)
         .with('git', '--no-pager', 'diff', '--color=always', 'master',
           'the-identifier-for-the-second-change', '--', 'change1.txt', 'change2.txt')
       expect(git).to receive(:push)
-        .with('the-identifier-for-the-second-change')
+        .with('the-identifier-for-the-second-change', change2.push_options)
 
       # Merge requests get created
       expect(gitlab_client).to receive(:create_or_update_merge_request)
@@ -163,7 +163,7 @@
           .with('git', '--no-pager', 'diff', '--color=always', 'master',
             'the-identifier-for-the-second-change', '--', 'change1.txt', 'change2.txt')
         expect(git).to receive(:push)
-          .with('the-identifier-for-the-second-change')
+          .with('the-identifier-for-the-second-change', change2.push_options)
 
         # Merge requests get created
         expect(gitlab_client).to receive(:create_or_update_merge_request)
@@ -207,9 +207,9 @@
         expect(::Gitlab::Housekeeper::Substitutor).to receive(:perform).with(change2)
 
         expect(git).not_to receive(:push)
-          .with('the-identifier-for-the-first-change')
+          .with('the-identifier-for-the-first-change', change1.push_options)
         expect(git).to receive(:push)
-          .with('the-identifier-for-the-second-change')
+          .with('the-identifier-for-the-second-change', change2.push_options)
 
         expect(gitlab_client).to receive(:create_or_update_merge_request)
           .with(