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