{"id":379610,"date":"2024-06-25T03:10:34","date_gmt":"2024-06-25T03:10:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=379610"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=379610","title":{"rendered":"<span>\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c \u043c\u0435\u043d\u044e \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Gitlab<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0418\u0422 \u0441\u0440\u0435\u0434\u044b, \u043c\u043d\u043e\u0433\u0438\u0435 \u0435\u0451 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u0438\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c. \u041d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u043f\u043b\u0430\u0442\u043d\u044b\u043c, \u043b\u0438\u0431\u043e \u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u044b\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b, \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0435\u0439 \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0441\u0432\u043e\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 &#171;\u0440\u044f\u0434\u043e\u043c&#187; \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0442\u0440\u0430\u0442 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Gitlab \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 &#171;\u0431\u0435\u0441\u0448\u043e\u0432\u043d\u0443\u044e&#187; \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430\u043c\u0438. <\/p>\n<h2>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d Gitlab ?<\/h2>\n<p>\u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438 \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e, \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0435\u0439 Gitlab \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0432 \u0446\u0435\u043b\u043e\u043c. \u0418\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>puma &#8212; \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u0435\u0431\u0441\u0435\u0440\u0432\u0435\u0440, \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0435\u0431\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>gitlab-workhorse &#8212; \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 reverse-proxy, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 nginx \u0438 puma<\/p>\n<\/li>\n<li>\n<p>gitlab-kas &#8212; \u043c\u043e\u0434\u0443\u043b\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>gitaly &#8212; \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c\u0438 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 RPC \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>registry &#8212; \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 registry \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438\u043b\u0438 \u043f\u0430\u043a\u0435\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>sidekiq \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0446\u0438\u044e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0438 \u0443\u0432\u044f\u0437\u043a\u0443 \u0438\u0445 \u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u043f\u043e \u0448\u0435\u0434\u0443\u043b\u0435\u0440\u0443 \u0437\u0430\u0434\u0430\u0447\u0438<\/p>\n<\/li>\n<li>\n<p>postgres \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f nginx, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0438\u0439 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u0432\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442.\u043a. \u043e\u043d\u0438 \u043d\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u0444\u0435\u0440\u0443 \u043d\u0430\u0448\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0441\u0432\u044f\u0449\u0451\u043d\u043d\u043e\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 Gitlab, \u043d\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 puma \u0438 nginx.<br \/>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430 puma. Puma \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0432\u0435\u0431 \u0441\u0435\u0440\u0432\u0435\u0440, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 ruby, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0448\u0438\u0440\u043e\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0438\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u0436\u0451\u0441\u0442\u043a\u043e\u0439 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u043e\u0439 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\/\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 vue.js \u0438 css. \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 Gitlab \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 haml \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u043e\u0439 \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f:<\/p>\n<ul>\n<li>\n<p>\u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0441\u0442\u0438\u043b\u0435\u0439 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0442\u0435\u043c\u044b<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f vue.js \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0439 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u0430 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f graphql \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (\u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446)<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043c\u0435\u043d\u044e, \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u0430\u043a json \u043e\u0431\u044a\u0435\u043a\u0442(\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u0440\u0430\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a Gitlab \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c, \u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0432\u0438\u0434 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u0447\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0434\u043b\u044f ce \u0438 ee \u0432\u0435\u0440\u0441\u0438\u0439 \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e. \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u044b haml \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u0432\u044b\u0433\u043e\u0434\u043d\u043e, \u0442.\u043a. \u043d\u0443\u0436\u043d\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e gitlab. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a \u043c\u0435\u043d\u044e, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a \u0432\u0435\u0440\u0441\u0438\u0438.<\/p>\n<h2>\u0412\u043d\u0435\u0434\u0440\u044f\u0435\u043c\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e<\/h2>\n<p>\u041c\u0435\u043d\u044e Gitlab \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0442\u0435\u043c\u0430, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0438 \u0437\u0430 \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a Javascript \u043a\u043e\u0434\u0430, \u0445\u043e\u0442\u044f \u0432\u0441\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a \u043c\u0430\u0433\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 ruby \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041f\u0440\u043e\u0432\u043e\u0434\u044f \u043f\u0435\u0440\u0432\u044b\u0435 \u0438\u0437\u044b\u0441\u043a\u0430\u043d\u0438\u044f \u0432 \u0447\u0430\u0441\u0442\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 Gitlab, \u044f \u0438\u0441\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u043d\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e \u043a 502 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 puma \u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f. \u041c\u0435\u043d\u044e Gitlab, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0441\u043b\u0435\u0432\u0430, \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438\u043c\u0435\u043d\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a sidebar \u0438 \u0438\u043c\u0435\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Gitlab \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0441\u043f\u0440\u0430\u0432\u0430, \u043f\u0440\u043e \u043d\u0435\u0433\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041d\u0438\u0436\u0435 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u043d\u044e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u0435\u043d\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 sidebar, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043f\u043e \u043f\u0443\u0442\u0438 <em>\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars. <\/em>\u041f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u043c\u0435\u043d\u044e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u043d\u043a\u0442\u0430 \u043c\u0435\u043d\u044e.<\/p>\n<p>Gitlab \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e, \u043d\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;<strong>Your Work&#187;<\/strong>. \u0418\u043c\u0435\u043d\u043d\u043e \u043e \u043d\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u0439\u0434\u0451\u0442 \u0440\u0435\u0447\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/857\/1d6\/e1e\/8571d6e1e76f4327c3761d6b01483715.png\" alt=\"\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e &quot;Your Work&quot;\" title=\"\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e &quot;Your Work&quot;\" width=\"1366\" height=\"649\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/857\/1d6\/e1e\/8571d6e1e76f4327c3761d6b01483715.png\"\/><\/p>\n<div><figcaption>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e &#171;Your Work&#187;<\/figcaption><\/div>\n<\/figure>\n<p>\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430 ruby, \u043c\u0435\u043d\u044e &#171;Your Work&#187; \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u044e \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <em>\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb<\/em><\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     class Panel &lt; ::Sidebars::Panel       override :configure_menus       def configure_menus         add_menus       end        override :aria_label       def aria_label         _('Your work')       end        override :super_sidebar_context_header       def super_sidebar_context_header         aria_label       end        private        def add_menus         return unless context.current_user          add_menu(Sidebars::YourWork::Menus::ProjectsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::GroupsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::OrganizationsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::IssuesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MergeRequestsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::TodosMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MilestonesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::SnippetsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::ActivityMenu.new(context))       end     end   end end Sidebars::YourWork::Panel.prepend_mod_with('Sidebars::YourWork::Panel') <\/code><\/pre>\n<p>\u0433\u0434\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e Projects \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a<\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     module Menus       class ProjectsMenu &lt; ::Sidebars::Menu         override :link         def link           dashboard_projects_path         end          override :title         def title           _('Projects')         end          override :sprite_icon         def sprite_icon           'project'         end          override :render?         def render?           !!context.current_user         end          override :active_routes         def active_routes           { controller: ['root', 'projects', 'dashboard\/projects'] }         end       end     end   end end <\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0435\u043d\u044e \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u043c\u0435\u043d\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u0444\u043e\u0440\u043c\u0443.<\/p>\n<pre><code class=\"ruby\">add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0444\u0430\u0439\u043b \u0441 \u043c\u0435\u043d\u044e &#171;Your Work&#187; \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a<\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     class Panel &lt; ::Sidebars::Panel       override :configure_menus       def configure_menus         add_menus       end        override :aria_label       def aria_label         _('Your work')       end        override :super_sidebar_context_header       def super_sidebar_context_header         aria_label       end        private        def add_menus         return unless context.current_user          add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))          add_menu(Sidebars::YourWork::Menus::ProjectsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::GroupsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::OrganizationsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::IssuesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MergeRequestsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::TodosMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MilestonesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::SnippetsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::ActivityMenu.new(context))       end     end   end end Sidebars::YourWork::Panel.prepend_mod_with('Sidebars::YourWork::Panel') <\/code><\/pre>\n<p>\u0423 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u043c\u0435\u043d\u044e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e &#171;\u0438\u043a\u043e\u043d\u043a\u0443&#187;, \u0432\u0437\u044f\u0432 \u0435\u0451 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <a href=\"https:\/\/gitlab-org.gitlab.io\/gitlab-svgs\/\" rel=\"noopener noreferrer nofollow\">https:\/\/gitlab-org.gitlab.io\/gitlab-svgs\/<\/a>. \u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>gitlab-ctl restart puma<\/code> \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043d\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0b0\/b2e\/f9d\/0b0b2ef9dafcef591129a7f19f2d883c.png\" alt=\"\u041d\u043e\u0432\u044b\u0439 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e\" title=\"\u041d\u043e\u0432\u044b\u0439 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e\" width=\"1366\" height=\"649\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0b0\/b2e\/f9d\/0b0b2ef9dafcef591129a7f19f2d883c.png\"\/><\/p>\n<div><figcaption>\u041d\u043e\u0432\u044b\u0439 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e<\/figcaption><\/div>\n<\/figure>\n<h2>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u0435\u043d\u044e \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c\u0438 ?<\/h2>\n<p>\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;\u041d\u0443 \u0432\u043e\u0442 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b \u044f \u044d\u0442\u043e \u043c\u0435\u043d\u044e, \u0430 \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u043f\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u0442\u044c?&#187;. \u0414\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0435\u0441\u0442\u044c &#171;\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0448 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e \u0432 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>\u041f\u0440\u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430\u043c\u0438 \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 github <a href=\"https:\/\/github.com\/Animalcule\/triggered-edit-deb-package\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Animalcule\/triggered-edit-deb-package<\/a> , \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u0435\u043d \u043c\u0435\u0442\u043e\u0434 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435\/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430<\/p>\n<pre><code>interest \/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u043c \u043d\u0430\u0441 \u0444\u0430\u0439\u043b\u043e\u043c.<\/p>\n<pre><code>#!\/bin\/sh  set -eu  if [ \"$1\" = \"triggered\" ]; then   if [ \"$2\" = \"\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb\" ]; then     logger \"Fix gitlab 'Your Work' menu\"     line=\"return unless context.current_user\"     addline=\"add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))\"     sed -i -e \"\/$line$\/a\"'\\\\n'\"\\t$addline\" \"$2\"   fi fi <\/code><\/pre>\n<p>\u0418\u0437 \u043d\u0430\u0431\u043e\u0440\u0430 \u043d\u0430\u0448\u0438\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f deb \u043f\u0430\u043a\u0435\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0437\u0430\u043c\u0435\u043d\u0435 \u0444\u0430\u0439\u043b\u0430 <code>panel.rb<\/code> \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439\/\u043d\u043e\u0432\u044b\u0439, \u043d\u0430\u0448 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0432 \u043c\u0435\u043d\u044e Gitlab \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u0443\u043d\u043a\u0442. \u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u0441\u0430\u043c \u043f\u0430\u043a\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <a href=\"https:\/\/github.com\/aborche\/gitlab-menu-changer\/\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/aborche\/gitlab-menu-changer\/<\/a><\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0434\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Gitlab \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 puma. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. <\/p>\n<pre><code class=\"bash\">sh \/var\/lib\/dpkg\/info\/gitlab-menu-changer.postinst triggered \/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>gitlab-ctl restart puma<\/code><\/p>\n<h2>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 ?<\/h2>\n<p>\u0421 \u043c\u0435\u043d\u044e \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: &#171;\u0427\u0442\u043e \u044d\u0442\u043e \u043d\u0430\u043c \u0434\u0430\u0451\u0442 ? \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443 \u043c\u0435\u043d\u044e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c 404\/502 \u043e\u0448\u0438\u0431\u043a\u0443, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442!&#187;<\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445 \u043a\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u043f\u043e\u044f\u0441\u043d\u044e. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e \u0441\u043e \u0441\u0441\u044b\u043b\u043a\u043e\u0439, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0435\u0439\u0441\u044f \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u0430 Gitlab, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u0441\u0430\u0439\u0442\u0430. \u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0443\u043a\u0438, csrf \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u043f\u0440\u043e\u0447\u0430\u044f.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#171;\u043c\u0430\u0433\u0438\u0438&#187;. \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u044b\u043b\u0430 \u0440\u0435\u043c\u0430\u0440\u043a\u0430 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 Nginx, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Gitlab \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c. \u041c\u0430\u043b\u043e \u043a\u0442\u043e \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u043b\u0441\u044f \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0443\u044e \u0440\u043e\u043b\u044c \u0438\u0433\u0440\u0430\u0435\u0442 Nginx \u0432 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0435 Gitlab, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044f \u0435\u0433\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c. \u0412 \u0444\u0430\u0439\u043b\u0435 <em>\/etc\/gitlab\/gitlab.rb <\/em>\u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430 \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a<\/p>\n<pre><code># nginx['custom_gitlab_server_config'] = \"location ^~ \/foo-namespace\/bar-project\/raw\/ {\\n deny all;\\n}\\n\" # nginx['custom_nginx_config'] = \"include \/etc\/nginx\/conf.d\/example.conf;\"<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 \u0434\u043b\u044f \u0431\u043b\u043e\u043a\u0430 http. \u042d\u0442\u043e \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u043e\u043c \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044e Gitlab. \u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432 \u0431\u043b\u043e\u043a\u0435 <code>nginx['custom_gitlab_server_config']<\/code>  \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e location<\/p>\n<pre><code>nginx['custom_gitlab_server_config'] = \"include \/etc\/nginx\/gitlab\/helper.conf;\"<\/code><\/pre>\n<p>\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0441 location<\/p>\n<pre><code>location \/-\/helper { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Original-ARGS $args; proxy_set_header X-Remote-Addr $remote_addr; proxy_set_header X-Original-Host $host; proxy_pass http:\/\/host.with.menu.app:8099; } location = \/api\/v4\/graphql {     rewrite \/api\/v4\/graphql \/api\/graphql last;      proxy_set_header Host $http_host;     proxy_set_header X-Real-IP $remote_addr;     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     proxy_set_header X-Forwarded-Proto https;     proxy_set_header X-Forwarded-Ssl on;      proxy_read_timeout                  900;     proxy_cache off;     proxy_buffering off;     proxy_request_buffering off;     proxy_http_version 1.1;      proxy_pass         http:\/\/gitlab-workhorse; } <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f <em>\/etc\/gitlab\/gitlab.rb<\/em> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>gitlab-ctl reconfigure nginx<\/code><strong>. <\/strong>\u041f\u0440\u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 location \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a nginx \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>gitlab-ctl restart nginx<\/code><strong>. <\/strong>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433 nginx \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>\/opt\/gitlab\/embedded\/sbin\/nginx -p \/var\/opt\/gitlab\/nginx\/ -tT<\/code><\/p>\n<p>\u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u0443\u0441\u043e\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 graphql \u0432 \u0432\u0435\u0442\u043a\u0435 \/api\/v4, \u043e\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f, \u0442.\u043a. \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 go-gitlab(\u043e \u043d\u0451\u043c \u043d\u0438\u0436\u0435) &#171;\u0437\u0430\u0442\u043e\u0447\u0435\u043d&#187; \u043d\u0430 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#171;\/api\/v4&#187; \u0438 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u043d\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u0430\u0448\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041a\u0430\u043a \u0440\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u0432\u043d\u0435\u0434\u0440\u044f\u044f\u0441\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u0441\u0430\u0439\u0442\u0430 Gitlab \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438 \u0438 \u0432\u0441\u0451 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 Gitlab. \u041f\u0435\u0440\u0432\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043d\u0430 bootstrap, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0443\u0442\u0451\u043c \u0432\u044b\u0437\u043e\u0432\u0430 api \u0438\u0437 ajax \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u0438 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 Gitlab. \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 Gitlab \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441 \u043d\u0443\u043b\u044f. \u0414\u0430 \u0435\u0441\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0435\u0448, \u043d\u043e \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 3-4 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0437\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b Gitlab \u0438\u0437 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043a\u0443\u043a \u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d middleware \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b Gitlab \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d Go 1.21, \u0442.\u043a. \u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u043c\u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f Gin framework, \u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e Go \u0432 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 *ML \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 python, java. \u041a \u0441\u043b\u043e\u0432\u0443 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u043d\u0430 Go \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 api Gitlab <a href=\"https:\/\/github.com\/xanzy\/go-gitlab\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/xanzy\/go-gitlab<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0430\u0432\u0434\u0430 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0443\u043a\u0430\u043c\u0438.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e middleware \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0430\u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f ?<\/p>\n<p>Middleware \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/p>\n<ul>\n<li>\n<p>\u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0431\u0430\u0437\u043e\u0432\u043e\u0439\/\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 Gitlab \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u043f\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0423\u043c\u0435\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0441\u043b\u0435\u043f\u043e\u043a \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u043e\u0433\u0430\u0449\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u043e\u0432\u044b\u043c \u043c\u0435\u043d\u044e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0430\u0434\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u043a\u0443\u043a\u0438. \u0414\u043e\u043b\u0436\u043d\u044b \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f, \u043e\u0431\u043e\u0433\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0435\u0441\u0441\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u0441\u0435\u0433\u0434\u0430. \u041e\u0431 \u044d\u0442\u043e\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430, \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. \u042d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u043e\u0441\u0442\u044c. \u0412\u0441\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0438 realtime \u0434\u0432\u0438\u0436\u043a\u0430 Gitlab, \u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u043c\u0441\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<\/li>\n<li>\n<p>\u041b\u044e\u0431\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0438\u043c\u0435\u0435\u0442 \u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f Vue.js, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 Gitlab. \u0421\u0432\u044f\u0437\u0430\u043d\u043e \u044d\u0442\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 dom \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Vue.js \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0451 \u0441\u0435\u0431\u0435 \u0434\u043e\u0440\u043e\u0436\u0435. \u041e\u0431 \u044d\u0442\u043e\u043c \u0438\u043d\u0444\u043e\u043c\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u0430\u043b\u044c\u0448\u0435<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Gitlab API \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043e\u0431\u044a\u0451\u043c\u0435, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#171;\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f deploy \u0442\u043e\u043a\u0435\u043d\u0430&#187;, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f graphql + csrf. \u041e\u0431 \u044d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u044b\u0448\u0435\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f middleware \u0441 Gitlab.<\/p>\n<h2>\u0421\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u044b\u0435 \u043a\u0443\u043a\u0438<\/h2>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0430\u0436\u043d\u0435\u0439\u0448\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 middleware. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f Gitlab \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043a\u0443\u043a \u0438 \u043d\u0435 \u0432\u0441\u0451 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f middleware. \u0422\u043e \u0447\u0442\u043e \u0442\u043e\u0447\u043d\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>known_sign_in &#8212; \u043a\u0443\u043a\u0430 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 Gitlab &#171;\u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442&#187; \u0431\u044b\u043b \u043b\u0438 \u0440\u0430\u043d\u0435\u0435 \u0432\u0445\u043e\u0434 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438\u043b\u0438 \u043d\u0435\u0442<\/p>\n<\/li>\n<li>\n<p>_gitlab_session &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u0430\u044f \u043a\u0443\u043a\u0430 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0432\u0445\u043e\u0434\u0435 \u0432 Gitlab. \u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043a\u0443\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u0432\u043e\u0434\u0430 \u043b\u043e\u0433\u0438\u043d\u0430\/\u043f\u0430\u0440\u043e\u043b\u044f<\/p>\n<\/li>\n<li>\n<p>remember_user_token &#8212; \u0442\u043e\u043a\u0435\u043d \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 checkbox &#171;Remember me&#187;, \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0432 \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u043e\u0439 \u043a\u0443\u043a\u0438 <em>&#171;_gitlab_session&#187;<\/em> \u043f\u0440\u0438 \u0435\u0451 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041e \u0447\u0451\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c ?<\/p>\n<ol>\n<li>\n<p>\u041a\u0443\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f middleware \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 &#171;<em>remember_user_token&#187;<\/em> \u0432 Gitlab, \u0434\u043e\u043b\u0436\u043d\u0430 \u0432 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438 middleware \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 Gitlab API \u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 \u043f\u0440\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 <\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u0442\u0435\u043a\u0448\u0430\u044f \u043a\u0443\u043a\u0430 &#171;<em>_gitlab_session<\/em>&#187; \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u0430 \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <em>&#171;remember_user_token&#187;<\/em>, \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438\u0437 \u043f.1<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 graphql \u0441 \u0438\u0441\u0442\u0451\u043a\u0448\u0438\u043c\u0438 \u043a\u0443\u043a\u0430\u043c\u0438 \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0447\u0435\u043c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 graphql \u043d\u0443\u0436\u043d\u0430 \u0434\u0432\u043e\u0439\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u0443\u043a\u0438 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 csrf \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u043e\u0439 \u043a\u0443\u043a\u0438 <em>&#171;_gitlab_session&#187;<\/em> Gitlab \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 \u043e\u0442\u0432\u0435\u0442 &#171;Status:302&#187; \u0438 middleware \u0434\u043e\u043b\u0436\u043d\u0430 \u0443\u043c\u0435\u0442\u044c &#171;\u043b\u043e\u0432\u0438\u0442\u044c&#187; \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 Gitlab<\/h2>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 Gitlab \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 middleware, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u043d\u0430\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u0412 99% \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u0441 dom \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u043c, \u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u043c \u043f\u0443\u0442\u044c \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0430\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/p>\n<p>\u0427\u0442\u043e \u0438 \u043a\u0430\u043a \u043d\u0443\u0436\u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c ?<\/p>\n<ol>\n<li>\n<p>\u0411\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u041d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0432 \u0431\u043b\u043e\u043a\u0435 &lt;<em>script>, <\/em>\u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u043a\u043e\u043c \u0431\u043b\u043e\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u0441 &#171;window.gon={};&#187;. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u0435\u043d \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c <em>&lt;script> <\/em>\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0411\u043b\u043e\u043a \u043c\u0435\u043d\u044e. \u041d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u0435\u043b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435 <em>&lt;aside> <\/em>\u0432 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u0435 &#171;data-sidebar&#187;. \u041f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0431\u043b\u043e\u043a\u0430 \u043c\u0435\u043d\u044e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0447\u0451\u0442\u043a\u043e\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0442.\u043a. \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0442\u043e\u043d\u043a\u0438\u0439 \u0438 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043b\u043e\u043a \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u0435\u043b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435 <em>&lt;main><\/em>. \u0414\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043d\u043e\u0434\u0443 <em>&lt;main>,<\/em> \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u0451 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b css \u0441\u0442\u0438\u043b\u0435\u0439 Gitlab \u0432 \u043d\u043e\u0432\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422.\u043a. \u044d\u043b\u0435\u043c\u0435\u043d\u0442 <em>&lt;main><\/em> \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b vue.js<\/p>\n<\/li>\n<li>\n<p>CSRF \u0442\u043e\u043a\u0435\u043d. \u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 graphql-explorer \u0442\u043e\u043a\u0435\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435 \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c &#171;graphql-container&#187; \u0432 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u0435 &#171;data-headers&#187;. \u041d\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0432 \u0431\u043b\u043e\u043a\u0435 meta \u0432 \u0432\u0438\u0434\u0435<br \/> <code>&lt;meta name=\"csrf-param\" content=\"authenticity_token\" \/> &lt;meta name=\"csrf-token\" content=\"RC5-m9R-db9Q\" \/><\/code><br \/>\u0414\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u0431\u043b\u043e\u043a graphql api \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445. \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u043e &#171;_gitlab_session&#187; \u043a\u0443\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 graphql.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u0432\u043d\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 <em>&lt;main><\/em> \u0438 <em>&lt;aside>, <\/em>\u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u043b\u043e\u043a \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 <em>&lt;nav>.<\/em><\/p>\n<h2>\u0411\u043b\u043e\u043a \u043c\u0435\u043d\u044e \u0438 \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/h2>\n<p>\u0411\u043b\u043e\u043a \u043c\u0435\u043d\u044e \u0438\u043c\u0435\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043d\u043e \u043e\u043d\u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b Go.<\/p>\n<pre><code class=\"go\">type GitlabSidebar struct { AdminMode                           AdminMode             `json:\"admin_mode\"` AdminURL                            string                `json:\"admin_url\"` AvatarURL                           string                `json:\"avatar_url\"` CanSignOut                          bool                  `json:\"can_sign_out\"` CanaryToggleCOMURL                  string                `json:\"canary_toggle_com_url\"` ContextSwitcherLinks                []ContextSwitcherLink `json:\"context_switcher_links\"` CreateNewMenuGroups                 []CreateNewMenuGroup  `json:\"create_new_menu_groups\"` CurrentContext                      CurrentContext        `json:\"current_context\"` CurrentContextHeader                string                `json:\"current_context_header\"` CurrentMenuItems                    []CurrentMenuItem     `json:\"current_menu_items\"` DisplayWhatsNew                     bool                  `json:\"display_whats_new\"` GitlabCOMAndCanary                  bool                  `json:\"gitlab_com_and_canary\"` GitlabCOMButNotCanary               bool                  `json:\"gitlab_com_but_not_canary\"` GitlabVersion                       GitlabVersion         `json:\"gitlab_version\"` GitlabVersionCheck                  interface{}           `json:\"gitlab_version_check\"` GroupsPath                          string                `json:\"groups_path\"` HasLinkToProfile                    bool                  `json:\"has_link_to_profile\"` IsAdmin                             bool                  `json:\"is_admin\"` IsImpersonating                     bool                  `json:\"is_impersonating\"` IsLoggedIn                          bool                  `json:\"is_logged_in\"` IssuesDashboardPath                 string                `json:\"issues_dashboard_path\"` LinkToProfile                       string                `json:\"link_to_profile\"` LogoURL                             interface{}           `json:\"logo_url\"` MergeRequestMenu                    []MergeRequestMenu    `json:\"merge_request_menu\"` Name                                string                `json:\"name\"` PanelType                           string                `json:\"panel_type\"` PinnedItems                         []interface{}         `json:\"pinned_items\"` ProjectsPath                        string                `json:\"projects_path\"` Search                              Search                `json:\"search\"` Settings                            Settings              `json:\"settings\"` ShortcutLinks                       []ShortcutLink        `json:\"shortcut_links\"` ShowVersionCheck                    bool                  `json:\"show_version_check\"` SignOutLink                         string                `json:\"sign_out_link\"` Status                              Status                `json:\"status\"` StopImpersonationPath               string                `json:\"stop_impersonation_path\"` SupportPath                         string                `json:\"support_path\"` TodosDashboardPath                  string                `json:\"todos_dashboard_path\"` TrackVisitsPath                     string                `json:\"track_visits_path\"` UpdatePinsURL                       string                `json:\"update_pins_url\"` UserCounts                          UserCounts            `json:\"user_counts\"` Username                            string                `json:\"username\"` WhatsNewMostRecentReleaseItemsCount int64                 `json:\"whats_new_most_recent_release_items_count\"` WhatsNewVersionDigest               string                `json:\"whats_new_version_digest\"` } <\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0432 \u043c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0443\u0436\u043d\u044b \u0438 \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c. \u041f\u0443\u0442\u0451\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 Marshall\/Unmarshall \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0437\u0430\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043d\u0430\u043c \u0432\u0438\u0434. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043c\u0435\u043d\u044e.<\/p>\n<pre><code>func TransformSidebar(c *gin.Context, cfg conf.Config, source *html.Node, fromFile bool) ([]byte, error) { \/\/ Get sidebar source from Gitlab page GitlabParsedSidebar, err := parsers.GetSideBarMenu(source) if err != nil { return nil, err }  var SourceSideBar GitlabSidebar err = json.Unmarshal([]byte(GitlabParsedSidebar), &amp;SourceSideBar) if err != nil { return nil, err } \/\/ Remove from menu unused items SourceSideBar.AdminMode.UserIsAdmin = false SourceSideBar.IsAdmin = false SourceSideBar.CanSignOut = false SourceSideBar.Status.CanUpdate = false SourceSideBar.HasLinkToProfile = false SourceSideBar.Settings.HasSettings = false SourceSideBar.ContextSwitcherLinks = []ContextSwitcherLink{} SourceSideBar.ShortcutLinks = []ShortcutLink{} SourceSideBar.MergeRequestMenu = []MergeRequestMenu{} SourceSideBar.CreateNewMenuGroups = []CreateNewMenuGroup{} SourceSideBar.DisplayWhatsNew = false if fromFile { SourceSideBar.CurrentMenuItems = BuildSidebarMenuFromFile(c, cfg) } else { SourceSideBar.CurrentMenuItems = BuildSidebarMenuFromStruct(c, cfg) } return json.Marshal(SourceSideBar)  } <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0435\u043d\u044e. \u041e\u043d\u0438 \u043f\u043e\u0434\u0447\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u043c\u0443 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0443 \u0432\u0438\u0434\u0430<\/p>\n<pre><code>type CurrentMenuItem struct { ActiveRoutes *ActiveRoutes         `json:\"active_routes,omitempty\"` Avatar       interface{}           `json:\"avatar\"` EntityID     interface{}           `json:\"entity_id\"` Icon         string                `json:\"icon\"` ID           string                `json:\"id\"` Link         string                `json:\"link\"` LinkClasses  interface{}           `json:\"link_classes\"` PillCount    interface{}           `json:\"pill_count\"` Title        string                `json:\"title\"` AvatarShape  string                `json:\"avatar_shape,omitempty\"` IsActive     bool                  `json:\"is_active,omitempty\"` Items        []CurrentMenuItemItem `json:\"items,omitempty\"` Separated    bool                  `json:\"separated,omitempty\"` }  type ActiveRoutes struct { Controller string `json:\"controller\"` }  type CurrentMenuItemItem struct { Avatar      interface{} `json:\"avatar\"` AvatarShape string      `json:\"avatar_shape,omitempty\"` EntityID    interface{} `json:\"entity_id\"` Icon        interface{} `json:\"icon\"` ID          string      `json:\"id\"` IsActive    bool        `json:\"is_active\"` Link        string      `json:\"link\"` LinkClasses interface{} `json:\"link_classes\"` PillCount   *int        `json:\"pill_count\"` Title       string      `json:\"title\"` } <\/code><\/pre>\n<p>\u041f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0437\u0430 \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442. \u0421\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>id &#8212; \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<li>\n<p>icon &#8212; \u0438\u043c\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u043a\u043e\u043d\u043e\u043a \u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a<\/p>\n<\/li>\n<li>\n<p>is_active &#8212; \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 true, \u0435\u0441\u043b\u0438 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e \u0430\u043a\u0442\u0438\u0432\u0435\u043d. \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043c\u0435\u043d\u044e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438 \u043f\u043e\u0434\u0447\u0438\u043d\u0451\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 is_active: true<\/p>\n<\/li>\n<li>\n<p>link &#8212; \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0438\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0441\u0441\u044b\u043b\u043a\u0430, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u043a\u0443\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<li>\n<p>pill_count &#8212; \u0447\u0438\u0441\u043b\u043e\u0432\u0430\u044f \u043c\u0435\u0442\u043a\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u044f title, \u0434\u043b\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f null<\/p>\n<\/li>\n<li>\n<p>title &#8212; \u0442\u0435\u043a\u0441\u0442 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0435 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<li>\n<p>link_classes &#8212; \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u0442\u0438\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u043a \u043f\u0443\u043d\u043a\u0442\u0443 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 CurrentMenuItemItem, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u0434\u043c\u0435\u043d\u044e.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u043d\u044e \u0434\u043b\u044f \u0431\u043b\u043e\u043a\u0430 \u0434\u0435\u043f\u043b\u043e\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0443 \u043d\u0430\u0441<\/p>\n<pre><code>[   {     \"avatar\": null,     \"entity_id\": null,     \"icon\": \"go-back\",     \"id\": \"back\",     \"link\": \"\/\",     \"link_classes\": null,     \"pill_count\": null,     \"title\": \"Back to Gitlab\"   },   {     \"avatar\": null,     \"entity_id\": null,     \"icon\": \"information-o\",     \"id\": \"helper\",     \"link\": \"\/-\/helper\/\",     \"link_classes\": null,     \"pill_count\": null,     \"title\": \"Deploy Information\"   },   {     \"avatar\": null,     \"entity_id\": null,     \"icon\": \"rocket-launch\",     \"id\": \"deploy\",     \"link\": \"\/-\/helper\/deploy\/to-development\",     \"link_classes\": \"show\",     \"pill_count\": null,     \"title\": \"Deploy Area (Alpha)\",     \"is_active\": false   },   {     \"avatar\": null,     \"entity_id\": null,     \"icon\": \"requirements\",     \"id\": \"projects\",     \"link\": \"\/-\/helper\/projects\",     \"link_classes\": \"show\",     \"pill_count\": null,     \"title\": \"Projects Audit (GraphQL)\",     \"is_active\": false   },   {     \"avatar\": null,     \"entity_id\": null,     \"icon\": \"users\",     \"id\": \"users\",     \"link\": \"\/-\/helper\/users\",     \"link_classes\": \"\",     \"pill_count\": null,     \"title\": \"Users Audit (GraphQL)\",     \"is_active\": false   } ] <\/code><\/pre>\n<p>\u041a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435.<\/p>\n<div class=\"floating-image\">\n<figure class=\"float\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ec7\/077\/767\/ec7077767e7eac6edbcfaf57de822b39.png\" width=\"254\" height=\"356\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ec7\/077\/767\/ec7077767e7eac6edbcfaf57de822b39.png\"\/><\/figure>\n<figure class=\"float\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/da0\/8ed\/d22\/da08edd22b3df0e211244e44a6a38bb0.png\" width=\"251\" height=\"344\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/da0\/8ed\/d22\/da08edd22b3df0e211244e44a6a38bb0.png\"\/><\/figure>\n<\/div>\n<p>\u041a\u0440\u0430\u0441\u0438\u0432\u043e, \u043d\u0435 \u043f\u0440\u0430\u0432\u0434\u0430 \u043b\u0438 ? \ud83d\ude42<\/p>\n<h2>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430<\/h2>\n<p>\u041c\u0435\u043d\u044e \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u043e \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c \u0441 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c.<\/p>\n<p>\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 API Gitlab<\/p>\n<\/li>\n<\/ol>\n<p>\u041a\u0430\u043a \u0440\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Gitlab \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u043d\u0430 Vue.JS. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0432\u0438\u0434\u0435 \u0432\u0435\u0441\u044c \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 &#171;\u0432 \u043b\u043e\u0431&#187; \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u041d\u043e \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, css \u0444\u0430\u0439\u043b\u044b Gitlab \u0438\u043c\u0435\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f flex \u0441 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, form-group, modal, dialog, \u0441\u0442\u0438\u043b\u0438 \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u0414\u043b\u044f \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0445 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Gitlab UI \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 <a href=\"https:\/\/gitlab-org.gitlab.io\/gitlab-ui\/\" rel=\"noopener noreferrer nofollow\">https:\/\/gitlab-org.gitlab.io\/gitlab-ui\/<\/a>. \u041a\u0440\u0430\u0441\u0438\u0432\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0441\u0445\u043e\u0434\u0443 \u043f\u043e\u0445\u0432\u0430\u0441\u0442\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043b\u044c\u0437\u044f, \u043d\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0438\u043b\u0435\u0439 \u0434\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043f\u043e\u043b\u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0441\u0442\u0438\u043b\u0435\u0439 \u0438 \u0446\u0432\u0435\u0442\u043e\u0432 \u0436\u0451\u0441\u0442\u043a\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a \u0446\u0432\u0435\u0442\u043e\u0432\u044b\u043c \u0441\u0445\u0435\u043c\u0430\u043c(\u0441\u0432\u0435\u0442\u043b\u0430\u044f\/\u0442\u0451\u043c\u043d\u0430\u044f). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u0440\u043e\u043f\u043e\u0442\u043b\u0438\u0432\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c33\/670\/945\/c336709452cff5a45be7e89d0da8ba08.png\" alt=\"\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0444\u043e\u0440\u043c\u044b\" title=\"\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0444\u043e\u0440\u043c\u044b\" width=\"1097\" height=\"434\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c33\/670\/945\/c336709452cff5a45be7e89d0da8ba08.png\"\/><\/p>\n<div><figcaption>\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0444\u043e\u0440\u043c\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b16\/e74\/1f4\/b16e741f431077a31e02d6fa8d216e46.png\" alt=\"\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\" title=\"\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\" width=\"1365\" height=\"648\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b16\/e74\/1f4\/b16e741f431077a31e02d6fa8d216e46.png\"\/><\/p>\n<div><figcaption>\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3a4\/f2d\/9e9\/3a4f2d9e91ec48fc7195c36c4e46f7d9.png\" alt=\"\u0421\u0432\u0435\u0442\u043b\u0430\u044f \u0442\u0435\u043c\u0430\" title=\"\u0421\u0432\u0435\u0442\u043b\u0430\u044f \u0442\u0435\u043c\u0430\" width=\"1097\" height=\"457\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3a4\/f2d\/9e9\/3a4f2d9e91ec48fc7195c36c4e46f7d9.png\"\/><\/p>\n<div><figcaption>\u0421\u0432\u0435\u0442\u043b\u0430\u044f \u0442\u0435\u043c\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d9b\/2dd\/127\/d9b2dd127a534c20499b654e73a5c30c.png\" alt=\"\u0422\u0451\u043c\u043d\u0430\u044f \u0442\u0435\u043c\u0430\" title=\"\u0422\u0451\u043c\u043d\u0430\u044f \u0442\u0435\u043c\u0430\" width=\"1097\" height=\"457\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d9b\/2dd\/127\/d9b2dd127a534c20499b654e73a5c30c.png\"\/><\/p>\n<div><figcaption>\u0422\u0451\u043c\u043d\u0430\u044f \u0442\u0435\u043c\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u043e\u0432 \u044f \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043b \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 <a href=\"https:\/\/github.com\/aborche\/gitlab-menu-extender-demo\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/aborche\/gitlab-menu-extender-demo<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043e\u0431\u0440\u0430\u043d \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f. \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c &#171;\u043d\u0438\u043e\u0447\u0435\u043d\u044c&#187;, \u043d\u043e \u0442\u0443\u0442 \u0441\u043c\u044b\u0441\u043b \u043d\u0435 \u0432 \u043a\u0440\u0430\u0441\u043e\u0442\u0435 \u043a\u043e\u0434\u0430, \u0430 \u0432 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0443\u0436\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0443\u043d\u043a\u0442\u044b \u043c\u0435\u043d\u044e \u0438 \u043e\u0431\u043e\u0433\u0430\u0442\u0438\u0442\u044c \u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0432 \u043d\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0431\u044b\u043b \u0432\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u0443\u0434\u0430\u0447\u0438 \u0432 \u043c\u043e\u0434\u0434\u0438\u043d\u0433\u0435 Gitlab \ud83d\ude42<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0ce\/d4c\/54f\/0ced4c54f2fbffae001d16b2e9654e71.png\" alt=\"(C) Aborche 2024\" title=\"(C) Aborche 2024\" width=\"100\" height=\"73\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0ce\/d4c\/54f\/0ced4c54f2fbffae001d16b2e9654e71.png\"\/><\/p>\n<div><figcaption>(C) Aborche 2024<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/814623\/\"> https:\/\/habr.com\/ru\/articles\/814623\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0418\u0422 \u0441\u0440\u0435\u0434\u044b, \u043c\u043d\u043e\u0433\u0438\u0435 \u0435\u0451 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u0438\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c. \u041d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u043f\u043b\u0430\u0442\u043d\u044b\u043c, \u043b\u0438\u0431\u043e \u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u044b\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b, \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0435\u0439 \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0441\u0432\u043e\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 &#171;\u0440\u044f\u0434\u043e\u043c&#187; \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0442\u0440\u0430\u0442 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Gitlab \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 &#171;\u0431\u0435\u0441\u0448\u043e\u0432\u043d\u0443\u044e&#187; \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430\u043c\u0438. <\/p>\n<h2>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d Gitlab ?<\/h2>\n<p>\u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438 \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e, \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0435\u0439 Gitlab \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0432 \u0446\u0435\u043b\u043e\u043c. \u0418\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>puma &#8212; \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u0435\u0431\u0441\u0435\u0440\u0432\u0435\u0440, \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0435\u0431\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>gitlab-workhorse &#8212; \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 reverse-proxy, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 nginx \u0438 puma<\/p>\n<\/li>\n<li>\n<p>gitlab-kas &#8212; \u043c\u043e\u0434\u0443\u043b\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>gitaly &#8212; \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c\u0438 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 RPC \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>registry &#8212; \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 registry \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438\u043b\u0438 \u043f\u0430\u043a\u0435\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>sidekiq \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0446\u0438\u044e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0438 \u0443\u0432\u044f\u0437\u043a\u0443 \u0438\u0445 \u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u043f\u043e \u0448\u0435\u0434\u0443\u043b\u0435\u0440\u0443 \u0437\u0430\u0434\u0430\u0447\u0438<\/p>\n<\/li>\n<li>\n<p>postgres \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f nginx, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0438\u0439 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u0432\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442.\u043a. \u043e\u043d\u0438 \u043d\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u0444\u0435\u0440\u0443 \u043d\u0430\u0448\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0441\u0432\u044f\u0449\u0451\u043d\u043d\u043e\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 Gitlab, \u043d\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 puma \u0438 nginx.<br \/>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430 puma. Puma \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0432\u0435\u0431 \u0441\u0435\u0440\u0432\u0435\u0440, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 ruby, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0448\u0438\u0440\u043e\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0438\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u0436\u0451\u0441\u0442\u043a\u043e\u0439 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u043e\u0439 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\/\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 vue.js \u0438 css. \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 Gitlab \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 haml \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u043e\u0439 \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f:<\/p>\n<ul>\n<li>\n<p>\u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0441\u0442\u0438\u043b\u0435\u0439 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0442\u0435\u043c\u044b<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f vue.js \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0439 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u0430 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f graphql \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (\u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446)<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043c\u0435\u043d\u044e, \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u0430\u043a json \u043e\u0431\u044a\u0435\u043a\u0442(\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u0440\u0430\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u043c\u0435\u043d\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a Gitlab \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c, \u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0432\u0438\u0434 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u0447\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0434\u043b\u044f ce \u0438 ee \u0432\u0435\u0440\u0441\u0438\u0439 \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e. \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u044b haml \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u0432\u044b\u0433\u043e\u0434\u043d\u043e, \u0442.\u043a. \u043d\u0443\u0436\u043d\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e gitlab. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a \u043c\u0435\u043d\u044e, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a \u0432\u0435\u0440\u0441\u0438\u0438.<\/p>\n<h2>\u0412\u043d\u0435\u0434\u0440\u044f\u0435\u043c\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e<\/h2>\n<p>\u041c\u0435\u043d\u044e Gitlab \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0442\u0435\u043c\u0430, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0438 \u0437\u0430 \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a Javascript \u043a\u043e\u0434\u0430, \u0445\u043e\u0442\u044f \u0432\u0441\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a \u043c\u0430\u0433\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 ruby \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041f\u0440\u043e\u0432\u043e\u0434\u044f \u043f\u0435\u0440\u0432\u044b\u0435 \u0438\u0437\u044b\u0441\u043a\u0430\u043d\u0438\u044f \u0432 \u0447\u0430\u0441\u0442\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 Gitlab, \u044f \u0438\u0441\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u043d\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e \u043a 502 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 puma \u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f. \u041c\u0435\u043d\u044e Gitlab, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0441\u043b\u0435\u0432\u0430, \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438\u043c\u0435\u043d\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a sidebar \u0438 \u0438\u043c\u0435\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Gitlab \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0441\u043f\u0440\u0430\u0432\u0430, \u043f\u0440\u043e \u043d\u0435\u0433\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041d\u0438\u0436\u0435 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u043d\u044e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u0435\u043d\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 sidebar, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043f\u043e \u043f\u0443\u0442\u0438 <em>\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars. <\/em>\u041f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u043c\u0435\u043d\u044e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u043d\u043a\u0442\u0430 \u043c\u0435\u043d\u044e.<\/p>\n<p>Gitlab \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e, \u043d\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;<strong>Your Work&#187;<\/strong>. \u0418\u043c\u0435\u043d\u043d\u043e \u043e \u043d\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u0439\u0434\u0451\u0442 \u0440\u0435\u0447\u044c.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e &#171;Your Work&#187;<\/figcaption><\/div>\n<\/figure>\n<p>\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430 ruby, \u043c\u0435\u043d\u044e &#171;Your Work&#187; \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u044e \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <em>\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb<\/em><\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     class Panel &lt; ::Sidebars::Panel       override :configure_menus       def configure_menus         add_menus       end        override :aria_label       def aria_label         _('Your work')       end        override :super_sidebar_context_header       def super_sidebar_context_header         aria_label       end        private        def add_menus         return unless context.current_user          add_menu(Sidebars::YourWork::Menus::ProjectsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::GroupsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::OrganizationsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::IssuesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MergeRequestsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::TodosMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MilestonesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::SnippetsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::ActivityMenu.new(context))       end     end   end end Sidebars::YourWork::Panel.prepend_mod_with('Sidebars::YourWork::Panel') <\/code><\/pre>\n<p>\u0433\u0434\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e Projects \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a<\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     module Menus       class ProjectsMenu &lt; ::Sidebars::Menu         override :link         def link           dashboard_projects_path         end          override :title         def title           _('Projects')         end          override :sprite_icon         def sprite_icon           'project'         end          override :render?         def render?           !!context.current_user         end          override :active_routes         def active_routes           { controller: ['root', 'projects', 'dashboard\/projects'] }         end       end     end   end end <\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0435\u043d\u044e \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u043c\u0435\u043d\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u0444\u043e\u0440\u043c\u0443.<\/p>\n<pre><code class=\"ruby\">add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0444\u0430\u0439\u043b \u0441 \u043c\u0435\u043d\u044e &#171;Your Work&#187; \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a<\/p>\n<pre><code class=\"ruby\"># frozen_string_literal: true  module Sidebars   module YourWork     class Panel &lt; ::Sidebars::Panel       override :configure_menus       def configure_menus         add_menus       end        override :aria_label       def aria_label         _('Your work')       end        override :super_sidebar_context_header       def super_sidebar_context_header         aria_label       end        private        def add_menus         return unless context.current_user          add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))          add_menu(Sidebars::YourWork::Menus::ProjectsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::GroupsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::OrganizationsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::IssuesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MergeRequestsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::TodosMenu.new(context))         add_menu(Sidebars::YourWork::Menus::MilestonesMenu.new(context))         add_menu(Sidebars::YourWork::Menus::SnippetsMenu.new(context))         add_menu(Sidebars::YourWork::Menus::ActivityMenu.new(context))       end     end   end end Sidebars::YourWork::Panel.prepend_mod_with('Sidebars::YourWork::Panel') <\/code><\/pre>\n<p>\u0423 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u043c\u0435\u043d\u044e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e &#171;\u0438\u043a\u043e\u043d\u043a\u0443&#187;, \u0432\u0437\u044f\u0432 \u0435\u0451 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <a href=\"https:\/\/gitlab-org.gitlab.io\/gitlab-svgs\/\" rel=\"noopener noreferrer nofollow\">https:\/\/gitlab-org.gitlab.io\/gitlab-svgs\/<\/a>. \u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>gitlab-ctl restart puma<\/code> \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043d\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u044e.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041d\u043e\u0432\u044b\u0439 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e<\/figcaption><\/div>\n<\/figure>\n<h2>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u0435\u043d\u044e \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c\u0438 ?<\/h2>\n<p>\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;\u041d\u0443 \u0432\u043e\u0442 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b \u044f \u044d\u0442\u043e \u043c\u0435\u043d\u044e, \u0430 \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u043f\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u0442\u044c?&#187;. \u0414\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0435\u0441\u0442\u044c &#171;\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0448 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e \u0432 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>\u041f\u0440\u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430\u043c\u0438 \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 github <a href=\"https:\/\/github.com\/Animalcule\/triggered-edit-deb-package\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Animalcule\/triggered-edit-deb-package<\/a> , \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u0435\u043d \u043c\u0435\u0442\u043e\u0434 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435\/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430<\/p>\n<pre><code>interest \/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u043c \u043d\u0430\u0441 \u0444\u0430\u0439\u043b\u043e\u043c.<\/p>\n<pre><code>#!\/bin\/sh  set -eu  if [ \"$1\" = \"triggered\" ]; then   if [ \"$2\" = \"\/opt\/gitlab\/embedded\/service\/gitlab-rails\/lib\/sidebars\/your_work\/panel.rb\" ]; then     logger \"Fix gitlab 'Your Work' menu\"     line=\"return unless context.current_user\"     addline=\"add_menu(::Sidebars::MenuItem.new(title: _('Helper Menu'), link: '\/-\/helper', sprite_icon: 'text-description', active_routes: {}, super_sidebar_parent: ::Sidebars::YourWork, item_id: :helper))\"     sed -i -e \"\/$line$\/a\"'\\\\n'\"\\t$addline\" \"$2\"   fi fi <\/code><\/pre>\n<p>\u0418\u0437 \u043d\u0430\u0431\u043e\u0440\u0430 \u043d\u0430\u0448\u0438\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f deb \u043f\u0430\u043a\u0435\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0437\u0430\u043c\u0435\u043d\u0435 \u0444\u0430\u0439\u043b\u0430 <code>panel.rb<\/code> \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439\/\u043d\u043e\u0432\u044b\u0439, \u043d\u0430\u0448 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0432 \u043c\u0435\u043d\u044e Gitlab \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u0443\u043d\u043a\u0442. \u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u0441\u0430\u043c \u043f\u0430\u043a\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <a href=\"https:\/\/github.com\/aborche\/gitlab-menu-changer\/\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/aborche\/gitlab-menu-ch<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-379610","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379610","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=379610"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379610\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=379610"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=379610"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=379610"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}