1{
2 bundlerEnv,
3 cacert,
4 defaultGemConfig,
5 fetchFromGitLab,
6 fetchYarnDeps,
7 yarnConfigHook,
8 git,
9 gitlabEnterprise ? false,
10 lib,
11 makeWrapper,
12 net-tools,
13 nixosTests,
14 nodejs_20,
15 replace,
16 ruby_3_3,
17 stdenv,
18 tzdata,
19
20 # gem dependencies:
21 # gitlab-glfm-markdown
22 buildRubyGem,
23 cargo,
24 rustc,
25 rustPlatform,
26
27 # gpgme
28 pkg-config,
29
30 # openssl
31 openssl,
32
33 # ruby-magic
34 file,
35
36 # static-holmes
37 icu,
38 which,
39 zlib,
40}:
41
42let
43 data = lib.importJSON ./data.json;
44
45 version = data.version;
46 src = fetchFromGitLab {
47 owner = data.owner;
48 repo = data.repo;
49 rev = data.rev;
50 sha256 = data.repo_hash;
51 };
52
53 rubyEnv = bundlerEnv rec {
54 name = "gitlab-env-${version}";
55 ruby = ruby_3_3;
56 gemdir = ./rubyEnv;
57 gemset = import (gemdir + "/gemset.nix") src;
58 gemConfig = defaultGemConfig // {
59 gpgme = attrs: {
60 nativeBuildInputs = [ pkg-config ];
61 };
62 # the openssl needs the openssl include files
63 openssl = attrs: {
64 buildInputs = [ openssl ];
65 };
66 ruby-magic = attrs: {
67 buildInputs = [ file ];
68 buildFlags = [ "--enable-system-libraries" ];
69 };
70 gitlab-glfm-markdown = attrs: {
71 cargoDeps = rustPlatform.fetchCargoVendor {
72 src = stdenv.mkDerivation {
73 inherit (buildRubyGem { inherit (attrs) gemName version source; })
74 name
75 src
76 unpackPhase
77 nativeBuildInputs
78 ;
79 dontBuilt = true;
80 installPhase = ''
81 cp -R ext/glfm_markdown $out
82 rm $out/Cargo.lock
83 cp Cargo.lock $out
84 '';
85 };
86 hash = "sha256-NJLpfIgVgqbf1fHIzEKxzpHOKvtY9QHXVQPpRdvH0Uo=";
87 };
88
89 dontBuild = false;
90
91 nativeBuildInputs = [
92 cargo
93 rustc
94 rustPlatform.cargoSetupHook
95 rustPlatform.bindgenHook
96 ];
97
98 disallowedReferences = [
99 rustc.unwrapped
100 ];
101
102 preInstall = ''
103 export CARGO_HOME="$PWD/../.cargo/"
104 '';
105
106 postInstall = ''
107 mv -v $GEM_HOME/gems/${attrs.gemName}-${attrs.version}/lib/{glfm_markdown/glfm_markdown.so,}
108 find $out -type f -name .rustc_info.json -delete
109 '';
110 };
111
112 static_holmes = attrs: {
113 nativeBuildInputs = [
114 icu
115 which
116 zlib.dev
117 ];
118 };
119 };
120 groups = [
121 "default"
122 "unicorn"
123 "ed25519"
124 "metrics"
125 "development"
126 "puma"
127 "test"
128 "kerberos"
129 "opentelemetry"
130 ];
131 # N.B. omniauth_oauth2_generic and apollo_upload_server both provide a
132 # `console` executable.
133 ignoreCollisions = true;
134
135 extraConfigPaths = [
136 "${src}/vendor"
137 "${src}/gems"
138 ];
139 };
140
141 assets = stdenv.mkDerivation {
142 pname = "gitlab-assets";
143 inherit version src;
144
145 yarnOfflineCache = fetchYarnDeps {
146 yarnLock = src + "/yarn.lock";
147 sha256 = data.yarn_hash;
148 };
149
150 nativeBuildInputs = [
151 rubyEnv.wrappedRuby
152 rubyEnv.bundler
153 nodejs_20
154 git
155 cacert
156 yarnConfigHook
157 ];
158
159 patches = [
160 # Since version 12.6.0, the rake tasks need the location of git,
161 # so we have to apply the location patches here too.
162 ./remove-hardcoded-locations.patch
163
164 # Gitlab edited the default database config since [1] and the
165 # installer now complains about valid keywords only being "main", "ci" and "embedded".
166 #
167 # [1]: https://gitlab.com/gitlab-org/gitlab/-/commit/99c0fac52b10cd9df62bbe785db799352a2d9028
168 ./Remove-unsupported-database-names.patch
169 ];
170 # One of the patches uses this variable - if it's unset, execution
171 # of rake tasks fails.
172 GITLAB_LOG_PATH = "log";
173 FOSS_ONLY = !gitlabEnterprise;
174
175 SKIP_YARN_INSTALL = 1;
176 NODE_OPTIONS = "--max-old-space-size=8192";
177
178 postConfigure = ''
179 # Some rake tasks try to run yarn automatically, which won't work
180 rm lib/tasks/yarn.rake
181
182 # The rake tasks won't run without a basic configuration in place
183 mv config/database.yml.postgresql config/database.yml
184 mv config/gitlab.yml.example config/gitlab.yml
185
186 patchShebangs scripts/frontend/
187 '';
188
189 buildPhase = ''
190 runHook preBuild
191
192 # TODO: Try to yarn install without --ignore-scripts
193 # Needed for the js dependency pinia to work
194 pushd node_modules/vue-demi
195 yarn run postinstall
196 popd
197
198 bundle exec rake gitlab:assets:compile RAILS_ENV=production NODE_ENV=production SKIP_YARN_INSTALL=true
199
200 runHook postBuild
201 '';
202
203 installPhase = ''
204 runHook preInstall
205
206 mv public/assets $out
207
208 runHook postInstall
209 '';
210 };
211in
212stdenv.mkDerivation {
213 name = "gitlab${lib.optionalString gitlabEnterprise "-ee"}-${version}";
214
215 inherit src;
216
217 nativeBuildInputs = [ makeWrapper ];
218 buildInputs = [
219 rubyEnv
220 rubyEnv.wrappedRuby
221 rubyEnv.bundler
222 tzdata
223 git
224 net-tools
225 ];
226
227 patches = [
228 # Change hardcoded paths to the NixOS equivalent
229 ./remove-hardcoded-locations.patch
230 ];
231
232 postPatch = ''
233 ${lib.optionalString (!gitlabEnterprise) ''
234 # Remove all proprietary components
235 rm -rf ee
236 sed -i 's/-ee//' ./VERSION
237 ''}
238
239 # For reasons I don't understand "bundle exec" ignores the
240 # RAILS_ENV causing tests to be executed that fail because we're
241 # not installing development and test gems above. Deleting the
242 # tests works though.
243 rm lib/tasks/test.rake
244
245 rm config/initializers/gitlab_shell_secret_token.rb
246
247 sed -i '/ask_to_continue/d' lib/tasks/gitlab/two_factor.rake
248 sed -ri -e '/log_level/a config.logger = Logger.new(STDERR)' config/environments/production.rb
249
250 mv config/puma.rb.example config/puma.rb
251 # Always require lib-files and application.rb through their store
252 # path, not their relative state directory path. This gets rid of
253 # warnings and means we don't have to link back to lib from the
254 # state directory.
255 ${replace}/bin/replace-literal -f -r -e '../../lib' "$out/share/gitlab/lib" config
256 ${replace}/bin/replace-literal -f -r -e '../lib' "$out/share/gitlab/lib" config
257 ${replace}/bin/replace-literal -f -r -e "require_relative 'application'" "require_relative '$out/share/gitlab/config/application'" config
258 ${replace}/bin/replace-literal -f -r -e 'require_relative "/home/git/gitlab/lib/gitlab/puma/error_handler"' "require_relative '$out/share/gitlab/lib/gitlab/puma/error_handler'" config
259 '';
260
261 buildPhase = ''
262 rm -f config/secrets.yml
263 mv config config.dist
264 rm -r tmp
265 '';
266
267 installPhase = ''
268 mkdir -p $out/share
269 cp -r . $out/share/gitlab
270 ln -sf ${assets} $out/share/gitlab/public/assets
271 rm -rf $out/share/gitlab/log
272 ln -sf /run/gitlab/log $out/share/gitlab/log
273 ln -sf /run/gitlab/uploads $out/share/gitlab/public/uploads
274 ln -sf /run/gitlab/config $out/share/gitlab/config
275 ln -sf /run/gitlab/tmp $out/share/gitlab/tmp
276
277 # rake tasks to mitigate CVE-2017-0882
278 # see https://about.gitlab.com/2017/03/20/gitlab-8-dot-17-dot-4-security-release/
279 cp ${./reset_token.rake} $out/share/gitlab/lib/tasks/reset_token.rake
280
281 # manually patch the shebang line in generate-loose-foreign-key
282 wrapProgram $out/share/gitlab/scripts/decomposition/generate-loose-foreign-key --set ENABLE_SPRING 0 --add-flags 'runner -e test'
283 '';
284
285 passthru = {
286 inherit rubyEnv assets;
287 ruby = rubyEnv.wrappedRuby;
288 GITALY_SERVER_VERSION = data.passthru.GITALY_SERVER_VERSION;
289 GITLAB_PAGES_VERSION = data.passthru.GITLAB_PAGES_VERSION;
290 GITLAB_SHELL_VERSION = data.passthru.GITLAB_SHELL_VERSION;
291 GITLAB_WORKHORSE_VERSION = data.passthru.GITLAB_WORKHORSE_VERSION;
292 gitlabEnv.FOSS_ONLY = lib.boolToString (!gitlabEnterprise);
293 tests = {
294 nixos-test-passes = nixosTests.gitlab;
295 };
296 };
297
298 meta =
299 with lib;
300 {
301 homepage = "http://www.gitlab.com/";
302 platforms = platforms.linux;
303 teams = [ teams.gitlab ];
304 }
305 // (
306 if gitlabEnterprise then
307 {
308 license = licenses.unfreeRedistributable; # https://gitlab.com/gitlab-org/gitlab-ee/raw/master/LICENSE
309 description = "GitLab Enterprise Edition";
310 }
311 else
312 {
313 license = licenses.mit;
314 description = "GitLab Community Edition";
315 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.";
316 }
317 );
318}