about summary refs log tree commit diff
path: root/pkgs/applications/version-management/gitlab
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/applications/version-management/gitlab')
-rw-r--r--pkgs/applications/version-management/gitlab/data.json32
-rw-r--r--pkgs/applications/version-management/gitlab/default.nix34
-rw-r--r--pkgs/applications/version-management/gitlab/gitaly/Gemfile30
-rw-r--r--pkgs/applications/version-management/gitlab/gitaly/Gemfile.lock170
-rw-r--r--pkgs/applications/version-management/gitlab/gitaly/default.nix41
-rw-r--r--pkgs/applications/version-management/gitlab/gitaly/gemset.nix562
-rw-r--r--pkgs/applications/version-management/gitlab/gitlab-shell/default.nix45
-rw-r--r--pkgs/applications/version-management/gitlab/gitlab-shell/remove-hardcoded-locations.patch45
-rw-r--r--pkgs/applications/version-management/gitlab/gitlab-workhorse/default.nix27
-rw-r--r--pkgs/applications/version-management/gitlab/gitlab-workhorse/remove-hardcoded-paths.patch12
-rwxr-xr-xpkgs/applications/version-management/gitlab/update.py234
11 files changed, 1212 insertions, 20 deletions
diff --git a/pkgs/applications/version-management/gitlab/data.json b/pkgs/applications/version-management/gitlab/data.json
new file mode 100644
index 000000000000..e2be6fb2a908
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/data.json
@@ -0,0 +1,32 @@
+{
+  "ce": {
+    "version": "11.5.0",
+    "repo_hash": "0cjkkap3n9g9zahrxk99a330ahyb6cvx97dsnrxcdsn0cbrsxsrb",
+    "deb_hash": "0kn7mg1lk4gvc3x76z4rbh0j03b0wk6x1p5938wx8sc50k0bgrcp",
+    "deb_url": "https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/stretch/gitlab-ce_11.5.0-ce.0_amd64.deb/download.deb",
+    "owner": "gitlab-org",
+    "repo": "gitlab-ce",
+    "rev": "v11.5.0",
+    "passthru": {
+      "GITALY_SERVER_VERSION": "0.129.0",
+      "GITLAB_PAGES_VERSION": "1.3.0",
+      "GITLAB_SHELL_VERSION": "8.4.1",
+      "GITLAB_WORKHORSE_VERSION": "7.1.0"
+    }
+  },
+  "ee": {
+    "version": "11.5.0",
+    "repo_hash": "1s2jr7vhbpklpcfjxgxnmq0zq14hh2aa6akdsb7ld7fj5lmzp00z",
+    "deb_hash": "108mgmlf947h200qrwg71ilhq5ihr4awxns6lqs2wa90ph9yq25c",
+    "deb_url": "https://packages.gitlab.com/gitlab/gitlab-ee/packages/debian/stretch/gitlab-ee_11.5.0-ee.0_amd64.deb/download.deb",
+    "owner": "gitlab-org",
+    "repo": "gitlab-ee",
+    "rev": "v11.5.0-ee",
+    "passthru": {
+      "GITALY_SERVER_VERSION": "0.129.0",
+      "GITLAB_PAGES_VERSION": "1.3.0",
+      "GITLAB_SHELL_VERSION": "8.4.1",
+      "GITLAB_WORKHORSE_VERSION": "7.1.0"
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkgs/applications/version-management/gitlab/default.nix b/pkgs/applications/version-management/gitlab/default.nix
index c1c4d20feacb..2ffe1141b5a0 100644
--- a/pkgs/applications/version-management/gitlab/default.nix
+++ b/pkgs/applications/version-management/gitlab/default.nix
@@ -11,32 +11,22 @@ let
     groups = [ "default" "unicorn" "ed25519" "metrics" ];
   };
 
-  version = "11.4.4";
+  flavour = if gitlabEnterprise then "ee" else "ce";
+  data = (builtins.fromJSON (builtins.readFile ./data.json)).${flavour};
 
-  sources = if gitlabEnterprise then {
-    gitlabDeb = fetchurl {
-      url = "https://packages.gitlab.com/gitlab/gitlab-ee/packages/debian/stretch/gitlab-ee_${version}-ee.0_amd64.deb/download.deb";
-      sha256 = "15lpcdjcw6lpmzlhqnpd6pgaxh7wvx2mldjd1vqr414r4bcnhgy4";
-    };
+  version = data.version;
+  sources = {
     gitlab = fetchFromGitLab {
-      owner = "gitlab-org";
-      repo = "gitlab-ee";
-      rev = "v${version}-ee";
-      sha256 = "046hchr7q4jnx3j4yxg3rdixfzlva35al3ci26pf9vxrbbl5y8cg";
+      owner = data.owner;
+      repo = data.repo;
+      rev = data.rev;
+      sha256 = data.repo_hash;
     };
-  } else {
     gitlabDeb = fetchurl {
-      url = "https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/stretch/gitlab-ce_${version}-ce.0_amd64.deb/download.deb";
-      sha256 = "02p7azyjgb984bk491q6f4zk1mikbcd38rif08kl07bjjzzkir81";
-    };
-    gitlab = fetchFromGitLab {
-      owner = "gitlab-org";
-      repo = "gitlab-ce";
-      rev = "v${version}";
-      sha256 = "1hq9iyp0xrxwmncn61ja3pdj9h2hmdy1l63d1ic3r1dyacybaf2g";
+      url = data.deb_url;
+      sha256 = data.deb_hash;
     };
   };
-
 in
 
 stdenv.mkDerivation rec {
@@ -101,6 +91,10 @@ stdenv.mkDerivation rec {
   passthru = {
     inherit rubyEnv;
     ruby = rubyEnv.wrappedRuby;
+    GITALY_SERVER_VERSION = data.passthru.GITALY_SERVER_VERSION;
+    GITLAB_PAGES_VERSION = data.passthru.GITLAB_PAGES_VERSION;
+    GITLAB_SHELL_VERSION = data.passthru.GITLAB_SHELL_VERSION;
+    GITLAB_WORKHORSE_VERSION = data.passthru.GITLAB_WORKHORSE_VERSION;
   };
 
   meta = with lib; {
diff --git a/pkgs/applications/version-management/gitlab/gitaly/Gemfile b/pkgs/applications/version-management/gitlab/gitaly/Gemfile
new file mode 100644
index 000000000000..016f80284da9
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitaly/Gemfile
@@ -0,0 +1,30 @@
+source 'https://rubygems.org'
+
+# Require bundler >= 1.16.5 to avoid this bug: https://github.com/bundler/bundler/issues/6537
+gem 'bundler', '>= 1.16.5'
+
+gem 'rugged', '~> 0.27'
+gem 'github-linguist', '~> 6.1', require: 'linguist'
+gem 'gitlab-markup', '~> 1.6.4'
+gem 'gitaly-proto', '~> 0.123.0', require: 'gitaly'
+gem 'activesupport', '~> 5.0.2'
+gem 'rdoc', '~> 4.2'
+gem 'gitlab-gollum-lib', '~> 4.2', require: false
+gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
+gem 'grpc', '~> 1.15.0'
+gem 'sentry-raven', '~> 2.7.2', require: false
+gem 'faraday', '~> 0.12'
+
+# Detects the open source license the repository includes
+# This version needs to be in sync with GitLab CE/EE
+gem 'licensee', '~> 8.9.0'
+
+gem 'google-protobuf', '~> 3.6'
+
+group :development, :test do
+  gem 'rubocop', '~> 0.50', require: false
+  gem 'rspec', require: false
+  gem 'rspec-parameterized', require: false
+  gem 'timecop', require: false
+  gem 'factory_bot', require: false
+end
diff --git a/pkgs/applications/version-management/gitlab/gitaly/Gemfile.lock b/pkgs/applications/version-management/gitlab/gitaly/Gemfile.lock
new file mode 100644
index 000000000000..0340853524b0
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitaly/Gemfile.lock
@@ -0,0 +1,170 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    abstract_type (0.0.7)
+    activesupport (5.0.6)
+      concurrent-ruby (~> 1.0, >= 1.0.2)
+      i18n (~> 0.7)
+      minitest (~> 5.1)
+      tzinfo (~> 1.1)
+    adamantium (0.2.0)
+      ice_nine (~> 0.11.0)
+      memoizable (~> 0.4.0)
+    ast (2.4.0)
+    binding_of_caller (0.8.0)
+      debug_inspector (>= 0.0.1)
+    charlock_holmes (0.7.6)
+    coderay (1.1.2)
+    concord (0.1.5)
+      adamantium (~> 0.2.0)
+      equalizer (~> 0.0.9)
+    concurrent-ruby (1.0.5)
+    crass (1.0.4)
+    debug_inspector (0.0.3)
+    diff-lcs (1.3)
+    equalizer (0.0.11)
+    escape_utils (1.2.1)
+    factory_bot (4.11.1)
+      activesupport (>= 3.0.0)
+    faraday (0.15.3)
+      multipart-post (>= 1.2, < 3)
+    gemojione (3.3.0)
+      json
+    gitaly-proto (0.123.0)
+      grpc (~> 1.0)
+    github-linguist (6.2.0)
+      charlock_holmes (~> 0.7.6)
+      escape_utils (~> 1.2.0)
+      mime-types (>= 1.19)
+      rugged (>= 0.25.1)
+    github-markup (1.7.0)
+    gitlab-gollum-lib (4.2.7.5)
+      gemojione (~> 3.2)
+      github-markup (~> 1.6)
+      gollum-grit_adapter (~> 1.0)
+      nokogiri (>= 1.6.1, < 2.0)
+      rouge (~> 3.1)
+      sanitize (~> 4.6.4)
+      stringex (~> 2.6)
+    gitlab-gollum-rugged_adapter (0.4.4.1)
+      mime-types (>= 1.15)
+      rugged (~> 0.25)
+    gitlab-grit (2.8.2)
+      charlock_holmes (~> 0.6)
+      diff-lcs (~> 1.1)
+      mime-types (>= 1.16)
+      posix-spawn (~> 0.3)
+    gitlab-markup (1.6.4)
+    gollum-grit_adapter (1.0.1)
+      gitlab-grit (~> 2.7, >= 2.7.1)
+    google-protobuf (3.6.1)
+    googleapis-common-protos-types (1.0.2)
+      google-protobuf (~> 3.0)
+    grpc (1.15.0)
+      google-protobuf (~> 3.1)
+      googleapis-common-protos-types (~> 1.0.0)
+    i18n (0.8.1)
+    ice_nine (0.11.2)
+    json (2.1.0)
+    licensee (8.9.2)
+      rugged (~> 0.24)
+    memoizable (0.4.2)
+      thread_safe (~> 0.3, >= 0.3.1)
+    mime-types (3.2.2)
+      mime-types-data (~> 3.2015)
+    mime-types-data (3.2018.0812)
+    mini_portile2 (2.3.0)
+    minitest (5.9.1)
+    multipart-post (2.0.0)
+    nokogiri (1.8.4)
+      mini_portile2 (~> 2.3.0)
+    nokogumbo (1.5.0)
+      nokogiri
+    parallel (1.12.1)
+    parser (2.5.1.2)
+      ast (~> 2.4.0)
+    posix-spawn (0.3.13)
+    powerpack (0.1.2)
+    proc_to_ast (0.1.0)
+      coderay
+      parser
+      unparser
+    procto (0.0.3)
+    rainbow (3.0.0)
+    rdoc (4.3.0)
+    rouge (3.3.0)
+    rspec (3.7.0)
+      rspec-core (~> 3.7.0)
+      rspec-expectations (~> 3.7.0)
+      rspec-mocks (~> 3.7.0)
+    rspec-core (3.7.1)
+      rspec-support (~> 3.7.0)
+    rspec-expectations (3.7.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.7.0)
+    rspec-mocks (3.7.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.7.0)
+    rspec-parameterized (0.4.0)
+      binding_of_caller
+      parser
+      proc_to_ast
+      rspec (>= 2.13, < 4)
+      unparser
+    rspec-support (3.7.1)
+    rubocop (0.54.0)
+      parallel (~> 1.10)
+      parser (>= 2.5)
+      powerpack (~> 0.1)
+      rainbow (>= 2.2.2, < 4.0)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (~> 1.0, >= 1.0.1)
+    ruby-progressbar (1.10.0)
+    rugged (0.27.5)
+    sanitize (4.6.6)
+      crass (~> 1.0.2)
+      nokogiri (>= 1.4.4)
+      nokogumbo (~> 1.4)
+    sentry-raven (2.7.2)
+      faraday (>= 0.7.6, < 1.0)
+    stringex (2.8.4)
+    thread_safe (0.3.6)
+    timecop (0.9.1)
+    tzinfo (1.2.2)
+      thread_safe (~> 0.1)
+    unicode-display_width (1.4.0)
+    unparser (0.2.8)
+      abstract_type (~> 0.0.7)
+      adamantium (~> 0.2.0)
+      concord (~> 0.1.5)
+      diff-lcs (~> 1.3)
+      equalizer (~> 0.0.9)
+      parser (>= 2.3.1.2, < 2.6)
+      procto (~> 0.0.2)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 5.0.2)
+  bundler (>= 1.16.5)
+  factory_bot
+  faraday (~> 0.12)
+  gitaly-proto (~> 0.123.0)
+  github-linguist (~> 6.1)
+  gitlab-gollum-lib (~> 4.2)
+  gitlab-gollum-rugged_adapter (~> 0.4.4)
+  gitlab-markup (~> 1.6.4)
+  google-protobuf (~> 3.6)
+  grpc (~> 1.15.0)
+  licensee (~> 8.9.0)
+  rdoc (~> 4.2)
+  rspec
+  rspec-parameterized
+  rubocop (~> 0.50)
+  rugged (~> 0.27)
+  sentry-raven (~> 2.7.2)
+  timecop
+
+BUNDLED WITH
+   1.17.1
diff --git a/pkgs/applications/version-management/gitlab/gitaly/default.nix b/pkgs/applications/version-management/gitlab/gitaly/default.nix
new file mode 100644
index 000000000000..951dbf0bf25a
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitaly/default.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchFromGitLab, buildGoPackage, ruby, bundlerEnv }:
+
+let
+  rubyEnv = bundlerEnv {
+    name = "gitaly-env";
+    inherit ruby;
+    gemdir = ./.;
+  };
+in buildGoPackage rec {
+  version = "0.129.0";
+  name = "gitaly-${version}";
+
+  src = fetchFromGitLab {
+    owner = "gitlab-org";
+    repo = "gitaly";
+    rev = "v${version}";
+    sha256 = "0lidqa0w0vy87p5xfmqrfvbyzvl9wj2p918qs2f5rc7shzm38rn6";
+  };
+
+  goPackagePath = "gitlab.com/gitlab-org/gitaly";
+
+  passthru = {
+    inherit rubyEnv;
+  };
+
+  buildInputs = [ rubyEnv.wrappedRuby ];
+
+  postInstall = ''
+    mkdir -p $ruby
+    cp -rv $src/ruby/{bin,lib} $ruby
+  '';
+
+  outputs = [ "bin" "out" "ruby" ];
+
+  meta = with stdenv.lib; {
+    homepage = http://www.gitlab.com/;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ roblabla ];
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/applications/version-management/gitlab/gitaly/gemset.nix b/pkgs/applications/version-management/gitlab/gitaly/gemset.nix
new file mode 100644
index 000000000000..9bf5601bf634
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitaly/gemset.nix
@@ -0,0 +1,562 @@
+{
+  abstract_type = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "09330cmhrc2wmfhdj9zzg82sv6cdhm3qgdkva5ni5xfjril2pf14";
+      type = "gem";
+    };
+    version = "0.0.7";
+  };
+  activesupport = {
+    dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0g85lqq0smj71g8a2dxb54ajjzw59c9snana4p61knryc83q3yg6";
+      type = "gem";
+    };
+    version = "5.0.6";
+  };
+  adamantium = {
+    dependencies = ["ice_nine" "memoizable"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0165r2ikgfwv2rm8dzyijkp74fvg0ni72hpdx8ay2v7cj08dqyak";
+      type = "gem";
+    };
+    version = "0.2.0";
+  };
+  ast = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "184ssy3w93nkajlz2c70ifm79jp3j737294kbc5fjw69v1w0n9x7";
+      type = "gem";
+    };
+    version = "2.4.0";
+  };
+  binding_of_caller = {
+    dependencies = ["debug_inspector"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05syqlks7463zsy1jdfbbdravdhj9hpj5pv2m74blqpv8bq4vv5g";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+  charlock_holmes = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nf1l31n10yaark2rrg5qzyzcx9w80681449s3j09qmnipsl8rl5";
+      type = "gem";
+    };
+    version = "0.7.6";
+  };
+  coderay = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15vav4bhcc2x3jmi3izb11l4d9f3xv8hp2fszb7iqmpsccv1pz4y";
+      type = "gem";
+    };
+    version = "1.1.2";
+  };
+  concord = {
+    dependencies = ["adamantium" "equalizer"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1b6cdn0fg4n9gzbdr7zyf4jq40y6h0c0g9cra7wk9hhmsylk91bg";
+      type = "gem";
+    };
+    version = "0.1.5";
+  };
+  concurrent-ruby = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf";
+      type = "gem";
+    };
+    version = "1.0.5";
+  };
+  crass = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bpxzy6gjw9ggjynlxschbfsgmx8lv3zw1azkjvnb8b9i895dqfi";
+      type = "gem";
+    };
+    version = "1.0.4";
+  };
+  debug_inspector = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0vxr0xa1mfbkfcrn71n7c4f2dj7la5hvphn904vh20j3x4j5lrx0";
+      type = "gem";
+    };
+    version = "0.0.3";
+  };
+  diff-lcs = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "18w22bjz424gzafv6nzv98h0aqkwz3d9xhm7cbr1wfbyas8zayza";
+      type = "gem";
+    };
+    version = "1.3";
+  };
+  equalizer = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1kjmx3fygx8njxfrwcmn7clfhjhb6bvv3scy2lyyi0wqyi3brra4";
+      type = "gem";
+    };
+    version = "0.0.11";
+  };
+  escape_utils = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qminivnyzwmqjhrh3b92halwbk0zcl9xn828p5rnap1szl2yag5";
+      type = "gem";
+    };
+    version = "1.2.1";
+  };
+  factory_bot = {
+    dependencies = ["activesupport"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13q1b7imb591068plg4ashgsqgzarvfjz6xxn3jk6klzikz5zhg1";
+      type = "gem";
+    };
+    version = "4.11.1";
+  };
+  faraday = {
+    dependencies = ["multipart-post"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "16hwxc8v0z6gkanckjhx0ffgqmzpc4ywz4dfhxpjlz2mbz8d5m52";
+      type = "gem";
+    };
+    version = "0.15.3";
+  };
+  gemojione = {
+    dependencies = ["json"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ayk8r147k1s38nj18pwk76npx1p7jhi86silk800nj913pjvrhj";
+      type = "gem";
+    };
+    version = "3.3.0";
+  };
+  gitaly-proto = {
+    dependencies = ["grpc"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "16b9sdaimhcda401z2s7apf0nz6y0lxs74xhkwlz4jzf6ms44mgg";
+      type = "gem";
+    };
+    version = "0.123.0";
+  };
+  github-linguist = {
+    dependencies = ["charlock_holmes" "escape_utils" "mime-types" "rugged"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1fs0i5xxsl91hnfa17ipk8cwxrg84kjg9mzxvxkd4ykldfdp353y";
+      type = "gem";
+    };
+    version = "6.2.0";
+  };
+  github-markup = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "17g6g18gdjg63k75sfwiskjzl9i0hfcnrkcpb4fwrnb20v3jgswp";
+      type = "gem";
+    };
+    version = "1.7.0";
+  };
+  gitlab-gollum-lib = {
+    dependencies = ["gemojione" "github-markup" "gollum-grit_adapter" "nokogiri" "rouge" "sanitize" "stringex"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15h6a7lsfkm967d5dhjlbcm2lnl1l9akzvaq92qlxq40r5apw0kn";
+      type = "gem";
+    };
+    version = "4.2.7.5";
+  };
+  gitlab-gollum-rugged_adapter = {
+    dependencies = ["mime-types" "rugged"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "092i02k3kd4ghk1h1l5yrvi9b180dgfxrvwni26facb2kc9f3wbi";
+      type = "gem";
+    };
+    version = "0.4.4.1";
+  };
+  gitlab-grit = {
+    dependencies = ["charlock_holmes" "diff-lcs" "mime-types" "posix-spawn"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0xgs3l81ghlc5nm75n0pz7b2cj3hpscfq5iy27c483nnjn2v5mc4";
+      type = "gem";
+    };
+    version = "2.8.2";
+  };
+  gitlab-markup = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1v6w3z7smmkqnhphb4ghgpqg61vimflqzpszybji0li99f2k1jb6";
+      type = "gem";
+    };
+    version = "1.6.4";
+  };
+  gollum-grit_adapter = {
+    dependencies = ["gitlab-grit"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0fcibm63v1afc0fj5rki0mm51m7nndil4cjcjjvkh3yigfn4nr4b";
+      type = "gem";
+    };
+    version = "1.0.1";
+  };
+  google-protobuf = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "134d3ini9ymdwxpz445m28ss9x0m6vcpijcdkzvgk4n538wdmppf";
+      type = "gem";
+    };
+    version = "3.6.1";
+  };
+  googleapis-common-protos-types = {
+    dependencies = ["google-protobuf"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "01ds7g01pxqm3mg283xjzy0lhhvvhvzw3m7gf7szd1r7la4wf0qq";
+      type = "gem";
+    };
+    version = "1.0.2";
+  };
+  grpc = {
+    dependencies = ["google-protobuf" "googleapis-common-protos-types"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0m2wspnm1cfkmhlbp7yqv5bb4vsfh246cm0aavxra67aw4l8plhb";
+      type = "gem";
+    };
+    version = "1.15.0";
+  };
+  i18n = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1s6971zmjxszdrp59vybns9gzxpdxzdklakc5lp8nl4fx5kpxkbp";
+      type = "gem";
+    };
+    version = "0.8.1";
+  };
+  ice_nine = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nv35qg1rps9fsis28hz2cq2fx1i96795f91q4nmkm934xynll2x";
+      type = "gem";
+    };
+    version = "0.11.2";
+  };
+  json = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "01v6jjpvh3gnq6sgllpfqahlgxzj50ailwhj9b3cd20hi2dx0vxp";
+      type = "gem";
+    };
+    version = "2.1.0";
+  };
+  licensee = {
+    dependencies = ["rugged"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0w6d2smhg3kzcx4m2ii06akakypwhiglansk51bpx290hhc8h3pc";
+      type = "gem";
+    };
+    version = "8.9.2";
+  };
+  memoizable = {
+    dependencies = ["thread_safe"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0v42bvghsvfpzybfazl14qhkrjvx0xlmxz0wwqc960ga1wld5x5c";
+      type = "gem";
+    };
+    version = "0.4.2";
+  };
+  mime-types = {
+    dependencies = ["mime-types-data"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0fjxy1jm52ixpnv3vg9ld9pr9f35gy0jp66i1njhqjvmnvq0iwwk";
+      type = "gem";
+    };
+    version = "3.2.2";
+  };
+  mime-types-data = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "07wvp0aw2gjm4njibb70as6rh5hi1zzri5vky1q6jx95h8l56idc";
+      type = "gem";
+    };
+    version = "3.2018.0812";
+  };
+  mini_portile2 = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13d32jjadpjj6d2wdhkfpsmy68zjx90p49bgf8f7nkpz86r1fr11";
+      type = "gem";
+    };
+    version = "2.3.0";
+  };
+  minitest = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0300naf4ilpd9sf0k8si9h9sclkizaschn8bpnri5fqmvm9ybdbq";
+      type = "gem";
+    };
+    version = "5.9.1";
+  };
+  multipart-post = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "09k0b3cybqilk1gwrwwain95rdypixb2q9w65gd44gfzsd84xi1x";
+      type = "gem";
+    };
+    version = "2.0.0";
+  };
+  nokogiri = {
+    dependencies = ["mini_portile2"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1h9nml9h3m0mpvmh8jfnqvblnz5n5y3mmhgfc38avfmfzdrq9bgc";
+      type = "gem";
+    };
+    version = "1.8.4";
+  };
+  nokogumbo = {
+    dependencies = ["nokogiri"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "09qc1c7acv9qm48vk2kzvnrq4ij8jrql1cv33nmv2nwmlggy0jyj";
+      type = "gem";
+    };
+    version = "1.5.0";
+  };
+  parallel = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "01hj8v1qnyl5ndrs33g8ld8ibk0rbcqdpkpznr04gkbxd11pqn67";
+      type = "gem";
+    };
+    version = "1.12.1";
+  };
+  parser = {
+    dependencies = ["ast"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1zp89zg7iypncszxsjp8kiccrpbdf728jl449g6cnfkz990fyb5k";
+      type = "gem";
+    };
+    version = "2.5.1.2";
+  };
+  posix-spawn = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1pmxmpins57qrbr31bs3bm7gidhaacmrp4md6i962gvpq4gyfcjw";
+      type = "gem";
+    };
+    version = "0.3.13";
+  };
+  powerpack = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1r51d67wd467rpdfl6x43y84vwm8f5ql9l9m85ak1s2sp3nc5hyv";
+      type = "gem";
+    };
+    version = "0.1.2";
+  };
+  proc_to_ast = {
+    dependencies = ["coderay" "parser" "unparser"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "14c65w48bbzp5lh1cngqd1y25kqvfnq1iy49hlzshl12dsk3z9wj";
+      type = "gem";
+    };
+    version = "0.1.0";
+  };
+  procto = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13imvg1x50rz3r0yyfbhxwv72lbf7q28qx9l9nfbb91h2n9ch58c";
+      type = "gem";
+    };
+    version = "0.0.3";
+  };
+  rainbow = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bb2fpjspydr6x0s8pn1pqkzmxszvkfapv0p4627mywl7ky4zkhk";
+      type = "gem";
+    };
+    version = "3.0.0";
+  };
+  rdoc = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13ba2mhqqcsp3k97x3iz9x29xk26rv4561lfzzzibcy41vvj1n4c";
+      type = "gem";
+    };
+    version = "4.3.0";
+  };
+  rouge = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1digsi2s8wyzx8vsqcxasw205lg6s7izx8jypl8rrpjwshmv83ql";
+      type = "gem";
+    };
+    version = "3.3.0";
+  };
+  rspec = {
+    dependencies = ["rspec-core" "rspec-expectations" "rspec-mocks"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0134g96wzxjlig2gxzd240gm2dxfw8izcyi2h6hjmr40syzcyx01";
+      type = "gem";
+    };
+    version = "3.7.0";
+  };
+  rspec-core = {
+    dependencies = ["rspec-support"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0zvjbymx3avxm3lf8v4gka3a862vnaxldmwvp6767bpy48nhnvjj";
+      type = "gem";
+    };
+    version = "3.7.1";
+  };
+  rspec-expectations = {
+    dependencies = ["diff-lcs" "rspec-support"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1fw06wm8jdj8k7wrb8xmzj0fr1wjyb0ya13x31hidnyblm41hmvy";
+      type = "gem";
+    };
+    version = "3.7.0";
+  };
+  rspec-mocks = {
+    dependencies = ["diff-lcs" "rspec-support"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0b02ya3qhqgmcywqv4570dlhav70r656f7dmvwg89whpkq1z1xr3";
+      type = "gem";
+    };
+    version = "3.7.0";
+  };
+  rspec-parameterized = {
+    dependencies = ["binding_of_caller" "parser" "proc_to_ast" "rspec" "unparser"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0arynbr6cfjhccwc8gy2xf87nybdnncsnmfwknnh8s7d4mj730p0";
+      type = "gem";
+    };
+    version = "0.4.0";
+  };
+  rspec-support = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nl30xb6jmcl0awhqp6jycl01wdssblifwy921phfml70rd9flj1";
+      type = "gem";
+    };
+    version = "3.7.1";
+  };
+  rubocop = {
+    dependencies = ["parallel" "parser" "powerpack" "rainbow" "ruby-progressbar" "unicode-display_width"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "106y99lq0fg62k3vk1w5wwb4vq16pnh4l61skc82xck627z0h8is";
+      type = "gem";
+    };
+    version = "0.54.0";
+  };
+  ruby-progressbar = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1cv2ym3rl09svw8940ny67bav7b2db4ms39i4raaqzkf59jmhglk";
+      type = "gem";
+    };
+    version = "1.10.0";
+  };
+  rugged = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1jv4nw9hvlxp8hhhlllrfcznki82i50fp1sj65zsjllfl2bvz8x6";
+      type = "gem";
+    };
+    version = "0.27.5";
+  };
+  sanitize = {
+    dependencies = ["crass" "nokogiri" "nokogumbo"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0j4j2a2mkk1a70vbx959pvx0gvr1zb9snjwvsppwj28bp0p0b2bv";
+      type = "gem";
+    };
+    version = "4.6.6";
+  };
+  sentry-raven = {
+    dependencies = ["faraday"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yf2gysjw6sy1xcp2jw35z9cp83pwx33lq0qyvaqbs969j4993r4";
+      type = "gem";
+    };
+    version = "2.7.2";
+  };
+  stringex = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0c5dfrjzkskzfsdvwsviq4111rwwpbk9022nxwdidz014mky5vi1";
+      type = "gem";
+    };
+    version = "2.8.4";
+  };
+  thread_safe = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy";
+      type = "gem";
+    };
+    version = "0.3.6";
+  };
+  timecop = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0d7mm786180v4kzvn1f77rhfppsg5n0sq2bdx63x9nv114zm8jrp";
+      type = "gem";
+    };
+    version = "0.9.1";
+  };
+  tzinfo = {
+    dependencies = ["thread_safe"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1c01p3kg6xvy1cgjnzdfq45fggbwish8krd0h864jvbpybyx7cgx";
+      type = "gem";
+    };
+    version = "1.2.2";
+  };
+  unicode-display_width = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0040bsdpcmvp8w31lqi2s9s4p4h031zv52401qidmh25cgyh4a57";
+      type = "gem";
+    };
+    version = "1.4.0";
+  };
+  unparser = {
+    dependencies = ["abstract_type" "adamantium" "concord" "diff-lcs" "equalizer" "parser" "procto"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0rh1649846ac17av30x0b0v9l45v0x1j2y1i8m1a7xdd0v4sld0z";
+      type = "gem";
+    };
+    version = "0.2.8";
+  };
+}
\ No newline at end of file
diff --git a/pkgs/applications/version-management/gitlab/gitlab-shell/default.nix b/pkgs/applications/version-management/gitlab/gitlab-shell/default.nix
new file mode 100644
index 000000000000..c9f21047e5b6
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitlab-shell/default.nix
@@ -0,0 +1,45 @@
+{ stdenv, ruby, bundler, fetchFromGitLab, go }:
+
+stdenv.mkDerivation rec {
+  version = "8.4.1";
+  name = "gitlab-shell-${version}";
+
+  src = fetchFromGitLab {
+    owner = "gitlab-org";
+    repo = "gitlab-shell";
+    rev = "v${version}";
+    sha256 = "00jzrpdfqgrba2qi5ngc0g07p7gmip7my563hw542gg8l88d27xq";
+  };
+
+  buildInputs = [ ruby bundler go ];
+
+  patches = [ ./remove-hardcoded-locations.patch ];
+
+  installPhase = ''
+    ruby bin/compile
+    mkdir -p $out/
+    cp -R . $out/
+
+    # Nothing to install ATM for non-development but keeping the
+    # install command anyway in case that changes in the future:
+    export HOME=$(pwd)
+    bundle install -j4 --verbose --local --deployment --without development test
+  '';
+
+  # gitlab-shell will try to read its config relative to the source
+  # code by default which doesn't work in nixos because it's a
+  # read-only filesystem
+  postPatch = ''
+    substituteInPlace lib/gitlab_config.rb --replace \
+       "File.join(ROOT_PATH, 'config.yml')" \
+       "'/run/gitlab/shell-config.yml'"
+  '';
+
+  meta = with stdenv.lib; {
+    description = "SSH access and repository management app for GitLab";
+    homepage = http://www.gitlab.com/;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ fpletz globin ];
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/applications/version-management/gitlab/gitlab-shell/remove-hardcoded-locations.patch b/pkgs/applications/version-management/gitlab/gitlab-shell/remove-hardcoded-locations.patch
new file mode 100644
index 000000000000..6d29f5f9e6c5
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitlab-shell/remove-hardcoded-locations.patch
@@ -0,0 +1,45 @@
+diff --git a/go/internal/config/config.go b/go/internal/config/config.go
+index 435cb29..078c1df 100644
+--- a/go/internal/config/config.go
++++ b/go/internal/config/config.go
+@@ -2,7 +2,6 @@ package config
+ 
+ import (
+ 	"io/ioutil"
+-	"os"
+ 	"path"
+ 
+ 	yaml "gopkg.in/yaml.v2"
+@@ -26,16 +25,13 @@ type Config struct {
+ }
+ 
+ func New() (*Config, error) {
+-	dir, err := os.Getwd()
+-	if err != nil {
+-		return nil, err
+-	}
++	dir := "/run/gitlab"
+ 
+ 	return NewFromDir(dir)
+ }
+ 
+ func NewFromDir(dir string) (*Config, error) {
+-	return newFromFile(path.Join(dir, configFile))
++	return newFromFile(path.Join(dir, "shell-config.yml"))
+ }
+ 
+ func newFromFile(filename string) (*Config, error) {
+diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb
+index 57c70f5..700569b 100644
+--- a/lib/gitlab_shell.rb
++++ b/lib/gitlab_shell.rb
+@@ -187,7 +187,8 @@ class GitlabShell # rubocop:disable Metrics/ClassLength
+ 
+     args = [executable, gitaly_address, json_args]
+     # We use 'chdir: ROOT_PATH' to let the next executable know where config.yml is.
+-    Kernel.exec(env, *args, unsetenv_others: true, chdir: ROOT_PATH)
++    # Except we don't, because we're already in the right directory on nixos!
++    Kernel.exec(env, *args, unsetenv_others: true)
+   end
+ 
+   def api
diff --git a/pkgs/applications/version-management/gitlab/gitlab-workhorse/default.nix b/pkgs/applications/version-management/gitlab/gitlab-workhorse/default.nix
new file mode 100644
index 000000000000..e77dbc323a3c
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitlab-workhorse/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchFromGitLab, git, go }:
+
+stdenv.mkDerivation rec {
+  name = "gitlab-workhorse-${version}";
+
+  version = "7.1.0";
+
+  src = fetchFromGitLab {
+    owner = "gitlab-org";
+    repo = "gitlab-workhorse";
+    rev = "v${version}";
+    sha256 = "1jq28z2kf58wnbv8jkwfx2bm8ki22hpm9ssdy2ymza22gq0zx00g";
+  };
+
+  buildInputs = [ git go ];
+
+  patches = [ ./remove-hardcoded-paths.patch ];
+
+  makeFlags = [ "PREFIX=$(out)" "VERSION=${version}" ];
+
+  meta = with stdenv.lib; {
+    homepage = http://www.gitlab.com/;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ fpletz globin ];
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/applications/version-management/gitlab/gitlab-workhorse/remove-hardcoded-paths.patch b/pkgs/applications/version-management/gitlab/gitlab-workhorse/remove-hardcoded-paths.patch
new file mode 100644
index 000000000000..d8313ecb433a
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/gitlab-workhorse/remove-hardcoded-paths.patch
@@ -0,0 +1,12 @@
+diff --git a/internal/git/command.go b/internal/git/command.go
+index 0e5496c..5778294 100644
+--- a/internal/git/command.go
++++ b/internal/git/command.go
+@@ -19,6 +19,7 @@ func gitCommand(gl_id string, name string, args ...string) *exec.Cmd {
+ 	cmd.Env = []string{
+ 		fmt.Sprintf("HOME=%s", os.Getenv("HOME")),
+ 		fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
++		fmt.Sprintf("GITLAB_SHELL_CONFIG_PATH=%s", os.Getenv("GITLAB_SHELL_CONFIG_PATH")),
+ 		fmt.Sprintf("LD_LIBRARY_PATH=%s", os.Getenv("LD_LIBRARY_PATH")),
+ 		fmt.Sprintf("GL_PROTOCOL=http"),
+ 	}
diff --git a/pkgs/applications/version-management/gitlab/update.py b/pkgs/applications/version-management/gitlab/update.py
new file mode 100755
index 000000000000..765f984fba5c
--- /dev/null
+++ b/pkgs/applications/version-management/gitlab/update.py
@@ -0,0 +1,234 @@
+#!/usr/bin/env nix-shell
+#! nix-shell -i python3 -p bundix common-updater-scripts nix nix-prefetch-git python3 python3Packages.requests python3Packages.lxml python3Packages.click python3Packages.click-log
+
+import click
+import click_log
+import os
+import re
+import logging
+import subprocess
+import json
+import pathlib
+from typing import Iterable
+
+import requests
+from xml.etree import ElementTree
+
+logger = logging.getLogger(__name__)
+
+
+class GitLabRepo:
+    def __init__(self, owner: str, repo: str):
+        self.owner = owner
+        self.repo = repo
+
+    @property
+    def url(self):
+        return f"https://gitlab.com/{self.owner}/{self.repo}"
+
+    @property
+    def tags(self) -> Iterable[str]:
+        r = requests.get(self.url + "/tags?format=atom", stream=True)
+
+        tree = ElementTree.fromstring(r.content)
+        return sorted((e.text for e in tree.findall(
+            '{http://www.w3.org/2005/Atom}entry/{http://www.w3.org/2005/Atom}title')), reverse=True)
+
+    def get_git_hash(self, rev: str):
+        out = subprocess.check_output(['nix-prefetch-git', self.url, rev])
+        j = json.loads(out)
+        return j['sha256']
+
+    def get_deb_url(self, flavour: str, version: str, arch: str = 'amd64') -> str:
+        """
+        gitlab builds debian packages, which we currently need as we don't build the frontend on our own
+        this returns the url of a given flavour, version and arch
+        :param flavour: 'ce' or 'ee'
+        :param version: a version, without 'v' prefix and '-ee' suffix
+        :param arch: amd64
+        :return: url of the debian package
+        """
+        if self.owner != "gitlab-org" or self.repo not in ['gitlab-ce', 'gitlab-ee']:
+            raise Exception(f"don't know how to get deb_url for {self.url}")
+        return f"https://packages.gitlab.com/gitlab/gitlab-{flavour}/packages" + \
+               f"/debian/stretch/gitlab-{flavour}_{version}-{flavour}.0_{arch}.deb/download.deb"
+
+    def get_deb_hash(self, flavour: str, version: str) -> str:
+        out = subprocess.check_output(['nix-prefetch-url', self.get_deb_url(flavour, version)])
+        return out.decode('utf-8').strip()
+
+    @staticmethod
+    def rev2version(tag: str) -> str:
+        """
+        normalize a tag to a version number.
+        This obviously isn't very smart if we don't pass something that looks like a tag
+        :param tag: the tag to normalize
+        :return: a normalized version number
+        """
+        # strip v prefix
+        version = re.sub(r"^v", '', tag)
+        # strip -ee suffix
+        return re.sub(r"-ee$", '', version)
+
+    def get_file(self, filepath, rev):
+        """
+        returns file contents at a given rev
+        :param filepath: the path to the file, relative to the repo root
+        :param rev: the rev to fetch at
+        :return:
+        """
+        return requests.get(self.url + f"/raw/{rev}/{filepath}").text
+
+    def get_data(self, rev, flavour):
+        version = self.rev2version(rev)
+
+        passthru = {v: self.get_file(v, rev).strip() for v in ['GITALY_SERVER_VERSION', 'GITLAB_PAGES_VERSION',
+                                                               'GITLAB_SHELL_VERSION', 'GITLAB_WORKHORSE_VERSION']}
+        return dict(version=self.rev2version(rev),
+                    repo_hash=self.get_git_hash(rev),
+                    deb_hash=self.get_deb_hash(flavour, version),
+                    deb_url=self.get_deb_url(flavour, version),
+                    owner=self.owner,
+                    repo=self.repo,
+                    rev=rev,
+                    passthru=passthru)
+
+
+def _flavour2gitlabrepo(flavour: str):
+    if flavour not in ['ce', 'ee']:
+        raise Exception(f"unknown gitlab flavour: {flavour}, needs to be ce or ee")
+
+    owner = 'gitlab-org'
+    repo = 'gitlab-' + flavour
+
+    return GitLabRepo(owner, repo)
+
+
+def _update_data_json(filename: str, repo: GitLabRepo, rev: str, flavour: str):
+    flavour_data = repo.get_data(rev, flavour)
+
+    if not os.path.exists(filename):
+        with open(filename, 'w') as f:
+            json.dump({flavour: flavour_data}, f, indent=2)
+    else:
+        with open(filename, 'r+') as f:
+            data = json.load(f)
+            data[flavour] = flavour_data
+            f.seek(0)
+            json.dump(data, f, indent=2)
+
+
+def _get_data_json():
+    data_file_path = pathlib.Path(__file__).parent / 'data.json'
+    with open(data_file_path, 'r') as f:
+        return json.load(f)
+
+
+def _call_update_source_version(pkg, version):
+    """calls update-source-version from nixpkgs root dir"""
+    nixpkgs_path = pathlib.Path(__file__).parent / '../../../../'
+    return subprocess.check_output(['update-source-version', pkg, version], cwd=nixpkgs_path)
+
+
+@click_log.simple_verbosity_option(logger)
+@click.group()
+def cli():
+    pass
+
+
+@cli.command('update-data')
+@click.option('--rev', default='latest', help='The rev to use, \'latest\' points to the latest (stable) tag')
+@click.argument('flavour')
+def update_data(rev: str, flavour: str):
+    """Update data.nix for a selected flavour"""
+    r = _flavour2gitlabrepo(flavour)
+
+    if rev == 'latest':
+        # filter out pre and re releases
+        rev = next(filter(lambda x: not ('rc' in x or x.endswith('pre')), r.tags))
+    logger.debug(f"Using rev {rev}")
+
+    version = r.rev2version(rev)
+    logger.debug(f"Using version {version}")
+
+    data_file_path = pathlib.Path(__file__).parent / 'data.json'
+
+    _update_data_json(filename=data_file_path.as_posix(),
+                      repo=r,
+                      rev=rev,
+                      flavour=flavour)
+
+
+@cli.command('update-rubyenv')
+@click.argument('flavour')
+def update_rubyenv(flavour):
+    """Update rubyEnv-${flavour}"""
+    if flavour not in ['ce', 'ee']:
+        raise Exception(f"unknown gitlab flavour: {flavour}, needs to be ce or ee")
+
+    r = _flavour2gitlabrepo(flavour)
+    rubyenv_dir = pathlib.Path(__file__).parent / f"rubyEnv-{flavour}"
+
+    # load rev from data.json
+    data = _get_data_json()
+    rev = data[flavour]['rev']
+
+    for fn in ['Gemfile.lock', 'Gemfile']:
+        with open(rubyenv_dir / fn, 'w') as f:
+            f.write(r.get_file(fn, rev))
+
+    subprocess.check_output(['bundix'], cwd=rubyenv_dir)
+
+
+@cli.command('update-gitaly')
+def update_gitaly():
+    """Update gitaly"""
+    data = _get_data_json()
+    gitaly_server_version = data['ce']['passthru']['GITALY_SERVER_VERSION']
+    r = GitLabRepo('gitlab-org', 'gitaly')
+    rubyenv_dir = pathlib.Path(__file__).parent / 'gitaly'
+
+    for fn in ['Gemfile.lock', 'Gemfile']:
+        with open(rubyenv_dir / fn, 'w') as f:
+            f.write(r.get_file(f"ruby/{fn}", f"v{gitaly_server_version}"))
+
+    subprocess.check_output(['bundix'], cwd=rubyenv_dir)
+    # currently broken, as `gitaly.meta.position` returns
+    # pkgs/development/go-modules/generic/default.nix
+    # so update-source-version doesn't know where to update hashes
+    # _call_update_source_version('gitaly', gitaly_server_version)
+    gitaly_hash = r.get_git_hash(f"v{gitaly_server_version}")
+    click.echo(f"Please update gitaly/default.nix to version {gitaly_server_version} and hash {gitaly_hash}")
+
+
+
+@cli.command('update-gitlab-shell')
+def update_gitlab_shell():
+    """Update gitlab-shell"""
+    data = _get_data_json()
+    gitlab_shell_version = data['ce']['passthru']['GITLAB_SHELL_VERSION']
+    _call_update_source_version('gitlab-shell', gitlab_shell_version)
+
+
+@cli.command('update-gitlab-workhorse')
+def update_gitlab_workhorse():
+    """Update gitlab-shell"""
+    data = _get_data_json()
+    gitlab_workhorse_version = data['ce']['passthru']['GITLAB_WORKHORSE_VERSION']
+    _call_update_source_version('gitlab-workhorse', gitlab_workhorse_version)
+
+
+@cli.command('update-all')
+@click.pass_context
+def update_all(ctx):
+    """Update gitlab ce and ee data.nix and rubyenvs to the latest stable release"""
+    for flavour in ['ce', 'ee']:
+        ctx.invoke(update_data, rev='latest', flavour=flavour)
+        ctx.invoke(update_rubyenv, flavour=flavour)
+    ctx.invoke(update_gitaly)
+    ctx.invoke(update_gitlab_shell)
+    ctx.invoke(update_gitlab_workhorse)
+
+
+if __name__ == '__main__':
+    cli()