From dffd33252f029901e33883935b20f6b0368d819b Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Sun, 25 Sep 2016 11:55:14 +0200 Subject: [PATCH 01/20] Move reply by email docs to a new location [ci skip] --- config/gitlab.yml.example | 2 +- doc/README.md | 2 +- doc/administration/reply_by_email.md | 302 ++++++++++++++++ .../reply_by_email_postfix_setup.md | 324 ++++++++++++++++++ doc/administration/restart_gitlab.md | 2 +- doc/incoming_email/README.md | 303 +--------------- doc/incoming_email/postfix.md | 322 +---------------- doc/install/installation.md | 2 +- lib/tasks/gitlab/check.rake | 6 +- 9 files changed, 635 insertions(+), 630 deletions(-) create mode 100644 doc/administration/reply_by_email.md create mode 100644 doc/administration/reply_by_email_postfix_setup.md diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 1470a6e2550..b26c9f7ccc9 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -111,7 +111,7 @@ production: &base ## Reply by email # Allow users to comment on issues and merge requests by replying to notification emails. - # For documentation on how to set this up, see http://doc.gitlab.com/ce/incoming_email/README.html + # For documentation on how to set this up, see http://doc.gitlab.com/ce/administration/reply_by_email.html incoming_email: enabled: false diff --git a/doc/README.md b/doc/README.md index dd0eb97489e..cb378e68c60 100644 --- a/doc/README.md +++ b/doc/README.md @@ -42,7 +42,7 @@ - [System hooks](system_hooks/system_hooks.md) Notifications when users, projects and keys are changed. - [Update](update/README.md) Update guides to upgrade your installation. - [Welcome message](customization/welcome_message.md) Add a custom welcome message to the sign-in page. -- [Reply by email](incoming_email/README.md) Allow users to comment on issues and merge requests by replying to notification emails. +- [Reply by email](administration/reply_by_email.md) Allow users to comment on issues and merge requests by replying to notification emails. - [Migrate GitLab CI to CE/EE](migrate_ci_to_ce/README.md) Follow this guide to migrate your existing GitLab CI data to GitLab CE/EE. - [Git LFS configuration](workflow/lfs/lfs_administration.md) - [Housekeeping](administration/housekeeping.md) Keep your Git repository tidy and fast. diff --git a/doc/administration/reply_by_email.md b/doc/administration/reply_by_email.md new file mode 100644 index 00000000000..5a9a1582877 --- /dev/null +++ b/doc/administration/reply_by_email.md @@ -0,0 +1,302 @@ +# Reply by email + +GitLab can be set up to allow users to comment on issues and merge requests by +replying to notification emails. + +## Requirement + +Reply by email requires an IMAP-enabled email account. GitLab allows you to use +three strategies for this feature: +- using email sub-addressing +- using a dedicated email address +- using a catch-all mailbox + +### Email sub-addressing + +**If your provider or server supports email sub-addressing, we recommend using it.** + +[Sub-addressing](https://en.wikipedia.org/wiki/Email_address#Sub-addressing) is +a feature where any email to `user+some_arbitrary_tag@example.com` will end up +in the mailbox for `user@example.com`, and is supported by providers such as +Gmail, Google Apps, Yahoo! Mail, Outlook.com and iCloud, as well as the Postfix +mail server which you can run on-premises. + +### Dedicated email address + +This solution is really simple to set up: you just have to create an email +address dedicated to receive your users' replies to GitLab notifications. + +### Catch-all mailbox + +A [catch-all mailbox](https://en.wikipedia.org/wiki/Catch-all) for a domain will +"catch all" the emails addressed to the domain that do not exist in the mail +server. + +## How it works? + +### 1. GitLab sends a notification email + +When GitLab sends a notification and Reply by email is enabled, the `Reply-To` +header is set to the address defined in your GitLab configuration, with the +`%{key}` placeholder (if present) replaced by a specific "reply key". In +addition, this "reply key" is also added to the `References` header. + +### 2. You reply to the notification email + +When you reply to the notification email, your email client will: + +- send the email to the `Reply-To` address it got from the notification email +- set the `In-Reply-To` header to the value of the `Message-ID` header from the + notification email +- set the `References` header to the value of the `Message-ID` plus the value of + the notification email's `References` header. + +### 3. GitLab receives your reply to the notification email + +When GitLab receives your reply, it will look for the "reply key" in the +following headers, in this order: + +1. the `To` header +1. the `References` header + +If it finds a reply key, it will be able to leave your reply as a comment on +the entity the notification was about (issue, merge request, commit...). + +For more details about the `Message-ID`, `In-Reply-To`, and `References headers`, +please consult [RFC 5322](https://tools.ietf.org/html/rfc5322#section-3.6.4). + +## Set it up + +If you want to use Gmail / Google Apps with Reply by email, make sure you have +[IMAP access enabled](https://support.google.com/mail/troubleshooter/1668960?hl=en#ts=1665018) +and [allowed less secure apps to access the account](https://support.google.com/accounts/answer/6010255). + +To set up a basic Postfix mail server with IMAP access on Ubuntu, follow +[these instructions](./postfix.md). + +### Omnibus package installations + +1. Find the `incoming_email` section in `/etc/gitlab/gitlab.rb`, enable the + feature and fill in the details for your specific IMAP server and email account: + + ```ruby + # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com + gitlab_rails['incoming_email_enabled'] = true + + # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. + # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + gitlab_rails['incoming_email_address'] = "incoming+%{key}@gitlab.example.com" + + # Email account username + # With third party providers, this is usually the full email address. + # With self-hosted email servers, this is usually the user part of the email address. + gitlab_rails['incoming_email_email'] = "incoming" + # Email account password + gitlab_rails['incoming_email_password'] = "[REDACTED]" + + # IMAP server host + gitlab_rails['incoming_email_host'] = "gitlab.example.com" + # IMAP server port + gitlab_rails['incoming_email_port'] = 143 + # Whether the IMAP server uses SSL + gitlab_rails['incoming_email_ssl'] = false + # Whether the IMAP server uses StartTLS + gitlab_rails['incoming_email_start_tls'] = false + + # The mailbox where incoming mail will end up. Usually "inbox". + gitlab_rails['incoming_email_mailbox_name'] = "inbox" + ``` + + ```ruby + # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com + gitlab_rails['incoming_email_enabled'] = true + + # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. + # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com" + + # Email account username + # With third party providers, this is usually the full email address. + # With self-hosted email servers, this is usually the user part of the email address. + gitlab_rails['incoming_email_email'] = "gitlab-incoming@gmail.com" + # Email account password + gitlab_rails['incoming_email_password'] = "[REDACTED]" + + # IMAP server host + gitlab_rails['incoming_email_host'] = "imap.gmail.com" + # IMAP server port + gitlab_rails['incoming_email_port'] = 993 + # Whether the IMAP server uses SSL + gitlab_rails['incoming_email_ssl'] = true + # Whether the IMAP server uses StartTLS + gitlab_rails['incoming_email_start_tls'] = false + + # The mailbox where incoming mail will end up. Usually "inbox". + gitlab_rails['incoming_email_mailbox_name'] = "inbox" + ``` + +1. Reconfigure GitLab and restart mailroom for the changes to take effect: + + ```sh + sudo gitlab-ctl reconfigure + sudo gitlab-ctl restart mailroom + ``` + +1. Verify that everything is configured correctly: + + ```sh + sudo gitlab-rake gitlab:incoming_email:check + ``` + +1. Reply by email should now be working. + +### Installations from source + +1. Go to the GitLab installation directory: + + ```sh + cd /home/git/gitlab + ``` + +1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature + and fill in the details for your specific IMAP server and email account: + + ```sh + sudo editor config/gitlab.yml + ``` + + ```yaml + # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com + incoming_email: + enabled: true + + # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. + # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + address: "incoming+%{key}@gitlab.example.com" + + # Email account username + # With third party providers, this is usually the full email address. + # With self-hosted email servers, this is usually the user part of the email address. + user: "incoming" + # Email account password + password: "[REDACTED]" + + # IMAP server host + host: "gitlab.example.com" + # IMAP server port + port: 143 + # Whether the IMAP server uses SSL + ssl: false + # Whether the IMAP server uses StartTLS + start_tls: false + + # The mailbox where incoming mail will end up. Usually "inbox". + mailbox: "inbox" + ``` + + ```yaml + # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com + incoming_email: + enabled: true + + # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. + # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + address: "gitlab-incoming+%{key}@gmail.com" + + # Email account username + # With third party providers, this is usually the full email address. + # With self-hosted email servers, this is usually the user part of the email address. + user: "gitlab-incoming@gmail.com" + # Email account password + password: "[REDACTED]" + + # IMAP server host + host: "imap.gmail.com" + # IMAP server port + port: 993 + # Whether the IMAP server uses SSL + ssl: true + # Whether the IMAP server uses StartTLS + start_tls: false + + # The mailbox where incoming mail will end up. Usually "inbox". + mailbox: "inbox" + ``` + +1. Enable `mail_room` in the init script at `/etc/default/gitlab`: + + ```sh + sudo mkdir -p /etc/default + echo 'mail_room_enabled=true' | sudo tee -a /etc/default/gitlab + ``` + +1. Restart GitLab: + + ```sh + sudo service gitlab restart + ``` + +1. Verify that everything is configured correctly: + + ```sh + sudo -u git -H bundle exec rake gitlab:incoming_email:check RAILS_ENV=production + ``` + +1. Reply by email should now be working. + +### Development + +1. Go to the GitLab installation directory. + +1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and fill in the details for your specific IMAP server and email account: + + ```yaml + # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com + incoming_email: + enabled: true + + # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. + # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + address: "gitlab-incoming+%{key}@gmail.com" + + # Email account username + # With third party providers, this is usually the full email address. + # With self-hosted email servers, this is usually the user part of the email address. + user: "gitlab-incoming@gmail.com" + # Email account password + password: "[REDACTED]" + + # IMAP server host + host: "imap.gmail.com" + # IMAP server port + port: 993 + # Whether the IMAP server uses SSL + ssl: true + # Whether the IMAP server uses StartTLS + start_tls: false + + # The mailbox where incoming mail will end up. Usually "inbox". + mailbox: "inbox" + ``` + + As mentioned, the part after `+` is ignored, and this will end up in the mailbox for `gitlab-incoming@gmail.com`. + +1. Uncomment the `mail_room` line in your `Procfile`: + + ```yaml + mail_room: bundle exec mail_room -q -c config/mail_room.yml + ``` + +1. Restart GitLab: + + ```sh + bundle exec foreman start + ``` + +1. Verify that everything is configured correctly: + + ```sh + bundle exec rake gitlab:incoming_email:check RAILS_ENV=development + ``` + +1. Reply by email should now be working. diff --git a/doc/administration/reply_by_email_postfix_setup.md b/doc/administration/reply_by_email_postfix_setup.md new file mode 100644 index 00000000000..22f10489a6c --- /dev/null +++ b/doc/administration/reply_by_email_postfix_setup.md @@ -0,0 +1,324 @@ +# Set up Postfix for Reply by email + +This document will take you through the steps of setting up a basic Postfix mail +server with IMAP authentication on Ubuntu, to be used with [Reply by email]. + +The instructions make the assumption that you will be using the email address `incoming@gitlab.example.com`, that is, username `incoming` on host `gitlab.example.com`. Don't forget to change it to your actual host when executing the example code snippets. + +## Configure your server firewall + +1. Open up port 25 on your server so that people can send email into the server over SMTP. +2. If the mail server is different from the server running GitLab, open up port 143 on your server so that GitLab can read email from the server over IMAP. + +## Install packages + +1. Install the `postfix` package if it is not installed already: + + ```sh + sudo apt-get install postfix + ``` + + When asked about the environment, select 'Internet Site'. When asked to confirm the hostname, make sure it matches `gitlab.example.com`. + +1. Install the `mailutils` package. + + ```sh + sudo apt-get install mailutils + ``` + +## Create user + +1. Create a user for incoming email. + + ```sh + sudo useradd -m -s /bin/bash incoming + ``` + +1. Set a password for this user. + + ```sh + sudo passwd incoming + ``` + + Be sure not to forget this, you'll need it later. + +## Test the out-of-the-box setup + +1. Connect to the local SMTP server: + + ```sh + telnet localhost 25 + ``` + + You should see a prompt like this: + + ```sh + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + 220 gitlab.example.com ESMTP Postfix (Ubuntu) + ``` + + If you get a `Connection refused` error instead, verify that `postfix` is running: + + ```sh + sudo postfix status + ``` + + If it is not, start it: + + ```sh + sudo postfix start + ``` + +1. Send the new `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt: + + ``` + ehlo localhost + mail from: root@localhost + rcpt to: incoming@localhost + data + Subject: Re: Some issue + + Sounds good! + . + quit + ``` + + _**Note:** The `.` is a literal period on its own line._ + + _**Note:** If you receive an error after entering `rcpt to: incoming@localhost` + then your Postfix `my_network` configuration is not correct. The error will + say 'Temporary lookup failure'. See + [Configure Postfix to receive email from the Internet](#configure-postfix-to-receive-email-from-the-internet)._ + +1. Check if the `incoming` user received the email: + + ```sh + su - incoming + mail + ``` + + You should see output like this: + + ``` + "/var/mail/incoming": 1 message 1 unread + >U 1 root@localhost 59/2842 Re: Some issue + ``` + + Quit the mail app: + + ```sh + q + ``` + +1. Log out of the `incoming` account and go back to being `root`: + + ```sh + logout + ``` + +## Configure Postfix to use Maildir-style mailboxes + +Courier, which we will install later to add IMAP authentication, requires mailboxes to have the Maildir format, rather than mbox. + +1. Configure Postfix to use Maildir-style mailboxes: + + ```sh + sudo postconf -e "home_mailbox = Maildir/" + ``` + +1. Restart Postfix: + + ```sh + sudo /etc/init.d/postfix restart + ``` + +1. Test the new setup: + + 1. Follow steps 1 and 2 of _[Test the out-of-the-box setup](#test-the-out-of-the-box-setup)_. + 1. Check if the `incoming` user received the email: + + ```sh + su - incoming + MAIL=/home/incoming/Maildir + mail + ``` + + You should see output like this: + + ``` + "/home/incoming/Maildir": 1 message 1 unread + >U 1 root@localhost 59/2842 Re: Some issue + ``` + + Quit the mail app: + + ```sh + q + ``` + + _**Note:** If `mail` returns an error `Maildir: Is a directory` then your + version of `mail` doesn't support Maildir style mailboxes. Install + `heirloom-mailx` by running `sudo apt-get install heirloom-mailx`. Then, + try the above steps again, substituting `heirloom-mailx` for the `mail` + command._ + +1. Log out of the `incoming` account and go back to being `root`: + + ```sh + logout + ``` + +## Install the Courier IMAP server + +1. Install the `courier-imap` package: + + ```sh + sudo apt-get install courier-imap + ``` + +## Configure Postfix to receive email from the internet + +1. Let Postfix know about the domains that it should consider local: + + ```sh + sudo postconf -e "mydestination = gitlab.example.com, localhost.localdomain, localhost" + ``` + +1. Let Postfix know about the IPs that it should consider part of the LAN: + + We'll assume `192.168.1.0/24` is your local LAN. You can safely skip this step if you don't have other machines in the same local network. + + ```sh + sudo postconf -e "mynetworks = 127.0.0.0/8, 192.168.1.0/24" + ``` + +1. Configure Postfix to receive mail on all interfaces, which includes the internet: + + ```sh + sudo postconf -e "inet_interfaces = all" + ``` + +1. Configure Postfix to use the `+` delimiter for sub-addressing: + + ```sh + sudo postconf -e "recipient_delimiter = +" + ``` + +1. Restart Postfix: + + ```sh + sudo service postfix restart + ``` + +## Test the final setup + +1. Test SMTP under the new setup: + + 1. Connect to the SMTP server: + + ```sh + telnet gitlab.example.com 25 + ``` + + You should see a prompt like this: + + ```sh + Trying 123.123.123.123... + Connected to gitlab.example.com. + Escape character is '^]'. + 220 gitlab.example.com ESMTP Postfix (Ubuntu) + ``` + + If you get a `Connection refused` error instead, make sure your firewall is setup to allow inbound traffic on port 25. + + 1. Send the `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt: + + ``` + ehlo gitlab.example.com + mail from: root@gitlab.example.com + rcpt to: incoming@gitlab.example.com + data + Subject: Re: Some issue + + Sounds good! + . + quit + ``` + + (Note: The `.` is a literal period on its own line) + + 1. Check if the `incoming` user received the email: + + ```sh + su - incoming + MAIL=/home/incoming/Maildir + mail + ``` + + You should see output like this: + + ``` + "/home/incoming/Maildir": 1 message 1 unread + >U 1 root@gitlab.example.com 59/2842 Re: Some issue + ``` + + Quit the mail app: + + ```sh + q + ``` + + 1. Log out of the `incoming` account and go back to being `root`: + + ```sh + logout + ``` + +1. Test IMAP under the new setup: + + 1. Connect to the IMAP server: + + ```sh + telnet gitlab.example.com 143 + ``` + + You should see a prompt like this: + + ```sh + Trying 123.123.123.123... + Connected to mail.example.gitlab.com. + Escape character is '^]'. + - OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc. See COPYING for distribution information. + ``` + + 1. Sign in as the `incoming` user to test IMAP, by entering the following into the IMAP prompt: + + ``` + a login incoming PASSWORD + ``` + + Replace PASSWORD with the password you set on the `incoming` user earlier. + + You should see output like this: + + ``` + a OK LOGIN Ok. + ``` + + 1. Disconnect from the IMAP server: + + ```sh + a logout + ``` + +## Done! + +If all the tests were successful, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab. + +--- + +_This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._ + +[reply by email]: reply_by_email.md diff --git a/doc/administration/restart_gitlab.md b/doc/administration/restart_gitlab.md index 483060395dd..b561c2f82aa 100644 --- a/doc/administration/restart_gitlab.md +++ b/doc/administration/restart_gitlab.md @@ -139,7 +139,7 @@ If you are using other init systems, like systemd, you can check the [omnibus-dl]: https://about.gitlab.com/downloads/ "Download the Omnibus packages" [install]: ../install/installation.md "Documentation to install GitLab from source" -[mailroom]: ../incoming_email/README.md "Used for replying by email in GitLab issues and merge requests" +[mailroom]: reply_by_email.md "Used for replying by email in GitLab issues and merge requests" [chef]: https://www.chef.io/chef/ "Chef official website" [src-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/support/init.d/gitlab "GitLab init service file" [gl-recipes]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/init "GitLab Recipes repository" diff --git a/doc/incoming_email/README.md b/doc/incoming_email/README.md index 5a9a1582877..db0f03f2c98 100644 --- a/doc/incoming_email/README.md +++ b/doc/incoming_email/README.md @@ -1,302 +1 @@ -# Reply by email - -GitLab can be set up to allow users to comment on issues and merge requests by -replying to notification emails. - -## Requirement - -Reply by email requires an IMAP-enabled email account. GitLab allows you to use -three strategies for this feature: -- using email sub-addressing -- using a dedicated email address -- using a catch-all mailbox - -### Email sub-addressing - -**If your provider or server supports email sub-addressing, we recommend using it.** - -[Sub-addressing](https://en.wikipedia.org/wiki/Email_address#Sub-addressing) is -a feature where any email to `user+some_arbitrary_tag@example.com` will end up -in the mailbox for `user@example.com`, and is supported by providers such as -Gmail, Google Apps, Yahoo! Mail, Outlook.com and iCloud, as well as the Postfix -mail server which you can run on-premises. - -### Dedicated email address - -This solution is really simple to set up: you just have to create an email -address dedicated to receive your users' replies to GitLab notifications. - -### Catch-all mailbox - -A [catch-all mailbox](https://en.wikipedia.org/wiki/Catch-all) for a domain will -"catch all" the emails addressed to the domain that do not exist in the mail -server. - -## How it works? - -### 1. GitLab sends a notification email - -When GitLab sends a notification and Reply by email is enabled, the `Reply-To` -header is set to the address defined in your GitLab configuration, with the -`%{key}` placeholder (if present) replaced by a specific "reply key". In -addition, this "reply key" is also added to the `References` header. - -### 2. You reply to the notification email - -When you reply to the notification email, your email client will: - -- send the email to the `Reply-To` address it got from the notification email -- set the `In-Reply-To` header to the value of the `Message-ID` header from the - notification email -- set the `References` header to the value of the `Message-ID` plus the value of - the notification email's `References` header. - -### 3. GitLab receives your reply to the notification email - -When GitLab receives your reply, it will look for the "reply key" in the -following headers, in this order: - -1. the `To` header -1. the `References` header - -If it finds a reply key, it will be able to leave your reply as a comment on -the entity the notification was about (issue, merge request, commit...). - -For more details about the `Message-ID`, `In-Reply-To`, and `References headers`, -please consult [RFC 5322](https://tools.ietf.org/html/rfc5322#section-3.6.4). - -## Set it up - -If you want to use Gmail / Google Apps with Reply by email, make sure you have -[IMAP access enabled](https://support.google.com/mail/troubleshooter/1668960?hl=en#ts=1665018) -and [allowed less secure apps to access the account](https://support.google.com/accounts/answer/6010255). - -To set up a basic Postfix mail server with IMAP access on Ubuntu, follow -[these instructions](./postfix.md). - -### Omnibus package installations - -1. Find the `incoming_email` section in `/etc/gitlab/gitlab.rb`, enable the - feature and fill in the details for your specific IMAP server and email account: - - ```ruby - # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com - gitlab_rails['incoming_email_enabled'] = true - - # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. - # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). - gitlab_rails['incoming_email_address'] = "incoming+%{key}@gitlab.example.com" - - # Email account username - # With third party providers, this is usually the full email address. - # With self-hosted email servers, this is usually the user part of the email address. - gitlab_rails['incoming_email_email'] = "incoming" - # Email account password - gitlab_rails['incoming_email_password'] = "[REDACTED]" - - # IMAP server host - gitlab_rails['incoming_email_host'] = "gitlab.example.com" - # IMAP server port - gitlab_rails['incoming_email_port'] = 143 - # Whether the IMAP server uses SSL - gitlab_rails['incoming_email_ssl'] = false - # Whether the IMAP server uses StartTLS - gitlab_rails['incoming_email_start_tls'] = false - - # The mailbox where incoming mail will end up. Usually "inbox". - gitlab_rails['incoming_email_mailbox_name'] = "inbox" - ``` - - ```ruby - # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com - gitlab_rails['incoming_email_enabled'] = true - - # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. - # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). - gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com" - - # Email account username - # With third party providers, this is usually the full email address. - # With self-hosted email servers, this is usually the user part of the email address. - gitlab_rails['incoming_email_email'] = "gitlab-incoming@gmail.com" - # Email account password - gitlab_rails['incoming_email_password'] = "[REDACTED]" - - # IMAP server host - gitlab_rails['incoming_email_host'] = "imap.gmail.com" - # IMAP server port - gitlab_rails['incoming_email_port'] = 993 - # Whether the IMAP server uses SSL - gitlab_rails['incoming_email_ssl'] = true - # Whether the IMAP server uses StartTLS - gitlab_rails['incoming_email_start_tls'] = false - - # The mailbox where incoming mail will end up. Usually "inbox". - gitlab_rails['incoming_email_mailbox_name'] = "inbox" - ``` - -1. Reconfigure GitLab and restart mailroom for the changes to take effect: - - ```sh - sudo gitlab-ctl reconfigure - sudo gitlab-ctl restart mailroom - ``` - -1. Verify that everything is configured correctly: - - ```sh - sudo gitlab-rake gitlab:incoming_email:check - ``` - -1. Reply by email should now be working. - -### Installations from source - -1. Go to the GitLab installation directory: - - ```sh - cd /home/git/gitlab - ``` - -1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature - and fill in the details for your specific IMAP server and email account: - - ```sh - sudo editor config/gitlab.yml - ``` - - ```yaml - # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com - incoming_email: - enabled: true - - # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. - # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). - address: "incoming+%{key}@gitlab.example.com" - - # Email account username - # With third party providers, this is usually the full email address. - # With self-hosted email servers, this is usually the user part of the email address. - user: "incoming" - # Email account password - password: "[REDACTED]" - - # IMAP server host - host: "gitlab.example.com" - # IMAP server port - port: 143 - # Whether the IMAP server uses SSL - ssl: false - # Whether the IMAP server uses StartTLS - start_tls: false - - # The mailbox where incoming mail will end up. Usually "inbox". - mailbox: "inbox" - ``` - - ```yaml - # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com - incoming_email: - enabled: true - - # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. - # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). - address: "gitlab-incoming+%{key}@gmail.com" - - # Email account username - # With third party providers, this is usually the full email address. - # With self-hosted email servers, this is usually the user part of the email address. - user: "gitlab-incoming@gmail.com" - # Email account password - password: "[REDACTED]" - - # IMAP server host - host: "imap.gmail.com" - # IMAP server port - port: 993 - # Whether the IMAP server uses SSL - ssl: true - # Whether the IMAP server uses StartTLS - start_tls: false - - # The mailbox where incoming mail will end up. Usually "inbox". - mailbox: "inbox" - ``` - -1. Enable `mail_room` in the init script at `/etc/default/gitlab`: - - ```sh - sudo mkdir -p /etc/default - echo 'mail_room_enabled=true' | sudo tee -a /etc/default/gitlab - ``` - -1. Restart GitLab: - - ```sh - sudo service gitlab restart - ``` - -1. Verify that everything is configured correctly: - - ```sh - sudo -u git -H bundle exec rake gitlab:incoming_email:check RAILS_ENV=production - ``` - -1. Reply by email should now be working. - -### Development - -1. Go to the GitLab installation directory. - -1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and fill in the details for your specific IMAP server and email account: - - ```yaml - # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com - incoming_email: - enabled: true - - # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. - # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). - address: "gitlab-incoming+%{key}@gmail.com" - - # Email account username - # With third party providers, this is usually the full email address. - # With self-hosted email servers, this is usually the user part of the email address. - user: "gitlab-incoming@gmail.com" - # Email account password - password: "[REDACTED]" - - # IMAP server host - host: "imap.gmail.com" - # IMAP server port - port: 993 - # Whether the IMAP server uses SSL - ssl: true - # Whether the IMAP server uses StartTLS - start_tls: false - - # The mailbox where incoming mail will end up. Usually "inbox". - mailbox: "inbox" - ``` - - As mentioned, the part after `+` is ignored, and this will end up in the mailbox for `gitlab-incoming@gmail.com`. - -1. Uncomment the `mail_room` line in your `Procfile`: - - ```yaml - mail_room: bundle exec mail_room -q -c config/mail_room.yml - ``` - -1. Restart GitLab: - - ```sh - bundle exec foreman start - ``` - -1. Verify that everything is configured correctly: - - ```sh - bundle exec rake gitlab:incoming_email:check RAILS_ENV=development - ``` - -1. Reply by email should now be working. +This document was moved to [administration/reply_by_email](../administration/reply_by_email.md). diff --git a/doc/incoming_email/postfix.md b/doc/incoming_email/postfix.md index 787d21f7f8f..90833238ac5 100644 --- a/doc/incoming_email/postfix.md +++ b/doc/incoming_email/postfix.md @@ -1,321 +1 @@ -# Set up Postfix for Reply by email - -This document will take you through the steps of setting up a basic Postfix mail server with IMAP authentication on Ubuntu, to be used with Reply by email. - -The instructions make the assumption that you will be using the email address `incoming@gitlab.example.com`, that is, username `incoming` on host `gitlab.example.com`. Don't forget to change it to your actual host when executing the example code snippets. - -## Configure your server firewall - -1. Open up port 25 on your server so that people can send email into the server over SMTP. -2. If the mail server is different from the server running GitLab, open up port 143 on your server so that GitLab can read email from the server over IMAP. - -## Install packages - -1. Install the `postfix` package if it is not installed already: - - ```sh - sudo apt-get install postfix - ``` - - When asked about the environment, select 'Internet Site'. When asked to confirm the hostname, make sure it matches `gitlab.example.com`. - -1. Install the `mailutils` package. - - ```sh - sudo apt-get install mailutils - ``` - -## Create user - -1. Create a user for incoming email. - - ```sh - sudo useradd -m -s /bin/bash incoming - ``` - -1. Set a password for this user. - - ```sh - sudo passwd incoming - ``` - - Be sure not to forget this, you'll need it later. - -## Test the out-of-the-box setup - -1. Connect to the local SMTP server: - - ```sh - telnet localhost 25 - ``` - - You should see a prompt like this: - - ```sh - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - 220 gitlab.example.com ESMTP Postfix (Ubuntu) - ``` - - If you get a `Connection refused` error instead, verify that `postfix` is running: - - ```sh - sudo postfix status - ``` - - If it is not, start it: - - ```sh - sudo postfix start - ``` - -1. Send the new `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt: - - ``` - ehlo localhost - mail from: root@localhost - rcpt to: incoming@localhost - data - Subject: Re: Some issue - - Sounds good! - . - quit - ``` - - _**Note:** The `.` is a literal period on its own line._ - - _**Note:** If you receive an error after entering `rcpt to: incoming@localhost` - then your Postfix `my_network` configuration is not correct. The error will - say 'Temporary lookup failure'. See - [Configure Postfix to receive email from the Internet](#configure-postfix-to-receive-email-from-the-internet)._ - -1. Check if the `incoming` user received the email: - - ```sh - su - incoming - mail - ``` - - You should see output like this: - - ``` - "/var/mail/incoming": 1 message 1 unread - >U 1 root@localhost 59/2842 Re: Some issue - ``` - - Quit the mail app: - - ```sh - q - ``` - -1. Log out of the `incoming` account and go back to being `root`: - - ```sh - logout - ``` - -## Configure Postfix to use Maildir-style mailboxes - -Courier, which we will install later to add IMAP authentication, requires mailboxes to have the Maildir format, rather than mbox. - -1. Configure Postfix to use Maildir-style mailboxes: - - ```sh - sudo postconf -e "home_mailbox = Maildir/" - ``` - -1. Restart Postfix: - - ```sh - sudo /etc/init.d/postfix restart - ``` - -1. Test the new setup: - - 1. Follow steps 1 and 2 of _[Test the out-of-the-box setup](#test-the-out-of-the-box-setup)_. - 1. Check if the `incoming` user received the email: - - ```sh - su - incoming - MAIL=/home/incoming/Maildir - mail - ``` - - You should see output like this: - - ``` - "/home/incoming/Maildir": 1 message 1 unread - >U 1 root@localhost 59/2842 Re: Some issue - ``` - - Quit the mail app: - - ```sh - q - ``` - - _**Note:** If `mail` returns an error `Maildir: Is a directory` then your - version of `mail` doesn't support Maildir style mailboxes. Install - `heirloom-mailx` by running `sudo apt-get install heirloom-mailx`. Then, - try the above steps again, substituting `heirloom-mailx` for the `mail` - command._ - -1. Log out of the `incoming` account and go back to being `root`: - - ```sh - logout - ``` - -## Install the Courier IMAP server - -1. Install the `courier-imap` package: - - ```sh - sudo apt-get install courier-imap - ``` - -## Configure Postfix to receive email from the internet - -1. Let Postfix know about the domains that it should consider local: - - ```sh - sudo postconf -e "mydestination = gitlab.example.com, localhost.localdomain, localhost" - ``` - -1. Let Postfix know about the IPs that it should consider part of the LAN: - - We'll assume `192.168.1.0/24` is your local LAN. You can safely skip this step if you don't have other machines in the same local network. - - ```sh - sudo postconf -e "mynetworks = 127.0.0.0/8, 192.168.1.0/24" - ``` - -1. Configure Postfix to receive mail on all interfaces, which includes the internet: - - ```sh - sudo postconf -e "inet_interfaces = all" - ``` - -1. Configure Postfix to use the `+` delimiter for sub-addressing: - - ```sh - sudo postconf -e "recipient_delimiter = +" - ``` - -1. Restart Postfix: - - ```sh - sudo service postfix restart - ``` - -## Test the final setup - -1. Test SMTP under the new setup: - - 1. Connect to the SMTP server: - - ```sh - telnet gitlab.example.com 25 - ``` - - You should see a prompt like this: - - ```sh - Trying 123.123.123.123... - Connected to gitlab.example.com. - Escape character is '^]'. - 220 gitlab.example.com ESMTP Postfix (Ubuntu) - ``` - - If you get a `Connection refused` error instead, make sure your firewall is setup to allow inbound traffic on port 25. - - 1. Send the `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt: - - ``` - ehlo gitlab.example.com - mail from: root@gitlab.example.com - rcpt to: incoming@gitlab.example.com - data - Subject: Re: Some issue - - Sounds good! - . - quit - ``` - - (Note: The `.` is a literal period on its own line) - - 1. Check if the `incoming` user received the email: - - ```sh - su - incoming - MAIL=/home/incoming/Maildir - mail - ``` - - You should see output like this: - - ``` - "/home/incoming/Maildir": 1 message 1 unread - >U 1 root@gitlab.example.com 59/2842 Re: Some issue - ``` - - Quit the mail app: - - ```sh - q - ``` - - 1. Log out of the `incoming` account and go back to being `root`: - - ```sh - logout - ``` - -1. Test IMAP under the new setup: - - 1. Connect to the IMAP server: - - ```sh - telnet gitlab.example.com 143 - ``` - - You should see a prompt like this: - - ```sh - Trying 123.123.123.123... - Connected to mail.example.gitlab.com. - Escape character is '^]'. - - OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc. See COPYING for distribution information. - ``` - - 1. Sign in as the `incoming` user to test IMAP, by entering the following into the IMAP prompt: - - ``` - a login incoming PASSWORD - ``` - - Replace PASSWORD with the password you set on the `incoming` user earlier. - - You should see output like this: - - ``` - a OK LOGIN Ok. - ``` - - 1. Disconnect from the IMAP server: - - ```sh - a logout - ``` - -## Done! - -If all the tests were successful, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab. - ---------- - -_This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._ +This document was moved to [administration/reply_by_email_postfix_setup](../administration/reply_by_email_postfix_setup.md). diff --git a/doc/install/installation.md b/doc/install/installation.md index 3ac813aa914..da3f92f9a6c 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -563,7 +563,7 @@ Using a self-signed certificate is discouraged but if you must use it follow the ### Enable Reply by email -See the ["Reply by email" documentation](../incoming_email/README.md) for more information on how to set this up. +See the ["Reply by email" documentation](../administration/reply_by_email.md) for more information on how to set this up. ### LDAP Authentication diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 5f4a6bbfa35..2ae48a970ce 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -671,7 +671,7 @@ namespace :gitlab do "Enable mail_room in the init.d configuration." ) for_more_information( - "doc/incoming_email/README.md" + "doc/administration/reply_by_email.md" ) fix_and_rerun end @@ -690,7 +690,7 @@ namespace :gitlab do "Enable mail_room in your Procfile." ) for_more_information( - "doc/incoming_email/README.md" + "doc/administration/reply_by_email.md" ) fix_and_rerun end @@ -747,7 +747,7 @@ namespace :gitlab do "Check that the information in config/gitlab.yml is correct" ) for_more_information( - "doc/incoming_email/README.md" + "doc/administration/reply_by_email.md" ) fix_and_rerun end From ffec230f537776959f40e66c3cb0809bb9c173b1 Mon Sep 17 00:00:00 2001 From: TMate Software Support Date: Tue, 27 Sep 2016 16:28:19 +0000 Subject: [PATCH 02/20] Update migrating_from_svn.md Documentation updated to cover Git/SVN mirror approach to migration from SVN to GitLab. --- doc/workflow/importing/migrating_from_svn.md | 92 +++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/doc/workflow/importing/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md index 4828bb5dce6..76839315c53 100644 --- a/doc/workflow/importing/migrating_from_svn.md +++ b/doc/workflow/importing/migrating_from_svn.md @@ -4,6 +4,94 @@ Subversion (SVN) is a central version control system (VCS) while Git is a distributed version control system. There are some major differences between the two, for more information consult your favorite search engine. +## Overview + +There are two approaches to SVN to Git migration: + +#### [Git/SVN Mirror](#mirror) + + Make GitLab repository mirror SVN project. + + Git and SVN project are kept in sync; use either one or another. + + Smoothens migration process and allows to manage migration risks. + +#### [Cut over migration](#cutover) + + Translate existing data and history from SVN to Git. + + Fire and forget approach, good for smaller teams. + +## Smooth migration with a Git/SVN mirror using SubGit + +#### Prerequisites + +Install Oracle JRE 1.8 or newer. On Debian-based Linux distributions follow this +[instruction](http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html). + +Download SubGit tool from [https://subgit.com/download/](https://subgit.com/download/) + +Unpack downloaded SubGit zip archive to `/opt` directory, subgit will be available +at `/opt/subgit-VERSION/bin/subgit` + +#### Configuration + +In GitLab create new empty repository. In filesystem it will be located at +`/var/opt/gitlab/git-data/repositories/USER/REPOS.git` path. + +Run SubGit to set up a Git/SVN mirror. Make sure `subgit` command is ran +on behalf of the same user that runs GitLab. + +``` +subgit configure --layout auto SVN_PROJECT_URL GIT_REPOS_PATH +``` + +Adjust authors and branches mappings, if necessary: + +``` +edit GIT_REPOS_PATH/subgit/authors.txt +edit GIT_REPOS_PATH/subgit/config +``` + +For more information regarding SubGit configuration options, refer to +[documentation](https://subgit.com/documentation.html) at SubGit web site. + +#### Initial translation + +Run `subgit` to perform initial translation of existing SVN revisions into +Git repository: + +``` +subgit install GIT_REPOS_PATH +``` + +After initial translation is completed, GitLab Git repository and SVN project +will be kept in sync by `subgit` - new Git commits will be translated to SVN +revisions and new SVN revisions will be translated to Git commits. Mirror works +transparently and does not require any special commands. + +Would you prefer to perform one-time cut over migration with `subgit` use +`import` command in place of `install`: + +``` +subgit import GIT_REPOS_PATH +``` + +#### Licensing + +Running SubGit in a mirror mode requires [registration](https://subgit.com/pricing.html). Registration is free for Open Source, +Academic and Startup projects. + +We're currently working on deeper GitLab/SubGit intergation. You may track our +progress at [this issue](https://gitlab.com/gitlab-org/gitlab-ee/issues/990). + +#### Support + +For any questions related to SVN to GitLab migration with SubGit contact us at [support@subgit.com](mailto:support@subgit.com). We support +all our users. + +## Cut over migration with svn2git + If you are currently using an SVN repository, you can migrate the repository to Git and GitLab. We recommend a hard cut over - run the migration command once and then have all developers start using the new GitLab repository immediately. @@ -74,6 +162,4 @@ git push --tags origin ## Contribute to this guide We welcome all contributions that would expand this guide with instructions on -how to migrate from SVN and other version control systems. - - +how to migrate from SVN and other version control systems. \ No newline at end of file From cc8ad60fc42e9a115da63f0e0eca71c4b2567c35 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Mon, 12 Sep 2016 12:19:20 +0200 Subject: [PATCH 03/20] Update pipeline graph styles to match mockup --- app/assets/javascripts/pipeline.js.es6 | 9 ++++++ app/assets/stylesheets/pages/pipelines.scss | 36 ++++++++++++--------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index 8813bb5dfef..d3ed9757afe 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -1,4 +1,12 @@ (function() { + + function addMarginToBuild () { + const $secondChild = $('.build:nth-child(2)'); + if ($secondChild.length) { + $secondChild.closest('.stage-column').addClass('left-margin'); + } + } + function toggleGraph() { const $pipelineBtn = $(this).closest('.toggle-pipeline-btn'); const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph'); @@ -21,4 +29,5 @@ } $(document).on('click', '.toggle-pipeline-btn', toggleGraph); + $(document).on('ready', addMarginToBuild); })(); diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index a2779704eff..e7e1a2a9b18 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -303,7 +303,13 @@ .stage-column { display: inline-block; vertical-align: top; - margin-right: 65px; + margin-right: 48px; + + &.left-margin { + &:not(:first-child) { + margin-left: 48px; + } + } li { list-style: none; @@ -321,9 +327,9 @@ .build { border: 1px solid $border-color; position: relative; - padding: 6px 10px; + padding: 8px 10px; border-radius: 30px; - width: 150px; + width: 186px; margin-bottom: 10px; &.playable { @@ -443,9 +449,9 @@ content: ''; position: absolute; top: 50%; - right: -69px; + right: -48px; border-top: 2px solid $border-color; - width: 69px; + width: 48px; height: 1px; } } @@ -457,22 +463,22 @@ top: -47px; position: absolute; border-bottom: 2px solid $border-color; - width: 20px; + width: 25px; height: 65px; } // Right connecting curves &::after { - right: -20px; + right: -25px; border-right: 2px solid $border-color; - border-radius: 0 0 15px; + border-radius: 0 0 20px; } // Left connecting curves &::before { - left: -20px; + left: -25px; border-left: 2px solid $border-color; - border-radius: 0 0 0 15px; + border-radius: 0 0 0 20px; } } @@ -538,20 +544,20 @@ width: 21px; height: 25px; position: absolute; - top: -29px; + top: -30px; border-top: 2px solid $border-color; } &::after { - left: -39px; + left: -44px; border-right: 2px solid $border-color; - border-radius: 0 15px; + border-radius: 0 20px; } &::before { - right: -39px; + right: -44px; border-left: 2px solid $border-color; - border-radius: 15px 0 0; + border-radius: 20px 0 0; } } } From ff0f70c0fe75773d060ecf5cf75d6fc5f879283b Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Wed, 14 Sep 2016 13:51:36 +0200 Subject: [PATCH 04/20] Change length of connecting lines based on number of builds --- app/assets/javascripts/pipeline.js.es6 | 9 +++++--- app/assets/stylesheets/pages/pipelines.scss | 24 ++++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index d3ed9757afe..f501761b1ec 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -1,9 +1,12 @@ (function() { function addMarginToBuild () { - const $secondChild = $('.build:nth-child(2)'); - if ($secondChild.length) { - $secondChild.closest('.stage-column').addClass('left-margin'); + const $secondChildBuildNode = $('.build:nth-child(2)'); + const $firstChildBuildNode = $secondChildBuildNode.prev('.build'); + // const $previousBuildColumn = $secondChildBuildNode.closest('.stage-column').prev('.stage-column'); + if ($secondChildBuildNode.length) { + $secondChildBuildNode.closest('.stage-column').addClass('left-margin'); + $firstChildBuildNode.addClass('left-connector'); } } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index e7e1a2a9b18..37df702ea13 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -303,11 +303,26 @@ .stage-column { display: inline-block; vertical-align: top; - margin-right: 48px; + + &:not(:last-child) { + margin-right: 44px; + } &.left-margin { &:not(:first-child) { - margin-left: 48px; + margin-left: 44px; + + .left-connector { + &::before { + content: ''; + position: absolute; + top: 50%; + left: -48px; + border-top: 2px solid $border-color; + width: 48px; + height: 1px; + } + } } } @@ -348,7 +363,10 @@ } .build-content { - width: 130px; + width: 164px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; .ci-status-text { width: 110px; From 65e482e7e9b7385e6d8ee72c102eca6e79ee97fa Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Fri, 16 Sep 2016 09:44:00 +0200 Subject: [PATCH 05/20] Change size of pipeline status icons and dropdowns --- app/assets/stylesheets/pages/pipelines.scss | 47 ++++++++++++------- .../ci/builds/_build_pipeline.html.haml | 6 ++- .../commit/_pipeline_status_group.html.haml | 3 +- .../_generic_commit_status_pipeline.html.haml | 6 ++- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 37df702ea13..547b9742dff 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -331,9 +331,9 @@ } .stage-name { - margin-bottom: 15px; + margin: 0 0 15px 10px; font-weight: bold; - width: 150px; + width: 176px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -364,12 +364,17 @@ .build-content { width: 164px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + + .ci-status-icon { + + svg { + height: 20px; + width: 20px; + } + } .ci-status-text { - width: 110px; + width: 135px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -397,27 +402,37 @@ color: $layout-link-gray; .ci-status-text { - width: 80px; + width: 112px; } } .grouped-pipeline-dropdown { padding: 8px 0; - width: 200px; + width: 168px; left: auto; - right: -214px; + right: -180px; top: -9px; max-height: 245px; overflow-y: scroll; - a:hover { - .ci-status-text { - text-decoration: none; + a { + padding: 7px 8px; + margin: 0 8px; + + &:hover { + .ci-status-text { + text-decoration: none; + } } } + svg { + width: 14px; + height: 14px; + } + .ci-status-text { - width: 145px; + width: 112px; } .arrow { @@ -482,7 +497,7 @@ position: absolute; border-bottom: 2px solid $border-color; width: 25px; - height: 65px; + height: 69px; } // Right connecting curves @@ -504,7 +519,7 @@ &:nth-child(2) { &::after, &::before { height: 29px; - top: -10px; + top: -7px; } .curve { display: block; @@ -562,7 +577,7 @@ width: 21px; height: 25px; position: absolute; - top: -30px; + top: -31.5px; border-top: 2px solid $border-color; } diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 547bc0c9c19..017d3ff6af2 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -5,8 +5,10 @@ .ci-status-text= subject.name - elsif can?(current_user, :read_build, @project) = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject) do - = render_status_with_link('build', subject.status) + %span.ci-status-icon + = render_status_with_link('build', subject.status) .ci-status-text= subject.name - else - = render_status_with_link('build', subject.status) + %span.ci-status-icon + = render_status_with_link('build', subject.status) = ci_icon_for_status(subject.status) diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index 4e7a6f1af08..2064242ab54 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -1,5 +1,6 @@ - group_status = CommitStatus.where(id: subject).status -= render_status_with_link('build', group_status) +%span.ci-status-icon + = render_status_with_link('build', group_status) .dropdown.inline %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } %span.ci-status-text diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml index 409f4701e4b..0a66d60accc 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml @@ -1,7 +1,9 @@ - if subject.target_url = link_to subject.target_url do - = render_status_with_link('commit status', subject.status) + %span.ci-status-icon + = render_status_with_link('commit status', subject.status) %span.ci-status-text= subject.name - else - = render_status_with_link('commit status', subject.status) + %span.ci-status-icon + = render_status_with_link('commit status', subject.status) %span.ci-status-text= subject.name From eb55ac7d4d13a2c404d24c68cef10675ce29cf3c Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Wed, 21 Sep 2016 01:45:39 +0100 Subject: [PATCH 06/20] Added final changes from handover --- .../stylesheets/framework/variables.scss | 5 +++ app/assets/stylesheets/pages/pipelines.scss | 38 +++++++++++-------- .../projects/commit/_pipeline_stage.html.haml | 2 +- .../commit/_pipeline_status_group.html.haml | 17 ++++----- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 14ec310de2d..4c34ed3ebf7 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -17,8 +17,10 @@ $white-normal: #ededed; $white-dark: #ececec; $gray-light: #fafafa; +$gray-lighter: #f9f9f9; $gray-normal: #f5f5f5; $gray-dark: #ededed; +$gray-darker: #eee; $gray-darkest: #c9c9c9; $green-light: #38ae67; @@ -33,6 +35,8 @@ $blue-medium-light: #3498cb; $blue-medium: #2f8ebf; $blue-medium-dark: #2d86b4; +$blue-light-transparent: rgba(44, 159, 216, 0.05); + $orange-light: #fc8a51; $orange-normal: #e75e40; $orange-dark: #ce5237; @@ -91,6 +95,7 @@ $table-text-gray: #8f8f8f; $gl-font-size: 15px; $gl-title-color: #333; $gl-text-color: #5c5c5c; +$gl-text-color-light: #8c8c8c; $gl-text-green: #4a2; $gl-text-red: #d12f19; $gl-text-orange: #d90; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 547b9742dff..36c57f3ca30 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -342,11 +342,18 @@ .build { border: 1px solid $border-color; position: relative; - padding: 8px 10px; + padding: 7px 10px 8px; border-radius: 30px; width: 186px; margin-bottom: 10px; + &:hover { + background-color: $gray-lighter; + .dropdown-menu-toggle { + background-color: transparent; + } + } + &.playable { background-color: $gray-light; @@ -366,7 +373,6 @@ width: 164px; .ci-status-icon { - svg { height: 20px; width: 20px; @@ -385,41 +391,40 @@ } a { - color: $layout-link-gray; + color: $gl-text-color-light; text-decoration: none; - - &:hover { - .ci-status-text { - text-decoration: underline; - } - } } .dropdown-menu-toggle { border: none; width: auto; padding: 0; - color: $layout-link-gray; + color: $gl-text-color-light; .ci-status-text { - width: 112px; + max-width: 112px; + width: auto; } } .grouped-pipeline-dropdown { padding: 8px 0; - width: 168px; + width: 186px; left: auto; - right: -180px; + right: -197px; top: -9px; max-height: 245px; overflow-y: scroll; a { - padding: 7px 8px; + color: $gl-text-color; + padding: 7px 8px 8px; margin: 0 8px; &:hover { + background-color: $blue-light-transparent; + border-radius: 3px; + .ci-status-text { text-decoration: none; } @@ -465,9 +470,10 @@ } .badge { - background-color: $gray-dark; - color: $layout-link-gray; + background-color: $gray-darker; + color: $gl-text-color-light; font-weight: normal; + margin-left: $btn-xs-side-margin; } } diff --git a/app/views/projects/commit/_pipeline_stage.html.haml b/app/views/projects/commit/_pipeline_stage.html.haml index 23c5c51fbc2..68d42126bf6 100644 --- a/app/views/projects/commit/_pipeline_stage.html.haml +++ b/app/views/projects/commit/_pipeline_stage.html.haml @@ -10,5 +10,5 @@ - else %li.build .curve - .build-content + .dropdown.inline.build-content{ type: 'button', data: { toggle: 'dropdown' } } = render "projects/commit/pipeline_status_group", name: group_name, subject: grouped_statuses diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index 2064242ab54..bff65bff653 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -1,12 +1,11 @@ - group_status = CommitStatus.where(id: subject).status %span.ci-status-icon = render_status_with_link('build', group_status) -.dropdown.inline - %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } - %span.ci-status-text - = name - %span.badge= subject.size - %ul.dropdown-menu.grouped-pipeline-dropdown - .arrow - - subject.each do |status| - = render "projects/#{status.to_partial_path}_pipeline", subject: status +%button.dropdown-menu-toggle + %span.ci-status-text + = name + %span.badge= subject.size +%ul.dropdown-menu.grouped-pipeline-dropdown + .arrow + - subject.each do |status| + = render "projects/#{status.to_partial_path}_pipeline", subject: status From 5defad2d21b6481c07fb4a77f0a56ed7c19ff899 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Thu, 29 Sep 2016 22:24:37 +0100 Subject: [PATCH 07/20] Finished up margin JS logic --- app/assets/javascripts/dispatcher.js | 3 + app/assets/javascripts/pipeline.js.es6 | 66 ++++++++-------- app/assets/stylesheets/pages/pipelines.scss | 4 + app/views/projects/commit/_pipeline.html.haml | 79 ++++++++++--------- 4 files changed, 82 insertions(+), 70 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 8d99b12102d..45494afe7aa 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -126,6 +126,9 @@ new TreeView(); } break; + case 'projects:pipelines:show': + new window.gl.Pipelines(); + break; case 'groups:activity': new Activities(); break; diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index f501761b1ec..6299ba2269d 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -1,36 +1,40 @@ -(function() { +((global) => { - function addMarginToBuild () { - const $secondChildBuildNode = $('.build:nth-child(2)'); - const $firstChildBuildNode = $secondChildBuildNode.prev('.build'); - // const $previousBuildColumn = $secondChildBuildNode.closest('.stage-column').prev('.stage-column'); - if ($secondChildBuildNode.length) { - $secondChildBuildNode.closest('.stage-column').addClass('left-margin'); - $firstChildBuildNode.addClass('left-connector'); + class Pipelines { + constructor() { + $(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph); + $(document).off('ready.addMarginToBuildColumns').on('ready.addMarginToBuildColumns', this.addMarginToBuildColumns); + } + + toggleGraph() { + const $pipelineBtn = $(this).closest('.toggle-pipeline-btn'); + const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph'); + const $btnText = $(this).find('.toggle-btn-text'); + + $($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed'); + + const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed'); + + graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') + } + + addMarginToBuildColumns() { + const $secondChildBuildNode = $('.build:nth-child(2)'); + if ($secondChildBuildNode.length) { + const $firstChildBuildNode = $secondChildBuildNode.prev('.build'); + const $multiBuildColumn = $secondChildBuildNode.closest('.stage-column'); + const $previousColumn = $multiBuildColumn.prev('.stage-column'); + $multiBuildColumn.addClass('left-margin'); + $firstChildBuildNode.addClass('left-connector'); + $previousColumn.each(function() { + $this = $(this); + if ($('.build', $this).length === 1) $this.addClass('no-margin'); + }); + } + $('.pipeline-graph-container').removeClass('hidden'); } } - function toggleGraph() { - const $pipelineBtn = $(this).closest('.toggle-pipeline-btn'); - const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph'); - const $btnText = $(this).find('.toggle-btn-text'); - const $icon = $(this).find('.fa'); + global.Pipelines = Pipelines; - $($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed'); - - const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed'); - const expandIcon = 'fa-caret-down'; - const hideIcon = 'fa-caret-up'; - - if(graphCollapsed) { - $btnText.text('Expand'); - $icon.removeClass(hideIcon).addClass(expandIcon); - } else { - $btnText.text('Hide'); - $icon.removeClass(expandIcon).addClass(hideIcon); - } - } - - $(document).on('click', '.toggle-pipeline-btn', toggleGraph); - $(document).on('ready', addMarginToBuild); -})(); +})(window.gl || (window.gl = {})); diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 36c57f3ca30..f4211ea3b2d 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -326,6 +326,10 @@ } } + &.no-margin { + margin: 0; + } + li { list-style: none; } diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index da5b9832ba5..bdf3c0a2aba 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,45 +1,46 @@ -.row-content-block.build-content.middle-block.pipeline-actions - .pull-right - .btn.btn-grouped.btn-white.toggle-pipeline-btn - %span.toggle-btn-text Hide - %span pipeline graph - = icon('caret-up') - - if can?(current_user, :update_pipeline, pipeline.project) - - if pipeline.builds.latest.failed.any?(&:retryable?) - = link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post +.pipeline-graph-container.hidden + .row-content-block.build-content.middle-block.pipeline-actions + .pull-right + .btn.btn-grouped.btn-white.toggle-pipeline-btn + %span.toggle-btn-text Hide + %span pipeline graph + %span.caret + - if can?(current_user, :update_pipeline, pipeline.project) + - if pipeline.builds.latest.failed.any?(&:retryable?) + = link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post - - if pipeline.builds.running_or_pending.any? - = link_to "Cancel running", cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post + - if pipeline.builds.running_or_pending.any? + = link_to "Cancel running", cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post - .oneline.clearfix - - if defined?(pipeline_details) && pipeline_details - Pipeline - = link_to "##{pipeline.id}", namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: "monospace" - with - = pluralize pipeline.statuses.count(:id), "build" - - if pipeline.ref - for - = link_to pipeline.ref, namespace_project_commits_path(pipeline.project.namespace, pipeline.project, pipeline.ref), class: "monospace" - - if defined?(link_to_commit) && link_to_commit - for commit - = link_to pipeline.short_sha, namespace_project_commit_path(pipeline.project.namespace, pipeline.project, pipeline.sha), class: "monospace" - - if pipeline.duration - in - = time_interval_in_words pipeline.duration + .oneline.clearfix + - if defined?(pipeline_details) && pipeline_details + Pipeline + = link_to "##{pipeline.id}", namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: "monospace" + with + = pluralize pipeline.statuses.count(:id), "build" + - if pipeline.ref + for + = link_to pipeline.ref, namespace_project_commits_path(pipeline.project.namespace, pipeline.project, pipeline.ref), class: "monospace" + - if defined?(link_to_commit) && link_to_commit + for commit + = link_to pipeline.short_sha, namespace_project_commit_path(pipeline.project.namespace, pipeline.project, pipeline.sha), class: "monospace" + - if pipeline.duration + in + = time_interval_in_words pipeline.duration -.row-content-block.build-content.middle-block.pipeline-graph - .pipeline-visualization - %ul.stage-column-list - - stages = pipeline.stages_with_latest_statuses - - stages.each do |stage, statuses| - %li.stage-column - .stage-name - %a{name: stage} - - if stage - = stage.titleize - .builds-container - %ul - = render "projects/commit/pipeline_stage", statuses: statuses + .row-content-block.build-content.middle-block.pipeline-graph + .pipeline-visualization + %ul.stage-column-list + - stages = pipeline.stages_with_latest_statuses + - stages.each do |stage, statuses| + %li.stage-column + .stage-name + %a{name: stage} + - if stage + = stage.titleize + .builds-container + %ul + = render "projects/commit/pipeline_stage", statuses: statuses - if pipeline.yaml_errors.present? From c2deaa7e0db808abad86e87bac9524784b02e602 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Tue, 4 Oct 2016 13:59:57 -0500 Subject: [PATCH 08/20] Move hidden class to graph itself; remove background color from play node & align icon --- app/assets/javascripts/pipeline.js.es6 | 2 +- app/assets/stylesheets/pages/pipelines.scss | 5 ++--- app/views/projects/commit/_pipeline.html.haml | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index 6299ba2269d..68a34dda2af 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -31,7 +31,7 @@ if ($('.build', $this).length === 1) $this.addClass('no-margin'); }); } - $('.pipeline-graph-container').removeClass('hidden'); + $('.pipeline-graph').removeClass('hidden'); } } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index f4211ea3b2d..4e53c9765df 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -359,11 +359,10 @@ } &.playable { - background-color: $gray-light; svg { - height: 12px; - width: 12px; + height: 13px; + width: 20px; position: relative; top: 1px; diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index bdf3c0a2aba..288c06d9b67 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,4 +1,4 @@ -.pipeline-graph-container.hidden +.pipeline-graph-container .row-content-block.build-content.middle-block.pipeline-actions .pull-right .btn.btn-grouped.btn-white.toggle-pipeline-btn @@ -28,7 +28,7 @@ in = time_interval_in_words pipeline.duration - .row-content-block.build-content.middle-block.pipeline-graph + .row-content-block.build-content.middle-block.pipeline-graph.hidden .pipeline-visualization %ul.stage-column-list - stages = pipeline.stages_with_latest_statuses From 113050c5709a204f58e0395b08e1582b3c862d66 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Thu, 6 Oct 2016 13:35:13 -0500 Subject: [PATCH 09/20] Fix ul html --- app/assets/stylesheets/pages/pipelines.scss | 1 - app/views/projects/commit/_pipeline_status_group.html.haml | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 4e53c9765df..9ce5bee466f 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -422,7 +422,6 @@ a { color: $gl-text-color; padding: 7px 8px 8px; - margin: 0 8px; &:hover { background-color: $blue-light-transparent; diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index bff65bff653..b26de822450 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -6,6 +6,7 @@ = name %span.badge= subject.size %ul.dropdown-menu.grouped-pipeline-dropdown - .arrow + %li.arrow - subject.each do |status| - = render "projects/#{status.to_partial_path}_pipeline", subject: status + %li + = render "projects/#{status.to_partial_path}_pipeline", subject: status From 6a7b673035752890023e630755f27ec0d412a129 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Thu, 6 Oct 2016 18:00:06 +0100 Subject: [PATCH 10/20] JS review changes - Removed window from window.gl in dispatcher Added page:load event as ready isnt fired by turbolinks Fix dropdown menu link click registration --- app/assets/javascripts/dispatcher.js | 2 +- app/assets/javascripts/pipeline.js.es6 | 1 + app/assets/stylesheets/pages/pipelines.scss | 4 ++++ app/views/projects/commit/_pipeline_stage.html.haml | 2 +- app/views/projects/commit/_pipeline_status_group.html.haml | 2 +- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 45494afe7aa..adff73af79c 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -127,7 +127,7 @@ } break; case 'projects:pipelines:show': - new window.gl.Pipelines(); + new gl.Pipelines(); break; case 'groups:activity': new Activities(); diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index 68a34dda2af..1030447f74a 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -4,6 +4,7 @@ constructor() { $(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph); $(document).off('ready.addMarginToBuildColumns').on('ready.addMarginToBuildColumns', this.addMarginToBuildColumns); + $(document).off('page:load.addMarginToBuildColumns').on('page:load.addMarginToBuildColumns', this.addMarginToBuildColumns); } toggleGraph() { diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 9ce5bee466f..0c3c1e404af 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -373,6 +373,9 @@ } .build-content { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; width: 164px; .ci-status-icon { @@ -403,6 +406,7 @@ width: auto; padding: 0; color: $gl-text-color-light; + flex-grow: 1; .ci-status-text { max-width: 112px; diff --git a/app/views/projects/commit/_pipeline_stage.html.haml b/app/views/projects/commit/_pipeline_stage.html.haml index 68d42126bf6..289aa5178b1 100644 --- a/app/views/projects/commit/_pipeline_stage.html.haml +++ b/app/views/projects/commit/_pipeline_stage.html.haml @@ -10,5 +10,5 @@ - else %li.build .curve - .dropdown.inline.build-content{ type: 'button', data: { toggle: 'dropdown' } } + .dropdown.inline.build-content = render "projects/commit/pipeline_status_group", name: group_name, subject: grouped_statuses diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index b26de822450..8582e9a8772 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -1,7 +1,7 @@ - group_status = CommitStatus.where(id: subject).status %span.ci-status-icon = render_status_with_link('build', group_status) -%button.dropdown-menu-toggle +%button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } %span.ci-status-text = name %span.badge= subject.size From 4e1efca14119a25c441d833268894a632eb269d5 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Thu, 6 Oct 2016 14:33:55 -0500 Subject: [PATCH 11/20] Fix node flex alignment --- app/views/projects/commit/_pipeline_status_group.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index 8582e9a8772..6ada719e006 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -1,7 +1,7 @@ - group_status = CommitStatus.where(id: subject).status -%span.ci-status-icon - = render_status_with_link('build', group_status) %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } + %span.ci-status-icon + = render_status_with_link('build', group_status) %span.ci-status-text = name %span.badge= subject.size From a57b3fc80c50b951d3a54ce2108608d45826c5ef Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Thu, 6 Oct 2016 21:20:25 +0100 Subject: [PATCH 12/20] Corrected my correction for turbolinks -.-' Removed extra cell on generic pipeline --- app/assets/javascripts/pipeline.js.es6 | 3 +-- .../generic_commit_statuses/_generic_commit_status.html.haml | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index 1030447f74a..a29f6ecdd59 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -3,8 +3,7 @@ class Pipelines { constructor() { $(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph); - $(document).off('ready.addMarginToBuildColumns').on('ready.addMarginToBuildColumns', this.addMarginToBuildColumns); - $(document).off('page:load.addMarginToBuildColumns').on('page:load.addMarginToBuildColumns', this.addMarginToBuildColumns); + this.addMarginToBuildColumns(); } toggleGraph() { diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml index 331dc1fcc29..80fe6be49b0 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml @@ -62,5 +62,3 @@ %td.coverage - if generic_commit_status.try(:coverage) #{generic_commit_status.coverage}% - - %td From 274ac4efdb94efe4d3ea4d5fff193eb2f02db507 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Fri, 7 Oct 2016 12:23:00 +0100 Subject: [PATCH 13/20] JS review changes and fixed conflicts --- app/assets/javascripts/pipeline.js.es6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index a29f6ecdd59..6bf63ee6979 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -10,10 +10,10 @@ const $pipelineBtn = $(this).closest('.toggle-pipeline-btn'); const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph'); const $btnText = $(this).find('.toggle-btn-text'); + const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed'); $($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed'); - const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed'); graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') } From 879a68a7c48c469c2646ecd89412cab9679d8860 Mon Sep 17 00:00:00 2001 From: Dimitrie Hoekstra Date: Fri, 7 Oct 2016 14:57:57 +0200 Subject: [PATCH 14/20] slight update to lines and curves positioning --- app/assets/stylesheets/pages/pipelines.scss | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 0c3c1e404af..04cce24ce7d 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -321,6 +321,7 @@ border-top: 2px solid $border-color; width: 48px; height: 1px; + margin-top: -1px; } } } @@ -498,6 +499,7 @@ border-top: 2px solid $border-color; width: 48px; height: 1px; + margin-top: -1px; } } @@ -505,7 +507,7 @@ &:not(:first-child) { &::after, &::before { content: ''; - top: -47px; + top: -49px; position: absolute; border-bottom: 2px solid $border-color; width: 25px; @@ -531,7 +533,7 @@ &:nth-child(2) { &::after, &::before { height: 29px; - top: -7px; + top: -9px; } .curve { display: block; @@ -589,7 +591,7 @@ width: 21px; height: 25px; position: absolute; - top: -31.5px; + top: -32.5px; border-top: 2px solid $border-color; } From 7a28205629962427bfe5a48610ee4890b37f5ae8 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Fri, 7 Oct 2016 08:57:30 -0500 Subject: [PATCH 15/20] Remove negative margins --- app/assets/stylesheets/pages/pipelines.scss | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 04cce24ce7d..21224447628 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -316,12 +316,11 @@ &::before { content: ''; position: absolute; - top: 50%; + top: 49%; left: -48px; border-top: 2px solid $border-color; width: 48px; height: 1px; - margin-top: -1px; } } } @@ -494,12 +493,11 @@ &::after { content: ''; position: absolute; - top: 50%; + top: 49%; right: -48px; border-top: 2px solid $border-color; width: 48px; height: 1px; - margin-top: -1px; } } @@ -591,7 +589,7 @@ width: 21px; height: 25px; position: absolute; - top: -32.5px; + top: -31px; border-top: 2px solid $border-color; } From f60e0b92b8cba1d70c40094511a87fc0ed62977d Mon Sep 17 00:00:00 2001 From: TMate Software Support Date: Mon, 10 Oct 2016 18:14:29 +0000 Subject: [PATCH 16/20] Update migrating_from_svn.md document on migration from SVN to GitLab as suggested by @axil in MR 6549. --- doc/workflow/importing/migrating_from_svn.md | 56 +++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/doc/workflow/importing/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md index 76839315c53..fc27a38f735 100644 --- a/doc/workflow/importing/migrating_from_svn.md +++ b/doc/workflow/importing/migrating_from_svn.md @@ -8,21 +8,16 @@ between the two, for more information consult your favorite search engine. There are two approaches to SVN to Git migration: -#### [Git/SVN Mirror](#mirror) +1. [Git/SVN Mirror](#smooth-migration-with-a-gitsvn-mirror-using-subgit) which: + - Makes the GitLab repository to mirror the SVN project. + - Git and SVN repositories are kept in sync; you can use either one. + - Smoothens the migration process and allows to manage migration risks. - Make GitLab repository mirror SVN project. - - Git and SVN project are kept in sync; use either one or another. - - Smoothens migration process and allows to manage migration risks. +1. [Cut over migration](#cut-over-migration-with-svn2git) which: + - Translates and imports the existing data and history from SVN to Git. + - Is a fire and forget approach, good for smaller teams. -#### [Cut over migration](#cutover) - - Translate existing data and history from SVN to Git. - - Fire and forget approach, good for smaller teams. - -## Smooth migration with a Git/SVN mirror using SubGit +## Smooth migration with a Git/SVN mirror using SubGit #### Prerequisites @@ -37,20 +32,32 @@ at `/opt/subgit-VERSION/bin/subgit` #### Configuration In GitLab create new empty repository. In filesystem it will be located at -`/var/opt/gitlab/git-data/repositories/USER/REPOS.git` path. - -Run SubGit to set up a Git/SVN mirror. Make sure `subgit` command is ran -on behalf of the same user that runs GitLab. +`/var/opt/gitlab/git-data/repositories/USER/REPOS.git` path by default. +For convenice, assign this path to a variable: ``` -subgit configure --layout auto SVN_PROJECT_URL GIT_REPOS_PATH +GIT_REPOS_PATH=/var/opt/gitlab/git-data/repositories/USER/REPOS.git +``` + +SubGit will keep this repository will be kept in sync with a remote SVN project. +For convenience, assign remote SVN project URL to a variable: + +``` +SVN_PROJECT_URL=http://svn.company.com/repos/project +``` + +Run SubGit to set up a Git/SVN mirror. Make sure `subgit` command is ran +on behalf of the same user that keeps ownership of GitLab Git repositories (`git` by default): + +``` +subgit configure --layout auto $SVN_PROJECT_URL $GIT_REPOS_PATH ``` Adjust authors and branches mappings, if necessary: ``` -edit GIT_REPOS_PATH/subgit/authors.txt -edit GIT_REPOS_PATH/subgit/config +edit $GIT_REPOS_PATH/subgit/authors.txt +edit $GIT_REPOS_PATH/subgit/config ``` For more information regarding SubGit configuration options, refer to @@ -62,7 +69,7 @@ Run `subgit` to perform initial translation of existing SVN revisions into Git repository: ``` -subgit install GIT_REPOS_PATH +subgit install $GIT_REPOS_PATH ``` After initial translation is completed, GitLab Git repository and SVN project @@ -74,7 +81,7 @@ Would you prefer to perform one-time cut over migration with `subgit` use `import` command in place of `install`: ``` -subgit import GIT_REPOS_PATH +subgit import $GIT_REPOS_PATH ``` #### Licensing @@ -87,10 +94,9 @@ progress at [this issue](https://gitlab.com/gitlab-org/gitlab-ee/issues/990). #### Support -For any questions related to SVN to GitLab migration with SubGit contact us at [support@subgit.com](mailto:support@subgit.com). We support -all our users. +For any questions related to SVN to GitLab migration with SubGit you can contact SubGit team at [support@subgit.com](mailto:support@subgit.com). -## Cut over migration with svn2git +## Cut over migration with svn2git If you are currently using an SVN repository, you can migrate the repository to Git and GitLab. We recommend a hard cut over - run the migration command once From d4fab17d7c8c2b233248295755a6277fdee09c9f Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 7 Oct 2016 22:48:23 -0700 Subject: [PATCH 17/20] Fix Error 500 when viewing old merge requests with bad diff data Customers running old versions of GitLab may have MergeRequestDiffs with the text ["--broken diff"] due to text generated by gitlab_git 1.0.3. To avoid the Error 500, verify that each element is a type that gitlab_git will accept before attempting to create a DiffCollection. Closes #20776 --- CHANGELOG | 1 + app/models/merge_request_diff.rb | 14 +++++++++++++- spec/models/merge_request_diff_spec.rb | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 24f77442f1a..dfb953fabd9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ v 8.13.0 (unreleased) - AbstractReferenceFilter caches project_refs on RequestStore when active - Replaced the check sign to arrow in the show build view. !6501 - Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar) + - Fix Error 500 when viewing old merge requests with bad diff data - Speed-up group milestones show page - Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs) - Add tag shortcut from the Commit page. !6543 diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 36b8b70870b..3f7e96186a1 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -6,6 +6,9 @@ class MergeRequestDiff < ActiveRecord::Base # Prevent store of diff if commits amount more then 500 COMMITS_SAFE_SIZE = 100 + # Valid types of serialized diffs allowed by Gitlab::Git::Diff + VALID_CLASSES = [Hash, Rugged::Patch, Rugged::Diff::Delta] + belongs_to :merge_request state_machine :state, initial: :empty do @@ -170,6 +173,15 @@ class MergeRequestDiff < ActiveRecord::Base private + # Old GitLab implementations may have generated diffs as ["--broken-diff"]. + # Avoid an error 500 by ignoring bad elements. See: + # https://gitlab.com/gitlab-org/gitlab-ce/issues/20776 + def valid_raw_diff?(raw) + return false unless raw.respond_to?(:each) + + raw.any? { |element| VALID_CLASSES.include?(element.class) } + end + def dump_commits(commits) commits.map(&:to_hash) end @@ -200,7 +212,7 @@ class MergeRequestDiff < ActiveRecord::Base end def load_diffs(raw, options) - if raw.respond_to?(:each) + if valid_raw_diff?(raw) if paths = options[:paths] raw = raw.select do |diff| paths.include?(diff[:old_path]) || paths.include?(diff[:new_path]) diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index 530a7def553..96f1f60dbc0 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -44,6 +44,16 @@ describe MergeRequestDiff, models: true do end end + context 'when the raw diffs have invalid content' do + before { mr_diff.update_attributes(st_diffs: ["--broken-diff"]) } + + it 'returns an empty DiffCollection' do + expect(mr_diff.raw_diffs.to_a).to be_empty + expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection) + expect(mr_diff.raw_diffs).to be_empty + end + end + context 'when the raw diffs exist' do it 'returns the diffs' do expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection) From d87df157987e5ba2690fc1a7937e557821efb997 Mon Sep 17 00:00:00 2001 From: Dimitrie Hoekstra Date: Tue, 11 Oct 2016 11:34:20 +0200 Subject: [PATCH 18/20] changed the scss for the top line connectors to be exactly centered --- app/assets/stylesheets/pages/pipelines.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 21224447628..05f59279637 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -316,7 +316,7 @@ &::before { content: ''; position: absolute; - top: 49%; + top: 48%; left: -48px; border-top: 2px solid $border-color; width: 48px; @@ -493,7 +493,7 @@ &::after { content: ''; position: absolute; - top: 49%; + top: 48%; right: -48px; border-top: 2px solid $border-color; width: 48px; @@ -589,7 +589,7 @@ width: 21px; height: 25px; position: absolute; - top: -31px; + top: -32px; border-top: 2px solid $border-color; } From c64721f16331f2115d3fe87f3c04134f8cba0163 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 5 Oct 2016 17:40:13 +0100 Subject: [PATCH 19/20] Document the new CI_DEBUG_TRACE variable [ci skip] --- doc/ci/pipelines.md | 2 ++ doc/ci/variables/README.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md index ca9b986a060..729c1dc8c0d 100644 --- a/doc/ci/pipelines.md +++ b/doc/ci/pipelines.md @@ -31,6 +31,8 @@ project. ## Seeing build status Clicking on a pipeline will show the builds that were run for that pipeline. +Clicking on an individual build will show you its build trace, and allow you to +cancel the build, retry it, or erase the build trace. ## Badges diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 22d67bd9964..a4c3a731a20 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -48,6 +48,7 @@ The `API_TOKEN` will take the Secure Variable value: `SECURE`. | **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used | | **CI_RUNNER_DESCRIPTION** | 8.10 | 0.5 | The description of the runner as saved in GitLab | | **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags | +| **CI_DEBUG_TRACE** | all | 1.7 | Whether [debug tracing](#debug-tracing) is enabled | | **GITLAB_USER_ID** | 8.12 | all | The id of the user who started the build | | **GITLAB_USER_EMAIL** | 8.12 | all | The email of the user who started the build | @@ -105,6 +106,39 @@ Variables can be defined at a global level, but also at a job level. More information about Docker integration can be found in [Using Docker Images](../docker/using_docker_images.md). +#### Debug tracing + +> **WARNING:** Enabling debug tracing can have severe security implications. The + output **will** contain the content of all your secure variables and any other + secrets! The output **will** be uploaded to the GitLab server and made visible + in build traces! + +By default, GitLab Runner hides most of the details of what it is doing when +processing a job. This behaviour keeps build traces short, and prevents secrets +from being leaked into the trace unless your script writes them to the screen. + +If a job isn't working as expected, this can make the problem difficult to +investigate; in these cases, you can enable debug tracing in `.gitlab-ci.yml`. +Available on GitLab Runner v1.7+, this feature enables the shell's execution +trace, resulting in a verbose build trace listing all commands that were run, +variables that were set, etc. + +Before enabling this, you should ensure builds are visible to +[team members only](../../../user/permissions.md#project-features). You should +also [erase](../pipelines.md#seeing-build-traces) all generated build traces +before making them visible again. + +To enable debug traces, set the `CI_DEBUG_TRACE` variable to `true`: + +```yaml +job1: + variables: + CI_DEBUG_TRACE: "true" +``` + +The [example project](https://gitlab.com/gitlab-examples/ci-debug-trace) +demonstrates a working configuration, including build trace examples. + ### User-defined variables (Secure Variables) **This feature requires GitLab Runner 0.4.0 or higher** From f361b1c624443f0e693d8b7c9bd81fb713c943cf Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 11 Oct 2016 14:22:18 +0200 Subject: [PATCH 20/20] Refactor the SubGit/SVN documentation [ci skip] --- doc/workflow/importing/migrating_from_svn.md | 92 +++++++++++--------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/doc/workflow/importing/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md index fc27a38f735..423b095e69e 100644 --- a/doc/workflow/importing/migrating_from_svn.md +++ b/doc/workflow/importing/migrating_from_svn.md @@ -10,7 +10,7 @@ There are two approaches to SVN to Git migration: 1. [Git/SVN Mirror](#smooth-migration-with-a-gitsvn-mirror-using-subgit) which: - Makes the GitLab repository to mirror the SVN project. - - Git and SVN repositories are kept in sync; you can use either one. + - Git and SVN repositories are kept in sync; you can use either one. - Smoothens the migration process and allows to manage migration risks. 1. [Cut over migration](#cut-over-migration-with-svn2git) which: @@ -19,82 +19,94 @@ There are two approaches to SVN to Git migration: ## Smooth migration with a Git/SVN mirror using SubGit -#### Prerequisites +[SubGit](https://subgit.com) is a tool for a smooth, stress-free SVN to Git +migration. It creates a writable Git mirror of a local or remote Subversion +repository and that way you can use both Subversion and Git as long as you like. +It requires access to your GitLab server as it talks with the Git repositories +directly in a filesystem level. -Install Oracle JRE 1.8 or newer. On Debian-based Linux distributions follow this -[instruction](http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html). +### SubGit prerequisites -Download SubGit tool from [https://subgit.com/download/](https://subgit.com/download/) +1. Install Oracle JRE 1.8 or newer. On Debian-based Linux distributions you can + follow [this article](http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html). +1. Download SubGit from https://subgit.com/download/. +1. Unpack the downloaded SubGit zip archive to the `/opt` directory. The `subgit` + command will be available at `/opt/subgit-VERSION/bin/subgit`. -Unpack downloaded SubGit zip archive to `/opt` directory, subgit will be available -at `/opt/subgit-VERSION/bin/subgit` +### SubGit configuration -#### Configuration - -In GitLab create new empty repository. In filesystem it will be located at -`/var/opt/gitlab/git-data/repositories/USER/REPOS.git` path by default. -For convenice, assign this path to a variable: +The first step to mirror you SVN repository in GitLab is to create a new empty +project which will be used as a mirror. For Omnibus installations the path to +the repository will be located at +`/var/opt/gitlab/git-data/repositories/USER/REPO.git` by default. For +installations from source, the default repository directory will be +`/home/git/repositories/USER/REPO.git`. For convenience, assign this path to a +variable: ``` -GIT_REPOS_PATH=/var/opt/gitlab/git-data/repositories/USER/REPOS.git +GIT_REPO_PATH=/var/opt/gitlab/git-data/repositories/USER/REPOS.git ``` -SubGit will keep this repository will be kept in sync with a remote SVN project. -For convenience, assign remote SVN project URL to a variable: +SubGit will keep this repository in sync with a remote SVN project. For +convenience, assign your remote SVN project URL to a variable: ``` SVN_PROJECT_URL=http://svn.company.com/repos/project ``` -Run SubGit to set up a Git/SVN mirror. Make sure `subgit` command is ran -on behalf of the same user that keeps ownership of GitLab Git repositories (`git` by default): +Next you need to run SubGit to set up a Git/SVN mirror. Make sure the following +`subgit` command is ran on behalf of the same user that keeps ownership of +GitLab Git repositories (by default `git`): ``` -subgit configure --layout auto $SVN_PROJECT_URL $GIT_REPOS_PATH +subgit configure --layout auto $SVN_PROJECT_URL $GIT_REPO_PATH ``` -Adjust authors and branches mappings, if necessary: +Adjust authors and branches mappings, if necessary. Open with your favorite +text editor: ``` -edit $GIT_REPOS_PATH/subgit/authors.txt -edit $GIT_REPOS_PATH/subgit/config +edit $GIT_REPO_PATH/subgit/authors.txt +edit $GIT_REPO_PATH/subgit/config ``` -For more information regarding SubGit configuration options, refer to -[documentation](https://subgit.com/documentation.html) at SubGit web site. +For more information regarding the SubGit configuration options, refer to +[SubGit's documentation](https://subgit.com/documentation.html) website. -#### Initial translation +### Initial translation -Run `subgit` to perform initial translation of existing SVN revisions into -Git repository: +Now that SubGit has configured the Git/SVN repos, run `subgit` to perform the +initial translation of existing SVN revisions into the Git repository: ``` subgit install $GIT_REPOS_PATH ``` -After initial translation is completed, GitLab Git repository and SVN project -will be kept in sync by `subgit` - new Git commits will be translated to SVN -revisions and new SVN revisions will be translated to Git commits. Mirror works -transparently and does not require any special commands. +After the initial translation is completed, the Git repository and the SVN +project will be kept in sync by `subgit` - new Git commits will be translated to +SVN revisions and new SVN revisions will be translated to Git commits. Mirror +works transparently and does not require any special commands. -Would you prefer to perform one-time cut over migration with `subgit` use -`import` command in place of `install`: +If you would prefer to perform one-time cut over migration with `subgit`, use +the `import` command instead of `install`: ``` -subgit import $GIT_REPOS_PATH +subgit import $GIT_REPO_PATH ``` -#### Licensing +### SubGit licensing -Running SubGit in a mirror mode requires [registration](https://subgit.com/pricing.html). Registration is free for Open Source, -Academic and Startup projects. +Running SubGit in a mirror mode requires a +[registration](https://subgit.com/pricing.html). Registration is free for open +source, academic and startup projects. -We're currently working on deeper GitLab/SubGit intergation. You may track our +We're currently working on deeper GitLab/SubGit integration. You may track our progress at [this issue](https://gitlab.com/gitlab-org/gitlab-ee/issues/990). -#### Support +### SubGit support -For any questions related to SVN to GitLab migration with SubGit you can contact SubGit team at [support@subgit.com](mailto:support@subgit.com). +For any questions related to SVN to GitLab migration with SubGit, you can +contact the SubGit team directly at [support@subgit.com](mailto:support@subgit.com). ## Cut over migration with svn2git @@ -168,4 +180,4 @@ git push --tags origin ## Contribute to this guide We welcome all contributions that would expand this guide with instructions on -how to migrate from SVN and other version control systems. \ No newline at end of file +how to migrate from SVN and other version control systems.