1{ stdenv, lib, fetchurl, fetchpatch, fetchFromGitLab, bundlerEnv
2, ruby, tzdata, git, nettools, nixosTests, nodejs, openssl
3, gitlabEnterprise ? false, callPackage, yarn
4, fixup_yarn_lock, replace, file, cacert, fetchYarnDeps
5}:
6
7let
8 data = lib.importJSON ./data.json;
9
10 version = data.version;
11 src = fetchFromGitLab {
12 owner = data.owner;
13 repo = data.repo;
14 rev = data.rev;
15 sha256 = data.repo_hash;
16 };
17
18 rubyEnv = bundlerEnv rec {
19 name = "gitlab-env-${version}";
20 inherit ruby;
21 gemdir = ./rubyEnv;
22 gemset =
23 let x = import (gemdir + "/gemset.nix");
24 in x // {
25 # grpc expects the AR environment variable to contain `ar rpc`. See the
26 # discussion in nixpkgs #63056.
27 grpc = x.grpc // {
28 patches = [ ./fix-grpc-ar.patch ];
29 dontBuild = false;
30 };
31 # the openssl needs the openssl include files
32 openssl = x.openssl // {
33 buildInputs = [ openssl ];
34 };
35 ruby-magic = x.ruby-magic // {
36 buildInputs = [ file ];
37 buildFlags = [ "--enable-system-libraries" ];
38 };
39 # the included yarn rake task attaches the yarn:install task
40 # to assets:precompile, which is both unnecessary (since we
41 # run `yarn install` ourselves) and undoes the shebang patches
42 # in node_modules
43 railties = x.railties // {
44 dontBuild = false;
45 patches = [ ./railties-remove-yarn-install-enhancement.patch ];
46 patchFlags = "-p2";
47 };
48 };
49 groups = [
50 "default" "unicorn" "ed25519" "metrics" "development" "puma" "test" "kerberos"
51 ];
52 # N.B. omniauth_oauth2_generic and apollo_upload_server both provide a
53 # `console` executable.
54 ignoreCollisions = true;
55 };
56
57 yarnOfflineCache = fetchYarnDeps {
58 yarnLock = src + "/yarn.lock";
59 sha256 = data.yarn_hash;
60 };
61
62 assets = stdenv.mkDerivation {
63 pname = "gitlab-assets";
64 inherit version src;
65
66 nativeBuildInputs = [ rubyEnv.wrappedRuby rubyEnv.bundler nodejs yarn git cacert ];
67
68 # Since version 12.6.0, the rake tasks need the location of git,
69 # so we have to apply the location patches here too.
70 patches = [ ./remove-hardcoded-locations.patch ];
71 # One of the patches uses this variable - if it's unset, execution
72 # of rake tasks fails.
73 GITLAB_LOG_PATH = "log";
74 FOSS_ONLY = !gitlabEnterprise;
75
76 configurePhase = ''
77 runHook preConfigure
78
79 # Some rake tasks try to run yarn automatically, which won't work
80 rm lib/tasks/yarn.rake
81
82 # The rake tasks won't run without a basic configuration in place
83 mv config/database.yml.env config/database.yml
84 mv config/gitlab.yml.example config/gitlab.yml
85
86 # Yarn and bundler wants a real home directory to write cache, config, etc to
87 export HOME=$NIX_BUILD_TOP/fake_home
88
89 # Make yarn install packages from our offline cache, not the registry
90 yarn config --offline set yarn-offline-mirror ${yarnOfflineCache}
91
92 # Fixup "resolved"-entries in yarn.lock to match our offline cache
93 ${fixup_yarn_lock}/bin/fixup_yarn_lock yarn.lock
94
95 yarn install --offline --frozen-lockfile --ignore-scripts --no-progress --non-interactive
96
97 patchShebangs node_modules/
98
99 runHook postConfigure
100 '';
101
102 buildPhase = ''
103 runHook preBuild
104
105 bundle exec rake gettext:po_to_json RAILS_ENV=production NODE_ENV=production
106 bundle exec rake rake:assets:precompile RAILS_ENV=production NODE_ENV=production
107 bundle exec rake gitlab:assets:compile_webpack_if_needed RAILS_ENV=production NODE_ENV=production
108 bundle exec rake gitlab:assets:fix_urls RAILS_ENV=production NODE_ENV=production
109 bundle exec rake gitlab:assets:check_page_bundle_mixins_css_for_sideeffects RAILS_ENV=production NODE_ENV=production
110
111 runHook postBuild
112 '';
113
114 installPhase = ''
115 runHook preInstall
116
117 mv public/assets $out
118
119 runHook postInstall
120 '';
121 };
122in
123stdenv.mkDerivation {
124 name = "gitlab${lib.optionalString gitlabEnterprise "-ee"}-${version}";
125
126 inherit src;
127
128 buildInputs = [
129 rubyEnv rubyEnv.wrappedRuby rubyEnv.bundler tzdata git nettools
130 ];
131
132 patches = [
133 # Change hardcoded paths to the NixOS equivalent
134 ./remove-hardcoded-locations.patch
135 ];
136
137 postPatch = ''
138 ${lib.optionalString (!gitlabEnterprise) ''
139 # Remove all proprietary components
140 rm -rf ee
141 sed -i 's/-ee//' ./VERSION
142 ''}
143
144 # For reasons I don't understand "bundle exec" ignores the
145 # RAILS_ENV causing tests to be executed that fail because we're
146 # not installing development and test gems above. Deleting the
147 # tests works though.
148 rm lib/tasks/test.rake
149
150 rm config/initializers/gitlab_shell_secret_token.rb
151
152 sed -i '/ask_to_continue/d' lib/tasks/gitlab/two_factor.rake
153 sed -ri -e '/log_level/a config.logger = Logger.new(STDERR)' config/environments/production.rb
154
155 mv config/puma.rb.example config/puma.rb
156 # Always require lib-files and application.rb through their store
157 # path, not their relative state directory path. This gets rid of
158 # warnings and means we don't have to link back to lib from the
159 # state directory.
160 ${replace}/bin/replace-literal -f -r -e '../lib' "$out/share/gitlab/lib" config
161 ${replace}/bin/replace-literal -f -r -e "require_relative 'application'" "require_relative '$out/share/gitlab/config/application'" config
162 '';
163
164 buildPhase = ''
165 rm -f config/secrets.yml
166 mv config config.dist
167 rm -r tmp
168 '';
169
170 installPhase = ''
171 mkdir -p $out/share
172 cp -r . $out/share/gitlab
173 ln -sf ${assets} $out/share/gitlab/public/assets
174 rm -rf $out/share/gitlab/log
175 ln -sf /run/gitlab/log $out/share/gitlab/log
176 ln -sf /run/gitlab/uploads $out/share/gitlab/public/uploads
177 ln -sf /run/gitlab/config $out/share/gitlab/config
178 ln -sf /run/gitlab/tmp $out/share/gitlab/tmp
179
180 # rake tasks to mitigate CVE-2017-0882
181 # see https://about.gitlab.com/2017/03/20/gitlab-8-dot-17-dot-4-security-release/
182 cp ${./reset_token.rake} $out/share/gitlab/lib/tasks/reset_token.rake
183 '';
184
185 passthru = {
186 inherit rubyEnv assets;
187 ruby = rubyEnv.wrappedRuby;
188 GITALY_SERVER_VERSION = data.passthru.GITALY_SERVER_VERSION;
189 GITLAB_PAGES_VERSION = data.passthru.GITLAB_PAGES_VERSION;
190 GITLAB_SHELL_VERSION = data.passthru.GITLAB_SHELL_VERSION;
191 GITLAB_WORKHORSE_VERSION = data.passthru.GITLAB_WORKHORSE_VERSION;
192 gitlabEnv.FOSS_ONLY = lib.boolToString (!gitlabEnterprise);
193 tests = {
194 nixos-test-passes = nixosTests.gitlab;
195 };
196 };
197
198 meta = with lib; {
199 homepage = "http://www.gitlab.com/";
200 platforms = platforms.linux;
201 maintainers = with maintainers; [ fpletz globin krav talyz yayayayaka yuka ];
202 } // (if gitlabEnterprise then
203 {
204 license = licenses.unfreeRedistributable; # https://gitlab.com/gitlab-org/gitlab-ee/raw/master/LICENSE
205 description = "GitLab Enterprise Edition";
206 }
207 else
208 {
209 license = licenses.mit;
210 description = "GitLab Community Edition";
211 longDescription = "GitLab Community Edition (CE) is an open source end-to-end software development platform with built-in version control, issue tracking, code review, CI/CD, and more. Self-host GitLab CE on your own servers, in a container, or on a cloud provider.";
212 });
213}