Commit 3ca1f6d0 authored by Nick Thomas's avatar Nick Thomas

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2017-06-07

parents 4471ca45 dbc7bbc3
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
import timeago from 'timeago.js'; import timeago from 'timeago.js';
import dateFormat from 'vendor/date.format'; import dateFormat from 'vendor/date.format';
import {
lang,
s__,
} from '../../locale';
window.timeago = timeago; window.timeago = timeago;
window.dateFormat = dateFormat; window.dateFormat = dateFormat;
...@@ -48,26 +53,45 @@ window.dateFormat = dateFormat; ...@@ -48,26 +53,45 @@ window.dateFormat = dateFormat;
var locale; var locale;
if (!timeagoInstance) { if (!timeagoInstance) {
const localeRemaining = function(number, index) {
return [
[s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
[s__('Timeago|less than a minute ago'), s__('Timeago|%s seconds remaining')],
[s__('Timeago|about a minute ago'), s__('Timeago|1 minute remaining')],
[s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
[s__('Timeago|about an hour ago'), s__('Timeago|1 hour remaining')],
[s__('Timeago|about %s hours ago'), s__('Timeago|%s hours remaining')],
[s__('Timeago|a day ago'), s__('Timeago|1 day remaining')],
[s__('Timeago|%s days ago'), s__('Timeago|%s days remaining')],
[s__('Timeago|a week ago'), s__('Timeago|1 week remaining')],
[s__('Timeago|%s weeks ago'), s__('Timeago|%s weeks remaining')],
[s__('Timeago|a month ago'), s__('Timeago|1 month remaining')],
[s__('Timeago|%s months ago'), s__('Timeago|%s months remaining')],
[s__('Timeago|a year ago'), s__('Timeago|1 year remaining')],
[s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')]
][index];
};
locale = function(number, index) { locale = function(number, index) {
return [ return [
['less than a minute ago', 'a while'], [s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
['less than a minute ago', 'in %s seconds'], [s__('Timeago|less than a minute ago'), s__('Timeago|in %s seconds')],
['about a minute ago', 'in 1 minute'], [s__('Timeago|about a minute ago'), s__('Timeago|in 1 minute')],
['%s minutes ago', 'in %s minutes'], [s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
['about an hour ago', 'in 1 hour'], [s__('Timeago|about an hour ago'), s__('Timeago|in 1 hour')],
['about %s hours ago', 'in %s hours'], [s__('Timeago|about %s hours ago'), s__('Timeago|in %s hours')],
['a day ago', 'in 1 day'], [s__('Timeago|a day ago'), s__('Timeago|in 1 day')],
['%s days ago', 'in %s days'], [s__('Timeago|%s days ago'), s__('Timeago|in %s days')],
['a week ago', 'in 1 week'], [s__('Timeago|a week ago'), s__('Timeago|in 1 week')],
['%s weeks ago', 'in %s weeks'], [s__('Timeago|%s weeks ago'), s__('Timeago|in %s weeks')],
['a month ago', 'in 1 month'], [s__('Timeago|a month ago'), s__('Timeago|in 1 month')],
['%s months ago', 'in %s months'], [s__('Timeago|%s months ago'), s__('Timeago|in %s months')],
['a year ago', 'in 1 year'], [s__('Timeago|a year ago'), s__('Timeago|in 1 year')],
['%s years ago', 'in %s years'] [s__('Timeago|%s years ago'), s__('Timeago|in %s years')]
][index]; ][index];
}; };
timeago.register('gl_en', locale); timeago.register(lang, locale);
timeago.register(`${lang}-remaining`, localeRemaining);
timeagoInstance = timeago(); timeagoInstance = timeago();
} }
...@@ -79,13 +103,11 @@ window.dateFormat = dateFormat; ...@@ -79,13 +103,11 @@ window.dateFormat = dateFormat;
if (!time) { if (!time) {
return ''; return '';
} }
suffix || (suffix = 'remaining'); if (new Date(time) < new Date()) {
expiredLabel || (expiredLabel = 'Past due'); expiredLabel || (expiredLabel = s__('Timeago|Past due'));
timefor = gl.utils.getTimeago().format(time).replace('in', '');
if (timefor.indexOf('ago') > -1) {
timefor = expiredLabel; timefor = expiredLabel;
} else { } else {
timefor = timefor.trim() + ' ' + suffix; timefor = gl.utils.getTimeago().format(time, `${lang}-remaining`).trim();
} }
return timefor; return timefor;
}; };
...@@ -102,7 +124,7 @@ window.dateFormat = dateFormat; ...@@ -102,7 +124,7 @@ window.dateFormat = dateFormat;
}; };
w.gl.utils.updateTimeagoText = function(el) { w.gl.utils.updateTimeagoText = function(el) {
const formattedDate = gl.utils.getTimeago().format(el.getAttribute('datetime'), 'gl_en'); const formattedDate = gl.utils.getTimeago().format(el.getAttribute('datetime'), lang);
if (el.textContent !== formattedDate) { if (el.textContent !== formattedDate) {
el.textContent = formattedDate; el.textContent = formattedDate;
......
var locales = locales || {}; locales['de'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-05-09 13:44+0200","Language-Team":"German","Language":"de","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"","X-Generator":"Poedit 2.0.1","lang":"de","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"ByAuthor|by":["Von"],"Commit":["Commit","Commits"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics liefern einen Überblick darüber, wie viel Zeit in Ihrem Projekt von einer Idee bis zum Produktivdeployment vergeht."],"CycleAnalyticsStage|Code":["Code"],"CycleAnalyticsStage|Issue":["Issue"],"CycleAnalyticsStage|Plan":["Planung"],"CycleAnalyticsStage|Production":["Produktiv"],"CycleAnalyticsStage|Review":["Review"],"CycleAnalyticsStage|Staging":["Staging"],"CycleAnalyticsStage|Test":["Test"],"Deploy":["Deployment","Deployments"],"FirstPushedBy|First":["Erster"],"FirstPushedBy|pushed by":["gepusht von"],"From issue creation until deploy to production":["Vom Anlegen des Issues bis zum Produktivdeployment"],"From merge request merge until deploy to production":["Vom Merge Request bis zum Produktivdeployment"],"Introducing Cycle Analytics":["Was sind Cycle Analytics?"],"Last %d day":["Letzter %d Tag","Letzten %d Tage"],"Limited to showing %d event at most":["Eingeschränkt auf maximal %d Ereignis","Eingeschränkt auf maximal %d Ereignisse"],"Median":["Median"],"New Issue":["Neues Issue","Neue Issues"],"Not available":["Nicht verfügbar"],"Not enough data":["Nicht genügend Daten"],"OpenedNDaysAgo|Opened":["Erstellt"],"Pipeline Health":["Pipeline Kennzahlen"],"ProjectLifecycle|Stage":["Phase"],"Read more":["Mehr"],"Related Commits":["Zugehörige Commits"],"Related Deployed Jobs":["Zugehörige Deploymentjobs"],"Related Issues":["Zugehörige Issues"],"Related Jobs":["Zugehörige Jobs"],"Related Merge Requests":["Zugehörige Merge Requests"],"Related Merged Requests":["Zugehörige abgeschlossene Merge Requests"],"Showing %d event":["Zeige %d Ereignis","Zeige %d Ereignisse"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["Die Code-Phase stellt die Zeit vom ersten Commit bis zum Erstellen eines Merge Requests dar. Sobald Sie Ihren ersten Merge Request anlegen, werden dessen Daten automatisch ergänzt."],"The collection of events added to the data gathered for that stage.":["Ereignisse, die für diese Phase ausgewertet wurden."],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":["Die Issue-Phase stellt die Zeit vom Anlegen eines Issues bis zum Zuweisen eines Meilensteins oder Hinzufügen zum Issue Board dar. Erstellen Sie einen Issue, damit dessen Daten hier erscheinen."],"The phase of the development lifecycle.":["Die Phase im Entwicklungsprozess."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["Die Planungsphase stellt die Zeit von der vorherigen Phase bis zum Pushen des ersten Commits dar. Sobald Sie den ersten Commit pushen, werden dessen Daten hier erscheinen."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["Die Produktiv-Phase stellt die Gesamtzeit vom Anlegen eines Issues bis zum Deployment auf dem Produktivsystem dar. Sobald Sie den vollständigen Entwicklungszyklus von einer Idee bis zum Produktivdeployment durchlaufen haben, erscheinen die zugehörigen Daten hier."],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["Die Review-Phase stellt die Zeit vom Anlegen eines Merge Requests bis zum Mergen dar. Sobald Sie Ihren ersten Merge Request abschließen, werden dessen Daten hier automatisch angezeigt."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["Die Staging-Phase stellt die Zeit zwischen Mergen eines Merge Requests und dem Produktivdeployment dar. Sobald Sie das erste Produktivdeployment durchgeführt haben, werden dessen Daten hier automatisch angezeigt."],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":["Die Test-Phase stellt die Zeit dar, die GitLab CI benötigt um die Pipelines von Merge Requests abzuarbeiten. Sobald die erste Pipeline abgeschlossen ist, werden deren Daten hier automatisch angezeigt."],"The time taken by each data entry gathered by that stage.":["Zeit die für das jeweilige Ereignis in der Phase ermittelt wurde."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["Der mittlere aller erfassten Werte. Zum Beispiel ist für 3, 5, 9 der Median 5. Bei 3, 5, 7, 8 ist der Median (5+7)/2 = 6."],"Time before an issue gets scheduled":["Zeit bis ein Issue geplant wird"],"Time before an issue starts implementation":["Zeit bis die Implementierung für ein Issue beginnt"],"Time between merge request creation and merge/close":["Zeit zwischen Anlegen und Mergen/Schließen eines Merge Requests"],"Time until first merge request":["Zeit bis zum ersten Merge Request"],"Time|hr":["h","h"],"Time|min":["min","min"],"Time|s":["s"],"Total Time":["Gesamtzeit"],"Total test time for all commits/merges":["Gesamte Testlaufzeit für alle Commits/Merges"],"Want to see the data? Please ask an administrator for access.":["Um diese Daten einsehen zu können, wenden Sie sich bitte an Ihren Administrator."],"We don't have enough data to show this stage.":["Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen."],"You need permission.":["Sie benötigen Zugriffsrechte."],"day":["Tag","Tage"]}}}; var locales = locales || {}; locales['de'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-06-07 12:17+0200","Language-Team":"German","Language":"de","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"Bob Van Landuyt <bob@gitlab.com>","X-Generator":"Poedit 2.0.2","lang":"de","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"About auto deploy":[""],"Activity":[""],"Add Changelog":[""],"Add Contribution guide":[""],"Add License":[""],"Add an SSH key to your profile to pull or push via SSH.":[""],"Add new directory":[""],"Archived project! Repository is read-only":[""],"Branch":["",""],"Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}":[""],"Branches":[""],"ByAuthor|by":["Von"],"CI configuration":[""],"Changelog":[""],"Charts":[""],"CiStatusLabel|canceled":[""],"CiStatusLabel|created":[""],"CiStatusLabel|failed":[""],"CiStatusLabel|manual action":[""],"CiStatusLabel|passed":[""],"CiStatusLabel|passed with warnings":[""],"CiStatusLabel|pending":[""],"CiStatusLabel|skipped":[""],"CiStatusLabel|waiting for manual action":[""],"CiStatusText|blocked":[""],"CiStatusText|canceled":[""],"CiStatusText|created":[""],"CiStatusText|failed":[""],"CiStatusText|manual":[""],"CiStatusText|passed":[""],"CiStatusText|pending":[""],"CiStatusText|skipped":[""],"CiStatus|running":[""],"Commit":["Commit","Commits"],"CommitMessage|Add %{file_name}":[""],"Commits":["Commits"],"Commits|History":["Commits"],"Compare":[""],"Contribution guide":[""],"Contributors":[""],"Copy URL to clipboard":[""],"Copy commit SHA to clipboard":[""],"Create New Directory":[""],"Create directory":[""],"Create empty bare repository":[""],"Create merge request":[""],"CreateNewFork|Fork":[""],"Custom notification events":[""],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":[""],"Cycle Analytics":[""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics liefern einen Überblick darüber, wie viel Zeit in Ihrem Projekt von einer Idee bis zum Produktivdeployment vergeht."],"CycleAnalyticsStage|Code":["Code"],"CycleAnalyticsStage|Issue":["Issue"],"CycleAnalyticsStage|Plan":["Planung"],"CycleAnalyticsStage|Production":["Produktiv"],"CycleAnalyticsStage|Review":["Review"],"CycleAnalyticsStage|Staging":["Staging"],"CycleAnalyticsStage|Test":["Test"],"Deploy":["Deployment","Deployments"],"Directory name":[""],"Don't show again":[""],"Download tar":[""],"Download tar.bz2":[""],"Download tar.gz":[""],"Download zip":[""],"DownloadArtifacts|Download":[""],"DownloadSource|Download":[""],"Files":[""],"Find by path":[""],"Find file":[""],"FirstPushedBy|First":["Erster"],"FirstPushedBy|pushed by":["gepusht von"],"ForkedFromProjectPath|Forked from":[""],"Forks":[""],"From issue creation until deploy to production":["Vom Anlegen des Issues bis zum Produktivdeployment"],"From merge request merge until deploy to production":["Vom Merge Request bis zum Produktivdeployment"],"Go to your fork":[""],"GoToYourFork|Fork":[""],"Home":[""],"Housekeeping successfully started":[""],"Import repository":[""],"Introducing Cycle Analytics":["Was sind Cycle Analytics?"],"LFSStatus|Disabled":[""],"LFSStatus|Enabled":[""],"Last %d day":["Letzter %d Tag","Letzten %d Tage"],"Last Update":[""],"Last commit":[""],"Leave group":[""],"Leave project":[""],"Limited to showing %d event at most":["Eingeschränkt auf maximal %d Ereignis","Eingeschränkt auf maximal %d Ereignisse"],"Median":["Median"],"MissingSSHKeyWarningLink|add an SSH key":[""],"New Issue":["Neues Issue","Neue Issues"],"New branch":[""],"New directory":[""],"New file":[""],"New issue":["Neues Issue"],"New merge request":[""],"New snippet":[""],"New tag":[""],"No repository":[""],"Not available":["Nicht verfügbar"],"Not enough data":["Nicht genügend Daten"],"Notification events":[""],"NotificationEvent|Close issue":[""],"NotificationEvent|Close merge request":[""],"NotificationEvent|Failed pipeline":[""],"NotificationEvent|Merge merge request":[""],"NotificationEvent|New issue":[""],"NotificationEvent|New merge request":[""],"NotificationEvent|New note":[""],"NotificationEvent|Reassign issue":[""],"NotificationEvent|Reassign merge request":[""],"NotificationEvent|Reopen issue":[""],"NotificationEvent|Successful pipeline":[""],"NotificationLevel|Custom":[""],"NotificationLevel|Disabled":[""],"NotificationLevel|Global":[""],"NotificationLevel|On mention":[""],"NotificationLevel|Participate":[""],"NotificationLevel|Watch":[""],"OpenedNDaysAgo|Opened":["Erstellt"],"Pipeline Health":["Pipeline Kennzahlen"],"Project '%{project_name}' queued for deletion.":[""],"Project '%{project_name}' was successfully created.":[""],"Project '%{project_name}' was successfully updated.":[""],"Project '%{project_name}' will be deleted.":[""],"Project access must be granted explicitly to each user.":[""],"Project export could not be deleted.":[""],"Project export has been deleted.":[""],"Project export link has expired. Please generate a new export from your project settings.":[""],"Project export started. A download link will be sent by email.":[""],"Project home":[""],"ProjectFeature|Disabled":[""],"ProjectFeature|Everyone with access":[""],"ProjectFeature|Only team members":[""],"ProjectFileTree|Name":[""],"ProjectLastActivity|Never":[""],"ProjectLifecycle|Stage":["Phase"],"ProjectNetworkGraph|Graph":[""],"Read more":["Mehr"],"Readme":[""],"RefSwitcher|Branches":[""],"RefSwitcher|Tags":[""],"Related Commits":["Zugehörige Commits"],"Related Deployed Jobs":["Zugehörige Deploymentjobs"],"Related Issues":["Zugehörige Issues"],"Related Jobs":["Zugehörige Jobs"],"Related Merge Requests":["Zugehörige Merge Requests"],"Related Merged Requests":["Zugehörige abgeschlossene Merge Requests"],"Remind later":[""],"Remove project":[""],"Request Access":[""],"Search branches and tags":[""],"Select Archive Format":[""],"Set a password on your account to pull or push via %{protocol}":[""],"Set up CI":[""],"Set up Koding":[""],"Set up auto deploy":[""],"SetPasswordToCloneLink|set a password":[""],"Showing %d event":["Zeige %d Ereignis","Zeige %d Ereignisse"],"Source code":[""],"StarProject|Star":[""],"Switch branch/tag":[""],"Tag":["",""],"Tags":[""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["Die Code-Phase stellt die Zeit vom ersten Commit bis zum Erstellen eines Merge Requests dar. Sobald Sie Ihren ersten Merge Request anlegen, werden dessen Daten automatisch ergänzt."],"The collection of events added to the data gathered for that stage.":["Ereignisse, die für diese Phase ausgewertet wurden."],"The fork relationship has been removed.":[""],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":["Die Issue-Phase stellt die Zeit vom Anlegen eines Issues bis zum Zuweisen eines Meilensteins oder Hinzufügen zum Issue Board dar. Erstellen Sie einen Issue, damit dessen Daten hier erscheinen."],"The phase of the development lifecycle.":["Die Phase im Entwicklungsprozess."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["Die Planungsphase stellt die Zeit von der vorherigen Phase bis zum Pushen des ersten Commits dar. Sobald Sie den ersten Commit pushen, werden dessen Daten hier erscheinen."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["Die Produktiv-Phase stellt die Gesamtzeit vom Anlegen eines Issues bis zum Deployment auf dem Produktivsystem dar. Sobald Sie den vollständigen Entwicklungszyklus von einer Idee bis zum Produktivdeployment durchlaufen haben, erscheinen die zugehörigen Daten hier."],"The project can be accessed by any logged in user.":[""],"The project can be accessed without any authentication.":[""],"The repository for this project does not exist.":[""],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["Die Review-Phase stellt die Zeit vom Anlegen eines Merge Requests bis zum Mergen dar. Sobald Sie Ihren ersten Merge Request abschließen, werden dessen Daten hier automatisch angezeigt."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["Die Staging-Phase stellt die Zeit zwischen Mergen eines Merge Requests und dem Produktivdeployment dar. Sobald Sie das erste Produktivdeployment durchgeführt haben, werden dessen Daten hier automatisch angezeigt."],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":["Die Test-Phase stellt die Zeit dar, die GitLab CI benötigt um die Pipelines von Merge Requests abzuarbeiten. Sobald die erste Pipeline abgeschlossen ist, werden deren Daten hier automatisch angezeigt."],"The time taken by each data entry gathered by that stage.":["Zeit die für das jeweilige Ereignis in der Phase ermittelt wurde."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["Der mittlere aller erfassten Werte. Zum Beispiel ist für 3, 5, 9 der Median 5. Bei 3, 5, 7, 8 ist der Median (5+7)/2 = 6."],"This means you can not push code until you create an empty repository or import existing one.":[""],"Time before an issue gets scheduled":["Zeit bis ein Issue geplant wird"],"Time before an issue starts implementation":["Zeit bis die Implementierung für ein Issue beginnt"],"Time between merge request creation and merge/close":["Zeit zwischen Anlegen und Mergen/Schließen eines Merge Requests"],"Time until first merge request":["Zeit bis zum ersten Merge Request"],"Timeago|%s days ago":[""],"Timeago|%s days remaining":[""],"Timeago|%s hours remaining":[""],"Timeago|%s minutes ago":[""],"Timeago|%s minutes remaining":[""],"Timeago|%s months ago":[""],"Timeago|%s months remaining":[""],"Timeago|%s seconds remaining":[""],"Timeago|%s weeks ago":[""],"Timeago|%s weeks remaining":[""],"Timeago|%s years ago":[""],"Timeago|%s years remaining":[""],"Timeago|1 day remaining":[""],"Timeago|1 hour remaining":[""],"Timeago|1 minute remaining":[""],"Timeago|1 month remaining":[""],"Timeago|1 week remaining":[""],"Timeago|1 year remaining":[""],"Timeago|Past due":[""],"Timeago|a day ago":[""],"Timeago|a month ago":[""],"Timeago|a week ago":[""],"Timeago|a while":[""],"Timeago|a year ago":[""],"Timeago|about %s hours ago":[""],"Timeago|about a minute ago":[""],"Timeago|about an hour ago":[""],"Timeago|in %s days":[""],"Timeago|in %s hours":[""],"Timeago|in %s minutes":[""],"Timeago|in %s months":[""],"Timeago|in %s seconds":[""],"Timeago|in %s weeks":[""],"Timeago|in %s years":[""],"Timeago|in 1 day":[""],"Timeago|in 1 hour":[""],"Timeago|in 1 minute":[""],"Timeago|in 1 month":[""],"Timeago|in 1 week":[""],"Timeago|in 1 year":[""],"Timeago|less than a minute ago":[""],"Time|hr":["h","h"],"Time|min":["min","min"],"Time|s":["s"],"Total Time":["Gesamtzeit"],"Total test time for all commits/merges":["Gesamte Testlaufzeit für alle Commits/Merges"],"Unstar":[""],"Upload New File":[""],"Upload file":[""],"Use your global notification setting":[""],"VisibilityLevel|Internal":[""],"VisibilityLevel|Private":[""],"VisibilityLevel|Public":[""],"Want to see the data? Please ask an administrator for access.":["Um diese Daten einsehen zu können, wenden Sie sich bitte an Ihren Administrator."],"We don't have enough data to show this stage.":["Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen."],"Withdraw Access Request":[""],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":[""],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":[""],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":[""],"You can only add files when you are on a branch":[""],"You must sign in to star a project":[""],"You need permission.":["Sie benötigen Zugriffsrechte."],"You will not get any notifications via email":[""],"You will only receive notifications for the events you choose":[""],"You will only receive notifications for threads you have participated in":[""],"You will receive notifications for any activity":[""],"You will receive notifications only for comments in which you were @mentioned":[""],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":[""],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":[""],"Your name":[""],"committed":[""],"day":["Tag","Tage"],"notification emails":[""]}}};
\ No newline at end of file \ No newline at end of file
var locales = locales || {}; locales['en'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-12 22:36-0500","Last-Translator":"FULL NAME <EMAIL@ADDRESS>","Language-Team":"English","Language":"en","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","lang":"en","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"ByAuthor|by":[""],"Commit":["",""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":[""],"CycleAnalyticsStage|Code":[""],"CycleAnalyticsStage|Issue":[""],"CycleAnalyticsStage|Plan":[""],"CycleAnalyticsStage|Production":[""],"CycleAnalyticsStage|Review":[""],"CycleAnalyticsStage|Staging":[""],"CycleAnalyticsStage|Test":[""],"Deploy":["",""],"FirstPushedBy|First":[""],"FirstPushedBy|pushed by":[""],"From issue creation until deploy to production":[""],"From merge request merge until deploy to production":[""],"Introducing Cycle Analytics":[""],"Last %d day":["",""],"Limited to showing %d event at most":["",""],"Median":[""],"New Issue":["",""],"Not available":[""],"Not enough data":[""],"OpenedNDaysAgo|Opened":[""],"Pipeline Health":[""],"ProjectLifecycle|Stage":[""],"Read more":[""],"Related Commits":[""],"Related Deployed Jobs":[""],"Related Issues":[""],"Related Jobs":[""],"Related Merge Requests":[""],"Related Merged Requests":[""],"Showing %d event":["",""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":[""],"The collection of events added to the data gathered for that stage.":[""],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":[""],"The phase of the development lifecycle.":[""],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":[""],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":[""],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":[""],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":[""],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":[""],"The time taken by each data entry gathered by that stage.":[""],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":[""],"Time before an issue gets scheduled":[""],"Time before an issue starts implementation":[""],"Time between merge request creation and merge/close":[""],"Time until first merge request":[""],"Time|hr":["",""],"Time|min":["",""],"Time|s":[""],"Total Time":[""],"Total test time for all commits/merges":[""],"Want to see the data? Please ask an administrator for access.":[""],"We don't have enough data to show this stage.":[""],"You need permission.":[""],"day":["",""]}}}; var locales = locales || {}; locales['en'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-06-07 12:14+0200","Language-Team":"English","Language":"en","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"Bob Van Landuyt <bob@gitlab.com>","X-Generator":"Poedit 2.0.2","lang":"en","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"About auto deploy":[""],"Activity":[""],"Add Changelog":[""],"Add Contribution guide":[""],"Add License":[""],"Add an SSH key to your profile to pull or push via SSH.":[""],"Add new directory":[""],"Archived project! Repository is read-only":[""],"Branch":["",""],"Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}":[""],"Branches":[""],"ByAuthor|by":[""],"CI configuration":[""],"Changelog":[""],"Charts":[""],"CiStatusLabel|canceled":[""],"CiStatusLabel|created":[""],"CiStatusLabel|failed":[""],"CiStatusLabel|manual action":[""],"CiStatusLabel|passed":[""],"CiStatusLabel|passed with warnings":[""],"CiStatusLabel|pending":[""],"CiStatusLabel|skipped":[""],"CiStatusLabel|waiting for manual action":[""],"CiStatusText|blocked":[""],"CiStatusText|canceled":[""],"CiStatusText|created":[""],"CiStatusText|failed":[""],"CiStatusText|manual":[""],"CiStatusText|passed":[""],"CiStatusText|pending":[""],"CiStatusText|skipped":[""],"CiStatus|running":[""],"Commit":["",""],"CommitMessage|Add %{file_name}":[""],"Commits":[""],"Commits|History":[""],"Compare":[""],"Contribution guide":[""],"Contributors":[""],"Copy URL to clipboard":[""],"Copy commit SHA to clipboard":[""],"Create New Directory":[""],"Create directory":[""],"Create empty bare repository":[""],"Create merge request":[""],"CreateNewFork|Fork":[""],"Custom notification events":[""],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":[""],"Cycle Analytics":[""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":[""],"CycleAnalyticsStage|Code":[""],"CycleAnalyticsStage|Issue":[""],"CycleAnalyticsStage|Plan":[""],"CycleAnalyticsStage|Production":[""],"CycleAnalyticsStage|Review":[""],"CycleAnalyticsStage|Staging":[""],"CycleAnalyticsStage|Test":[""],"Deploy":["",""],"Directory name":[""],"Don't show again":[""],"Download tar":[""],"Download tar.bz2":[""],"Download tar.gz":[""],"Download zip":[""],"DownloadArtifacts|Download":[""],"DownloadSource|Download":[""],"Files":[""],"Find by path":[""],"Find file":[""],"FirstPushedBy|First":[""],"FirstPushedBy|pushed by":[""],"ForkedFromProjectPath|Forked from":[""],"Forks":[""],"From issue creation until deploy to production":[""],"From merge request merge until deploy to production":[""],"Go to your fork":[""],"GoToYourFork|Fork":[""],"Home":[""],"Housekeeping successfully started":[""],"Import repository":[""],"Introducing Cycle Analytics":[""],"LFSStatus|Disabled":[""],"LFSStatus|Enabled":[""],"Last %d day":["",""],"Last Update":[""],"Last commit":[""],"Leave group":[""],"Leave project":[""],"Limited to showing %d event at most":["",""],"Median":[""],"MissingSSHKeyWarningLink|add an SSH key":[""],"New Issue":["",""],"New branch":[""],"New directory":[""],"New file":[""],"New issue":[""],"New merge request":[""],"New snippet":[""],"New tag":[""],"No repository":[""],"Not available":[""],"Not enough data":[""],"Notification events":[""],"NotificationEvent|Close issue":[""],"NotificationEvent|Close merge request":[""],"NotificationEvent|Failed pipeline":[""],"NotificationEvent|Merge merge request":[""],"NotificationEvent|New issue":[""],"NotificationEvent|New merge request":[""],"NotificationEvent|New note":[""],"NotificationEvent|Reassign issue":[""],"NotificationEvent|Reassign merge request":[""],"NotificationEvent|Reopen issue":[""],"NotificationEvent|Successful pipeline":[""],"NotificationLevel|Custom":[""],"NotificationLevel|Disabled":[""],"NotificationLevel|Global":[""],"NotificationLevel|On mention":[""],"NotificationLevel|Participate":[""],"NotificationLevel|Watch":[""],"OpenedNDaysAgo|Opened":[""],"Pipeline Health":[""],"Project '%{project_name}' queued for deletion.":[""],"Project '%{project_name}' was successfully created.":[""],"Project '%{project_name}' was successfully updated.":[""],"Project '%{project_name}' will be deleted.":[""],"Project access must be granted explicitly to each user.":[""],"Project export could not be deleted.":[""],"Project export has been deleted.":[""],"Project export link has expired. Please generate a new export from your project settings.":[""],"Project export started. A download link will be sent by email.":[""],"Project home":[""],"ProjectFeature|Disabled":[""],"ProjectFeature|Everyone with access":[""],"ProjectFeature|Only team members":[""],"ProjectFileTree|Name":[""],"ProjectLastActivity|Never":[""],"ProjectLifecycle|Stage":[""],"ProjectNetworkGraph|Graph":[""],"Read more":[""],"Readme":[""],"RefSwitcher|Branches":[""],"RefSwitcher|Tags":[""],"Related Commits":[""],"Related Deployed Jobs":[""],"Related Issues":[""],"Related Jobs":[""],"Related Merge Requests":[""],"Related Merged Requests":[""],"Remind later":[""],"Remove project":[""],"Request Access":[""],"Search branches and tags":[""],"Select Archive Format":[""],"Set a password on your account to pull or push via %{protocol}":[""],"Set up CI":[""],"Set up Koding":[""],"Set up auto deploy":[""],"SetPasswordToCloneLink|set a password":[""],"Showing %d event":["",""],"Source code":[""],"StarProject|Star":[""],"Switch branch/tag":[""],"Tag":["",""],"Tags":[""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":[""],"The collection of events added to the data gathered for that stage.":[""],"The fork relationship has been removed.":[""],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":[""],"The phase of the development lifecycle.":[""],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":[""],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":[""],"The project can be accessed by any logged in user.":[""],"The project can be accessed without any authentication.":[""],"The repository for this project does not exist.":[""],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":[""],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":[""],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":[""],"The time taken by each data entry gathered by that stage.":[""],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":[""],"This means you can not push code until you create an empty repository or import existing one.":[""],"Time before an issue gets scheduled":[""],"Time before an issue starts implementation":[""],"Time between merge request creation and merge/close":[""],"Time until first merge request":[""],"Timeago|%s days ago":[""],"Timeago|%s days remaining":[""],"Timeago|%s hours remaining":[""],"Timeago|%s minutes ago":[""],"Timeago|%s minutes remaining":[""],"Timeago|%s months ago":[""],"Timeago|%s months remaining":[""],"Timeago|%s seconds remaining":[""],"Timeago|%s weeks ago":[""],"Timeago|%s weeks remaining":[""],"Timeago|%s years ago":[""],"Timeago|%s years remaining":[""],"Timeago|1 day remaining":[""],"Timeago|1 hour remaining":[""],"Timeago|1 minute remaining":[""],"Timeago|1 month remaining":[""],"Timeago|1 week remaining":[""],"Timeago|1 year remaining":[""],"Timeago|Past due":[""],"Timeago|a day ago":[""],"Timeago|a month ago":[""],"Timeago|a week ago":[""],"Timeago|a while":[""],"Timeago|a year ago":[""],"Timeago|about %s hours ago":[""],"Timeago|about a minute ago":[""],"Timeago|about an hour ago":[""],"Timeago|in %s days":[""],"Timeago|in %s hours":[""],"Timeago|in %s minutes":[""],"Timeago|in %s months":[""],"Timeago|in %s seconds":[""],"Timeago|in %s weeks":[""],"Timeago|in %s years":[""],"Timeago|in 1 day":[""],"Timeago|in 1 hour":[""],"Timeago|in 1 minute":[""],"Timeago|in 1 month":[""],"Timeago|in 1 week":[""],"Timeago|in 1 year":[""],"Timeago|less than a minute ago":[""],"Time|hr":["",""],"Time|min":["",""],"Time|s":[""],"Total Time":[""],"Total test time for all commits/merges":[""],"Unstar":[""],"Upload New File":[""],"Upload file":[""],"Use your global notification setting":[""],"VisibilityLevel|Internal":[""],"VisibilityLevel|Private":[""],"VisibilityLevel|Public":[""],"Want to see the data? Please ask an administrator for access.":[""],"We don't have enough data to show this stage.":[""],"Withdraw Access Request":[""],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":[""],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":[""],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":[""],"You can only add files when you are on a branch":[""],"You must sign in to star a project":[""],"You need permission.":[""],"You will not get any notifications via email":[""],"You will only receive notifications for the events you choose":[""],"You will only receive notifications for threads you have participated in":[""],"You will receive notifications for any activity":[""],"You will receive notifications only for comments in which you were @mentioned":[""],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":[""],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":[""],"Your name":[""],"committed":[""],"day":["",""],"notification emails":[""]}}};
\ No newline at end of file \ No newline at end of file
var locales = locales || {}; locales['es'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-05-20 22:37-0500","Language-Team":"Spanish","Language":"es","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"","X-Generator":"Poedit 2.0.1","lang":"es","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"ByAuthor|by":["por"],"Commit":["Cambio","Cambios"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."],"CycleAnalyticsStage|Code":["Código"],"CycleAnalyticsStage|Issue":["Incidencia"],"CycleAnalyticsStage|Plan":["Planificación"],"CycleAnalyticsStage|Production":["Producción"],"CycleAnalyticsStage|Review":["Revisión"],"CycleAnalyticsStage|Staging":["Puesta en escena"],"CycleAnalyticsStage|Test":["Pruebas"],"Deploy":["Despliegue","Despliegues"],"FirstPushedBy|First":["Primer"],"FirstPushedBy|pushed by":["enviado por"],"From issue creation until deploy to production":["Desde la creación de la incidencia hasta el despliegue a producción"],"From merge request merge until deploy to production":["Desde la integración de la solicitud de fusión hasta el despliegue a producción"],"Introducing Cycle Analytics":["Introducción a Cycle Analytics"],"Last %d day":["Último %d día","Últimos %d días"],"Limited to showing %d event at most":["Limitado a mostrar máximo %d evento","Limitado a mostrar máximo %d eventos"],"Median":["Mediana"],"New Issue":["Nueva incidencia","Nuevas incidencias"],"Not available":["No disponible"],"Not enough data":["No hay suficientes datos"],"OpenedNDaysAgo|Opened":["Abierto"],"Pipeline Health":["Estado del Pipeline"],"ProjectLifecycle|Stage":["Etapa"],"Read more":["Leer más"],"Related Commits":["Cambios Relacionados"],"Related Deployed Jobs":["Trabajos Desplegados Relacionados"],"Related Issues":["Incidencias Relacionadas"],"Related Jobs":["Trabajos Relacionados"],"Related Merge Requests":["Solicitudes de fusión Relacionadas"],"Related Merged Requests":["Solicitudes de fusión Relacionadas"],"Showing %d event":["Mostrando %d evento","Mostrando %d eventos"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."],"The collection of events added to the data gathered for that stage.":["La colección de eventos agregados a los datos recopilados para esa etapa."],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":["La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa."],"The phase of the development lifecycle.":["La etapa del ciclo de vida de desarrollo."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["La etapa de planificación muestra el tiempo desde el paso anterior hasta el envío de tu primera confirmación. Este tiempo se añadirá automáticamente una vez que usted envíe el primer cambio."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción."],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["La etapa de puesta en escena muestra el tiempo entre la fusión y el despliegue de código en el entorno de producción. Los datos se añadirán automáticamente una vez que se despliega a producción por primera vez."],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":["La etapa de pruebas muestra el tiempo que GitLab CI toma para ejecutar cada pipeline para la solicitud de fusión relacionada. Los datos se añadirán automáticamente luego de que el primer pipeline termine de ejecutarse."],"The time taken by each data entry gathered by that stage.":["El tiempo utilizado por cada entrada de datos obtenido por esa etapa."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6."],"Time before an issue gets scheduled":["Tiempo antes de que una incidencia sea programada"],"Time before an issue starts implementation":["Tiempo antes de que empieze la implementación de una incidencia"],"Time between merge request creation and merge/close":["Tiempo entre la creación de la solicitud de fusión y la integración o cierre de ésta"],"Time until first merge request":["Tiempo hasta la primera solicitud de fusión"],"Time|hr":["hr","hrs"],"Time|min":["min","mins"],"Time|s":["s"],"Total Time":["Tiempo Total"],"Total test time for all commits/merges":["Tiempo total de pruebas para todos los cambios o integraciones"],"Want to see the data? Please ask an administrator for access.":["¿Quieres ver los datos? Por favor pide acceso al administrador."],"We don't have enough data to show this stage.":["No hay suficientes datos para mostrar en esta etapa."],"You need permission.":["Necesitas permisos."],"day":["día","días"]}}}; var locales = locales || {}; locales['es'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-06-07 12:29-0500","Language-Team":"Spanish","Language":"es","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"Bob Van Landuyt <bob@gitlab.com>","X-Generator":"Poedit 2.0.2","lang":"es","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"About auto deploy":["Acerca del auto despliegue"],"Activity":["Actividad"],"Add Changelog":["Agregar Changelog"],"Add Contribution guide":["Agregar guía de contribución"],"Add License":["Agregar Licencia"],"Add an SSH key to your profile to pull or push via SSH.":["Agregar una clave SSH a tu perfil para actualizar o enviar a través de SSH."],"Add new directory":["Agregar nuevo directorio"],"Archived project! Repository is read-only":["¡Proyecto archivado! El repositorio es de sólo lectura"],"Branch":["Rama","Ramas"],"Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}":["La rama <strong>%{branch_name}</strong> fue creada. Para configurar el auto despliegue, escoge una plantilla Yaml para GitLab CI y envía tus cambios. %{link_to_autodeploy_doc}"],"Branches":["Ramas"],"ByAuthor|by":["por"],"CI configuration":["Configuración de CI"],"Changelog":["Changelog"],"Charts":["Gráficos"],"CiStatusLabel|canceled":["cancelado"],"CiStatusLabel|created":["creado"],"CiStatusLabel|failed":["fallado"],"CiStatusLabel|manual action":["acción manual"],"CiStatusLabel|passed":["pasó"],"CiStatusLabel|passed with warnings":["pasó con advertencias"],"CiStatusLabel|pending":["pendiente"],"CiStatusLabel|skipped":["omitido"],"CiStatusLabel|waiting for manual action":["esperando acción manual"],"CiStatusText|blocked":["bloqueado"],"CiStatusText|canceled":["cancelado"],"CiStatusText|created":["creado"],"CiStatusText|failed":["fallado"],"CiStatusText|manual":["manual"],"CiStatusText|passed":["pasó"],"CiStatusText|pending":["pendiente"],"CiStatusText|skipped":["omitido"],"CiStatus|running":["en ejecución"],"Commit":["Cambio","Cambios"],"CommitMessage|Add %{file_name}":["Agregar %{file_name}"],"Commits":["Cambios"],"Commits|History":["Historial"],"Compare":["Comparar"],"Contribution guide":["Guía de contribución"],"Contributors":["Contribuidores"],"Copy URL to clipboard":["Copiar URL al portapapeles"],"Copy commit SHA to clipboard":["Copiar SHA del cambio al portapapeles"],"Create New Directory":["Crear Nuevo Directorio"],"Create directory":["Crear directorio"],"Create empty bare repository":["Crear repositorio vacío"],"Create merge request":["Crear solicitud de fusión"],"CreateNewFork|Fork":["Bifurcar"],"Custom notification events":["Eventos de notificaciones personalizadas"],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":["Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."],"Cycle Analytics":["Cycle Analytics"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."],"CycleAnalyticsStage|Code":["Código"],"CycleAnalyticsStage|Issue":["Incidencia"],"CycleAnalyticsStage|Plan":["Planificación"],"CycleAnalyticsStage|Production":["Producción"],"CycleAnalyticsStage|Review":["Revisión"],"CycleAnalyticsStage|Staging":["Puesta en escena"],"CycleAnalyticsStage|Test":["Pruebas"],"Deploy":["Despliegue","Despliegues"],"Directory name":["Nombre del directorio"],"Don't show again":["No mostrar de nuevo"],"Download tar":["Descargar tar"],"Download tar.bz2":["Descargar tar.bz2"],"Download tar.gz":["Descargar tar.gz"],"Download zip":["Descargar zip"],"DownloadArtifacts|Download":["Descargar"],"DownloadSource|Download":["Descargar"],"Files":["Archivos"],"Find by path":["Buscar por ruta"],"Find file":["Buscar archivo"],"FirstPushedBy|First":["Primer"],"FirstPushedBy|pushed by":["enviado por"],"ForkedFromProjectPath|Forked from":["Bifurcado de"],"Forks":["Bifurcaciones"],"From issue creation until deploy to production":["Desde la creación de la incidencia hasta el despliegue a producción"],"From merge request merge until deploy to production":["Desde la integración de la solicitud de fusión hasta el despliegue a producción"],"Go to your fork":["Ir a tu bifurcación"],"GoToYourFork|Fork":["Bifurcación"],"Home":["Inicio"],"Housekeeping successfully started":["Servicio de limpieza iniciado con éxito"],"Import repository":["Importar repositorio"],"Introducing Cycle Analytics":["Introducción a Cycle Analytics"],"LFSStatus|Disabled":["Deshabilitado"],"LFSStatus|Enabled":["Habilitado"],"Last %d day":["Último %d día","Últimos %d días"],"Last Update":["Última actualización"],"Last commit":["Último cambio"],"Leave group":["Abandonar grupo"],"Leave project":["Abandonar proyecto"],"Limited to showing %d event at most":["Limitado a mostrar máximo %d evento","Limitado a mostrar máximo %d eventos"],"Median":["Mediana"],"MissingSSHKeyWarningLink|add an SSH key":["agregar una clave SSH"],"New Issue":["Nueva incidencia","Nuevas incidencias"],"New branch":["Nueva rama"],"New directory":["Nuevo directorio"],"New file":["Nuevo archivo"],"New issue":["Nueva incidencia"],"New merge request":["Nueva solicitud de fusión"],"New snippet":["Nuevo fragmento de código"],"New tag":["Nueva etiqueta"],"No repository":["No hay repositorio"],"Not available":["No disponible"],"Not enough data":["No hay suficientes datos"],"Notification events":["Eventos de notificación"],"NotificationEvent|Close issue":["Cerrar incidencia"],"NotificationEvent|Close merge request":["Cerrar solicitud de fusión"],"NotificationEvent|Failed pipeline":["Pipeline fallido"],"NotificationEvent|Merge merge request":["Integrar solicitud de fusión"],"NotificationEvent|New issue":["Nueva incidencia"],"NotificationEvent|New merge request":["Nueva solicitud de fusión"],"NotificationEvent|New note":["Nueva nota"],"NotificationEvent|Reassign issue":["Reasignar incidencia"],"NotificationEvent|Reassign merge request":["Reasignar solicitud de fusión"],"NotificationEvent|Reopen issue":["Reabrir incidencia"],"NotificationEvent|Successful pipeline":["Pipeline exitoso"],"NotificationLevel|Custom":["Personalizado"],"NotificationLevel|Disabled":["Deshabilitado"],"NotificationLevel|Global":["Global"],"NotificationLevel|On mention":["Cuando me mencionan"],"NotificationLevel|Participate":["Participación"],"NotificationLevel|Watch":["Vigilancia"],"OpenedNDaysAgo|Opened":["Abierto"],"Pipeline Health":["Estado del Pipeline"],"Project '%{project_name}' queued for deletion.":["Proyecto ‘%{project_name}’ en cola para eliminación."],"Project '%{project_name}' was successfully created.":["Proyecto ‘%{project_name}’ fue creado satisfactoriamente."],"Project '%{project_name}' was successfully updated.":["Proyecto ‘%{project_name}’ fue actualizado satisfactoriamente."],"Project '%{project_name}' will be deleted.":["Proyecto ‘%{project_name}’ será eliminado."],"Project access must be granted explicitly to each user.":["El acceso al proyecto debe concederse explícitamente a cada usuario."],"Project export could not be deleted.":["No se pudo eliminar la exportación del proyecto."],"Project export has been deleted.":["La exportación del proyecto ha sido eliminada."],"Project export link has expired. Please generate a new export from your project settings.":["El enlace de exportación del proyecto ha caducado. Por favor, genera una nueva exportación desde la configuración del proyecto."],"Project export started. A download link will be sent by email.":["Se inició la exportación del proyecto. Se enviará un enlace de descarga por correo electrónico."],"Project home":["Inicio del proyecto"],"ProjectFeature|Disabled":["Deshabilitada"],"ProjectFeature|Everyone with access":["Todos con acceso"],"ProjectFeature|Only team members":["Solo miembros del equipo"],"ProjectFileTree|Name":["Nombre"],"ProjectLastActivity|Never":["Nunca"],"ProjectLifecycle|Stage":["Etapa"],"ProjectNetworkGraph|Graph":["Historial gráfico"],"Read more":["Leer más"],"Readme":["Readme"],"RefSwitcher|Branches":["Ramas"],"RefSwitcher|Tags":["Etiquetas"],"Related Commits":["Cambios Relacionados"],"Related Deployed Jobs":["Trabajos Desplegados Relacionados"],"Related Issues":["Incidencias Relacionadas"],"Related Jobs":["Trabajos Relacionados"],"Related Merge Requests":["Solicitudes de fusión Relacionadas"],"Related Merged Requests":["Solicitudes de fusión Relacionadas"],"Remind later":["Recordar después"],"Remove project":["Eliminar proyecto"],"Request Access":["Solicitar acceso"],"Search branches and tags":["Buscar ramas y etiquetas"],"Select Archive Format":["Seleccionar formato de archivo"],"Set a password on your account to pull or push via %{protocol}":["Establezca una contraseña en su cuenta para actualizar o enviar a través de% {protocol}"],"Set up CI":["Configurar CI"],"Set up Koding":["Configurar Koding"],"Set up auto deploy":["Configurar auto despliegue"],"SetPasswordToCloneLink|set a password":["establecer una contraseña"],"Showing %d event":["Mostrando %d evento","Mostrando %d eventos"],"Source code":["Código fuente"],"StarProject|Star":["Destacar"],"Switch branch/tag":["Cambiar rama/etiqueta"],"Tag":["Etiqueta","Etiquetas"],"Tags":["Etiquetas"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."],"The collection of events added to the data gathered for that stage.":["La colección de eventos agregados a los datos recopilados para esa etapa."],"The fork relationship has been removed.":["La relación con la bifurcación se ha eliminado."],"The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.":["La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa."],"The phase of the development lifecycle.":["La etapa del ciclo de vida de desarrollo."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["La etapa de planificación muestra el tiempo desde el paso anterior hasta el envío de tu primera confirmación. Este tiempo se añadirá automáticamente una vez que usted envíe el primer cambio."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción."],"The project can be accessed by any logged in user.":["El proyecto puede ser accedido por cualquier usuario conectado."],"The project can be accessed without any authentication.":["El proyecto puede accederse sin ninguna autenticación."],"The repository for this project does not exist.":["El repositorio para este proyecto no existe."],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["La etapa de puesta en escena muestra el tiempo entre la fusión y el despliegue de código en el entorno de producción. Los datos se añadirán automáticamente una vez que se despliega a producción por primera vez."],"The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.":["La etapa de pruebas muestra el tiempo que GitLab CI toma para ejecutar cada pipeline para la solicitud de fusión relacionada. Los datos se añadirán automáticamente luego de que el primer pipeline termine de ejecutarse."],"The time taken by each data entry gathered by that stage.":["El tiempo utilizado por cada entrada de datos obtenido por esa etapa."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6."],"This means you can not push code until you create an empty repository or import existing one.":["Esto significa que no puede enviar código hasta que cree un repositorio vacío o importe uno existente."],"Time before an issue gets scheduled":["Tiempo antes de que una incidencia sea programada"],"Time before an issue starts implementation":["Tiempo antes de que empieze la implementación de una incidencia"],"Time between merge request creation and merge/close":["Tiempo entre la creación de la solicitud de fusión y la integración o cierre de ésta"],"Time until first merge request":["Tiempo hasta la primera solicitud de fusión"],"Timeago|%s days ago":["hace %s días"],"Timeago|%s days remaining":["%s días restantes"],"Timeago|%s hours remaining":["%s horas restantes"],"Timeago|%s minutes ago":["hace %s minutos"],"Timeago|%s minutes remaining":["%s minutos restantes"],"Timeago|%s months ago":["hace %s meses"],"Timeago|%s months remaining":["%s meses restantes"],"Timeago|%s seconds remaining":["%s segundos restantes"],"Timeago|%s weeks ago":["hace %s semanas"],"Timeago|%s weeks remaining":["%s semanas restantes"],"Timeago|%s years ago":["hace %s años"],"Timeago|%s years remaining":["%s años restantes"],"Timeago|1 day remaining":["1 día restante"],"Timeago|1 hour remaining":["1 hora restante"],"Timeago|1 minute remaining":["1 minuto restante"],"Timeago|1 month remaining":["1 mes restante"],"Timeago|1 week remaining":["1 semana restante"],"Timeago|1 year remaining":["1 año restante"],"Timeago|Past due":["Atrasado"],"Timeago|a day ago":["hace un día"],"Timeago|a month ago":["hace 1 mes"],"Timeago|a week ago":["hace 1 semana"],"Timeago|a while":["hace un momento"],"Timeago|a year ago":["hace 1 año"],"Timeago|about %s hours ago":["hace alrededor de %s horas"],"Timeago|about a minute ago":["hace alrededor de 1 minuto"],"Timeago|about an hour ago":["hace alrededor de 1 hora"],"Timeago|in %s days":["en %s días"],"Timeago|in %s hours":["en %s horas"],"Timeago|in %s minutes":["en %s minutos"],"Timeago|in %s months":["en %s meses"],"Timeago|in %s seconds":["en %s segundos"],"Timeago|in %s weeks":["en %s semanas"],"Timeago|in %s years":["en %s años"],"Timeago|in 1 day":["en 1 día"],"Timeago|in 1 hour":["en 1 hora"],"Timeago|in 1 minute":["en 1 minuto"],"Timeago|in 1 month":["en 1 mes"],"Timeago|in 1 week":["en 1 semana"],"Timeago|in 1 year":["en 1 año"],"Timeago|less than a minute ago":["hace menos de 1 minuto"],"Time|hr":["hr","hrs"],"Time|min":["min","mins"],"Time|s":["s"],"Total Time":["Tiempo Total"],"Total test time for all commits/merges":["Tiempo total de pruebas para todos los cambios o integraciones"],"Unstar":["No Destacar"],"Upload New File":["Subir nuevo archivo"],"Upload file":["Subir archivo"],"Use your global notification setting":["Utiliza tu configuración de notificación global"],"VisibilityLevel|Internal":["Interno"],"VisibilityLevel|Private":["Privado"],"VisibilityLevel|Public":["Público"],"Want to see the data? Please ask an administrator for access.":["¿Quieres ver los datos? Por favor pide acceso al administrador."],"We don't have enough data to show this stage.":["No hay suficientes datos para mostrar en esta etapa."],"Withdraw Access Request":["Retirar Solicitud de Acceso"],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":["Va a eliminar %{project_name_with_namespace}.\\n¡El proyecto eliminado NO puede ser restaurado!\\n¿Estás TOTALMENTE seguro?"],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":["Vas a eliminar el enlace de la bifurcación con el proyecto original %{forked_from_project}. ¿Estás TOTALMENTE seguro?"],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":["Vas a transferir %{project_name_with_namespace} a otro propietario. ¿Estás TOTALMENTE seguro?"],"You can only add files when you are on a branch":["Sólo puede agregar archivos cuando estas en una rama"],"You must sign in to star a project":["Debes iniciar sesión para destacar un proyecto"],"You need permission.":["Necesitas permisos."],"You will not get any notifications via email":["No recibirás ninguna notificación por correo electrónico"],"You will only receive notifications for the events you choose":["Solo recibirás notificaciones de los eventos que elijas"],"You will only receive notifications for threads you have participated in":["Solo recibirás notificaciones de los temas en los que has participado"],"You will receive notifications for any activity":["Recibirás notificaciones para cualquier actividad"],"You will receive notifications only for comments in which you were @mentioned":["Recibirás notificaciones sólo para los comentarios en los que se te mencionó"],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":["No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":["No podrás actualizar o enviar código al proyecto a través de SSH hasta que %{add_ssh_key_link} en su perfil"],"Your name":["Tu nombre"],"committed":["cambió"],"day":["día","días"],"notification emails":["correos electrónicos de notificación"]}}};
\ No newline at end of file \ No newline at end of file
...@@ -9,7 +9,7 @@ class ProfilesController < Profiles::ApplicationController ...@@ -9,7 +9,7 @@ class ProfilesController < Profiles::ApplicationController
end end
def update def update
user_params.except!(:email) if @user.ldap_user? user_params.except!(:email) if @user.external_email?
respond_to do |format| respond_to do |format|
if @user.update_attributes(user_params) if @user.update_attributes(user_params)
...@@ -76,7 +76,7 @@ class ProfilesController < Profiles::ApplicationController ...@@ -76,7 +76,7 @@ class ProfilesController < Profiles::ApplicationController
end end
def user_params def user_params
params.require(:user).permit( @user_params ||= params.require(:user).permit(
:avatar, :avatar,
:bio, :bio,
:email, :email,
......
module Projects
class IssueLinksController < ApplicationController
before_action :authorize_admin_issue_link!, only: [:create, :destroy]
def index
render json: issues
end
def create
create_params = params.slice(:issue_references)
result = IssueLinks::CreateService.new(issue, current_user, create_params).execute
render json: { message: result[:message], issues: issues }, status: result[:http_status]
end
def destroy
issue_link = IssueLink.find(params[:id])
return render_403 unless can?(current_user, :admin_issue_link, issue_link.target.project)
IssueLinks::DestroyService.new(issue_link, current_user).execute
render json: { issues: issues }
end
private
def issues
IssueLinks::ListService.new(issue, current_user).execute
end
def authorize_admin_issue_link!
render_403 unless can?(current_user, :admin_issue_link, @project)
end
def issue
@issue ||=
IssuesFinder.new(current_user, project_id: @project.id)
.execute
.find_by!(iid: params[:issue_id])
end
end
end
...@@ -34,7 +34,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -34,7 +34,7 @@ class ProjectsController < Projects::ApplicationController
redirect_to( redirect_to(
project_path(@project), project_path(@project),
notice: "Project '#{@project.name}' was successfully created." notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name }
) )
else else
render 'new' render 'new'
...@@ -49,7 +49,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -49,7 +49,7 @@ class ProjectsController < Projects::ApplicationController
respond_to do |format| respond_to do |format|
if result[:status] == :success if result[:status] == :success
flash[:notice] = "Project '#{@project.name}' was successfully updated." flash[:notice] = _("Project '%{project_name}' was successfully updated.") % { project_name: @project.name }
format.html do format.html do
redirect_to(edit_project_path(@project)) redirect_to(edit_project_path(@project))
end end
...@@ -76,7 +76,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -76,7 +76,7 @@ class ProjectsController < Projects::ApplicationController
return access_denied! unless can?(current_user, :remove_fork_project, @project) return access_denied! unless can?(current_user, :remove_fork_project, @project)
if ::Projects::UnlinkForkService.new(@project, current_user).execute if ::Projects::UnlinkForkService.new(@project, current_user).execute
flash[:notice] = 'The fork relationship has been removed.' flash[:notice] = _('The fork relationship has been removed.')
end end
end end
...@@ -98,7 +98,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -98,7 +98,7 @@ class ProjectsController < Projects::ApplicationController
end end
if @project.pending_delete? if @project.pending_delete?
flash[:alert] = "Project #{@project.name} queued for deletion." flash[:alert] = _("Project '%{project_name}' queued for deletion.") % { project_name: @project.name }
end end
respond_to do |format| respond_to do |format|
...@@ -118,7 +118,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -118,7 +118,7 @@ class ProjectsController < Projects::ApplicationController
return access_denied! unless can?(current_user, :remove_project, @project) return access_denied! unless can?(current_user, :remove_project, @project)
::Projects::DestroyService.new(@project, current_user, {}).async_execute ::Projects::DestroyService.new(@project, current_user, {}).async_execute
flash[:alert] = "Project '#{@project.name_with_namespace}' will be deleted." flash[:alert] = _("Project '%{project_name}' will be deleted.") % { project_name: @project.name_with_namespace }
redirect_to dashboard_projects_path, status: 302 redirect_to dashboard_projects_path, status: 302
rescue Projects::DestroyService::DestroyError => ex rescue Projects::DestroyService::DestroyError => ex
...@@ -157,7 +157,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -157,7 +157,7 @@ class ProjectsController < Projects::ApplicationController
redirect_to( redirect_to(
project_path(@project), project_path(@project),
notice: "Housekeeping successfully started" notice: _("Housekeeping successfully started")
) )
rescue ::Projects::HousekeepingService::LeaseTaken => ex rescue ::Projects::HousekeepingService::LeaseTaken => ex
redirect_to( redirect_to(
...@@ -171,7 +171,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -171,7 +171,7 @@ class ProjectsController < Projects::ApplicationController
redirect_to( redirect_to(
edit_project_path(@project), edit_project_path(@project),
notice: "Project export started. A download link will be sent by email." notice: _("Project export started. A download link will be sent by email.")
) )
end end
...@@ -183,16 +183,16 @@ class ProjectsController < Projects::ApplicationController ...@@ -183,16 +183,16 @@ class ProjectsController < Projects::ApplicationController
else else
redirect_to( redirect_to(
edit_project_path(@project), edit_project_path(@project),
alert: "Project export link has expired. Please generate a new export from your project settings." alert: _("Project export link has expired. Please generate a new export from your project settings.")
) )
end end
end end
def remove_export def remove_export
if @project.remove_exports if @project.remove_exports
flash[:notice] = "Project export has been deleted." flash[:notice] = _("Project export has been deleted.")
else else
flash[:alert] = "Project export could not be deleted." flash[:alert] = _("Project export could not be deleted.")
end end
redirect_to(edit_project_path(@project)) redirect_to(edit_project_path(@project))
end end
...@@ -203,7 +203,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -203,7 +203,7 @@ class ProjectsController < Projects::ApplicationController
else else
redirect_to( redirect_to(
edit_project_path(@project), edit_project_path(@project),
alert: "Project export could not be deleted." alert: _("Project export could not be deleted.")
) )
end end
end end
...@@ -221,13 +221,13 @@ class ProjectsController < Projects::ApplicationController ...@@ -221,13 +221,13 @@ class ProjectsController < Projects::ApplicationController
branches = BranchesFinder.new(@repository, params).execute.map(&:name) branches = BranchesFinder.new(@repository, params).execute.map(&:name)
options = { options = {
'Branches' => branches.take(100) s_('RefSwitcher|Branches') => branches.take(100)
} }
unless @repository.tag_count.zero? unless @repository.tag_count.zero?
tags = TagsFinder.new(@repository, params).execute.map(&:name) tags = TagsFinder.new(@repository, params).execute.map(&:name)
options['Tags'] = tags.take(100) options[s_('RefSwitcher|Tags')] = tags.take(100)
end end
# If reference is commit id - we should add it to branch/tag selectbox # If reference is commit id - we should add it to branch/tag selectbox
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
# label_name: string # label_name: string
# sort: string # sort: string
# non_archived: boolean # non_archived: boolean
# feature_availability_check: boolean (default: true)
# iids: integer[] # iids: integer[]
# #
class IssuableFinder class IssuableFinder
...@@ -26,15 +25,11 @@ class IssuableFinder ...@@ -26,15 +25,11 @@ class IssuableFinder
ARRAY_PARAMS = { label_name: [], iids: [] }.freeze ARRAY_PARAMS = { label_name: [], iids: [] }.freeze
VALID_PARAMS = (SCALAR_PARAMS + [ARRAY_PARAMS]).freeze VALID_PARAMS = (SCALAR_PARAMS + [ARRAY_PARAMS]).freeze
DEFAULT_PARAMS = {
feature_availability_check: true
}.freeze
attr_accessor :current_user, :params attr_accessor :current_user, :params
def initialize(current_user, params = {}) def initialize(current_user, params = {})
@current_user = current_user @current_user = current_user
@params = DEFAULT_PARAMS.merge(params).with_indifferent_access @params = params
end end
def execute def execute
...@@ -131,20 +126,7 @@ class IssuableFinder ...@@ -131,20 +126,7 @@ class IssuableFinder
ProjectsFinder.new(current_user: current_user, project_ids_relation: item_project_ids(items)).execute ProjectsFinder.new(current_user: current_user, project_ids_relation: item_project_ids(items)).execute
end end
# Querying through feature availability for an user is expensive @projects = projects.with_feature_available_for_user(klass, current_user).reorder(nil)
# (i.e. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1719#note_31406525),
# and there are cases which a project level access check should be enough.
# In any case, `feature_availability_check` param should be kept with `true`
# by default.
#
projects =
if params[:feature_availability_check]
projects.with_feature_available_for_user(klass, current_user)
else
projects
end
@projects = projects.reorder(nil)
end end
def search def search
......
...@@ -61,7 +61,7 @@ module ButtonHelper ...@@ -61,7 +61,7 @@ module ButtonHelper
html: true, html: true,
placement: placement, placement: placement,
container: 'body', container: 'body',
title: "Set a password on your account<br>to pull or push via #{protocol}", title: _("Set a password on your account to pull or push via %{protocol}") % { protocol: protocol },
primary_url: (geo_primary_http_url_to_repo(project) if Gitlab::Geo.secondary?) primary_url: (geo_primary_http_url_to_repo(project) if Gitlab::Geo.secondary?)
} }
end end
...@@ -77,7 +77,7 @@ module ButtonHelper ...@@ -77,7 +77,7 @@ module ButtonHelper
html: true, html: true,
placement: placement, placement: placement,
container: 'body', container: 'body',
title: 'Add an SSH key to your profile<br>to pull or push via SSH.' title: _('Add an SSH key to your profile to pull or push via SSH.')
} }
end end
......
...@@ -16,16 +16,18 @@ module CiStatusHelper ...@@ -16,16 +16,18 @@ module CiStatusHelper
return status.label return status.label
end end
case status label = case status
when 'success' when 'success'
'passed' 'passed'
when 'success_with_warnings' when 'success_with_warnings'
'passed with warnings' 'passed with warnings'
when 'manual' when 'manual'
'waiting for manual action' 'waiting for manual action'
else else
status status
end end
translation = "CiStatusLabel|#{label}"
s_(translation)
end end
def ci_text_for_status(status) def ci_text_for_status(status)
...@@ -35,13 +37,22 @@ module CiStatusHelper ...@@ -35,13 +37,22 @@ module CiStatusHelper
case status case status
when 'success' when 'success'
'passed' s_('CiStatusText|passed')
when 'success_with_warnings' when 'success_with_warnings'
'passed' s_('CiStatusText|passed')
when 'manual' when 'manual'
'blocked' s_('CiStatusText|blocked')
else else
status # All states are already being translated inside the detailed statuses:
# :running => Gitlab::Ci::Status::Running
# :skipped => Gitlab::Ci::Status::Skipped
# :failed => Gitlab::Ci::Status::Failed
# :success => Gitlab::Ci::Status::Success
# :canceled => Gitlab::Ci::Status::Canceled
# The following states are customized above:
# :manual => Gitlab::Ci::Status::Manual
status_translation = "CiStatusText|#{status}"
s_(status_translation)
end end
end end
......
...@@ -21,30 +21,36 @@ module NotificationsHelper ...@@ -21,30 +21,36 @@ module NotificationsHelper
end end
def notification_title(level) def notification_title(level)
# Can be anything in `NotificationSetting.level:
case level.to_sym case level.to_sym
when :participating when :participating
'Participate' s_('NotificationLevel|Participate')
when :mention when :mention
'On mention' s_('NotificationLevel|On mention')
else else
level.to_s.titlecase N_('NotificationLevel|Global')
N_('NotificationLevel|Watch')
N_('NotificationLevel|Disabled')
N_('NotificationLevel|Custom')
level = "NotificationLevel|#{level.to_s.humanize}"
s_(level)
end end
end end
def notification_description(level) def notification_description(level)
case level.to_sym case level.to_sym
when :participating when :participating
'You will only receive notifications for threads you have participated in' _('You will only receive notifications for threads you have participated in')
when :mention when :mention
'You will receive notifications only for comments in which you were @mentioned' _('You will receive notifications only for comments in which you were @mentioned')
when :watch when :watch
'You will receive notifications for any activity' _('You will receive notifications for any activity')
when :disabled when :disabled
'You will not get any notifications via email' _('You will not get any notifications via email')
when :global when :global
'Use your global notification setting' _('Use your global notification setting')
when :custom when :custom
'You will only receive notifications for the events you choose' _('You will only receive notifications for the events you choose')
end end
end end
...@@ -76,11 +82,22 @@ module NotificationsHelper ...@@ -76,11 +82,22 @@ module NotificationsHelper
end end
def notification_event_name(event) def notification_event_name(event)
# All values from NotificationSetting::EMAIL_EVENTS
case event case event
when :success_pipeline when :success_pipeline
'Successful pipeline' s_('NotificationEvent|Successful pipeline')
else else
event.to_s.humanize N_('NotificationEvent|New note')
N_('NotificationEvent|New issue')
N_('NotificationEvent|Reopen issue')
N_('NotificationEvent|Close issue')
N_('NotificationEvent|Reassign issue')
N_('NotificationEvent|New merge request')
N_('NotificationEvent|Close merge request')
N_('NotificationEvent|Reassign merge request')
N_('NotificationEvent|Merge merge request')
N_('NotificationEvent|Failed pipeline')
s_(event.to_s.humanize)
end end
end end
end end
module ProfilesHelper
def email_provider_label
return unless current_user.external_email?
current_user.email_provider.present? ? Gitlab::OAuth::Provider.label_for(current_user.email_provider) : "LDAP"
end
end
...@@ -70,15 +70,18 @@ module ProjectsHelper ...@@ -70,15 +70,18 @@ module ProjectsHelper
end end
def remove_project_message(project) def remove_project_message(project)
"You are going to remove #{project.name_with_namespace}.\n Removed project CANNOT be restored!\n Are you ABSOLUTELY sure?" _("You are going to remove %{project_name_with_namespace}.\nRemoved project CANNOT be restored!\nAre you ABSOLUTELY sure?") %
{ project_name_with_namespace: project.name_with_namespace }
end end
def transfer_project_message(project) def transfer_project_message(project)
"You are going to transfer #{project.name_with_namespace} to another owner. Are you ABSOLUTELY sure?" _("You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?") %
{ project_name_with_namespace: project.name_with_namespace }
end end
def remove_fork_project_message(project) def remove_fork_project_message(project)
"You are going to remove the fork relationship to source project #{@project.forked_from_project.name_with_namespace}. Are you ABSOLUTELY sure?" _("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") %
{ forked_from_project: @project.forked_from_project.name_with_namespace }
end end
def project_nav_tabs def project_nav_tabs
...@@ -159,12 +162,13 @@ module ProjectsHelper ...@@ -159,12 +162,13 @@ module ProjectsHelper
end end
def link_to_autodeploy_doc def link_to_autodeploy_doc
link_to 'About auto deploy', help_page_path('ci/autodeploy/index'), target: '_blank' link_to _('About auto deploy'), help_page_path('ci/autodeploy/index'), target: '_blank'
end end
def autodeploy_flash_notice(branch_name) def autodeploy_flash_notice(branch_name)
"Branch <strong>#{truncate(sanitize(branch_name))}</strong> was created. To set up auto deploy, \ translation = _("Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}") %
choose a GitLab CI Yaml template and commit your changes. #{link_to_autodeploy_doc}".html_safe { branch_name: truncate(sanitize(branch_name)), link_to_autodeploy_doc: link_to_autodeploy_doc }
translation.html_safe
end end
def project_list_cache_key(project) def project_list_cache_key(project)
...@@ -250,11 +254,11 @@ module ProjectsHelper ...@@ -250,11 +254,11 @@ module ProjectsHelper
def project_lfs_status(project) def project_lfs_status(project)
if project.lfs_enabled? if project.lfs_enabled?
content_tag(:span, class: 'lfs-enabled') do content_tag(:span, class: 'lfs-enabled') do
'Enabled' s_('LFSStatus|Enabled')
end end
else else
content_tag(:span, class: 'lfs-disabled') do content_tag(:span, class: 'lfs-disabled') do
'Disabled' s_('LFSStatus|Disabled')
end end
end end
end end
...@@ -273,7 +277,7 @@ module ProjectsHelper ...@@ -273,7 +277,7 @@ module ProjectsHelper
if current_user if current_user
current_user.name current_user.name
else else
"Your name" _("Your name")
end end
end end
...@@ -319,17 +323,18 @@ module ProjectsHelper ...@@ -319,17 +323,18 @@ module ProjectsHelper
if project.last_activity_at if project.last_activity_at
time_ago_with_tooltip(project.last_activity_at, placement: 'bottom', html_class: 'last_activity_time_ago') time_ago_with_tooltip(project.last_activity_at, placement: 'bottom', html_class: 'last_activity_time_ago')
else else
"Never" s_("ProjectLastActivity|Never")
end end
end end
def add_special_file_path(project, file_name:, commit_message: nil, branch_name: nil, context: nil) def add_special_file_path(project, file_name:, commit_message: nil, branch_name: nil, context: nil)
commit_message ||= s_("CommitMessage|Add %{file_name}") % { file_name: file_name.downcase }
namespace_project_new_blob_path( namespace_project_new_blob_path(
project.namespace, project.namespace,
project, project,
project.default_branch || 'master', project.default_branch || 'master',
file_name: file_name, file_name: file_name,
commit_message: commit_message || "Add #{file_name.downcase}", commit_message: commit_message,
branch_name: branch_name, branch_name: branch_name,
context: context context: context
) )
...@@ -480,9 +485,9 @@ module ProjectsHelper ...@@ -480,9 +485,9 @@ module ProjectsHelper
def project_feature_options def project_feature_options
{ {
'Disabled' => ProjectFeature::DISABLED, s_('ProjectFeature|Disabled') => ProjectFeature::DISABLED,
'Only team members' => ProjectFeature::PRIVATE, s_('ProjectFeature|Only team members') => ProjectFeature::PRIVATE,
'Everyone with access' => ProjectFeature::ENABLED s_('ProjectFeature|Everyone with access') => ProjectFeature::ENABLED
} }
end end
......
...@@ -29,11 +29,11 @@ module VisibilityLevelHelper ...@@ -29,11 +29,11 @@ module VisibilityLevelHelper
def project_visibility_level_description(level) def project_visibility_level_description(level)
case level case level
when Gitlab::VisibilityLevel::PRIVATE when Gitlab::VisibilityLevel::PRIVATE
"Project access must be granted explicitly to each user." _("Project access must be granted explicitly to each user.")
when Gitlab::VisibilityLevel::INTERNAL when Gitlab::VisibilityLevel::INTERNAL
"The project can be accessed by any logged in user." _("The project can be accessed by any logged in user.")
when Gitlab::VisibilityLevel::PUBLIC when Gitlab::VisibilityLevel::PUBLIC
"The project can be accessed without any authentication." _("The project can be accessed without any authentication.")
end end
end end
...@@ -81,7 +81,9 @@ module VisibilityLevelHelper ...@@ -81,7 +81,9 @@ module VisibilityLevelHelper
end end
def visibility_level_label(level) def visibility_level_label(level)
Project.visibility_levels.key(level) # The visibility level can be:
# 'VisibilityLevel|Private', 'VisibilityLevel|Internal', 'VisibilityLevel|Public'
s_(Project.visibility_levels.key(level))
end end
def restricted_visibility_levels(show_all = false) def restricted_visibility_levels(show_all = false)
......
class IssueLink < ActiveRecord::Base
belongs_to :source, class_name: 'Issue'
belongs_to :target, class_name: 'Issue'
validates :source, presence: true
validates :target, presence: true
validates :source, uniqueness: { scope: :target_id, message: 'is already related' }
validate :check_self_relation
private
def check_self_relation
return unless source && target
if source == target
errors.add(:source, 'cannot be related to itself')
end
end
end
...@@ -7,14 +7,12 @@ class License < ActiveRecord::Base ...@@ -7,14 +7,12 @@ class License < ActiveRecord::Base
AUDITOR_USER_FEATURE = 'GitLab_Auditor_User'.freeze AUDITOR_USER_FEATURE = 'GitLab_Auditor_User'.freeze
SERVICE_DESK_FEATURE = 'GitLab_ServiceDesk'.freeze SERVICE_DESK_FEATURE = 'GitLab_ServiceDesk'.freeze
OBJECT_STORAGE_FEATURE = 'GitLab_ObjectStorage'.freeze OBJECT_STORAGE_FEATURE = 'GitLab_ObjectStorage'.freeze
RELATED_ISSUES_FEATURE = 'RelatedIssues'.freeze
FEATURE_CODES = { FEATURE_CODES = {
geo: GEO_FEATURE, geo: GEO_FEATURE,
auditor_user: AUDITOR_USER_FEATURE, auditor_user: AUDITOR_USER_FEATURE,
service_desk: SERVICE_DESK_FEATURE, service_desk: SERVICE_DESK_FEATURE,
object_storage: OBJECT_STORAGE_FEATURE, object_storage: OBJECT_STORAGE_FEATURE,
related_issues: RELATED_ISSUES_FEATURE,
# Features that make sense to Namespace: # Features that make sense to Namespace:
deploy_board: DEPLOY_BOARD_FEATURE, deploy_board: DEPLOY_BOARD_FEATURE,
file_lock: FILE_LOCK_FEATURE file_lock: FILE_LOCK_FEATURE
...@@ -26,7 +24,7 @@ class License < ActiveRecord::Base ...@@ -26,7 +24,7 @@ class License < ActiveRecord::Base
EARLY_ADOPTER_PLAN = 'early_adopter'.freeze EARLY_ADOPTER_PLAN = 'early_adopter'.freeze
EES_FEATURES = [ EES_FEATURES = [
{ RELATED_ISSUES_FEATURE => 1 } # ..
].freeze ].freeze
EEP_FEATURES = [ EEP_FEATURES = [
......
...@@ -3,7 +3,7 @@ class SystemNoteMetadata < ActiveRecord::Base ...@@ -3,7 +3,7 @@ class SystemNoteMetadata < ActiveRecord::Base
commit description merge confidential visible label assignee cross_reference commit description merge confidential visible label assignee cross_reference
title time_tracking branch milestone discussion task moved opened closed merged title time_tracking branch milestone discussion task moved opened closed merged
outdated outdated
approved unapproved relate unrelate approved unapproved
].freeze ].freeze
validates :note, presence: true validates :note, presence: true
......
...@@ -22,11 +22,6 @@ module EE ...@@ -22,11 +22,6 @@ module EE
cannot! :create_note cannot! :create_note
cannot! :read_project cannot! :read_project
end end
unless project.feature_available?(:related_issues)
cannot! :read_issue_link
cannot! :admin_issue_link
end
end end
end end
end end
...@@ -55,9 +55,6 @@ class ProjectPolicy < BasePolicy ...@@ -55,9 +55,6 @@ class ProjectPolicy < BasePolicy
can! :read_pipeline_schedule can! :read_pipeline_schedule
can! :read_build can! :read_build
end end
# EE-only
can! :read_issue_link
end end
def reporter_access! def reporter_access!
...@@ -82,9 +79,6 @@ class ProjectPolicy < BasePolicy ...@@ -82,9 +79,6 @@ class ProjectPolicy < BasePolicy
if project.feature_available?(:deploy_board) || Rails.env.development? if project.feature_available?(:deploy_board) || Rails.env.development?
can! :read_deploy_board can! :read_deploy_board
end end
# EE-only
can! :admin_issue_link
end end
# Permissions given when an user is team member of a project # Permissions given when an user is team member of a project
...@@ -327,8 +321,5 @@ class ProjectPolicy < BasePolicy ...@@ -327,8 +321,5 @@ class ProjectPolicy < BasePolicy
# NOTE: may be overridden by IssuePolicy # NOTE: may be overridden by IssuePolicy
can! :read_issue can! :read_issue
# EE-only
can! :read_issue_link
end end
end end
module IssueLinks
class CreateService < BaseService
def initialize(issue, user, params)
@issue, @current_user, @params = issue, user, params.dup
end
def execute
if referenced_issues.blank?
return error('No Issue found for given reference', 401)
end
create_issue_links
success
end
private
def create_issue_links
referenced_issues.each do |referenced_issue|
create_notes(referenced_issue) if relate_issues(referenced_issue)
end
end
def relate_issues(referenced_issue)
IssueLink.create(source: @issue, target: referenced_issue)
end
def create_notes(referenced_issue)
SystemNoteService.relate_issue(@issue, referenced_issue, current_user)
SystemNoteService.relate_issue(referenced_issue, @issue, current_user)
end
def referenced_issues
@referenced_issues ||= begin
issue_references = params[:issue_references]
text = issue_references.join(' ')
extractor = Gitlab::ReferenceExtractor.new(@issue.project, @current_user)
extractor.analyze(text)
extractor.issues.select do |issue|
can?(current_user, :admin_issue_link, issue)
end
end
end
end
end
module IssueLinks
class DestroyService < BaseService
def initialize(issue_link, user)
@issue_link = issue_link
@current_user = user
@issue = issue_link.source
@referenced_issue = issue_link.target
end
def execute
remove_relation
create_notes
success(message: 'Relation was removed')
end
private
def remove_relation
@issue_link.destroy!
end
def create_notes
SystemNoteService.unrelate_issue(@issue, @referenced_issue, current_user)
SystemNoteService.unrelate_issue(@referenced_issue, @issue, current_user)
end
end
end
module IssueLinks
class ListService
include Gitlab::Routing
def initialize(issue, user)
@issue, @current_user, @project = issue, user, issue.project
end
def execute
issues.map do |referenced_issue|
{
id: referenced_issue.id,
iid: referenced_issue.iid,
title: referenced_issue.title,
state: referenced_issue.state,
project_path: referenced_issue.project.path,
namespace_full_path: referenced_issue.project.namespace.full_path,
path: namespace_project_issue_path(referenced_issue.project.namespace, referenced_issue.project, referenced_issue.iid),
destroy_relation_path: destroy_relation_path(referenced_issue)
}
end
end
private
def issues
related_issues = Issue
.select(['issues.*', 'issue_links.id AS issue_links_id'])
.joins("INNER JOIN issue_links ON
(issue_links.source_id = issues.id AND issue_links.target_id = #{@issue.id})
OR
(issue_links.target_id = issues.id AND issue_links.source_id = #{@issue.id})")
.preload(project: :namespace)
.reorder('issue_links_id')
Ability.issues_readable_by_user(related_issues, @current_user)
end
def destroy_relation_path(issue)
# Make sure the user can admin both the current issue AND the
# referenced issue projects in order to return the removal link.
if can_destroy_issue_link_on_current_project? && can_destroy_issue_link?(issue.project)
namespace_project_issue_link_path(@project.namespace,
@issue.project,
@issue.iid,
issue.issue_links_id)
end
end
def can_destroy_issue_link_on_current_project?
return @can_destroy_on_current_project if defined?(@can_destroy_on_current_project)
@can_destroy_on_current_project = can_destroy_issue_link?(@project)
end
def can_destroy_issue_link?(project)
Ability.allowed?(@current_user, :admin_issue_link, project)
end
end
end
...@@ -552,38 +552,6 @@ module SystemNoteService ...@@ -552,38 +552,6 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'moved')) create_note(NoteSummary.new(noteable, project, author, body, action: 'moved'))
end end
#
# noteable - Noteable object
# noteable_ref - Referenced noteable object
# user - User performing reference
#
# Example Note text:
#
# "marked this issue as related to gitlab-ce#9001"
#
# Returns the created Note object
def relate_issue(noteable, noteable_ref, user)
body = "marked this issue as related to #{noteable_ref.to_reference(noteable.project)}"
create_note(NoteSummary.new(noteable, noteable.project, user, body, action: 'relate'))
end
#
# noteable - Noteable object
# noteable_ref - Referenced noteable object
# user - User performing reference
#
# Example Note text:
#
# "removed the relation with gitlab-ce#9001"
#
# Returns the created Note object
def unrelate_issue(noteable, noteable_ref, user)
body = "removed the relation with #{noteable_ref.to_reference(noteable.project)}"
create_note(NoteSummary.new(noteable, noteable.project, user, body, action: 'unrelate'))
end
# Called when the merge request is approved by user # Called when the merge request is approved by user
# #
# noteable - Noteable object # noteable - Noteable object
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
= webpack_bundle_tag "runtime" = webpack_bundle_tag "runtime"
= webpack_bundle_tag "common" = webpack_bundle_tag "common"
= webpack_bundle_tag "locale"
= webpack_bundle_tag "main" = webpack_bundle_tag "main"
= webpack_bundle_tag "raven" if current_application_settings.clientside_sentry_enabled = webpack_bundle_tag "raven" if current_application_settings.clientside_sentry_enabled
= webpack_bundle_tag "test" if Rails.env.test? = webpack_bundle_tag "test" if Rails.env.test?
......
...@@ -49,10 +49,10 @@ ...@@ -49,10 +49,10 @@
.form-group .form-group
= f.label :email, class: "label-light" = f.label :email, class: "label-light"
- if @user.ldap_user? && @user.ldap_email? - if @user.external_email?
= f.text_field :email, class: "form-control", required: true, readonly: true = f.text_field :email, class: "form-control", required: true, readonly: true
%span.help-block.light %span.help-block.light
Your email address was automatically set based on the LDAP server. Your email address was automatically set based on your #{email_provider_label} account.
- else - else
- if @user.temp_oauth_email? - if @user.temp_oauth_email?
= f.text_field :email, class: "form-control", required: true, value: nil = f.text_field :email, class: "form-control", required: true, value: nil
......
= link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn btn-grouped shortcuts-find-file', rel: 'nofollow' do = link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn btn-grouped shortcuts-find-file', rel: 'nofollow' do
= icon('search') = icon('search')
%span Find file %span= _('Find file')
...@@ -4,17 +4,14 @@ ...@@ -4,17 +4,14 @@
.nav-links.sub-nav.scrolling-tabs .nav-links.sub-nav.scrolling-tabs
%ul{ class: container_class } %ul{ class: container_class }
= nav_link(path: 'projects#show') do = nav_link(path: 'projects#show') do
= link_to project_path(@project), title: 'Project home', class: 'shortcuts-project' do = link_to project_path(@project), title: _('Project home'), class: 'shortcuts-project' do
%span %span= _('Home')
Home
= nav_link(path: 'projects#activity') do = nav_link(path: 'projects#activity') do
= link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do
%span %span= _('Activity')
Activity
- if can?(current_user, :read_cycle_analytics, @project) - if can?(current_user, :read_cycle_analytics, @project)
= nav_link(path: 'cycle_analytics#show') do = nav_link(path: 'cycle_analytics#show') do
= link_to project_cycle_analytics_path(@project), title: 'Cycle Analytics', class: 'shortcuts-project-cycle-analytics' do = link_to project_cycle_analytics_path(@project), title: _('Cycle Analytics'), class: 'shortcuts-project-cycle-analytics' do
%span %span= _('Cycle Analytics')
Cycle Analytics
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
- if forked_from_project = @project.forked_from_project - if forked_from_project = @project.forked_from_project
%p %p
Forked from #{ s_('ForkedFromProjectPath|Forked from') }
= link_to project_path(forked_from_project) do = link_to project_path(forked_from_project) do
= forked_from_project.namespace.try(:name) = forked_from_project.namespace.try(:name)
- if @project.mirror? - if @project.mirror?
......
...@@ -15,4 +15,4 @@ ...@@ -15,4 +15,4 @@
.pull-right .pull-right
= link_to new_mr_path_from_push_event(event), title: "New merge request", class: "btn btn-info btn-sm" do = link_to new_mr_path_from_push_event(event), title: "New merge request", class: "btn btn-info btn-sm" do
Create merge request #{ _('Create merge request') }
...@@ -3,18 +3,18 @@ ...@@ -3,18 +3,18 @@
.modal-content .modal-content
.modal-header .modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } × %a.close{ href: "#", "data-dismiss" => "modal" } ×
%h3.page-title Create New Directory %h3.page-title= _('Create New Directory')
.modal-body .modal-body
= form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-quick-submit js-requires-input' do = form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-quick-submit js-requires-input' do
.form-group .form-group
= label_tag :dir_name, 'Directory name', class: 'control-label' = label_tag :dir_name, _('Directory name'), class: 'control-label'
.col-sm-10 .col-sm-10
= text_field_tag :dir_name, params[:dir_name], required: true, class: 'form-control' = text_field_tag :dir_name, params[:dir_name], required: true, class: 'form-control'
= render 'shared/new_commit_form', placeholder: "Add new directory" = render 'shared/new_commit_form', placeholder: _("Add new directory")
.form-actions .form-actions
= submit_tag "Create directory", class: 'btn btn-create' = submit_tag _("Create directory"), class: 'btn btn-create'
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
- unless can?(current_user, :push_code, @project) - unless can?(current_user, :push_code, @project)
......
...@@ -2,29 +2,29 @@ ...@@ -2,29 +2,29 @@
- if !project.empty_repo? && can?(current_user, :download_code, project) - if !project.empty_repo? && can?(current_user, :download_code, project)
.project-action-button.dropdown.inline> .project-action-button.dropdown.inline>
%button.btn.has-tooltip{ title: 'Download', 'data-toggle' => 'dropdown', 'aria-label' => 'Download' } %button.btn.has-tooltip{ title: 'Download', 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download') }
= icon('download') = icon('download')
= icon("caret-down") = icon("caret-down")
%span.sr-only %span.sr-only= _('Select Archive Format')
Select Archive Format
%ul.dropdown-menu.dropdown-menu-align-right{ role: 'menu' } %ul.dropdown-menu.dropdown-menu-align-right{ role: 'menu' }
%li.dropdown-header Source code %li.dropdown-header
#{ _('Source code') }
%li %li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), rel: 'nofollow', download: '' do = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), rel: 'nofollow', download: '' do
%i.fa.fa-download %i.fa.fa-download
%span Download zip %span= _('Download zip')
%li %li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow', download: '' do = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow', download: '' do
%i.fa.fa-download %i.fa.fa-download
%span Download tar.gz %span= _('Download tar.gz')
%li %li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.bz2'), rel: 'nofollow', download: '' do = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.bz2'), rel: 'nofollow', download: '' do
%i.fa.fa-download %i.fa.fa-download
%span Download tar.bz2 %span= _('Download tar.bz2')
%li %li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar'), rel: 'nofollow', download: '' do = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar'), rel: 'nofollow', download: '' do
%i.fa.fa-download %i.fa.fa-download
%span Download tar %span= _('Download tar')
- if pipeline - if pipeline
- artifacts = pipeline.builds.latest.with_artifacts - artifacts = pipeline.builds.latest.with_artifacts
...@@ -39,4 +39,5 @@ ...@@ -39,4 +39,5 @@
%li %li
= link_to latest_succeeded_namespace_project_artifacts_path(project.namespace, project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do = link_to latest_succeeded_namespace_project_artifacts_path(project.namespace, project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do
%i.fa.fa-download %i.fa.fa-download
%span Download '#{job.name}' %span
#{ s_('DownloadArtifacts|Download') } '#{job.name}'
...@@ -12,19 +12,19 @@ ...@@ -12,19 +12,19 @@
%li %li
= link_to new_namespace_project_issue_path(@project.namespace, @project) do = link_to new_namespace_project_issue_path(@project.namespace, @project) do
= icon('exclamation-circle fw') = icon('exclamation-circle fw')
New issue #{ _('New issue') }
- if merge_project - if merge_project
%li %li
= link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project) do = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project) do
= icon('tasks fw') = icon('tasks fw')
New merge request #{ _('New merge request') }
- if can_create_snippet - if can_create_snippet
%li %li
= link_to new_namespace_project_snippet_path(@project.namespace, @project) do = link_to new_namespace_project_snippet_path(@project.namespace, @project) do
= icon('file-text-o fw') = icon('file-text-o fw')
New snippet #{ _('New snippet') }
- if can_create_issue || merge_project || can_create_snippet - if can_create_issue || merge_project || can_create_snippet
%li.divider %li.divider
...@@ -33,20 +33,20 @@ ...@@ -33,20 +33,20 @@
%li %li
= link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do = link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do
= icon('file fw') = icon('file fw')
New file #{ _('New file') }
%li %li
= link_to new_namespace_project_branch_path(@project.namespace, @project) do = link_to new_namespace_project_branch_path(@project.namespace, @project) do
= icon('code-fork fw') = icon('code-fork fw')
New branch #{ _('New branch') }
%li %li
= link_to new_namespace_project_tag_path(@project.namespace, @project) do = link_to new_namespace_project_tag_path(@project.namespace, @project) do
= icon('tags fw') = icon('tags fw')
New tag #{ _('New tag') }
- elsif current_user && current_user.already_forked?(@project) - elsif current_user && current_user.already_forked?(@project)
%li %li
= link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do = link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do
= icon('file fw') = icon('file fw')
New file #{ _('New file') }
- elsif can?(current_user, :fork_project, @project) - elsif can?(current_user, :fork_project, @project)
%li %li
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'),
...@@ -56,4 +56,4 @@ ...@@ -56,4 +56,4 @@
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
New file #{ _('New file') }
- unless @project.empty_repo? - unless @project.empty_repo?
- if current_user && can?(current_user, :fork_project, @project) - if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn has-tooltip' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span Fork %span= s_('GoToYourFork|Fork')
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), class: 'btn' do = link_to new_namespace_project_fork_path(@project.namespace, @project), class: 'btn' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span Fork %span= s_('CreateNewFork|Fork')
.count-with-arrow .count-with-arrow
%span.arrow %span.arrow
= link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks', class: 'count' do = link_to namespace_project_forks_path(@project.namespace, @project), title: n_('Forks', @project.forks_count), class: 'count' do
= @project.forks_count = @project.forks_count
- if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch) - if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch)
= link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank', rel: 'noopener noreferrer' do = link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank', rel: 'noopener noreferrer' do
Run in IDE (Koding) _('Run in IDE (Koding)')
...@@ -2,19 +2,19 @@ ...@@ -2,19 +2,19 @@
= link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do = link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do
- if current_user.starred?(@project) - if current_user.starred?(@project)
= icon('star') = icon('star')
%span.starred Unstar %span.starred= _('Unstar')
- else - else
= icon('star-o') = icon('star-o')
%span Star %span= s_('StarProject|Star')
.count-with-arrow .count-with-arrow
%span.arrow %span.arrow
%span.count.star-count %span.count.star-count
= @project.star_count = @project.star_count
- else - else
= link_to new_user_session_path, class: 'btn has-tooltip star-btn', title: 'You must sign in to star a project' do = link_to new_user_session_path, class: 'btn has-tooltip star-btn', title: _('You must sign in to star a project') do
= icon('star') = icon('star')
Star #{ s_('StarProject|Star') }
.count-with-arrow .count-with-arrow
%span.arrow %span.arrow
%span.count %span.count
......
...@@ -31,12 +31,12 @@ ...@@ -31,12 +31,12 @@
= preserve(markdown(commit.description, pipeline: :single_line, author: commit.author)) = preserve(markdown(commit.description, pipeline: :single_line, author: commit.author))
.commiter .commiter
= commit_author_link(commit, avatar: false, size: 24) = commit_author_link(commit, avatar: false, size: 24)
committed #{ _('committed') }
#{time_ago_with_tooltip(commit.committed_date)} #{time_ago_with_tooltip(commit.committed_date)}
.commit-actions.flex-row.hidden-xs .commit-actions.flex-row.hidden-xs
- if commit.status(ref) - if commit.status(ref)
= render_commit_status(commit, ref: ref) = render_commit_status(commit, ref: ref)
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-sha btn btn-transparent" = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-sha btn btn-transparent"
= clipboard_button(text: commit.id, title: "Copy commit SHA to clipboard") = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
= link_to_browse_code(project, commit) = link_to_browse_code(project, commit)
...@@ -5,35 +5,35 @@ ...@@ -5,35 +5,35 @@
%ul{ class: (container_class) } %ul{ class: (container_class) }
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
= link_to project_files_path(@project) do = link_to project_files_path(@project) do
Files #{ _('Files') }
= nav_link(controller: [:commit, :commits]) do = nav_link(controller: [:commit, :commits]) do
= link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
Commits #{ _('Commits') }
= nav_link(html_options: {class: branches_tab_class}) do = nav_link(html_options: {class: branches_tab_class}) do
= link_to namespace_project_branches_path(@project.namespace, @project) do = link_to namespace_project_branches_path(@project.namespace, @project) do
Branches #{ _('Branches') }
= nav_link(controller: [:tags, :releases]) do = nav_link(controller: [:tags, :releases]) do
= link_to namespace_project_tags_path(@project.namespace, @project) do = link_to namespace_project_tags_path(@project.namespace, @project) do
Tags #{ _('Tags') }
= nav_link(path: 'graphs#show') do = nav_link(path: 'graphs#show') do
= link_to namespace_project_graph_path(@project.namespace, @project, current_ref) do = link_to namespace_project_graph_path(@project.namespace, @project, current_ref) do
Contributors #{ _('Contributors') }
= nav_link(controller: %w(network)) do = nav_link(controller: %w(network)) do
= link_to namespace_project_network_path(@project.namespace, @project, current_ref) do = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do
Graph #{ s_('ProjectNetworkGraph|Graph') }
= nav_link(controller: :compare) do = nav_link(controller: :compare) do
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do
Compare #{ _('Compare') }
= nav_link(path: 'graphs#charts') do = nav_link(path: 'graphs#charts') do
= link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref) do = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref) do
Charts #{ _('Charts') }
- if @project.feature_available?(:file_lock) - if @project.feature_available?(:file_lock)
= nav_link(controller: [:path_locks]) do = nav_link(controller: [:path_locks]) do
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
- page_title "Cycle Analytics" - page_title "Cycle Analytics"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('locale')
= page_specific_javascript_bundle_tag('cycle_analytics') = page_specific_javascript_bundle_tag('cycle_analytics')
= render "projects/head" = render "projects/head"
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= link_to namespace_project_tree_path(@project.namespace, @project, @ref) do = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
= @project.path = @project.path
%li.file-finder %li.file-finder
%input#file_find.form-control.file-finder-input{ type: "text", placeholder: 'Find by path', autocomplete: 'off' } %input#file_find.form-control.file-finder-input{ type: "text", placeholder: _('Find by path'), autocomplete: 'off' }
.tree-content-holder .tree-content-holder
.table-holder .table-holder
......
%h2 %h2
%i.fa.fa-warning %i.fa.fa-warning
No repository #{ _('No repository') }
%p.slead %p.slead
The repository for this project does not exist. #{ _('The repository for this project does not exist.') }
%br %br
This means you can not push code until you create an empty repository or import existing one. #{ _('This means you can not push code until you create an empty repository or import existing one.') }
%hr %hr
.no-repo-actions .no-repo-actions
= link_to namespace_project_repository_path(@project.namespace, @project), method: :post, class: 'btn btn-primary' do = link_to namespace_project_repository_path(@project.namespace, @project), method: :post, class: 'btn btn-primary' do
Create empty bare repository #{ _('Create empty bare repository') }
%strong.prepend-left-10.append-right-10 or %strong.prepend-left-10.append-right-10 or
= link_to new_namespace_project_import_path(@project.namespace, @project), class: 'btn' do = link_to new_namespace_project_import_path(@project.namespace, @project), class: 'btn' do
Import repository #{ _('Import repository') }
- if can? current_user, :remove_project, @project - if can? current_user, :remove_project, @project
.prepend-top-20 .prepend-top-20
= link_to 'Remove project', project_path(@project), data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right" = link_to _('Remove project'), project_path(@project), data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right"
...@@ -20,24 +20,24 @@ ...@@ -20,24 +20,24 @@
%ul.nav %ul.nav
%li %li
= link_to project_files_path(@project) do = link_to project_files_path(@project) do
Files (#{storage_counter(@project.statistics.total_repository_size)}) #{_('Files')} (#{storage_counter(@project.statistics.total_repository_size)})
%li %li
= link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
#{'Commit'.pluralize(@project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)}) #{n_('Commit', 'Commits', @project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)})
%li %l
= link_to namespace_project_branches_path(@project.namespace, @project) do = link_to namespace_project_branches_path(@project.namespace, @project) do
#{'Branch'.pluralize(@repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)}) #{n_('Branch', 'Branches', @repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)})
%li %li
= link_to namespace_project_tags_path(@project.namespace, @project) do = link_to namespace_project_tags_path(@project.namespace, @project) do
#{'Tag'.pluralize(@repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)}) #{n_('Tag', 'Tags', @repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)})
- if default_project_view != 'readme' && @repository.readme - if default_project_view != 'readme' && @repository.readme
%li %li
= link_to 'Readme', readme_path(@project) = link_to _('Readme'), readme_path(@project)
- if @repository.changelog - if @repository.changelog
%li %li
= link_to 'Changelog', changelog_path(@project) = link_to _('Changelog'), changelog_path(@project)
- if @repository.license_blob - if @repository.license_blob
%li %li
...@@ -45,43 +45,43 @@ ...@@ -45,43 +45,43 @@
- if @repository.contribution_guide - if @repository.contribution_guide
%li %li
= link_to 'Contribution guide', contribution_guide_path(@project) = link_to _('Contribution guide'), contribution_guide_path(@project)
- if @repository.gitlab_ci_yml - if @repository.gitlab_ci_yml
%li %li
= link_to 'CI configuration', ci_configuration_path(@project) = link_to _('CI configuration'), ci_configuration_path(@project)
- if current_user && can_push_branch?(@project, @project.default_branch) - if current_user && can_push_branch?(@project, @project.default_branch)
- unless @repository.changelog - unless @repository.changelog
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'CHANGELOG') do = link_to add_special_file_path(@project, file_name: 'CHANGELOG') do
Add Changelog #{ _('Add Changelog') }
- unless @repository.license_blob - unless @repository.license_blob
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'LICENSE') do = link_to add_special_file_path(@project, file_name: 'LICENSE') do
Add License #{ _('Add License') }
- unless @repository.contribution_guide - unless @repository.contribution_guide
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do
Add Contribution guide #{ _('Add Contribution guide') }
- unless @repository.gitlab_ci_yml - unless @repository.gitlab_ci_yml
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do
Set up CI #{ _('Set up CI') }
- if koding_enabled? && @repository.koding_yml.blank? - if koding_enabled? && @repository.koding_yml.blank?
%li.missing %li.missing
= link_to 'Set up Koding', add_koding_stack_path(@project) = link_to _('Set up Koding'), add_koding_stack_path(@project)
- if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present? - if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present?
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', branch_name: 'auto-deploy', context: 'autodeploy') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', branch_name: 'auto-deploy', context: 'autodeploy') do
Set up auto deploy #{ _('Set up auto deploy') }
%div{ class: container_class } %div{ class: container_class }
- if @project.archived? - if @project.archived?
.text-warning.center.prepend-top-20 .text-warning.center.prepend-top-20
%p %p
= icon("exclamation-triangle fw") = icon("exclamation-triangle fw")
Archived project! Repository is read-only #{ _('Archived project! Repository is read-only') }
- view_path = default_project_view - view_path = default_project_view
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
%table.table#tree-slider{ class: "table_#{@hex_path} tree-table" } %table.table#tree-slider{ class: "table_#{@hex_path} tree-table" }
%thead %thead
%tr %tr
%th Name %th= s_('ProjectFileTree|Name')
%th.hidden-xs %th.hidden-xs
.pull-left Last commit .pull-left= _('Last commit')
%th.text-right Last Update %th.text-right= _('Last Update')
- if @path.present? - if @path.present?
%tr.tree-item %tr.tree-item
%td.tree-item-file-name %td.tree-item-file-name
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
= render "projects/tree/readme", readme: tree.readme = render "projects/tree/readme", readme: tree.readme
- if can_edit_tree? - if can_edit_tree?
= render 'projects/blob/upload', title: 'Upload New File', placeholder: 'Upload new file', button_title: 'Upload file', form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post
= render 'projects/blob/new_dir' = render 'projects/blob/new_dir'
- if @project.feature_available?(:file_lock) - if @project.feature_available?(:file_lock)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= render 'projects/find_file_link' = render 'projects/find_file_link'
= link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn btn-grouped' = link_to s_('Commits|History'), namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn btn-grouped'
= render 'projects/buttons/download', project: @project, ref: @ref = render 'projects/buttons/download', project: @project, ref: @ref
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
- if current_user - if current_user
%li %li
- if !on_top_of_branch? - if !on_top_of_branch?
%span.btn.add-to-tree.disabled.has-tooltip{ title: "You can only add files when you are on a branch", data: { container: 'body' } } %span.btn.add-to-tree.disabled.has-tooltip{ title: _("You can only add files when you are on a branch"), data: { container: 'body' } }
= icon('plus') = icon('plus')
- else - else
%span.dropdown %span.dropdown
...@@ -33,15 +33,15 @@ ...@@ -33,15 +33,15 @@
%li %li
= link_to namespace_project_new_blob_path(@project.namespace, @project, @id) do = link_to namespace_project_new_blob_path(@project.namespace, @project, @id) do
= icon('pencil fw') = icon('pencil fw')
New file #{ _('New file') }
%li %li
= link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do = link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do
= icon('file fw') = icon('file fw')
Upload file #{ _('Upload file') }
%li %li
= link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do = link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do
= icon('folder fw') = icon('folder fw')
New directory #{ _('New directory') }
- elsif can?(current_user, :fork_project, @project) - elsif can?(current_user, :fork_project, @project)
%li %li
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id),
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('pencil fw') = icon('pencil fw')
New file #{ _('New file') }
%li %li
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to upload a file again.", notice: edit_in_new_fork_notice + " Try to upload a file again.",
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
Upload file #{ _('Upload file') }
%li %li
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to create a new directory again.", notice: edit_in_new_fork_notice + " Try to create a new directory again.",
...@@ -69,14 +69,14 @@ ...@@ -69,14 +69,14 @@
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('folder fw') = icon('folder fw')
New directory #{ _('New directory') }
%li.divider %li.divider
%li %li
= link_to new_namespace_project_branch_path(@project.namespace, @project) do = link_to new_namespace_project_branch_path(@project.namespace, @project) do
= icon('code-fork fw') = icon('code-fork fw')
New branch #{ _('New branch') }
%li %li
= link_to new_namespace_project_tag_path(@project.namespace, @project) do = link_to new_namespace_project_tag_path(@project.namespace, @project) do
= icon('tags fw') = icon('tags fw')
New tag #{ _('New tag') }
- @no_container = true - @no_container = true
- page_title @path.presence || "Files", @ref - page_title @path.presence || _("Files"), @ref
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits")
= render "projects/commits/head" = render "projects/commits/head"
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' } = text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-btn .input-group-btn
= clipboard_button(target: '#project_clone', title: "Copy URL to clipboard") = clipboard_button(target: '#project_clone', title: _("Copy URL to clipboard"))
= geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary? = geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary?
......
- if cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.require_password? - if cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.require_password?
.no-password-message.alert.alert-warning .no-password-message.alert.alert-warning
You won't be able to pull or push project code via #{gitlab_config.protocol.upcase} until you #{link_to 'set a password', edit_profile_password_path} on your account - set_password_link = link_to s_('SetPasswordToCloneLink|set a password'), edit_profile_password_path
- translation_params = { protocol: gitlab_config.protocol.upcase, set_password_link: set_password_link }
- set_password_message = _("You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account") % translation_params
.alert-link-group .alert-link-group
= link_to "Don't show again", profile_path(user: {hide_no_password: true}), method: :put = link_to _("Don't show again"), profile_path(user: {hide_no_password: true}), method: :put
| |
= link_to 'Remind later', '#', class: 'hide-no-password-message' = link_to _('Remind later'), '#', class: 'hide-no-password-message'
- if cookies[:hide_no_ssh_message].blank? && !current_user.hide_no_ssh_key && current_user.require_ssh_key? - if cookies[:hide_no_ssh_message].blank? && !current_user.hide_no_ssh_key && current_user.require_ssh_key?
.no-ssh-key-message.alert.alert-warning .no-ssh-key-message.alert.alert-warning
You won't be able to pull or push project code via SSH until you #{link_to 'add an SSH key', profile_keys_path, class: 'alert-link'} to your profile - add_ssh_key_link = link_to s_('MissingSSHKeyWarningLink|add an SSH key'), profile_keys_path, class: 'alert-link'
- ssh_message = _("You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile") % { add_ssh_key_link: add_ssh_key_link }
#{ ssh_message.html_safe }
.alert-link-group .alert-link-group
= link_to "Don't show again", profile_path(user: {hide_no_ssh_key: true}), method: :put, class: 'alert-link' = link_to _("Don't show again"), profile_path(user: {hide_no_ssh_key: true}), method: :put, class: 'alert-link'
| |
= link_to 'Remind later', '#', class: 'hide-no-ssh-message alert-link' = link_to _('Remind later'), '#', class: 'hide-no-ssh-message alert-link'
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
- @options && @options.each do |key, value| - @options && @options.each do |key, value|
= hidden_field_tag key, value, id: nil = hidden_field_tag key, value, id: nil
.dropdown .dropdown
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project), field_name: 'ref', submit_form_on_click: true }, { toggle_class: "js-project-refs-dropdown git-revision-dropdown-toggle" } = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project), field_name: 'ref', submit_form_on_click: true }, { toggle_class: "js-project-refs-dropdown" }
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
= dropdown_title "Switch branch/tag" = dropdown_title _("Switch branch/tag")
= dropdown_filter "Search branches and tags" = dropdown_filter _("Search branches and tags")
= dropdown_content = dropdown_content
= dropdown_loading = dropdown_loading
...@@ -2,16 +2,17 @@ ...@@ -2,16 +2,17 @@
.project-action-button.inline .project-action-button.inline
- if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id)) - if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id))
= link_to "Leave #{model_name}", polymorphic_path([:leave, source, :members]), - link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project')
= link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete, method: :delete,
data: { confirm: leave_confirmation_message(source) }, data: { confirm: leave_confirmation_message(source) },
class: 'btn' class: 'btn'
- elsif requester = source.requesters.find_by(user_id: current_user.id) - elsif requester = source.requesters.find_by(user_id: current_user.id)
= link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]), = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
method: :delete, method: :delete,
data: { confirm: remove_member_message(requester) }, data: { confirm: remove_member_message(requester) },
class: 'btn' class: 'btn'
- elsif source.request_access_enabled && can?(current_user, :request_access, source) - elsif source.request_access_enabled && can?(current_user, :request_access, source)
= link_to 'Request Access', polymorphic_path([:request_access, source, :members]), = link_to _('Request Access'), polymorphic_path([:request_access, source, :members]),
method: :post, method: :post,
class: 'btn' class: 'btn'
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%button.close{ type: "button", "aria-label": "close", data: { dismiss: "modal" } } %button.close{ type: "button", "aria-label": "close", data: { dismiss: "modal" } }
%span{ "aria-hidden": "true" } } × %span{ "aria-hidden": "true" } } ×
%h4#custom-notifications-title.modal-title %h4#custom-notifications-title.modal-title
Custom notification events #{ _('Custom notification events') }
.modal-body .modal-body
.container-fluid .container-fluid
...@@ -13,12 +13,11 @@ ...@@ -13,12 +13,11 @@
= hidden_setting_source_input(notification_setting) = hidden_setting_source_input(notification_setting)
.row .row
.col-lg-4 .col-lg-4
%h4.prepend-top-0 %h4.prepend-top-0= _('Notification events')
Notification events
%p %p
Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out - notification_link = link_to _('notification emails'), help_page_path('workflow/notifications'), target: '_blank'
= succeed "." do - paragraph = _('Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.') % { notification_link: notification_link.html_safe }
%a{ href: help_page_path('workflow/notifications'), target: "_blank" } notification emails #{ paragraph.html_safe }
.col-lg-8 .col-lg-8
- NotificationSetting::EMAIL_EVENTS.each_with_index do |event, index| - NotificationSetting::EMAIL_EVENTS.each_with_index do |event, index|
- field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]" - field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]"
......
---
title: Allows manually adding bi-directional relationships between issues in the issue page (EES feature)
merge_request:
author:
---
title: Translate backend for Project & Repository pages
merge_request: 11183
author:
---
title: Sync email address from specified omniauth provider
merge_request: 11268
author: Robin Bobbitt
...@@ -432,6 +432,10 @@ production: &base ...@@ -432,6 +432,10 @@ production: &base
# showing GitLab's sign-in page (default: show the GitLab sign-in page) # showing GitLab's sign-in page (default: show the GitLab sign-in page)
# auto_sign_in_with_provider: saml # auto_sign_in_with_provider: saml
# Sync user's email address from the specified Omniauth provider every time the user logs
# in (default: nil). And consequently make this field read-only.
# sync_email_from_provider: cas3
# CAUTION! # CAUTION!
# This allows users to login without having a user account first. Define the allowed providers # This allows users to login without having a user account first. Define the allowed providers
# using an array, e.g. ["saml", "twitter"], or as true/false to allow all providers or none. # using an array, e.g. ["saml", "twitter"], or as true/false to allow all providers or none.
......
...@@ -190,6 +190,7 @@ Settings.omniauth['external_providers'] = [] if Settings.omniauth['external_prov ...@@ -190,6 +190,7 @@ Settings.omniauth['external_providers'] = [] if Settings.omniauth['external_prov
Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block_auto_created_users'].nil? Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block_auto_created_users'].nil?
Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil? Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil?
Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil? Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil?
Settings.omniauth['sync_email_from_provider'] ||= nil
Settings.omniauth['providers'] ||= [] Settings.omniauth['providers'] ||= []
Settings.omniauth['cas3'] ||= Settingslogic.new({}) Settings.omniauth['cas3'] ||= Settingslogic.new({})
......
...@@ -3,11 +3,6 @@ ...@@ -3,11 +3,6 @@
en: en:
hello: "Hello world" hello: "Hello world"
activerecord:
attributes:
issue_link:
source: Source issue
target: Target issue
errors: errors:
messages: messages:
label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one." label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one."
......
...@@ -311,8 +311,6 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -311,8 +311,6 @@ constraints(ProjectUrlConstrainer.new) do
post :bulk_update post :bulk_update
post :export_csv post :export_csv
end end
resources :issue_links, only: [:index, :create, :destroy], as: 'links', path: 'links'
end end
resources :project_members, except: [:show, :new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ }, concerns: :access_requestable do resources :project_members, except: [:show, :new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ }, concerns: :access_requestable do
......
...@@ -188,15 +188,7 @@ var config = { ...@@ -188,15 +188,7 @@ var config = {
// create cacheable common library bundles // create cacheable common library bundles
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
names: ['main', 'common', 'runtime'], names: ['main', 'locale', 'common', 'runtime'],
}),
// locale common library
new webpack.optimize.CommonsChunkPlugin({
name: 'locale',
chunks: [
'cycle_analytics',
],
}), }),
], ],
......
class CreateIssueLinksTable < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
create_table :issue_links do |t|
t.integer :source_id, null: false, index: true
t.integer :target_id, null: false, index: true
t.timestamps null: true
end
add_index :issue_links, [:source_id, :target_id], unique: true
add_concurrent_foreign_key :issue_links, :issues, column: :source_id
add_concurrent_foreign_key :issue_links, :issues, column: :target_id
end
def down
drop_table :issue_links
end
end
class RenameUsersLdapEmailToExternalEmail < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
rename_column_concurrently :users, :ldap_email, :external_email
end
def down
cleanup_concurrent_column_rename :users, :external_email, :ldap_email
end
end
class AddEmailProviderToUsers < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :users, :email_provider, :string
end
end
class CleanupUsersLdapEmailRename < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
cleanup_concurrent_column_rename :users, :ldap_email, :external_email
end
def down
rename_column_concurrently :users, :external_email, :ldap_email
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170602003304) do ActiveRecord::Schema.define(version: 20170603200744) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -655,17 +655,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do ...@@ -655,17 +655,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do
add_index "issue_assignees", ["issue_id", "user_id"], name: "index_issue_assignees_on_issue_id_and_user_id", unique: true, using: :btree add_index "issue_assignees", ["issue_id", "user_id"], name: "index_issue_assignees_on_issue_id_and_user_id", unique: true, using: :btree
add_index "issue_assignees", ["user_id"], name: "index_issue_assignees_on_user_id", using: :btree add_index "issue_assignees", ["user_id"], name: "index_issue_assignees_on_user_id", using: :btree
create_table "issue_links", force: :cascade do |t|
t.integer "source_id", null: false
t.integer "target_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "issue_links", ["source_id", "target_id"], name: "index_issue_links_on_source_id_and_target_id", unique: true, using: :btree
add_index "issue_links", ["source_id"], name: "index_issue_links_on_source_id", using: :btree
add_index "issue_links", ["target_id"], name: "index_issue_links_on_target_id", using: :btree
create_table "issue_metrics", force: :cascade do |t| create_table "issue_metrics", force: :cascade do |t|
t.integer "issue_id", null: false t.integer "issue_id", null: false
t.datetime "first_mentioned_in_commit_at" t.datetime "first_mentioned_in_commit_at"
...@@ -1682,7 +1671,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do ...@@ -1682,7 +1671,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do
t.text "note" t.text "note"
t.string "unlock_token" t.string "unlock_token"
t.datetime "otp_grace_period_started_at" t.datetime "otp_grace_period_started_at"
t.boolean "ldap_email", default: false, null: false
t.boolean "external", default: false t.boolean "external", default: false
t.string "incoming_email_token" t.string "incoming_email_token"
t.string "organization" t.string "organization"
...@@ -1695,6 +1683,8 @@ ActiveRecord::Schema.define(version: 20170602003304) do ...@@ -1695,6 +1683,8 @@ ActiveRecord::Schema.define(version: 20170602003304) do
t.boolean "support_bot" t.boolean "support_bot"
t.string "preferred_language" t.string "preferred_language"
t.string "rss_token" t.string "rss_token"
t.boolean "external_email", default: false, null: false
t.string "email_provider"
end end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
...@@ -1790,8 +1780,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do ...@@ -1790,8 +1780,6 @@ ActiveRecord::Schema.define(version: 20170602003304) do
add_foreign_key "geo_repository_updated_events", "projects", on_delete: :cascade add_foreign_key "geo_repository_updated_events", "projects", on_delete: :cascade
add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade
add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
add_foreign_key "issue_links", "issues", column: "source_id", name: "fk_c900194ff2", on_delete: :cascade
add_foreign_key "issue_links", "issues", column: "target_id", name: "fk_e71bb44f1f", on_delete: :cascade
add_foreign_key "issue_metrics", "issues", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade
add_foreign_key "label_priorities", "labels", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade
add_foreign_key "label_priorities", "projects", on_delete: :cascade add_foreign_key "label_priorities", "projects", on_delete: :cascade
......
...@@ -14,7 +14,7 @@ Constants for project visibility levels are next: ...@@ -14,7 +14,7 @@ Constants for project visibility levels are next:
The project can be cloned by any logged in user. The project can be cloned by any logged in user.
* `public`: * `public`:
The project can be cloned without any authentication. The project can be accessed without any authentication.
## List projects ## List projects
......
# Runners # Runners
In GitLab CI, Runners run your [yaml](../yaml/README.md). In GitLab CI, Runners run the code defined in [`.gitlab-ci.yml`](../yaml/README.md).
A Runner is an isolated (virtual) machine that picks up jobs They are isolated (virtual) machines that pick up jobs through the coordinator
through the coordinator API of GitLab CI. API of GitLab CI.
A Runner can be specific to a certain project or serve any project A Runner can be specific to a certain project or serve any project
in GitLab CI. A Runner that serves all projects is called a shared Runner. in GitLab CI. A Runner that serves all projects is called a shared Runner.
Ideally, GitLab Runner should not be installed on the same machine as GitLab. Ideally, the GitLab Runner should not be installed on the same machine as GitLab.
Read the [requirements documentation](../../install/requirements.md#gitlab-runner) Read the [requirements documentation](../../install/requirements.md#gitlab-runner)
for more information. for more information.
## Shared vs. Specific Runners ## Shared vs specific Runners
A Runner that is specific only runs for the specified project. A shared Runner After [installing the Runner][install], you can either register it as shared or
can run jobs for every project that has enabled the option **Allow shared Runners**. specific. You can only register a shared Runner if you have admin access to
the GitLab instance. The main differences between a shared and a specific Runner
**Shared Runners** are useful for jobs that have similar requirements, are:
between multiple projects. Rather than having multiple Runners idling for
many projects, you can have a single or a small number of Runners that handle - **Shared Runners** are useful for jobs that have similar requirements,
multiple projects. This makes it easier to maintain and update Runners. between multiple projects. Rather than having multiple Runners idling for
many projects, you can have a single or a small number of Runners that handle
**Specific Runners** are useful for jobs that have special requirements or for multiple projects. This makes it easier to maintain and update them.
projects with a specific demand. If a job has certain requirements, you can set Shared Runners process jobs using a [fair usage queue](#how-shared-runners-pick-jobs).
up the specific Runner with this in mind, while not having to do this for all In contrast to specific Runners that use a FIFO queue, this prevents
Runners. For example, if you want to deploy a certain project, you can setup cases where projects create hundreds of jobs which can lead to eating all
a specific Runner to have the right credentials for this. available shared Runners resources.
- **Specific Runners** are useful for jobs that have special requirements or for
Projects with high demand of CI activity can also benefit from using specific Runners. projects with a specific demand. If a job has certain requirements, you can set
By having dedicated Runners you are guaranteed that the Runner is not being held up the specific Runner with this in mind, while not having to do this for all
up by another project's jobs. Runners. For example, if you want to deploy a certain project, you can setup
a specific Runner to have the right credentials for this. The [usage of tags](#using-tags)
may be useful in this case. Specific Runners process jobs using a [FIFO] queue.
A Runner that is specific only runs for the specified project(s). A shared Runner
can run jobs for every project that has enabled the option **Allow shared Runners**
under **Settings ➔ Pipelines**.
Projects with high demand of CI activity can also benefit from using specific
Runners. By having dedicated Runners you are guaranteed that the Runner is not
being held up by another project's jobs.
You can set up a specific Runner to be used by multiple projects. The difference You can set up a specific Runner to be used by multiple projects. The difference
with a shared Runner is that you have to enable each project explicitly for with a shared Runner is that you have to enable each project explicitly for
the Runner to be able to run its jobs. the Runner to be able to run its jobs.
Specific Runners do not get shared with forked projects automatically. Specific Runners do not get shared with forked projects automatically.
A fork does copy the CI settings (jobs, allow shared, etc) of the cloned repository. A fork does copy the CI settings (jobs, allow shared, etc) of the cloned
repository.
# Creating and Registering a Runner
There are several ways to create a Runner. Only after creation, upon
registration its status as Shared or Specific is determined.
[See the documentation for](https://docs.gitlab.com/runner/install)
the different methods of installing a Runner instance.
After installing the Runner, you can either register it as `Shared` or as `Specific`. ## Registering a shared Runner
You can only register a Shared Runner if you have admin access to the GitLab instance.
## Registering a Shared Runner You can only register a shared Runner if you are an admin of the GitLab instance.
You can only register a shared Runner if you are an admin on the linked 1. Grab the shared-Runner token on the `admin/runners` page
GitLab instance.
Grab the shared-Runner token on the `admin/runners` page of your GitLab CI ![Shared Runners admin area](img/shared_runners_admin.png)
instance.
![shared token](shared_runner.png) 1. [Register the Runner][register]
Now simply register the Runner as any Runner: Shared Runners are enabled by default as of GitLab 8.2, but can be disabled
with the **Disable shared Runners** button which is present under each project's
**Settings ➔ Pipelines** page. Previous versions of GitLab defaulted shared
Runners to disabled.
``` ## Registering a specific Runner
sudo gitlab-ci-multi-runner register
```
Shared Runners are enabled by default as of GitLab 8.2, but can be disabled with the
`DISABLE SHARED RUNNERS` button. Previous versions of GitLab defaulted shared Runners to
disabled.
## Registering a Specific Runner
Registering a specific can be done in two ways: Registering a specific can be done in two ways:
1. Creating a Runner with the project registration token 1. Creating a Runner with the project registration token
1. Converting a shared Runner into a specific Runner (one-way, admin only) 1. Converting a shared Runner into a specific Runner (one-way, admin only)
There are several ways to create a Runner instance. The steps below only ### Registering a specific Runner with a project registration token
concern registering the Runner on GitLab CI.
### Registering a Specific Runner with a Project Registration token
To create a specific Runner without having admin rights to the GitLab instance, To create a specific Runner without having admin rights to the GitLab instance,
visit the project you want to make the Runner work for in GitLab CI. visit the project you want to make the Runner work for in GitLab:
Click on the Runner tab and use the registration token you find there to 1. Go to **Settings ➔ Pipelines** to obtain the token
setup a specific Runner for this project. 1. [Register the Runner][register]
![project Runners in GitLab CI](project_specific.png) ### Making an existing shared Runner specific
To register the Runner, run the command below and follow instructions: If you are an admin on your GitLab instance, you can turn any shared Runner into
a specific one, but not the other way around. Keep in mind that this is a one
way transition.
``` 1. Go to the Runners in the admin area **Overview ➔ Runners** (`/admin/runners`)
sudo gitlab-ci-multi-runner register and find your Runner
``` 1. Enable any projects under **Restrict projects for this Runner** to be used
with the Runner
### Lock a specific Runner from being enabled for other projects From now on, the shared Runner will be specific to those projects.
## Locking a specific Runner from being enabled for other projects
You can configure a Runner to assign it exclusively to a project. When a You can configure a Runner to assign it exclusively to a project. When a
Runner is locked this way, it can no longer be enabled for other projects. Runner is locked this way, it can no longer be enabled for other projects.
This setting is available on each Runner in *Project Settings* > *Runners*. This setting can be enabled the first time you [register a Runner][register] and
can be changed afterwards under each Runner's settings.
To lock/unlock a Runner:
1. Visit your project's **Settings ➔ Pipelines**
1. Find the Runner you wish to lock/unlock and make sure it's enabled
1. Click the pencil button
1. Check the **Lock to current projects** option
1. Click **Save changes** for the changes to take effect
### Making an existing Shared Runner Specific ## How shared Runners pick jobs
If you are an admin on your GitLab instance, Shared Runners abide to a process queue we call fair usage. The fair usage
you can make any shared Runner a specific Runner, _but you can not algorithm tries to assign jobs to shared Runners from projects that have the
make a specific Runner a shared Runner_. lowest number of jobs currently running on shared Runners.
To make a shared Runner specific, go to the Runner page (`/admin/runners`) **Example 1**
and find your Runner. Add any projects on the left to make this Runner
run exclusively for these projects, therefore making it a specific Runner.
![making a shared Runner specific](shared_to_specific_admin.png) We have following jobs in queue:
## Using Shared Runners Effectively - job 1 for project 1
- job 2 for project 1
- job 3 for project 1
- job 4 for project 2
- job 5 for project 2
- job 6 for project 3
With the fair usage algorithm jobs are assigned in following order:
1. We choose job 1, because project 1 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We choose job 4, because project 2 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We choose job 6, because project 3 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We choose job 2, because project 1 as other it runs 1 job
1. We choose job 5, because project 2 runs 1 job, where project 1 runs 2 jobs now
1. We choose job 3, because project 1 and runs 2 jobs
---
**Example 2**
We have following jobs in queue:
- job 1 for project 1
- job 2 for project 1
- job 3 for project 1
- job 4 for project 2
- job 5 for project 2
- job 6 for project 3
With the fair usage algorithm jobs are assigned in following order:
1. We choose job 1, because project 1 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We finish job 1
1. We choose job 2, because project 1 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We choose job 4, because project 2 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We finish job 4
1. We choose job 5, because project 2 doesn't run currently any jobs and has the lowest job number from projects that doesn't run jobs
1. We choose job 6, because project 3 doesn't run currently any jobs
1. We choose job 3, because project 1, 2 and 3 runs exactly one job now
## Using shared Runners effectively
If you are planning to use shared Runners, there are several things you If you are planning to use shared Runners, there are several things you
should keep in mind. should keep in mind.
### Use Tags ### Using tags
You must setup a Runner to be able to run all the different types of jobs You must setup a Runner to be able to run all the different types of jobs
that it may encounter on the projects it's shared over. This would be that it may encounter on the projects it's shared over. This would be
...@@ -130,17 +174,27 @@ shared Runners will only run the jobs they are equipped to run. ...@@ -130,17 +174,27 @@ shared Runners will only run the jobs they are equipped to run.
For instance, at GitLab we have Runners tagged with "rails" if they contain For instance, at GitLab we have Runners tagged with "rails" if they contain
the appropriate dependencies to run Rails test suites. the appropriate dependencies to run Rails test suites.
### Prevent Runner with tags from picking jobs without tags ### Preventing Runners with tags from picking jobs without tags
You can configure a Runner to prevent it from picking jobs with tags when You can configure a Runner to prevent it from picking jobs with tags when
the Runner does not have tags assigned. This setting is available on each the Runner does not have tags assigned. This setting can be enabled the first
Runner in *Project Settings* > *Runners*. time you [register a Runner][register] and can be changed afterwards under
each Runner's settings.
To make a Runner pick tagged/untagged jobs:
1. Visit your project's **Settings ➔ Pipelines**
1. Find the Runner you wish and make sure it's enabled
1. Click the pencil button
1. Check the **Run untagged jobs** option
1. Click **Save changes** for the changes to take effect
### Be careful with sensitive information ### Be careful with sensitive information
If you can run a job on a Runner, you can get access to any code it runs If you can run a job on a Runner, you can get access to any code it runs
and get the token of the Runner. With shared Runners, this means that anyone and get the token of the Runner. With shared Runners, this means that anyone
that runs jobs on the Runner, can access anyone else's code that runs on the Runner. that runs jobs on the Runner, can access anyone else's code that runs on the
Runner.
In addition, because you can get access to the Runner token, it is possible In addition, because you can get access to the Runner token, it is possible
to create a clone of a Runner and submit false jobs, for example. to create a clone of a Runner and submit false jobs, for example.
...@@ -160,3 +214,7 @@ project. ...@@ -160,3 +214,7 @@ project.
Mentioned briefly earlier, but the following things of Runners can be exploited. Mentioned briefly earlier, but the following things of Runners can be exploited.
We're always looking for contributions that can mitigate these We're always looking for contributions that can mitigate these
[Security Considerations](https://docs.gitlab.com/runner/security/). [Security Considerations](https://docs.gitlab.com/runner/security/).
[install]: http://docs.gitlab.com/runner/install/
[fifo]: https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)
[register]: http://docs.gitlab.com/runner/register/
...@@ -4,16 +4,49 @@ ...@@ -4,16 +4,49 @@
- [Introduced][ci-229] in GitLab CE 7.14. - [Introduced][ci-229] in GitLab CE 7.14.
- GitLab 8.12 has a completely redesigned job permissions system. Read all - GitLab 8.12 has a completely redesigned job permissions system. Read all
about the [new model and its implications](../../user/project/new_ci_build_permissions_model.md#job-triggers). about the [new model and its implications](../../user/project/new_ci_build_permissions_model.md#job-triggers).
- GitLab 9.0 introduced a trigger ownership to solve permission problems,
- GitLab 9.3 introduced an ability to use CI Job Token to trigger dependent pipelines,
Triggers can be used to force a rebuild of a specific `ref` (branch or tag) Triggers can be used to force a pipeline rerun of a specific `ref` (branch or
with an API call. tag) with an API call.
## Add a trigger ## Authentication tokens
The following methods of authentication are supported.
### Trigger token
A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
### CI job token
> **Note**:
[Introduced][ee-2017] in [GitLab Enterprise Edition Premium][ee] 9.3
You can trigger a new pipeline using the `CI_JOB_TOKEN` [variable][predef]
which is used to authenticate with the [GitLab Container Registry][registry].
This way of triggering can only be used when invoked inside `.gitlab-ci.yml`,
and it creates a dependent pipeline relation visible on the
[pipeline graph](../pipelines.md#pipelines-graphs). For example:
```yaml
build_docs:
stage: deploy
script:
- "curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=master https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
only:
- tags
```
Pipelines triggered that way also expose a special variable:
`CI_PIPELINE_SOURCE=pipeline`. This method currently doesn't support
[the usage of trigger variables](#making-use-of-trigger-variables).
For more information, read about [triggering a pipeline](#triggering-a-pipeline).
## Adding a new trigger
You can add a new trigger by going to your project's You can add a new trigger by going to your project's
**Settings ➔ PipelinesTriggers**. The **Add trigger** button will **Settings ➔ Pipelines** under **Triggers**. The **Add trigger** button will
create a new token which you can then use to trigger a rerun of this create a new token which you can then use to trigger a rerun of this
particular project's pipeline. particular project's pipeline.
...@@ -23,7 +56,10 @@ overview of the time the triggers were last used. ...@@ -23,7 +56,10 @@ overview of the time the triggers were last used.
![Triggers page overview](img/triggers_page.png) ![Triggers page overview](img/triggers_page.png)
## Take ownership ## Taking ownership of a trigger
> **Note**:
GitLab 9.0 introduced a trigger ownership to solve permission problems.
Each created trigger when run will impersonate their associated user including Each created trigger when run will impersonate their associated user including
their access to projects and their project permissions. their access to projects and their project permissions.
...@@ -31,26 +67,20 @@ their access to projects and their project permissions. ...@@ -31,26 +67,20 @@ their access to projects and their project permissions.
You can take ownership of existing triggers by clicking *Take ownership*. You can take ownership of existing triggers by clicking *Take ownership*.
From now on the trigger will be run as you. From now on the trigger will be run as you.
## Legacy triggers ## Revoking a trigger
Old triggers, created before 9.0 will be marked as Legacy. Triggers with
the legacy label do not have an associated user and only have access
to the current project.
Legacy trigger are considered deprecated and will be removed
with one of the future versions of GitLab.
## Revoke a trigger
You can revoke a trigger any time by going at your project's You can revoke a trigger any time by going at your project's
**Settings > Triggers** and hitting the **Revoke** button. The action is **Settings ➔ Pipelines** under **Triggers** and hitting the **Revoke** button.
irreversible. The action is irreversible.
## Trigger a pipeline ## Triggering a pipeline
> **Note**: > **Notes**:
Valid refs are only the branches and tags. If you pass a commit SHA as a ref, - Valid refs are only the branches and tags. If you pass a commit SHA as a ref,
it will not trigger a job. it will not trigger a job.
- If your project is public, passing the token in plain text is probably not the
wisest idea, so you might want to use a
[secret variable](../variables/README.md#secret-variables) for that purpose.
To trigger a job you need to send a `POST` request to GitLab's API endpoint: To trigger a job you need to send a `POST` request to GitLab's API endpoint:
...@@ -58,11 +88,11 @@ To trigger a job you need to send a `POST` request to GitLab's API endpoint: ...@@ -58,11 +88,11 @@ To trigger a job you need to send a `POST` request to GitLab's API endpoint:
POST /projects/:id/trigger/pipeline POST /projects/:id/trigger/pipeline
``` ```
The required parameters are the trigger's `token` and the Git `ref` on which The required parameters are the [trigger's `token`](#authentication-tokens)
the trigger will be performed. Valid refs are the branch and the tag. The `:id` and the Git `ref` on which the trigger will be performed. Valid refs are the
of a project can be found by [querying the API](../../api/projects.md) branch and the tag. The `:id` of a project can be found by
or by visiting the **Pipelines** settings page which provides [querying the API](../../api/projects.md) or by visiting the **Pipelines**
self-explanatory examples. settings page which provides self-explanatory examples.
When a rerun of a pipeline is triggered, the information is exposed in GitLab's When a rerun of a pipeline is triggered, the information is exposed in GitLab's
UI under the **Jobs** page and the jobs are marked as triggered 'by API'. UI under the **Jobs** page and the jobs are marked as triggered 'by API'.
...@@ -79,46 +109,7 @@ below. ...@@ -79,46 +109,7 @@ below.
--- ---
See the [Examples](#examples) section for more details on how to actually By using cURL you can trigger a pipeline rerun with minimal effort, for example:
trigger a rebuild.
## Trigger a pipeline from webhook
> Introduced in GitLab 8.14.
To trigger a job from webhook of another project you need to add the following
webhook url for Push and Tag push events:
```
https://gitlab.example.com/api/v4/projects/:id/ref/:ref/trigger/pipeline?token=TOKEN
```
> **Note**:
- `ref` should be passed as part of url in order to take precedence over `ref`
from webhook body that designates the branchref that fired the trigger in the source repository.
- `ref` should be url encoded if contains slashes.
## Pass job variables to a trigger
You can pass any number of arbitrary variables in the trigger API call and they
will be available in GitLab CI so that they can be used in your `.gitlab-ci.yml`
file. The parameter is of the form:
```
variables[key]=value
```
This information is also exposed in the UI.
![Job variables in UI](img/trigger_variables.png)
---
See the [Examples](#examples) section below for more details.
## Examples
Using cURL you can trigger a rebuild with minimal effort, for example:
```bash ```bash
curl --request POST \ curl --request POST \
...@@ -136,8 +127,6 @@ curl --request POST \ ...@@ -136,8 +127,6 @@ curl --request POST \
"https://gitlab.example.com/api/v4/projects/9/trigger/pipeline?token=TOKEN&ref=master" "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline?token=TOKEN&ref=master"
``` ```
### Triggering a pipeline within `.gitlab-ci.yml`
You can also benefit by using triggers in your `.gitlab-ci.yml`. Let's say that You can also benefit by using triggers in your `.gitlab-ci.yml`. Let's say that
you have two projects, A and B, and you want to trigger a rebuild on the `master` you have two projects, A and B, and you want to trigger a rebuild on the `master`
branch of project B whenever a tag on project A is created. This is the job you branch of project B whenever a tag on project A is created. This is the job you
...@@ -157,33 +146,37 @@ Now, whenever a new tag is pushed on project A, the job will run and the ...@@ -157,33 +146,37 @@ Now, whenever a new tag is pushed on project A, the job will run and the
`stage: deploy` ensures that this job will run only after all jobs with `stage: deploy` ensures that this job will run only after all jobs with
`stage: test` complete successfully. `stage: test` complete successfully.
_**Note:** If your project is public, passing the token in plain text is ## Triggering a pipeline from a webhook
probably not the wisest idea, so you might want to use a
[secure variable](../variables/README.md#user-defined-variables-secure-variables)
for that purpose._
--- > **Notes**:
- Introduced in GitLab 8.14.
- `ref` should be passed as part of the URL in order to take precedence over
`ref` from the webhook body that designates the branch ref that fired the
trigger in the source repository.
- `ref` should be URL-encoded if it contains slashes.
Since GitLab 9.3 you can trigger a new pipeline using a CI_JOB_TOKEN. To trigger a job from a webhook of another project you need to add the following
This method currently doesn't support Variables. webhook URL for Push and Tag events (change the project ID, ref and token):
The support for them will be included in 9.4 of GitLab.
This way of triggering creates a dependent pipeline relation visible on the Pipeline Graph. ```
https://gitlab.example.com/api/v4/projects/9/ref/master/trigger/pipeline?token=TOKEN
```
## Making use of trigger variables
You can pass any number of arbitrary variables in the trigger API call and they
will be available in GitLab CI so that they can be used in your `.gitlab-ci.yml`
file. The parameter is of the form:
```yaml ```
build_docs: variables[key]=value
stage: deploy
script:
- "curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=master https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
only:
- tags
``` ```
Pipelines triggered that way do expose a special variable: `CI_PIPELINE_SOURCE=pipeline`. This information is also exposed in the UI.
### Making use of trigger variables ![Job variables in UI](img/trigger_variables.png)
Using trigger variables can be proven useful for a variety of reasons. Using trigger variables can be proven useful for a variety of reasons:
* Identifiable jobs. Since the variable is exposed in the UI you can know * Identifiable jobs. Since the variable is exposed in the UI you can know
why the rebuild was triggered if you pass a variable that explains the why the rebuild was triggered if you pass a variable that explains the
...@@ -228,15 +221,7 @@ curl --request POST \ ...@@ -228,15 +221,7 @@ curl --request POST \
https://gitlab.example.com/api/v4/projects/9/trigger/pipeline https://gitlab.example.com/api/v4/projects/9/trigger/pipeline
``` ```
### Using a webhook to trigger a pipeline ## Using cron to trigger nightly pipelines
You can add the following webhook to another project in order to trigger a job:
```
https://gitlab.example.com/api/v4/projects/9/ref/master/trigger/pipeline?token=TOKEN&variables[UPLOAD_TO_S3]=true
```
### Using cron to trigger nightly pipelines
>**Note:** >**Note:**
The following behavior can also be achieved through GitLab's UI with The following behavior can also be achieved through GitLab's UI with
...@@ -250,4 +235,18 @@ branch of project with ID `9` every night at `00:30`: ...@@ -250,4 +235,18 @@ branch of project with ID `9` every night at `00:30`:
30 0 * * * curl --request POST --form token=TOKEN --form ref=master https://gitlab.example.com/api/v4/projects/9/trigger/pipeline 30 0 * * * curl --request POST --form token=TOKEN --form ref=master https://gitlab.example.com/api/v4/projects/9/trigger/pipeline
``` ```
## Legacy triggers
Old triggers, created before GitLab 9.0 will be marked as legacy.
Triggers with the legacy label do not have an associated user and only have
access to the current project. They are considered deprecated and will be
removed with one of the future versions of GitLab. You are advised to
[take ownership](#taking-ownership) of any legacy triggers.
[ee-2017]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2017
[ci-229]: https://gitlab.com/gitlab-org/gitlab-ci/merge_requests/229 [ci-229]: https://gitlab.com/gitlab-org/gitlab-ci/merge_requests/229
[ee]: https://about.gitlab.com/gitlab-ee/
[variables]: ../variables/README.md
[predef]: ../variables/README.md#predefined-variables-environment-variables
[registry]: ../../user/project/container_registry.md
doc/ci/triggers/img/triggers_page.png

108 KB | W: | H:

doc/ci/triggers/img/triggers_page.png

20.4 KB | W: | H:

doc/ci/triggers/img/triggers_page.png
doc/ci/triggers/img/triggers_page.png
doc/ci/triggers/img/triggers_page.png
doc/ci/triggers/img/triggers_page.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -54,7 +54,7 @@ future GitLab releases.** ...@@ -54,7 +54,7 @@ future GitLab releases.**
| **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used | | **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used |
| **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags | | **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags |
| **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally | | **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally |
| **CI_PIPELINE_SOURCE** | 9.3 | all | The variable indicates how the pipeline was triggered, possible options are: push, web, trigger, schedule, api, pipeline | | **CI_PIPELINE_SOURCE** | 9.3 | all | ([EEP]) The variable indicates how the pipeline was triggered, possible options are: push, web, trigger, schedule, api, pipeline |
| **CI_PIPELINE_TRIGGERED** | all | all | The flag to indicate that job was [triggered] | | **CI_PIPELINE_TRIGGERED** | all | all | The flag to indicate that job was [triggered] |
| **CI_PROJECT_DIR** | all | all | The full path where the repository is cloned and where the job is run | | **CI_PROJECT_DIR** | all | all | The full path where the repository is cloned and where the job is run |
| **CI_PROJECT_ID** | all | all | The unique id of the current project that GitLab CI uses internally | | **CI_PROJECT_ID** | all | all | The unique id of the current project that GitLab CI uses internally |
...@@ -432,3 +432,4 @@ export CI_REGISTRY_PASSWORD="longalfanumstring" ...@@ -432,3 +432,4 @@ export CI_REGISTRY_PASSWORD="longalfanumstring"
[protected branches]: ../../user/project/protected_branches.md [protected branches]: ../../user/project/protected_branches.md
[protected tags]: ../../user/project/protected_tags.md [protected tags]: ../../user/project/protected_tags.md
[shellexecutors]: https://docs.gitlab.com/runner/executors/ [shellexecutors]: https://docs.gitlab.com/runner/executors/
[eep]: https://about.gitlab.com/gitlab-ee/ "Available only in GitLab Enterprise Edition Premium"
...@@ -112,8 +112,33 @@ all matching branches: ...@@ -112,8 +112,33 @@ all matching branches:
![Protected branch matches](img/protected_branches_matches.png) ![Protected branch matches](img/protected_branches_matches.png)
## Deleting a protected branch
> [Introduced][ce-21393] in GitLab 9.3.
From time to time, it may be required to delete or clean up branches that are
protected.
User with [Master permissions][perm] and up can manually delete protected
branches via GitLab's web interface:
1. Visit **Repository > Branches**
1. Click on the delete icon next to the branch you wish to delete
1. In order to prevent accidental deletion, an additional confirmation is
required
![Delete protected branches](img/protected_branches_delete.png)
Deleting a protected branch is only allowed via the web interface, not via Git.
This means that you can't accidentally delete a protected branch from your
command line or a Git client application.
## Changelog ## Changelog
**9.2**
- Allow deletion of protected branches via the web interface [gitlab-org/gitlab-ce#21393][ce-21393]
**8.11** **8.11**
- Allow creating protected branches that can't be pushed to [gitlab-org/gitlab-ce!5081][ce-5081] - Allow creating protected branches that can't be pushed to [gitlab-org/gitlab-ce!5081][ce-5081]
...@@ -128,4 +153,6 @@ all matching branches: ...@@ -128,4 +153,6 @@ all matching branches:
[ce-4665]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4665 "Allow specifying protected branches using wildcards" [ce-4665]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4665 "Allow specifying protected branches using wildcards"
[ce-4892]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4892 "Allow developers to merge into a protected branch without having push access" [ce-4892]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4892 "Allow developers to merge into a protected branch without having push access"
[ce-5081]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5081 "Allow creating protected branches that can't be pushed to" [ce-5081]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5081 "Allow creating protected branches that can't be pushed to"
[ce-21393]: https://gitlab.com/gitlab-org/gitlab-ce/issues/21393
[ee-restrict]: http://docs.gitlab.com/ee/user/project/protected_branches.html#restricting-push-and-merge-access-to-certain-users [ee-restrict]: http://docs.gitlab.com/ee/user/project/protected_branches.html#restricting-push-and-merge-access-to-certain-users
[perm]: ../permissions.md
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Canceled < Status::Core class Canceled < Status::Core
def text def text
'canceled' s_('CiStatusText|canceled')
end end
def label def label
'canceled' s_('CiStatusLabel|canceled')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Created < Status::Core class Created < Status::Core
def text def text
'created' s_('CiStatusText|created')
end end
def label def label
'created' s_('CiStatusLabel|created')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Failed < Status::Core class Failed < Status::Core
def text def text
'failed' s_('CiStatusText|failed')
end end
def label def label
'failed' s_('CiStatusLabel|failed')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Manual < Status::Core class Manual < Status::Core
def text def text
'manual' s_('CiStatusText|manual')
end end
def label def label
'manual action' s_('CiStatusLabel|manual action')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Pending < Status::Core class Pending < Status::Core
def text def text
'pending' s_('CiStatusText|pending')
end end
def label def label
'pending' s_('CiStatusLabel|pending')
end end
def icon def icon
......
...@@ -4,11 +4,11 @@ module Gitlab ...@@ -4,11 +4,11 @@ module Gitlab
module Pipeline module Pipeline
class Blocked < Status::Extended class Blocked < Status::Extended
def text def text
'blocked' s_('CiStatusText|blocked')
end end
def label def label
'waiting for manual action' s_('CiStatusLabel|waiting for manual action')
end end
def self.matches?(pipeline, user) def self.matches?(pipeline, user)
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Running < Status::Core class Running < Status::Core
def text def text
'running' s_('CiStatus|running')
end end
def label def label
'running' s_('CiStatus|running')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Skipped < Status::Core class Skipped < Status::Core
def text def text
'skipped' s_('CiStatusText|skipped')
end end
def label def label
'skipped' s_('CiStatusLabel|skipped')
end end
def icon def icon
......
...@@ -3,11 +3,11 @@ module Gitlab ...@@ -3,11 +3,11 @@ module Gitlab
module Status module Status
class Success < Status::Core class Success < Status::Core
def text def text
'passed' s_('CiStatusText|passed')
end end
def label def label
'passed' s_('CiStatusLabel|passed')
end end
def icon def icon
......
...@@ -7,11 +7,11 @@ module Gitlab ...@@ -7,11 +7,11 @@ module Gitlab
# #
class SuccessWarning < Status::Extended class SuccessWarning < Status::Extended
def text def text
'passed' s_('CiStatusText|passed')
end end
def label def label
'passed with warnings' s_('CiStatusLabel|passed with warnings')
end end
def icon def icon
......
...@@ -70,7 +70,7 @@ module Gitlab ...@@ -70,7 +70,7 @@ module Gitlab
found_user = Gitlab::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter) found_user = Gitlab::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter)
return found_user if found_user return found_user if found_user
if user.ldap_email? if user.external_email? && [nil, provider].include?(user.email_provider)
Gitlab::LDAP::Person.find_by_email(user.email, adapter) Gitlab::LDAP::Person.find_by_email(user.email, adapter)
end end
end end
......
...@@ -41,11 +41,6 @@ module Gitlab ...@@ -41,11 +41,6 @@ module Gitlab
def update_user_attributes def update_user_attributes
if persisted? if persisted?
if auth_hash.has_email?
gl_user.skip_reconfirmation!
gl_user.email = auth_hash.email
end
# find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved. # find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved.
identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider } identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider }
identity ||= gl_user.identities.build(provider: auth_hash.provider) identity ||= gl_user.identities.build(provider: auth_hash.provider)
...@@ -55,10 +50,6 @@ module Gitlab ...@@ -55,10 +50,6 @@ module Gitlab
# For an existing identity with no change in DN, this line changes nothing. # For an existing identity with no change in DN, this line changes nothing.
identity.extern_uid = auth_hash.uid identity.extern_uid = auth_hash.uid
end end
gl_user.ldap_email = auth_hash.has_email?
gl_user
end end
def changed? def changed?
...@@ -69,6 +60,10 @@ module Gitlab ...@@ -69,6 +60,10 @@ module Gitlab
ldap_config.block_auto_created_users ldap_config.block_auto_created_users
end end
def sync_email_from_provider?
true
end
def allowed? def allowed?
Gitlab::LDAP::Access.allowed?(gl_user) Gitlab::LDAP::Access.allowed?(gl_user)
end end
......
...@@ -12,6 +12,7 @@ module Gitlab ...@@ -12,6 +12,7 @@ module Gitlab
def initialize(auth_hash) def initialize(auth_hash)
self.auth_hash = auth_hash self.auth_hash = auth_hash
update_email
end end
def persisted? def persisted?
...@@ -174,6 +175,22 @@ module Gitlab ...@@ -174,6 +175,22 @@ module Gitlab
} }
end end
def sync_email_from_provider?
auth_hash.provider.to_s == Gitlab.config.omniauth.sync_email_from_provider.to_s
end
def update_email
if auth_hash.has_email? && sync_email_from_provider?
if persisted?
gl_user.skip_reconfirmation!
gl_user.email = auth_hash.email
end
gl_user.external_email = true
gl_user.email_provider = auth_hash.provider
end
end
def log def log
Gitlab::AppLogger Gitlab::AppLogger
end end
......
...@@ -41,9 +41,9 @@ module Gitlab ...@@ -41,9 +41,9 @@ module Gitlab
def options def options
{ {
'Private' => PRIVATE, N_('VisibilityLevel|Private') => PRIVATE,
'Internal' => INTERNAL, N_('VisibilityLevel|Internal') => INTERNAL,
'Public' => PUBLIC N_('VisibilityLevel|Public') => PUBLIC
} }
end end
......
...@@ -7,24 +7,170 @@ msgid "" ...@@ -7,24 +7,170 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2017-05-09 13:44+0200\n" "PO-Revision-Date: 2017-06-07 12:17+0200\n"
"Language-Team: German\n" "Language-Team: German\n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"Last-Translator: \n" "Last-Translator: Bob Van Landuyt <bob@gitlab.com>\n"
"X-Generator: Poedit 2.0.1\n" "X-Generator: Poedit 2.0.2\n"
msgid "About auto deploy"
msgstr ""
msgid "Activity"
msgstr ""
msgid "Add Changelog"
msgstr ""
msgid "Add Contribution guide"
msgstr ""
msgid "Add License"
msgstr ""
msgid "Add an SSH key to your profile to pull or push via SSH."
msgstr ""
msgid "Add new directory"
msgstr ""
msgid "Archived project! Repository is read-only"
msgstr ""
msgid "Branch"
msgid_plural "Branches"
msgstr[0] ""
msgstr[1] ""
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
msgid "Branches"
msgstr ""
msgid "ByAuthor|by" msgid "ByAuthor|by"
msgstr "Von" msgstr "Von"
msgid "CI configuration"
msgstr ""
msgid "Changelog"
msgstr ""
msgid "Charts"
msgstr ""
msgid "CiStatusLabel|canceled"
msgstr ""
msgid "CiStatusLabel|created"
msgstr ""
msgid "CiStatusLabel|failed"
msgstr ""
msgid "CiStatusLabel|manual action"
msgstr ""
msgid "CiStatusLabel|passed"
msgstr ""
msgid "CiStatusLabel|passed with warnings"
msgstr ""
msgid "CiStatusLabel|pending"
msgstr ""
msgid "CiStatusLabel|skipped"
msgstr ""
msgid "CiStatusLabel|waiting for manual action"
msgstr ""
msgid "CiStatusText|blocked"
msgstr ""
msgid "CiStatusText|canceled"
msgstr ""
msgid "CiStatusText|created"
msgstr ""
msgid "CiStatusText|failed"
msgstr ""
msgid "CiStatusText|manual"
msgstr ""
msgid "CiStatusText|passed"
msgstr ""
msgid "CiStatusText|pending"
msgstr ""
msgid "CiStatusText|skipped"
msgstr ""
msgid "CiStatus|running"
msgstr ""
msgid "Commit" msgid "Commit"
msgid_plural "Commits" msgid_plural "Commits"
msgstr[0] "Commit" msgstr[0] "Commit"
msgstr[1] "Commits" msgstr[1] "Commits"
msgid "CommitMessage|Add %{file_name}"
msgstr ""
msgid "Commits"
msgstr "Commits"
msgid "Commits|History"
msgstr "Commits"
msgid "Compare"
msgstr ""
msgid "Contribution guide"
msgstr ""
msgid "Contributors"
msgstr ""
msgid "Copy URL to clipboard"
msgstr ""
msgid "Copy commit SHA to clipboard"
msgstr ""
msgid "Create New Directory"
msgstr ""
msgid "Create directory"
msgstr ""
msgid "Create empty bare repository"
msgstr ""
msgid "Create merge request"
msgstr ""
msgid "CreateNewFork|Fork"
msgstr ""
msgid "Custom notification events"
msgstr ""
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr ""
msgid "Cycle Analytics"
msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project." msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "Cycle Analytics liefern einen Überblick darüber, wie viel Zeit in Ihrem Projekt von einer Idee bis zum Produktivdeployment vergeht." msgstr "Cycle Analytics liefern einen Überblick darüber, wie viel Zeit in Ihrem Projekt von einer Idee bis zum Produktivdeployment vergeht."
...@@ -54,26 +200,98 @@ msgid_plural "Deploys" ...@@ -54,26 +200,98 @@ msgid_plural "Deploys"
msgstr[0] "Deployment" msgstr[0] "Deployment"
msgstr[1] "Deployments" msgstr[1] "Deployments"
msgid "Directory name"
msgstr ""
msgid "Don't show again"
msgstr ""
msgid "Download tar"
msgstr ""
msgid "Download tar.bz2"
msgstr ""
msgid "Download tar.gz"
msgstr ""
msgid "Download zip"
msgstr ""
msgid "DownloadArtifacts|Download"
msgstr ""
msgid "DownloadSource|Download"
msgstr ""
msgid "Files"
msgstr ""
msgid "Find by path"
msgstr ""
msgid "Find file"
msgstr ""
msgid "FirstPushedBy|First" msgid "FirstPushedBy|First"
msgstr "Erster" msgstr "Erster"
msgid "FirstPushedBy|pushed by" msgid "FirstPushedBy|pushed by"
msgstr "gepusht von" msgstr "gepusht von"
msgid "ForkedFromProjectPath|Forked from"
msgstr ""
msgid "Forks"
msgstr ""
msgid "From issue creation until deploy to production" msgid "From issue creation until deploy to production"
msgstr "Vom Anlegen des Issues bis zum Produktivdeployment" msgstr "Vom Anlegen des Issues bis zum Produktivdeployment"
msgid "From merge request merge until deploy to production" msgid "From merge request merge until deploy to production"
msgstr "Vom Merge Request bis zum Produktivdeployment" msgstr "Vom Merge Request bis zum Produktivdeployment"
msgid "Go to your fork"
msgstr ""
msgid "GoToYourFork|Fork"
msgstr ""
msgid "Home"
msgstr ""
msgid "Housekeeping successfully started"
msgstr ""
msgid "Import repository"
msgstr ""
msgid "Introducing Cycle Analytics" msgid "Introducing Cycle Analytics"
msgstr "Was sind Cycle Analytics?" msgstr "Was sind Cycle Analytics?"
msgid "LFSStatus|Disabled"
msgstr ""
msgid "LFSStatus|Enabled"
msgstr ""
msgid "Last %d day" msgid "Last %d day"
msgid_plural "Last %d days" msgid_plural "Last %d days"
msgstr[0] "Letzter %d Tag" msgstr[0] "Letzter %d Tag"
msgstr[1] "Letzten %d Tage" msgstr[1] "Letzten %d Tage"
msgid "Last Update"
msgstr ""
msgid "Last commit"
msgstr ""
msgid "Leave group"
msgstr ""
msgid "Leave project"
msgstr ""
msgid "Limited to showing %d event at most" msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most" msgid_plural "Limited to showing %d events at most"
msgstr[0] "Eingeschränkt auf maximal %d Ereignis" msgstr[0] "Eingeschränkt auf maximal %d Ereignis"
...@@ -82,29 +300,167 @@ msgstr[1] "Eingeschränkt auf maximal %d Ereignisse" ...@@ -82,29 +300,167 @@ msgstr[1] "Eingeschränkt auf maximal %d Ereignisse"
msgid "Median" msgid "Median"
msgstr "Median" msgstr "Median"
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr ""
msgid "New Issue" msgid "New Issue"
msgid_plural "New Issues" msgid_plural "New Issues"
msgstr[0] "Neues Issue" msgstr[0] "Neues Issue"
msgstr[1] "Neue Issues" msgstr[1] "Neue Issues"
msgid "New branch"
msgstr ""
msgid "New directory"
msgstr ""
msgid "New file"
msgstr ""
msgid "New issue"
msgstr "Neues Issue"
msgid "New merge request"
msgstr ""
msgid "New snippet"
msgstr ""
msgid "New tag"
msgstr ""
msgid "No repository"
msgstr ""
msgid "Not available" msgid "Not available"
msgstr "Nicht verfügbar" msgstr "Nicht verfügbar"
msgid "Not enough data" msgid "Not enough data"
msgstr "Nicht genügend Daten" msgstr "Nicht genügend Daten"
msgid "Notification events"
msgstr ""
msgid "NotificationEvent|Close issue"
msgstr ""
msgid "NotificationEvent|Close merge request"
msgstr ""
msgid "NotificationEvent|Failed pipeline"
msgstr ""
msgid "NotificationEvent|Merge merge request"
msgstr ""
msgid "NotificationEvent|New issue"
msgstr ""
msgid "NotificationEvent|New merge request"
msgstr ""
msgid "NotificationEvent|New note"
msgstr ""
msgid "NotificationEvent|Reassign issue"
msgstr ""
msgid "NotificationEvent|Reassign merge request"
msgstr ""
msgid "NotificationEvent|Reopen issue"
msgstr ""
msgid "NotificationEvent|Successful pipeline"
msgstr ""
msgid "NotificationLevel|Custom"
msgstr ""
msgid "NotificationLevel|Disabled"
msgstr ""
msgid "NotificationLevel|Global"
msgstr ""
msgid "NotificationLevel|On mention"
msgstr ""
msgid "NotificationLevel|Participate"
msgstr ""
msgid "NotificationLevel|Watch"
msgstr ""
msgid "OpenedNDaysAgo|Opened" msgid "OpenedNDaysAgo|Opened"
msgstr "Erstellt" msgstr "Erstellt"
msgid "Pipeline Health" msgid "Pipeline Health"
msgstr "Pipeline Kennzahlen" msgstr "Pipeline Kennzahlen"
msgid "Project '%{project_name}' queued for deletion."
msgstr ""
msgid "Project '%{project_name}' was successfully created."
msgstr ""
msgid "Project '%{project_name}' was successfully updated."
msgstr ""
msgid "Project '%{project_name}' will be deleted."
msgstr ""
msgid "Project access must be granted explicitly to each user."
msgstr ""
msgid "Project export could not be deleted."
msgstr ""
msgid "Project export has been deleted."
msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
msgid "Project export started. A download link will be sent by email."
msgstr ""
msgid "Project home"
msgstr ""
msgid "ProjectFeature|Disabled"
msgstr ""
msgid "ProjectFeature|Everyone with access"
msgstr ""
msgid "ProjectFeature|Only team members"
msgstr ""
msgid "ProjectFileTree|Name"
msgstr ""
msgid "ProjectLastActivity|Never"
msgstr ""
msgid "ProjectLifecycle|Stage" msgid "ProjectLifecycle|Stage"
msgstr "Phase" msgstr "Phase"
msgid "ProjectNetworkGraph|Graph"
msgstr ""
msgid "Read more" msgid "Read more"
msgstr "Mehr" msgstr "Mehr"
msgid "Readme"
msgstr ""
msgid "RefSwitcher|Branches"
msgstr ""
msgid "RefSwitcher|Tags"
msgstr ""
msgid "Related Commits" msgid "Related Commits"
msgstr "Zugehörige Commits" msgstr "Zugehörige Commits"
...@@ -123,17 +479,67 @@ msgstr "Zugehörige Merge Requests" ...@@ -123,17 +479,67 @@ msgstr "Zugehörige Merge Requests"
msgid "Related Merged Requests" msgid "Related Merged Requests"
msgstr "Zugehörige abgeschlossene Merge Requests" msgstr "Zugehörige abgeschlossene Merge Requests"
msgid "Remind later"
msgstr ""
msgid "Remove project"
msgstr ""
msgid "Request Access"
msgstr ""
msgid "Search branches and tags"
msgstr ""
msgid "Select Archive Format"
msgstr ""
msgid "Set a password on your account to pull or push via %{protocol}"
msgstr ""
msgid "Set up CI"
msgstr ""
msgid "Set up Koding"
msgstr ""
msgid "Set up auto deploy"
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
msgstr ""
msgid "Showing %d event" msgid "Showing %d event"
msgid_plural "Showing %d events" msgid_plural "Showing %d events"
msgstr[0] "Zeige %d Ereignis" msgstr[0] "Zeige %d Ereignis"
msgstr[1] "Zeige %d Ereignisse" msgstr[1] "Zeige %d Ereignisse"
msgid "Source code"
msgstr ""
msgid "StarProject|Star"
msgstr ""
msgid "Switch branch/tag"
msgstr ""
msgid "Tag"
msgid_plural "Tags"
msgstr[0] ""
msgstr[1] ""
msgid "Tags"
msgstr ""
msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request." msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
msgstr "Die Code-Phase stellt die Zeit vom ersten Commit bis zum Erstellen eines Merge Requests dar. Sobald Sie Ihren ersten Merge Request anlegen, werden dessen Daten automatisch ergänzt." msgstr "Die Code-Phase stellt die Zeit vom ersten Commit bis zum Erstellen eines Merge Requests dar. Sobald Sie Ihren ersten Merge Request anlegen, werden dessen Daten automatisch ergänzt."
msgid "The collection of events added to the data gathered for that stage." msgid "The collection of events added to the data gathered for that stage."
msgstr "Ereignisse, die für diese Phase ausgewertet wurden." msgstr "Ereignisse, die für diese Phase ausgewertet wurden."
msgid "The fork relationship has been removed."
msgstr ""
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage." msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr "Die Issue-Phase stellt die Zeit vom Anlegen eines Issues bis zum Zuweisen eines Meilensteins oder Hinzufügen zum Issue Board dar. Erstellen Sie einen Issue, damit dessen Daten hier erscheinen." msgstr "Die Issue-Phase stellt die Zeit vom Anlegen eines Issues bis zum Zuweisen eines Meilensteins oder Hinzufügen zum Issue Board dar. Erstellen Sie einen Issue, damit dessen Daten hier erscheinen."
...@@ -146,6 +552,15 @@ msgstr "Die Planungsphase stellt die Zeit von der vorherigen Phase bis zum Pushe ...@@ -146,6 +552,15 @@ msgstr "Die Planungsphase stellt die Zeit von der vorherigen Phase bis zum Pushe
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle." msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr "Die Produktiv-Phase stellt die Gesamtzeit vom Anlegen eines Issues bis zum Deployment auf dem Produktivsystem dar. Sobald Sie den vollständigen Entwicklungszyklus von einer Idee bis zum Produktivdeployment durchlaufen haben, erscheinen die zugehörigen Daten hier." msgstr "Die Produktiv-Phase stellt die Gesamtzeit vom Anlegen eines Issues bis zum Deployment auf dem Produktivsystem dar. Sobald Sie den vollständigen Entwicklungszyklus von einer Idee bis zum Produktivdeployment durchlaufen haben, erscheinen die zugehörigen Daten hier."
msgid "The project can be accessed by any logged in user."
msgstr ""
msgid "The project can be accessed without any authentication."
msgstr ""
msgid "The repository for this project does not exist."
msgstr ""
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request." msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr "Die Review-Phase stellt die Zeit vom Anlegen eines Merge Requests bis zum Mergen dar. Sobald Sie Ihren ersten Merge Request abschließen, werden dessen Daten hier automatisch angezeigt." msgstr "Die Review-Phase stellt die Zeit vom Anlegen eines Merge Requests bis zum Mergen dar. Sobald Sie Ihren ersten Merge Request abschließen, werden dessen Daten hier automatisch angezeigt."
...@@ -161,6 +576,9 @@ msgstr "Zeit die für das jeweilige Ereignis in der Phase ermittelt wurde." ...@@ -161,6 +576,9 @@ msgstr "Zeit die für das jeweilige Ereignis in der Phase ermittelt wurde."
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6." msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "Der mittlere aller erfassten Werte. Zum Beispiel ist für 3, 5, 9 der Median 5. Bei 3, 5, 7, 8 ist der Median (5+7)/2 = 6." msgstr "Der mittlere aller erfassten Werte. Zum Beispiel ist für 3, 5, 9 der Median 5. Bei 3, 5, 7, 8 ist der Median (5+7)/2 = 6."
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
msgid "Time before an issue gets scheduled" msgid "Time before an issue gets scheduled"
msgstr "Zeit bis ein Issue geplant wird" msgstr "Zeit bis ein Issue geplant wird"
...@@ -173,6 +591,129 @@ msgstr "Zeit zwischen Anlegen und Mergen/Schließen eines Merge Requests" ...@@ -173,6 +591,129 @@ msgstr "Zeit zwischen Anlegen und Mergen/Schließen eines Merge Requests"
msgid "Time until first merge request" msgid "Time until first merge request"
msgstr "Zeit bis zum ersten Merge Request" msgstr "Zeit bis zum ersten Merge Request"
msgid "Timeago|%s days ago"
msgstr ""
msgid "Timeago|%s days remaining"
msgstr ""
msgid "Timeago|%s hours remaining"
msgstr ""
msgid "Timeago|%s minutes ago"
msgstr ""
msgid "Timeago|%s minutes remaining"
msgstr ""
msgid "Timeago|%s months ago"
msgstr ""
msgid "Timeago|%s months remaining"
msgstr ""
msgid "Timeago|%s seconds remaining"
msgstr ""
msgid "Timeago|%s weeks ago"
msgstr ""
msgid "Timeago|%s weeks remaining"
msgstr ""
msgid "Timeago|%s years ago"
msgstr ""
msgid "Timeago|%s years remaining"
msgstr ""
msgid "Timeago|1 day remaining"
msgstr ""
msgid "Timeago|1 hour remaining"
msgstr ""
msgid "Timeago|1 minute remaining"
msgstr ""
msgid "Timeago|1 month remaining"
msgstr ""
msgid "Timeago|1 week remaining"
msgstr ""
msgid "Timeago|1 year remaining"
msgstr ""
msgid "Timeago|Past due"
msgstr ""
msgid "Timeago|a day ago"
msgstr ""
msgid "Timeago|a month ago"
msgstr ""
msgid "Timeago|a week ago"
msgstr ""
msgid "Timeago|a while"
msgstr ""
msgid "Timeago|a year ago"
msgstr ""
msgid "Timeago|about %s hours ago"
msgstr ""
msgid "Timeago|about a minute ago"
msgstr ""
msgid "Timeago|about an hour ago"
msgstr ""
msgid "Timeago|in %s days"
msgstr ""
msgid "Timeago|in %s hours"
msgstr ""
msgid "Timeago|in %s minutes"
msgstr ""
msgid "Timeago|in %s months"
msgstr ""
msgid "Timeago|in %s seconds"
msgstr ""
msgid "Timeago|in %s weeks"
msgstr ""
msgid "Timeago|in %s years"
msgstr ""
msgid "Timeago|in 1 day"
msgstr ""
msgid "Timeago|in 1 hour"
msgstr ""
msgid "Timeago|in 1 minute"
msgstr ""
msgid "Timeago|in 1 month"
msgstr ""
msgid "Timeago|in 1 week"
msgstr ""
msgid "Timeago|in 1 year"
msgstr ""
msgid "Timeago|less than a minute ago"
msgstr ""
msgid "Time|hr" msgid "Time|hr"
msgid_plural "Time|hrs" msgid_plural "Time|hrs"
msgstr[0] "h" msgstr[0] "h"
...@@ -192,16 +733,88 @@ msgstr "Gesamtzeit" ...@@ -192,16 +733,88 @@ msgstr "Gesamtzeit"
msgid "Total test time for all commits/merges" msgid "Total test time for all commits/merges"
msgstr "Gesamte Testlaufzeit für alle Commits/Merges" msgstr "Gesamte Testlaufzeit für alle Commits/Merges"
msgid "Unstar"
msgstr ""
msgid "Upload New File"
msgstr ""
msgid "Upload file"
msgstr ""
msgid "Use your global notification setting"
msgstr ""
msgid "VisibilityLevel|Internal"
msgstr ""
msgid "VisibilityLevel|Private"
msgstr ""
msgid "VisibilityLevel|Public"
msgstr ""
msgid "Want to see the data? Please ask an administrator for access." msgid "Want to see the data? Please ask an administrator for access."
msgstr "Um diese Daten einsehen zu können, wenden Sie sich bitte an Ihren Administrator." msgstr "Um diese Daten einsehen zu können, wenden Sie sich bitte an Ihren Administrator."
msgid "We don't have enough data to show this stage." msgid "We don't have enough data to show this stage."
msgstr "Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen." msgstr "Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen."
msgid "Withdraw Access Request"
msgstr ""
msgid ""
"You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You can only add files when you are on a branch"
msgstr ""
msgid "You must sign in to star a project"
msgstr ""
msgid "You need permission." msgid "You need permission."
msgstr "Sie benötigen Zugriffsrechte." msgstr "Sie benötigen Zugriffsrechte."
msgid "You will not get any notifications via email"
msgstr ""
msgid "You will only receive notifications for the events you choose"
msgstr ""
msgid "You will only receive notifications for threads you have participated in"
msgstr ""
msgid "You will receive notifications for any activity"
msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
msgstr ""
msgid "Your name"
msgstr ""
msgid "committed"
msgstr ""
msgid "day" msgid "day"
msgid_plural "days" msgid_plural "days"
msgstr[0] "Tag" msgstr[0] "Tag"
msgstr[1] "Tage" msgstr[1] "Tage"
msgid "notification emails"
msgstr ""
...@@ -7,24 +7,170 @@ msgid "" ...@@ -7,24 +7,170 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2017-04-12 22:36-0500\n" "PO-Revision-Date: 2017-06-07 12:14+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English\n" "Language-Team: English\n"
"Language: en\n" "Language: en\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"\n" "Last-Translator: Bob Van Landuyt <bob@gitlab.com>\n"
"X-Generator: Poedit 2.0.2\n"
msgid "About auto deploy"
msgstr ""
msgid "Activity"
msgstr ""
msgid "Add Changelog"
msgstr ""
msgid "Add Contribution guide"
msgstr ""
msgid "Add License"
msgstr ""
msgid "Add an SSH key to your profile to pull or push via SSH."
msgstr ""
msgid "Add new directory"
msgstr ""
msgid "Archived project! Repository is read-only"
msgstr ""
msgid "Branch"
msgid_plural "Branches"
msgstr[0] ""
msgstr[1] ""
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
msgid "Branches"
msgstr ""
msgid "ByAuthor|by" msgid "ByAuthor|by"
msgstr "" msgstr ""
msgid "CI configuration"
msgstr ""
msgid "Changelog"
msgstr ""
msgid "Charts"
msgstr ""
msgid "CiStatusLabel|canceled"
msgstr ""
msgid "CiStatusLabel|created"
msgstr ""
msgid "CiStatusLabel|failed"
msgstr ""
msgid "CiStatusLabel|manual action"
msgstr ""
msgid "CiStatusLabel|passed"
msgstr ""
msgid "CiStatusLabel|passed with warnings"
msgstr ""
msgid "CiStatusLabel|pending"
msgstr ""
msgid "CiStatusLabel|skipped"
msgstr ""
msgid "CiStatusLabel|waiting for manual action"
msgstr ""
msgid "CiStatusText|blocked"
msgstr ""
msgid "CiStatusText|canceled"
msgstr ""
msgid "CiStatusText|created"
msgstr ""
msgid "CiStatusText|failed"
msgstr ""
msgid "CiStatusText|manual"
msgstr ""
msgid "CiStatusText|passed"
msgstr ""
msgid "CiStatusText|pending"
msgstr ""
msgid "CiStatusText|skipped"
msgstr ""
msgid "CiStatus|running"
msgstr ""
msgid "Commit" msgid "Commit"
msgid_plural "Commits" msgid_plural "Commits"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "CommitMessage|Add %{file_name}"
msgstr ""
msgid "Commits"
msgstr ""
msgid "Commits|History"
msgstr ""
msgid "Compare"
msgstr ""
msgid "Contribution guide"
msgstr ""
msgid "Contributors"
msgstr ""
msgid "Copy URL to clipboard"
msgstr ""
msgid "Copy commit SHA to clipboard"
msgstr ""
msgid "Create New Directory"
msgstr ""
msgid "Create directory"
msgstr ""
msgid "Create empty bare repository"
msgstr ""
msgid "Create merge request"
msgstr ""
msgid "CreateNewFork|Fork"
msgstr ""
msgid "Custom notification events"
msgstr ""
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr ""
msgid "Cycle Analytics"
msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project." msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "" msgstr ""
...@@ -54,26 +200,98 @@ msgid_plural "Deploys" ...@@ -54,26 +200,98 @@ msgid_plural "Deploys"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Directory name"
msgstr ""
msgid "Don't show again"
msgstr ""
msgid "Download tar"
msgstr ""
msgid "Download tar.bz2"
msgstr ""
msgid "Download tar.gz"
msgstr ""
msgid "Download zip"
msgstr ""
msgid "DownloadArtifacts|Download"
msgstr ""
msgid "DownloadSource|Download"
msgstr ""
msgid "Files"
msgstr ""
msgid "Find by path"
msgstr ""
msgid "Find file"
msgstr ""
msgid "FirstPushedBy|First" msgid "FirstPushedBy|First"
msgstr "" msgstr ""
msgid "FirstPushedBy|pushed by" msgid "FirstPushedBy|pushed by"
msgstr "" msgstr ""
msgid "ForkedFromProjectPath|Forked from"
msgstr ""
msgid "Forks"
msgstr ""
msgid "From issue creation until deploy to production" msgid "From issue creation until deploy to production"
msgstr "" msgstr ""
msgid "From merge request merge until deploy to production" msgid "From merge request merge until deploy to production"
msgstr "" msgstr ""
msgid "Go to your fork"
msgstr ""
msgid "GoToYourFork|Fork"
msgstr ""
msgid "Home"
msgstr ""
msgid "Housekeeping successfully started"
msgstr ""
msgid "Import repository"
msgstr ""
msgid "Introducing Cycle Analytics" msgid "Introducing Cycle Analytics"
msgstr "" msgstr ""
msgid "LFSStatus|Disabled"
msgstr ""
msgid "LFSStatus|Enabled"
msgstr ""
msgid "Last %d day" msgid "Last %d day"
msgid_plural "Last %d days" msgid_plural "Last %d days"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Last Update"
msgstr ""
msgid "Last commit"
msgstr ""
msgid "Leave group"
msgstr ""
msgid "Leave project"
msgstr ""
msgid "Limited to showing %d event at most" msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most" msgid_plural "Limited to showing %d events at most"
msgstr[0] "" msgstr[0] ""
...@@ -82,29 +300,167 @@ msgstr[1] "" ...@@ -82,29 +300,167 @@ msgstr[1] ""
msgid "Median" msgid "Median"
msgstr "" msgstr ""
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr ""
msgid "New Issue" msgid "New Issue"
msgid_plural "New Issues" msgid_plural "New Issues"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "New branch"
msgstr ""
msgid "New directory"
msgstr ""
msgid "New file"
msgstr ""
msgid "New issue"
msgstr ""
msgid "New merge request"
msgstr ""
msgid "New snippet"
msgstr ""
msgid "New tag"
msgstr ""
msgid "No repository"
msgstr ""
msgid "Not available" msgid "Not available"
msgstr "" msgstr ""
msgid "Not enough data" msgid "Not enough data"
msgstr "" msgstr ""
msgid "Notification events"
msgstr ""
msgid "NotificationEvent|Close issue"
msgstr ""
msgid "NotificationEvent|Close merge request"
msgstr ""
msgid "NotificationEvent|Failed pipeline"
msgstr ""
msgid "NotificationEvent|Merge merge request"
msgstr ""
msgid "NotificationEvent|New issue"
msgstr ""
msgid "NotificationEvent|New merge request"
msgstr ""
msgid "NotificationEvent|New note"
msgstr ""
msgid "NotificationEvent|Reassign issue"
msgstr ""
msgid "NotificationEvent|Reassign merge request"
msgstr ""
msgid "NotificationEvent|Reopen issue"
msgstr ""
msgid "NotificationEvent|Successful pipeline"
msgstr ""
msgid "NotificationLevel|Custom"
msgstr ""
msgid "NotificationLevel|Disabled"
msgstr ""
msgid "NotificationLevel|Global"
msgstr ""
msgid "NotificationLevel|On mention"
msgstr ""
msgid "NotificationLevel|Participate"
msgstr ""
msgid "NotificationLevel|Watch"
msgstr ""
msgid "OpenedNDaysAgo|Opened" msgid "OpenedNDaysAgo|Opened"
msgstr "" msgstr ""
msgid "Pipeline Health" msgid "Pipeline Health"
msgstr "" msgstr ""
msgid "Project '%{project_name}' queued for deletion."
msgstr ""
msgid "Project '%{project_name}' was successfully created."
msgstr ""
msgid "Project '%{project_name}' was successfully updated."
msgstr ""
msgid "Project '%{project_name}' will be deleted."
msgstr ""
msgid "Project access must be granted explicitly to each user."
msgstr ""
msgid "Project export could not be deleted."
msgstr ""
msgid "Project export has been deleted."
msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
msgid "Project export started. A download link will be sent by email."
msgstr ""
msgid "Project home"
msgstr ""
msgid "ProjectFeature|Disabled"
msgstr ""
msgid "ProjectFeature|Everyone with access"
msgstr ""
msgid "ProjectFeature|Only team members"
msgstr ""
msgid "ProjectFileTree|Name"
msgstr ""
msgid "ProjectLastActivity|Never"
msgstr ""
msgid "ProjectLifecycle|Stage" msgid "ProjectLifecycle|Stage"
msgstr "" msgstr ""
msgid "ProjectNetworkGraph|Graph"
msgstr ""
msgid "Read more" msgid "Read more"
msgstr "" msgstr ""
msgid "Readme"
msgstr ""
msgid "RefSwitcher|Branches"
msgstr ""
msgid "RefSwitcher|Tags"
msgstr ""
msgid "Related Commits" msgid "Related Commits"
msgstr "" msgstr ""
...@@ -123,17 +479,67 @@ msgstr "" ...@@ -123,17 +479,67 @@ msgstr ""
msgid "Related Merged Requests" msgid "Related Merged Requests"
msgstr "" msgstr ""
msgid "Remind later"
msgstr ""
msgid "Remove project"
msgstr ""
msgid "Request Access"
msgstr ""
msgid "Search branches and tags"
msgstr ""
msgid "Select Archive Format"
msgstr ""
msgid "Set a password on your account to pull or push via %{protocol}"
msgstr ""
msgid "Set up CI"
msgstr ""
msgid "Set up Koding"
msgstr ""
msgid "Set up auto deploy"
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
msgstr ""
msgid "Showing %d event" msgid "Showing %d event"
msgid_plural "Showing %d events" msgid_plural "Showing %d events"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Source code"
msgstr ""
msgid "StarProject|Star"
msgstr ""
msgid "Switch branch/tag"
msgstr ""
msgid "Tag"
msgid_plural "Tags"
msgstr[0] ""
msgstr[1] ""
msgid "Tags"
msgstr ""
msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request." msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
msgstr "" msgstr ""
msgid "The collection of events added to the data gathered for that stage." msgid "The collection of events added to the data gathered for that stage."
msgstr "" msgstr ""
msgid "The fork relationship has been removed."
msgstr ""
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage." msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr "" msgstr ""
...@@ -146,6 +552,15 @@ msgstr "" ...@@ -146,6 +552,15 @@ msgstr ""
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle." msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr "" msgstr ""
msgid "The project can be accessed by any logged in user."
msgstr ""
msgid "The project can be accessed without any authentication."
msgstr ""
msgid "The repository for this project does not exist."
msgstr ""
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request." msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr "" msgstr ""
...@@ -161,6 +576,9 @@ msgstr "" ...@@ -161,6 +576,9 @@ msgstr ""
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6." msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "" msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
msgid "Time before an issue gets scheduled" msgid "Time before an issue gets scheduled"
msgstr "" msgstr ""
...@@ -173,6 +591,129 @@ msgstr "" ...@@ -173,6 +591,129 @@ msgstr ""
msgid "Time until first merge request" msgid "Time until first merge request"
msgstr "" msgstr ""
msgid "Timeago|%s days ago"
msgstr ""
msgid "Timeago|%s days remaining"
msgstr ""
msgid "Timeago|%s hours remaining"
msgstr ""
msgid "Timeago|%s minutes ago"
msgstr ""
msgid "Timeago|%s minutes remaining"
msgstr ""
msgid "Timeago|%s months ago"
msgstr ""
msgid "Timeago|%s months remaining"
msgstr ""
msgid "Timeago|%s seconds remaining"
msgstr ""
msgid "Timeago|%s weeks ago"
msgstr ""
msgid "Timeago|%s weeks remaining"
msgstr ""
msgid "Timeago|%s years ago"
msgstr ""
msgid "Timeago|%s years remaining"
msgstr ""
msgid "Timeago|1 day remaining"
msgstr ""
msgid "Timeago|1 hour remaining"
msgstr ""
msgid "Timeago|1 minute remaining"
msgstr ""
msgid "Timeago|1 month remaining"
msgstr ""
msgid "Timeago|1 week remaining"
msgstr ""
msgid "Timeago|1 year remaining"
msgstr ""
msgid "Timeago|Past due"
msgstr ""
msgid "Timeago|a day ago"
msgstr ""
msgid "Timeago|a month ago"
msgstr ""
msgid "Timeago|a week ago"
msgstr ""
msgid "Timeago|a while"
msgstr ""
msgid "Timeago|a year ago"
msgstr ""
msgid "Timeago|about %s hours ago"
msgstr ""
msgid "Timeago|about a minute ago"
msgstr ""
msgid "Timeago|about an hour ago"
msgstr ""
msgid "Timeago|in %s days"
msgstr ""
msgid "Timeago|in %s hours"
msgstr ""
msgid "Timeago|in %s minutes"
msgstr ""
msgid "Timeago|in %s months"
msgstr ""
msgid "Timeago|in %s seconds"
msgstr ""
msgid "Timeago|in %s weeks"
msgstr ""
msgid "Timeago|in %s years"
msgstr ""
msgid "Timeago|in 1 day"
msgstr ""
msgid "Timeago|in 1 hour"
msgstr ""
msgid "Timeago|in 1 minute"
msgstr ""
msgid "Timeago|in 1 month"
msgstr ""
msgid "Timeago|in 1 week"
msgstr ""
msgid "Timeago|in 1 year"
msgstr ""
msgid "Timeago|less than a minute ago"
msgstr ""
msgid "Time|hr" msgid "Time|hr"
msgid_plural "Time|hrs" msgid_plural "Time|hrs"
msgstr[0] "" msgstr[0] ""
...@@ -192,16 +733,88 @@ msgstr "" ...@@ -192,16 +733,88 @@ msgstr ""
msgid "Total test time for all commits/merges" msgid "Total test time for all commits/merges"
msgstr "" msgstr ""
msgid "Unstar"
msgstr ""
msgid "Upload New File"
msgstr ""
msgid "Upload file"
msgstr ""
msgid "Use your global notification setting"
msgstr ""
msgid "VisibilityLevel|Internal"
msgstr ""
msgid "VisibilityLevel|Private"
msgstr ""
msgid "VisibilityLevel|Public"
msgstr ""
msgid "Want to see the data? Please ask an administrator for access." msgid "Want to see the data? Please ask an administrator for access."
msgstr "" msgstr ""
msgid "We don't have enough data to show this stage." msgid "We don't have enough data to show this stage."
msgstr "" msgstr ""
msgid "Withdraw Access Request"
msgstr ""
msgid ""
"You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You can only add files when you are on a branch"
msgstr ""
msgid "You must sign in to star a project"
msgstr ""
msgid "You need permission." msgid "You need permission."
msgstr "" msgstr ""
msgid "You will not get any notifications via email"
msgstr ""
msgid "You will only receive notifications for the events you choose"
msgstr ""
msgid "You will only receive notifications for threads you have participated in"
msgstr ""
msgid "You will receive notifications for any activity"
msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
msgstr ""
msgid "Your name"
msgstr ""
msgid "committed"
msgstr ""
msgid "day" msgid "day"
msgid_plural "days" msgid_plural "days"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "notification emails"
msgstr ""
...@@ -7,24 +7,170 @@ msgid "" ...@@ -7,24 +7,170 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2017-05-20 22:37-0500\n" "PO-Revision-Date: 2017-06-07 12:29-0500\n"
"Language-Team: Spanish\n" "Language-Team: Spanish\n"
"Language: es\n" "Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"Last-Translator: \n" "Last-Translator: Bob Van Landuyt <bob@gitlab.com>\n"
"X-Generator: Poedit 2.0.1\n" "X-Generator: Poedit 2.0.2\n"
msgid "About auto deploy"
msgstr "Acerca del auto despliegue"
msgid "Activity"
msgstr "Actividad"
msgid "Add Changelog"
msgstr "Agregar Changelog"
msgid "Add Contribution guide"
msgstr "Agregar guía de contribución"
msgid "Add License"
msgstr "Agregar Licencia"
msgid "Add an SSH key to your profile to pull or push via SSH."
msgstr "Agregar una clave SSH a tu perfil para actualizar o enviar a través de SSH."
msgid "Add new directory"
msgstr "Agregar nuevo directorio"
msgid "Archived project! Repository is read-only"
msgstr "¡Proyecto archivado! El repositorio es de sólo lectura"
msgid "Branch"
msgid_plural "Branches"
msgstr[0] "Rama"
msgstr[1] "Ramas"
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr "La rama <strong>%{branch_name}</strong> fue creada. Para configurar el auto despliegue, escoge una plantilla Yaml para GitLab CI y envía tus cambios. %{link_to_autodeploy_doc}"
msgid "Branches"
msgstr "Ramas"
msgid "ByAuthor|by" msgid "ByAuthor|by"
msgstr "por" msgstr "por"
msgid "CI configuration"
msgstr "Configuración de CI"
msgid "Changelog"
msgstr "Changelog"
msgid "Charts"
msgstr "Gráficos"
msgid "CiStatusLabel|canceled"
msgstr "cancelado"
msgid "CiStatusLabel|created"
msgstr "creado"
msgid "CiStatusLabel|failed"
msgstr "fallado"
msgid "CiStatusLabel|manual action"
msgstr "acción manual"
msgid "CiStatusLabel|passed"
msgstr "pasó"
msgid "CiStatusLabel|passed with warnings"
msgstr "pasó con advertencias"
msgid "CiStatusLabel|pending"
msgstr "pendiente"
msgid "CiStatusLabel|skipped"
msgstr "omitido"
msgid "CiStatusLabel|waiting for manual action"
msgstr "esperando acción manual"
msgid "CiStatusText|blocked"
msgstr "bloqueado"
msgid "CiStatusText|canceled"
msgstr "cancelado"
msgid "CiStatusText|created"
msgstr "creado"
msgid "CiStatusText|failed"
msgstr "fallado"
msgid "CiStatusText|manual"
msgstr "manual"
msgid "CiStatusText|passed"
msgstr "pasó"
msgid "CiStatusText|pending"
msgstr "pendiente"
msgid "CiStatusText|skipped"
msgstr "omitido"
msgid "CiStatus|running"
msgstr "en ejecución"
msgid "Commit" msgid "Commit"
msgid_plural "Commits" msgid_plural "Commits"
msgstr[0] "Cambio" msgstr[0] "Cambio"
msgstr[1] "Cambios" msgstr[1] "Cambios"
msgid "CommitMessage|Add %{file_name}"
msgstr "Agregar %{file_name}"
msgid "Commits"
msgstr "Cambios"
msgid "Commits|History"
msgstr "Historial"
msgid "Compare"
msgstr "Comparar"
msgid "Contribution guide"
msgstr "Guía de contribución"
msgid "Contributors"
msgstr "Contribuidores"
msgid "Copy URL to clipboard"
msgstr "Copiar URL al portapapeles"
msgid "Copy commit SHA to clipboard"
msgstr "Copiar SHA del cambio al portapapeles"
msgid "Create New Directory"
msgstr "Crear Nuevo Directorio"
msgid "Create directory"
msgstr "Crear directorio"
msgid "Create empty bare repository"
msgstr "Crear repositorio vacío"
msgid "Create merge request"
msgstr "Crear solicitud de fusión"
msgid "CreateNewFork|Fork"
msgstr "Bifurcar"
msgid "Custom notification events"
msgstr "Eventos de notificaciones personalizadas"
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr "Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."
msgid "Cycle Analytics"
msgstr "Cycle Analytics"
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project." msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto." msgstr "Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."
...@@ -43,7 +189,6 @@ msgstr "Producción" ...@@ -43,7 +189,6 @@ msgstr "Producción"
msgid "CycleAnalyticsStage|Review" msgid "CycleAnalyticsStage|Review"
msgstr "Revisión" msgstr "Revisión"
#, fuzzy
msgid "CycleAnalyticsStage|Staging" msgid "CycleAnalyticsStage|Staging"
msgstr "Puesta en escena" msgstr "Puesta en escena"
...@@ -55,26 +200,98 @@ msgid_plural "Deploys" ...@@ -55,26 +200,98 @@ msgid_plural "Deploys"
msgstr[0] "Despliegue" msgstr[0] "Despliegue"
msgstr[1] "Despliegues" msgstr[1] "Despliegues"
msgid "Directory name"
msgstr "Nombre del directorio"
msgid "Don't show again"
msgstr "No mostrar de nuevo"
msgid "Download tar"
msgstr "Descargar tar"
msgid "Download tar.bz2"
msgstr "Descargar tar.bz2"
msgid "Download tar.gz"
msgstr "Descargar tar.gz"
msgid "Download zip"
msgstr "Descargar zip"
msgid "DownloadArtifacts|Download"
msgstr "Descargar"
msgid "DownloadSource|Download"
msgstr "Descargar"
msgid "Files"
msgstr "Archivos"
msgid "Find by path"
msgstr "Buscar por ruta"
msgid "Find file"
msgstr "Buscar archivo"
msgid "FirstPushedBy|First" msgid "FirstPushedBy|First"
msgstr "Primer" msgstr "Primer"
msgid "FirstPushedBy|pushed by" msgid "FirstPushedBy|pushed by"
msgstr "enviado por" msgstr "enviado por"
msgid "ForkedFromProjectPath|Forked from"
msgstr "Bifurcado de"
msgid "Forks"
msgstr "Bifurcaciones"
msgid "From issue creation until deploy to production" msgid "From issue creation until deploy to production"
msgstr "Desde la creación de la incidencia hasta el despliegue a producción" msgstr "Desde la creación de la incidencia hasta el despliegue a producción"
msgid "From merge request merge until deploy to production" msgid "From merge request merge until deploy to production"
msgstr "Desde la integración de la solicitud de fusión hasta el despliegue a producción" msgstr "Desde la integración de la solicitud de fusión hasta el despliegue a producción"
msgid "Go to your fork"
msgstr "Ir a tu bifurcación"
msgid "GoToYourFork|Fork"
msgstr "Bifurcación"
msgid "Home"
msgstr "Inicio"
msgid "Housekeeping successfully started"
msgstr "Servicio de limpieza iniciado con éxito"
msgid "Import repository"
msgstr "Importar repositorio"
msgid "Introducing Cycle Analytics" msgid "Introducing Cycle Analytics"
msgstr "Introducción a Cycle Analytics" msgstr "Introducción a Cycle Analytics"
msgid "LFSStatus|Disabled"
msgstr "Deshabilitado"
msgid "LFSStatus|Enabled"
msgstr "Habilitado"
msgid "Last %d day" msgid "Last %d day"
msgid_plural "Last %d days" msgid_plural "Last %d days"
msgstr[0] "Último %d día" msgstr[0] "Último %d día"
msgstr[1] "Últimos %d días" msgstr[1] "Últimos %d días"
msgid "Last Update"
msgstr "Última actualización"
msgid "Last commit"
msgstr "Último cambio"
msgid "Leave group"
msgstr "Abandonar grupo"
msgid "Leave project"
msgstr "Abandonar proyecto"
msgid "Limited to showing %d event at most" msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most" msgid_plural "Limited to showing %d events at most"
msgstr[0] "Limitado a mostrar máximo %d evento" msgstr[0] "Limitado a mostrar máximo %d evento"
...@@ -83,29 +300,167 @@ msgstr[1] "Limitado a mostrar máximo %d eventos" ...@@ -83,29 +300,167 @@ msgstr[1] "Limitado a mostrar máximo %d eventos"
msgid "Median" msgid "Median"
msgstr "Mediana" msgstr "Mediana"
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr "agregar una clave SSH"
msgid "New Issue" msgid "New Issue"
msgid_plural "New Issues" msgid_plural "New Issues"
msgstr[0] "Nueva incidencia" msgstr[0] "Nueva incidencia"
msgstr[1] "Nuevas incidencias" msgstr[1] "Nuevas incidencias"
msgid "New branch"
msgstr "Nueva rama"
msgid "New directory"
msgstr "Nuevo directorio"
msgid "New file"
msgstr "Nuevo archivo"
msgid "New issue"
msgstr "Nueva incidencia"
msgid "New merge request"
msgstr "Nueva solicitud de fusión"
msgid "New snippet"
msgstr "Nuevo fragmento de código"
msgid "New tag"
msgstr "Nueva etiqueta"
msgid "No repository"
msgstr "No hay repositorio"
msgid "Not available" msgid "Not available"
msgstr "No disponible" msgstr "No disponible"
msgid "Not enough data" msgid "Not enough data"
msgstr "No hay suficientes datos" msgstr "No hay suficientes datos"
msgid "Notification events"
msgstr "Eventos de notificación"
msgid "NotificationEvent|Close issue"
msgstr "Cerrar incidencia"
msgid "NotificationEvent|Close merge request"
msgstr "Cerrar solicitud de fusión"
msgid "NotificationEvent|Failed pipeline"
msgstr "Pipeline fallido"
msgid "NotificationEvent|Merge merge request"
msgstr "Integrar solicitud de fusión"
msgid "NotificationEvent|New issue"
msgstr "Nueva incidencia"
msgid "NotificationEvent|New merge request"
msgstr "Nueva solicitud de fusión"
msgid "NotificationEvent|New note"
msgstr "Nueva nota"
msgid "NotificationEvent|Reassign issue"
msgstr "Reasignar incidencia"
msgid "NotificationEvent|Reassign merge request"
msgstr "Reasignar solicitud de fusión"
msgid "NotificationEvent|Reopen issue"
msgstr "Reabrir incidencia"
msgid "NotificationEvent|Successful pipeline"
msgstr "Pipeline exitoso"
msgid "NotificationLevel|Custom"
msgstr "Personalizado"
msgid "NotificationLevel|Disabled"
msgstr "Deshabilitado"
msgid "NotificationLevel|Global"
msgstr "Global"
msgid "NotificationLevel|On mention"
msgstr "Cuando me mencionan"
msgid "NotificationLevel|Participate"
msgstr "Participación"
msgid "NotificationLevel|Watch"
msgstr "Vigilancia"
msgid "OpenedNDaysAgo|Opened" msgid "OpenedNDaysAgo|Opened"
msgstr "Abierto" msgstr "Abierto"
msgid "Pipeline Health" msgid "Pipeline Health"
msgstr "Estado del Pipeline" msgstr "Estado del Pipeline"
msgid "Project '%{project_name}' queued for deletion."
msgstr "Proyecto ‘%{project_name}’ en cola para eliminación."
msgid "Project '%{project_name}' was successfully created."
msgstr "Proyecto ‘%{project_name}’ fue creado satisfactoriamente."
msgid "Project '%{project_name}' was successfully updated."
msgstr "Proyecto ‘%{project_name}’ fue actualizado satisfactoriamente."
msgid "Project '%{project_name}' will be deleted."
msgstr "Proyecto ‘%{project_name}’ será eliminado."
msgid "Project access must be granted explicitly to each user."
msgstr "El acceso al proyecto debe concederse explícitamente a cada usuario."
msgid "Project export could not be deleted."
msgstr "No se pudo eliminar la exportación del proyecto."
msgid "Project export has been deleted."
msgstr "La exportación del proyecto ha sido eliminada."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "El enlace de exportación del proyecto ha caducado. Por favor, genera una nueva exportación desde la configuración del proyecto."
msgid "Project export started. A download link will be sent by email."
msgstr "Se inició la exportación del proyecto. Se enviará un enlace de descarga por correo electrónico."
msgid "Project home"
msgstr "Inicio del proyecto"
msgid "ProjectFeature|Disabled"
msgstr "Deshabilitada"
msgid "ProjectFeature|Everyone with access"
msgstr "Todos con acceso"
msgid "ProjectFeature|Only team members"
msgstr "Solo miembros del equipo"
msgid "ProjectFileTree|Name"
msgstr "Nombre"
msgid "ProjectLastActivity|Never"
msgstr "Nunca"
msgid "ProjectLifecycle|Stage" msgid "ProjectLifecycle|Stage"
msgstr "Etapa" msgstr "Etapa"
msgid "ProjectNetworkGraph|Graph"
msgstr "Historial gráfico"
msgid "Read more" msgid "Read more"
msgstr "Leer más" msgstr "Leer más"
msgid "Readme"
msgstr "Readme"
msgid "RefSwitcher|Branches"
msgstr "Ramas"
msgid "RefSwitcher|Tags"
msgstr "Etiquetas"
msgid "Related Commits" msgid "Related Commits"
msgstr "Cambios Relacionados" msgstr "Cambios Relacionados"
...@@ -124,17 +479,67 @@ msgstr "Solicitudes de fusión Relacionadas" ...@@ -124,17 +479,67 @@ msgstr "Solicitudes de fusión Relacionadas"
msgid "Related Merged Requests" msgid "Related Merged Requests"
msgstr "Solicitudes de fusión Relacionadas" msgstr "Solicitudes de fusión Relacionadas"
msgid "Remind later"
msgstr "Recordar después"
msgid "Remove project"
msgstr "Eliminar proyecto"
msgid "Request Access"
msgstr "Solicitar acceso"
msgid "Search branches and tags"
msgstr "Buscar ramas y etiquetas"
msgid "Select Archive Format"
msgstr "Seleccionar formato de archivo"
msgid "Set a password on your account to pull or push via %{protocol}"
msgstr "Establezca una contraseña en su cuenta para actualizar o enviar a través de% {protocol}"
msgid "Set up CI"
msgstr "Configurar CI"
msgid "Set up Koding"
msgstr "Configurar Koding"
msgid "Set up auto deploy"
msgstr "Configurar auto despliegue"
msgid "SetPasswordToCloneLink|set a password"
msgstr "establecer una contraseña"
msgid "Showing %d event" msgid "Showing %d event"
msgid_plural "Showing %d events" msgid_plural "Showing %d events"
msgstr[0] "Mostrando %d evento" msgstr[0] "Mostrando %d evento"
msgstr[1] "Mostrando %d eventos" msgstr[1] "Mostrando %d eventos"
msgid "Source code"
msgstr "Código fuente"
msgid "StarProject|Star"
msgstr "Destacar"
msgid "Switch branch/tag"
msgstr "Cambiar rama/etiqueta"
msgid "Tag"
msgid_plural "Tags"
msgstr[0] "Etiqueta"
msgstr[1] "Etiquetas"
msgid "Tags"
msgstr "Etiquetas"
msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request." msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
msgstr "La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión." msgstr "La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."
msgid "The collection of events added to the data gathered for that stage." msgid "The collection of events added to the data gathered for that stage."
msgstr "La colección de eventos agregados a los datos recopilados para esa etapa." msgstr "La colección de eventos agregados a los datos recopilados para esa etapa."
msgid "The fork relationship has been removed."
msgstr "La relación con la bifurcación se ha eliminado."
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage." msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr "La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa." msgstr "La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa."
...@@ -147,6 +552,15 @@ msgstr "La etapa de planificación muestra el tiempo desde el paso anterior hast ...@@ -147,6 +552,15 @@ msgstr "La etapa de planificación muestra el tiempo desde el paso anterior hast
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle." msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr "La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción." msgstr "La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción."
msgid "The project can be accessed by any logged in user."
msgstr "El proyecto puede ser accedido por cualquier usuario conectado."
msgid "The project can be accessed without any authentication."
msgstr "El proyecto puede accederse sin ninguna autenticación."
msgid "The repository for this project does not exist."
msgstr "El repositorio para este proyecto no existe."
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request." msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr "La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión." msgstr "La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión."
...@@ -162,6 +576,9 @@ msgstr "El tiempo utilizado por cada entrada de datos obtenido por esa etapa." ...@@ -162,6 +576,9 @@ msgstr "El tiempo utilizado por cada entrada de datos obtenido por esa etapa."
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6." msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6." msgstr "El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6."
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Esto significa que no puede enviar código hasta que cree un repositorio vacío o importe uno existente."
msgid "Time before an issue gets scheduled" msgid "Time before an issue gets scheduled"
msgstr "Tiempo antes de que una incidencia sea programada" msgstr "Tiempo antes de que una incidencia sea programada"
...@@ -174,6 +591,129 @@ msgstr "Tiempo entre la creación de la solicitud de fusión y la integración o ...@@ -174,6 +591,129 @@ msgstr "Tiempo entre la creación de la solicitud de fusión y la integración o
msgid "Time until first merge request" msgid "Time until first merge request"
msgstr "Tiempo hasta la primera solicitud de fusión" msgstr "Tiempo hasta la primera solicitud de fusión"
msgid "Timeago|%s days ago"
msgstr "hace %s días"
msgid "Timeago|%s days remaining"
msgstr "%s días restantes"
msgid "Timeago|%s hours remaining"
msgstr "%s horas restantes"
msgid "Timeago|%s minutes ago"
msgstr "hace %s minutos"
msgid "Timeago|%s minutes remaining"
msgstr "%s minutos restantes"
msgid "Timeago|%s months ago"
msgstr "hace %s meses"
msgid "Timeago|%s months remaining"
msgstr "%s meses restantes"
msgid "Timeago|%s seconds remaining"
msgstr "%s segundos restantes"
msgid "Timeago|%s weeks ago"
msgstr "hace %s semanas"
msgid "Timeago|%s weeks remaining"
msgstr "%s semanas restantes"
msgid "Timeago|%s years ago"
msgstr "hace %s años"
msgid "Timeago|%s years remaining"
msgstr "%s años restantes"
msgid "Timeago|1 day remaining"
msgstr "1 día restante"
msgid "Timeago|1 hour remaining"
msgstr "1 hora restante"
msgid "Timeago|1 minute remaining"
msgstr "1 minuto restante"
msgid "Timeago|1 month remaining"
msgstr "1 mes restante"
msgid "Timeago|1 week remaining"
msgstr "1 semana restante"
msgid "Timeago|1 year remaining"
msgstr "1 año restante"
msgid "Timeago|Past due"
msgstr "Atrasado"
msgid "Timeago|a day ago"
msgstr "hace un día"
msgid "Timeago|a month ago"
msgstr "hace 1 mes"
msgid "Timeago|a week ago"
msgstr "hace 1 semana"
msgid "Timeago|a while"
msgstr "hace un momento"
msgid "Timeago|a year ago"
msgstr "hace 1 año"
msgid "Timeago|about %s hours ago"
msgstr "hace alrededor de %s horas"
msgid "Timeago|about a minute ago"
msgstr "hace alrededor de 1 minuto"
msgid "Timeago|about an hour ago"
msgstr "hace alrededor de 1 hora"
msgid "Timeago|in %s days"
msgstr "en %s días"
msgid "Timeago|in %s hours"
msgstr "en %s horas"
msgid "Timeago|in %s minutes"
msgstr "en %s minutos"
msgid "Timeago|in %s months"
msgstr "en %s meses"
msgid "Timeago|in %s seconds"
msgstr "en %s segundos"
msgid "Timeago|in %s weeks"
msgstr "en %s semanas"
msgid "Timeago|in %s years"
msgstr "en %s años"
msgid "Timeago|in 1 day"
msgstr "en 1 día"
msgid "Timeago|in 1 hour"
msgstr "en 1 hora"
msgid "Timeago|in 1 minute"
msgstr "en 1 minuto"
msgid "Timeago|in 1 month"
msgstr "en 1 mes"
msgid "Timeago|in 1 week"
msgstr "en 1 semana"
msgid "Timeago|in 1 year"
msgstr "en 1 año"
msgid "Timeago|less than a minute ago"
msgstr "hace menos de 1 minuto"
msgid "Time|hr" msgid "Time|hr"
msgid_plural "Time|hrs" msgid_plural "Time|hrs"
msgstr[0] "hr" msgstr[0] "hr"
...@@ -193,16 +733,91 @@ msgstr "Tiempo Total" ...@@ -193,16 +733,91 @@ msgstr "Tiempo Total"
msgid "Total test time for all commits/merges" msgid "Total test time for all commits/merges"
msgstr "Tiempo total de pruebas para todos los cambios o integraciones" msgstr "Tiempo total de pruebas para todos los cambios o integraciones"
msgid "Unstar"
msgstr "No Destacar"
msgid "Upload New File"
msgstr "Subir nuevo archivo"
msgid "Upload file"
msgstr "Subir archivo"
msgid "Use your global notification setting"
msgstr "Utiliza tu configuración de notificación global"
msgid "VisibilityLevel|Internal"
msgstr "Interno"
msgid "VisibilityLevel|Private"
msgstr "Privado"
msgid "VisibilityLevel|Public"
msgstr "Público"
msgid "Want to see the data? Please ask an administrator for access." msgid "Want to see the data? Please ask an administrator for access."
msgstr "¿Quieres ver los datos? Por favor pide acceso al administrador." msgstr "¿Quieres ver los datos? Por favor pide acceso al administrador."
msgid "We don't have enough data to show this stage." msgid "We don't have enough data to show this stage."
msgstr "No hay suficientes datos para mostrar en esta etapa." msgstr "No hay suficientes datos para mostrar en esta etapa."
msgid "Withdraw Access Request"
msgstr "Retirar Solicitud de Acceso"
msgid ""
"You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
"Va a eliminar %{project_name_with_namespace}.\n"
"¡El proyecto eliminado NO puede ser restaurado!\n"
"¿Estás TOTALMENTE seguro?"
msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr "Vas a eliminar el enlace de la bifurcación con el proyecto original %{forked_from_project}. ¿Estás TOTALMENTE seguro?"
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr "Vas a transferir %{project_name_with_namespace} a otro propietario. ¿Estás TOTALMENTE seguro?"
msgid "You can only add files when you are on a branch"
msgstr "Sólo puede agregar archivos cuando estas en una rama"
msgid "You must sign in to star a project"
msgstr "Debes iniciar sesión para destacar un proyecto"
msgid "You need permission." msgid "You need permission."
msgstr "Necesitas permisos." msgstr "Necesitas permisos."
msgid "You will not get any notifications via email"
msgstr "No recibirás ninguna notificación por correo electrónico"
msgid "You will only receive notifications for the events you choose"
msgstr "Solo recibirás notificaciones de los eventos que elijas"
msgid "You will only receive notifications for threads you have participated in"
msgstr "Solo recibirás notificaciones de los temas en los que has participado"
msgid "You will receive notifications for any activity"
msgstr "Recibirás notificaciones para cualquier actividad"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Recibirás notificaciones sólo para los comentarios en los que se te mencionó"
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"
msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
msgstr "No podrás actualizar o enviar código al proyecto a través de SSH hasta que %{add_ssh_key_link} en su perfil"
msgid "Your name"
msgstr "Tu nombre"
msgid "committed"
msgstr "cambió"
msgid "day" msgid "day"
msgid_plural "days" msgid_plural "days"
msgstr[0] "día" msgstr[0] "día"
msgstr[1] "días" msgstr[1] "días"
msgid "notification emails"
msgstr "correos electrónicos de notificación"
...@@ -8,8 +8,8 @@ msgid "" ...@@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-04 19:24-0500\n" "POT-Creation-Date: 2017-06-07 17:36+0200\n"
"PO-Revision-Date: 2017-05-04 19:24-0500\n" "PO-Revision-Date: 2017-06-07 17:36+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
...@@ -18,14 +18,160 @@ msgstr "" ...@@ -18,14 +18,160 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
msgid "About auto deploy"
msgstr ""
msgid "Activity"
msgstr ""
msgid "Add Changelog"
msgstr ""
msgid "Add Contribution guide"
msgstr ""
msgid "Add License"
msgstr ""
msgid "Add an SSH key to your profile to pull or push via SSH."
msgstr ""
msgid "Add new directory"
msgstr ""
msgid "Archived project! Repository is read-only"
msgstr ""
msgid "Branch"
msgid_plural "Branches"
msgstr[0] ""
msgstr[1] ""
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
msgid "Branches"
msgstr ""
msgid "ByAuthor|by" msgid "ByAuthor|by"
msgstr "" msgstr ""
msgid "CI configuration"
msgstr ""
msgid "Changelog"
msgstr ""
msgid "Charts"
msgstr ""
msgid "CiStatusLabel|canceled"
msgstr ""
msgid "CiStatusLabel|created"
msgstr ""
msgid "CiStatusLabel|failed"
msgstr ""
msgid "CiStatusLabel|manual action"
msgstr ""
msgid "CiStatusLabel|passed"
msgstr ""
msgid "CiStatusLabel|passed with warnings"
msgstr ""
msgid "CiStatusLabel|pending"
msgstr ""
msgid "CiStatusLabel|skipped"
msgstr ""
msgid "CiStatusLabel|waiting for manual action"
msgstr ""
msgid "CiStatusText|blocked"
msgstr ""
msgid "CiStatusText|canceled"
msgstr ""
msgid "CiStatusText|created"
msgstr ""
msgid "CiStatusText|failed"
msgstr ""
msgid "CiStatusText|manual"
msgstr ""
msgid "CiStatusText|passed"
msgstr ""
msgid "CiStatusText|pending"
msgstr ""
msgid "CiStatusText|skipped"
msgstr ""
msgid "CiStatus|running"
msgstr ""
msgid "Commit" msgid "Commit"
msgid_plural "Commits" msgid_plural "Commits"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "CommitMessage|Add %{file_name}"
msgstr ""
msgid "Commits"
msgstr ""
msgid "Commits|History"
msgstr ""
msgid "Compare"
msgstr ""
msgid "Contribution guide"
msgstr ""
msgid "Contributors"
msgstr ""
msgid "Copy URL to clipboard"
msgstr ""
msgid "Copy commit SHA to clipboard"
msgstr ""
msgid "Create New Directory"
msgstr ""
msgid "Create directory"
msgstr ""
msgid "Create empty bare repository"
msgstr ""
msgid "Create merge request"
msgstr ""
msgid "CreateNewFork|Fork"
msgstr ""
msgid "Custom notification events"
msgstr ""
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr ""
msgid "Cycle Analytics"
msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project." msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "" msgstr ""
...@@ -55,26 +201,98 @@ msgid_plural "Deploys" ...@@ -55,26 +201,98 @@ msgid_plural "Deploys"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Directory name"
msgstr ""
msgid "Don't show again"
msgstr ""
msgid "Download tar"
msgstr ""
msgid "Download tar.bz2"
msgstr ""
msgid "Download tar.gz"
msgstr ""
msgid "Download zip"
msgstr ""
msgid "DownloadArtifacts|Download"
msgstr ""
msgid "DownloadSource|Download"
msgstr ""
msgid "Files"
msgstr ""
msgid "Find by path"
msgstr ""
msgid "Find file"
msgstr ""
msgid "FirstPushedBy|First" msgid "FirstPushedBy|First"
msgstr "" msgstr ""
msgid "FirstPushedBy|pushed by" msgid "FirstPushedBy|pushed by"
msgstr "" msgstr ""
msgid "ForkedFromProjectPath|Forked from"
msgstr ""
msgid "Forks"
msgstr ""
msgid "From issue creation until deploy to production" msgid "From issue creation until deploy to production"
msgstr "" msgstr ""
msgid "From merge request merge until deploy to production" msgid "From merge request merge until deploy to production"
msgstr "" msgstr ""
msgid "Go to your fork"
msgstr ""
msgid "GoToYourFork|Fork"
msgstr ""
msgid "Home"
msgstr ""
msgid "Housekeeping successfully started"
msgstr ""
msgid "Import repository"
msgstr ""
msgid "Introducing Cycle Analytics" msgid "Introducing Cycle Analytics"
msgstr "" msgstr ""
msgid "LFSStatus|Disabled"
msgstr ""
msgid "LFSStatus|Enabled"
msgstr ""
msgid "Last %d day" msgid "Last %d day"
msgid_plural "Last %d days" msgid_plural "Last %d days"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Last Update"
msgstr ""
msgid "Last commit"
msgstr ""
msgid "Leave group"
msgstr ""
msgid "Leave project"
msgstr ""
msgid "Limited to showing %d event at most" msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most" msgid_plural "Limited to showing %d events at most"
msgstr[0] "" msgstr[0] ""
...@@ -83,29 +301,167 @@ msgstr[1] "" ...@@ -83,29 +301,167 @@ msgstr[1] ""
msgid "Median" msgid "Median"
msgstr "" msgstr ""
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr ""
msgid "New Issue" msgid "New Issue"
msgid_plural "New Issues" msgid_plural "New Issues"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "New branch"
msgstr ""
msgid "New directory"
msgstr ""
msgid "New file"
msgstr ""
msgid "New issue"
msgstr ""
msgid "New merge request"
msgstr ""
msgid "New snippet"
msgstr ""
msgid "New tag"
msgstr ""
msgid "No repository"
msgstr ""
msgid "Not available" msgid "Not available"
msgstr "" msgstr ""
msgid "Not enough data" msgid "Not enough data"
msgstr "" msgstr ""
msgid "Notification events"
msgstr ""
msgid "NotificationEvent|Close issue"
msgstr ""
msgid "NotificationEvent|Close merge request"
msgstr ""
msgid "NotificationEvent|Failed pipeline"
msgstr ""
msgid "NotificationEvent|Merge merge request"
msgstr ""
msgid "NotificationEvent|New issue"
msgstr ""
msgid "NotificationEvent|New merge request"
msgstr ""
msgid "NotificationEvent|New note"
msgstr ""
msgid "NotificationEvent|Reassign issue"
msgstr ""
msgid "NotificationEvent|Reassign merge request"
msgstr ""
msgid "NotificationEvent|Reopen issue"
msgstr ""
msgid "NotificationEvent|Successful pipeline"
msgstr ""
msgid "NotificationLevel|Custom"
msgstr ""
msgid "NotificationLevel|Disabled"
msgstr ""
msgid "NotificationLevel|Global"
msgstr ""
msgid "NotificationLevel|On mention"
msgstr ""
msgid "NotificationLevel|Participate"
msgstr ""
msgid "NotificationLevel|Watch"
msgstr ""
msgid "OpenedNDaysAgo|Opened" msgid "OpenedNDaysAgo|Opened"
msgstr "" msgstr ""
msgid "Pipeline Health" msgid "Pipeline Health"
msgstr "" msgstr ""
msgid "Project '%{project_name}' queued for deletion."
msgstr ""
msgid "Project '%{project_name}' was successfully created."
msgstr ""
msgid "Project '%{project_name}' was successfully updated."
msgstr ""
msgid "Project '%{project_name}' will be deleted."
msgstr ""
msgid "Project access must be granted explicitly to each user."
msgstr ""
msgid "Project export could not be deleted."
msgstr ""
msgid "Project export has been deleted."
msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
msgid "Project export started. A download link will be sent by email."
msgstr ""
msgid "Project home"
msgstr ""
msgid "ProjectFeature|Disabled"
msgstr ""
msgid "ProjectFeature|Everyone with access"
msgstr ""
msgid "ProjectFeature|Only team members"
msgstr ""
msgid "ProjectFileTree|Name"
msgstr ""
msgid "ProjectLastActivity|Never"
msgstr ""
msgid "ProjectLifecycle|Stage" msgid "ProjectLifecycle|Stage"
msgstr "" msgstr ""
msgid "ProjectNetworkGraph|Graph"
msgstr ""
msgid "Read more" msgid "Read more"
msgstr "" msgstr ""
msgid "Readme"
msgstr ""
msgid "RefSwitcher|Branches"
msgstr ""
msgid "RefSwitcher|Tags"
msgstr ""
msgid "Related Commits" msgid "Related Commits"
msgstr "" msgstr ""
...@@ -124,17 +480,67 @@ msgstr "" ...@@ -124,17 +480,67 @@ msgstr ""
msgid "Related Merged Requests" msgid "Related Merged Requests"
msgstr "" msgstr ""
msgid "Remind later"
msgstr ""
msgid "Remove project"
msgstr ""
msgid "Request Access"
msgstr ""
msgid "Search branches and tags"
msgstr ""
msgid "Select Archive Format"
msgstr ""
msgid "Set a password on your account to pull or push via %{protocol}"
msgstr ""
msgid "Set up CI"
msgstr ""
msgid "Set up Koding"
msgstr ""
msgid "Set up auto deploy"
msgstr ""
msgid "SetPasswordToCloneLink|set a password"
msgstr ""
msgid "Showing %d event" msgid "Showing %d event"
msgid_plural "Showing %d events" msgid_plural "Showing %d events"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "Source code"
msgstr ""
msgid "StarProject|Star"
msgstr ""
msgid "Switch branch/tag"
msgstr ""
msgid "Tag"
msgid_plural "Tags"
msgstr[0] ""
msgstr[1] ""
msgid "Tags"
msgstr ""
msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request." msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
msgstr "" msgstr ""
msgid "The collection of events added to the data gathered for that stage." msgid "The collection of events added to the data gathered for that stage."
msgstr "" msgstr ""
msgid "The fork relationship has been removed."
msgstr ""
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage." msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr "" msgstr ""
...@@ -147,6 +553,15 @@ msgstr "" ...@@ -147,6 +553,15 @@ msgstr ""
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle." msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr "" msgstr ""
msgid "The project can be accessed by any logged in user."
msgstr ""
msgid "The project can be accessed without any authentication."
msgstr ""
msgid "The repository for this project does not exist."
msgstr ""
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request." msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr "" msgstr ""
...@@ -162,6 +577,9 @@ msgstr "" ...@@ -162,6 +577,9 @@ msgstr ""
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6." msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "" msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
msgid "Time before an issue gets scheduled" msgid "Time before an issue gets scheduled"
msgstr "" msgstr ""
...@@ -174,6 +592,129 @@ msgstr "" ...@@ -174,6 +592,129 @@ msgstr ""
msgid "Time until first merge request" msgid "Time until first merge request"
msgstr "" msgstr ""
msgid "Timeago|%s days ago"
msgstr ""
msgid "Timeago|%s days remaining"
msgstr ""
msgid "Timeago|%s hours remaining"
msgstr ""
msgid "Timeago|%s minutes ago"
msgstr ""
msgid "Timeago|%s minutes remaining"
msgstr ""
msgid "Timeago|%s months ago"
msgstr ""
msgid "Timeago|%s months remaining"
msgstr ""
msgid "Timeago|%s seconds remaining"
msgstr ""
msgid "Timeago|%s weeks ago"
msgstr ""
msgid "Timeago|%s weeks remaining"
msgstr ""
msgid "Timeago|%s years ago"
msgstr ""
msgid "Timeago|%s years remaining"
msgstr ""
msgid "Timeago|1 day remaining"
msgstr ""
msgid "Timeago|1 hour remaining"
msgstr ""
msgid "Timeago|1 minute remaining"
msgstr ""
msgid "Timeago|1 month remaining"
msgstr ""
msgid "Timeago|1 week remaining"
msgstr ""
msgid "Timeago|1 year remaining"
msgstr ""
msgid "Timeago|Past due"
msgstr ""
msgid "Timeago|a day ago"
msgstr ""
msgid "Timeago|a month ago"
msgstr ""
msgid "Timeago|a week ago"
msgstr ""
msgid "Timeago|a while"
msgstr ""
msgid "Timeago|a year ago"
msgstr ""
msgid "Timeago|about %s hours ago"
msgstr ""
msgid "Timeago|about a minute ago"
msgstr ""
msgid "Timeago|about an hour ago"
msgstr ""
msgid "Timeago|in %s days"
msgstr ""
msgid "Timeago|in %s hours"
msgstr ""
msgid "Timeago|in %s minutes"
msgstr ""
msgid "Timeago|in %s months"
msgstr ""
msgid "Timeago|in %s seconds"
msgstr ""
msgid "Timeago|in %s weeks"
msgstr ""
msgid "Timeago|in %s years"
msgstr ""
msgid "Timeago|in 1 day"
msgstr ""
msgid "Timeago|in 1 hour"
msgstr ""
msgid "Timeago|in 1 minute"
msgstr ""
msgid "Timeago|in 1 month"
msgstr ""
msgid "Timeago|in 1 week"
msgstr ""
msgid "Timeago|in 1 year"
msgstr ""
msgid "Timeago|less than a minute ago"
msgstr ""
msgid "Time|hr" msgid "Time|hr"
msgid_plural "Time|hrs" msgid_plural "Time|hrs"
msgstr[0] "" msgstr[0] ""
...@@ -193,16 +734,88 @@ msgstr "" ...@@ -193,16 +734,88 @@ msgstr ""
msgid "Total test time for all commits/merges" msgid "Total test time for all commits/merges"
msgstr "" msgstr ""
msgid "Unstar"
msgstr ""
msgid "Upload New File"
msgstr ""
msgid "Upload file"
msgstr ""
msgid "Use your global notification setting"
msgstr ""
msgid "VisibilityLevel|Internal"
msgstr ""
msgid "VisibilityLevel|Private"
msgstr ""
msgid "VisibilityLevel|Public"
msgstr ""
msgid "Want to see the data? Please ask an administrator for access." msgid "Want to see the data? Please ask an administrator for access."
msgstr "" msgstr ""
msgid "We don't have enough data to show this stage." msgid "We don't have enough data to show this stage."
msgstr "" msgstr ""
msgid "Withdraw Access Request"
msgstr ""
msgid ""
"You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr ""
msgid "You can only add files when you are on a branch"
msgstr ""
msgid "You must sign in to star a project"
msgstr ""
msgid "You need permission." msgid "You need permission."
msgstr "" msgstr ""
msgid "You will not get any notifications via email"
msgstr ""
msgid "You will only receive notifications for the events you choose"
msgstr ""
msgid "You will only receive notifications for threads you have participated in"
msgstr ""
msgid "You will receive notifications for any activity"
msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
msgstr ""
msgid "Your name"
msgstr ""
msgid "committed"
msgstr ""
msgid "day" msgid "day"
msgid_plural "days" msgid_plural "days"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "notification emails"
msgstr ""
require('spec_helper')
describe ProfilesController do
describe "PUT update" do
it "allows an email update from a user without an external email address" do
user = create(:user)
sign_in(user)
put :update,
user: { email: "john@gmail.com", name: "John" }
user.reload
expect(response.status).to eq(302)
expect(user.unconfirmed_email).to eq('john@gmail.com')
end
it "ignores an email update from a user with an external email address" do
ldap_user = create(:omniauth_user, external_email: true)
sign_in(ldap_user)
put :update,
user: { email: "john@gmail.com", name: "John" }
ldap_user.reload
expect(response.status).to eq(302)
expect(ldap_user.unconfirmed_email).not_to eq('john@gmail.com')
end
end
end
...@@ -284,18 +284,13 @@ describe Projects::MergeRequestsController do ...@@ -284,18 +284,13 @@ describe Projects::MergeRequestsController do
context 'number of queries' do context 'number of queries' do
it 'verifies number of queries' do it 'verifies number of queries' do
RequestStore.begin!
# pre-create objects # pre-create objects
merge_request merge_request
recorded = ActiveRecord::QueryRecorder.new { go(format: :json) } recorded = ActiveRecord::QueryRecorder.new { go(format: :json) }
expect(recorded.count).to be_within(1).of(31) expect(recorded.count).to be_within(10).of(100)
expect(recorded.cached_count).to eq(0) expect(recorded.cached_count).to eq(0)
RequestStore.end!
RequestStore.clear!
end end
end end
end end
......
FactoryGirl.define do
factory :issue_link do
source factory: :issue
target factory: :issue
end
end
...@@ -56,11 +56,10 @@ describe 'Admin::AuditLogs', feature: true, js: true do ...@@ -56,11 +56,10 @@ describe 'Admin::AuditLogs', feature: true, js: true do
end end
describe 'project events' do describe 'project events' do
let(:project) { create(:empty_project) }
let(:project_member) { create(:project_member, user: user) } let(:project_member) { create(:project_member, user: user) }
before do before do
AuditEventService.new(user, project, { action: :destroy }). AuditEventService.new(user, project_member.project, { action: :destroy }).
for_member(project_member).security_event for_member(project_member).security_event
visit admin_audit_logs_path visit admin_audit_logs_path
......
...@@ -17,10 +17,10 @@ feature "New project", feature: true do ...@@ -17,10 +17,10 @@ feature "New project", feature: true do
expect(find_field("project_visibility_level_#{level}")).to be_checked expect(find_field("project_visibility_level_#{level}")).to be_checked
end end
it 'saves visibility level on validation error' do it "saves visibility level #{level} on validation error" do
visit new_project_path visit new_project_path
choose(key) choose(s_(key))
click_button('Create project') click_button('Create project')
expect(find_field("project_visibility_level_#{level}")).to be_checked expect(find_field("project_visibility_level_#{level}")).to be_checked
......
...@@ -288,18 +288,6 @@ describe IssuesFinder do ...@@ -288,18 +288,6 @@ describe IssuesFinder do
expect(issues.count).to eq 0 expect(issues.count).to eq 0
end end
it 'returns disabled issues if feature_availability_check param set to false' do
[project1, project2].each do |project|
project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED)
end
issues = described_class
.new(search_user, params.reverse_merge(scope: scope, state: 'opened', feature_availability_check: false))
.execute
expect(issues.count).to eq 3
end
end end
end end
......
...@@ -12,5 +12,11 @@ describe NotificationsHelper do ...@@ -12,5 +12,11 @@ describe NotificationsHelper do
describe 'notification_title' do describe 'notification_title' do
it { expect(notification_title(:watch)).to match('Watch') } it { expect(notification_title(:watch)).to match('Watch') }
it { expect(notification_title(:mention)).to match('On mention') } it { expect(notification_title(:mention)).to match('On mention') }
it { expect(notification_title(:global)).to match('Global') }
end
describe '#notification_event_name' do
it { expect(notification_event_name(:success_pipeline)).to match('Successful pipeline') }
it { expect(notification_event_name(:failed_pipeline)).to match('Failed pipeline') }
end end
end end
require 'rails_helper'
describe ProfilesHelper do
describe '#email_provider_label' do
it "returns nil for users without external email" do
user = create(:user)
allow(helper).to receive(:current_user).and_return(user)
expect(helper.email_provider_label).to be_nil
end
it "returns omniauth provider label for users with external email" do
stub_cas_omniauth_provider
cas_user = create(:omniauth_user, provider: 'cas3', external_email: true, email_provider: 'cas3')
allow(helper).to receive(:current_user).and_return(cas_user)
expect(helper.email_provider_label).to eq('CAS')
end
it "returns 'LDAP' for users with external email but no email provider" do
ldap_user = create(:omniauth_user, external_email: true)
allow(helper).to receive(:current_user).and_return(ldap_user)
expect(helper.email_provider_label).to eq('LDAP')
end
end
def stub_cas_omniauth_provider
provider = OpenStruct.new(
'name' => 'cas3',
'label' => 'CAS'
)
stub_omniauth_setting(providers: [provider])
end
end
...@@ -58,7 +58,7 @@ describe('Build', () => { ...@@ -58,7 +58,7 @@ describe('Build', () => {
it('displays the remove date correctly', () => { it('displays the remove date correctly', () => {
const removeDateElement = document.querySelector('.js-artifacts-remove'); const removeDateElement = document.querySelector('.js-artifacts-remove');
expect(removeDateElement.innerText.trim()).toBe('1 year'); expect(removeDateElement.innerText.trim()).toBe('1 year remaining');
}); });
}); });
......
...@@ -2,6 +2,26 @@ import '~/lib/utils/datetime_utility'; ...@@ -2,6 +2,26 @@ import '~/lib/utils/datetime_utility';
(() => { (() => {
describe('Date time utils', () => { describe('Date time utils', () => {
describe('timeFor', () => {
it('returns `past due` when in past', () => {
const date = new Date();
date.setFullYear(date.getFullYear() - 1);
expect(
gl.utils.timeFor(date),
).toBe('Past due');
});
it('returns remaining time when in the future', () => {
const date = new Date();
date.setFullYear(date.getFullYear() + 1);
expect(
gl.utils.timeFor(date),
).toBe('1 year remaining');
});
});
describe('get day name', () => { describe('get day name', () => {
it('should return Sunday', () => { it('should return Sunday', () => {
const day = gl.utils.getDayName(new Date('07/17/2016')); const day = gl.utils.getDayName(new Date('07/17/2016'));
......
...@@ -8,14 +8,14 @@ describe Gitlab::LDAP::Access, lib: true do ...@@ -8,14 +8,14 @@ describe Gitlab::LDAP::Access, lib: true do
describe '#find_ldap_user' do describe '#find_ldap_user' do
it 'finds a user by dn first' do it 'finds a user by dn first' do
expect(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(:ldap_user) expect(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(:ldap_user)
expect(user).not_to receive(:ldap_email?) expect(user).not_to receive(:external_email?)
access.find_ldap_user access.find_ldap_user
end end
it 'finds a user by email if the email came from LDAP' do it 'finds a user by email if the email came from LDAP' do
expect(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(nil) expect(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(nil)
expect(user).to receive(:ldap_email?).and_return(true) expect(user).to receive(:external_email?).and_return(true)
expect(Gitlab::LDAP::Person).to receive(:find_by_email) expect(Gitlab::LDAP::Person).to receive(:find_by_email)
access.find_ldap_user access.find_ldap_user
......
...@@ -37,7 +37,7 @@ describe Gitlab::LDAP::User, lib: true do ...@@ -37,7 +37,7 @@ describe Gitlab::LDAP::User, lib: true do
end end
it "does not mark existing ldap user as changed" do it "does not mark existing ldap user as changed" do
create(:omniauth_user, email: 'john@example.com', extern_uid: 'my-uid', provider: 'ldapmain', ldap_email: true) create(:omniauth_user, email: 'john@example.com', extern_uid: 'my-uid', provider: 'ldapmain', external_email: true, email_provider: 'ldapmain')
expect(ldap_user.changed?).to be_falsey expect(ldap_user.changed?).to be_falsey
end end
end end
...@@ -141,8 +141,12 @@ describe Gitlab::LDAP::User, lib: true do ...@@ -141,8 +141,12 @@ describe Gitlab::LDAP::User, lib: true do
expect(ldap_user.gl_user.email).to eq(info[:email]) expect(ldap_user.gl_user.email).to eq(info[:email])
end end
it "has ldap_email set to true" do it "has external_email set to true" do
expect(ldap_user.gl_user.ldap_email?).to be(true) expect(ldap_user.gl_user.external_email?).to be(true)
end
it "has email_provider set to provider" do
expect(ldap_user.gl_user.email_provider).to eql 'ldapmain'
end end
end end
...@@ -155,8 +159,8 @@ describe Gitlab::LDAP::User, lib: true do ...@@ -155,8 +159,8 @@ describe Gitlab::LDAP::User, lib: true do
expect(ldap_user.gl_user.temp_oauth_email?).to be(true) expect(ldap_user.gl_user.temp_oauth_email?).to be(true)
end end
it "has ldap_email set to false" do it "has external_email set to false" do
expect(ldap_user.gl_user.ldap_email?).to be(false) expect(ldap_user.gl_user.external_email?).to be(false)
end end
end end
end end
......
...@@ -28,11 +28,11 @@ describe Gitlab::OAuth::User, lib: true do ...@@ -28,11 +28,11 @@ describe Gitlab::OAuth::User, lib: true do
end end
end end
describe '#save' do def stub_omniauth_config(messages)
def stub_omniauth_config(messages) allow(Gitlab.config.omniauth).to receive_messages(messages)
allow(Gitlab.config.omniauth).to receive_messages(messages) end
end
describe '#save' do
def stub_ldap_config(messages) def stub_ldap_config(messages)
allow(Gitlab::LDAP::Config).to receive_messages(messages) allow(Gitlab::LDAP::Config).to receive_messages(messages)
end end
...@@ -377,4 +377,40 @@ describe Gitlab::OAuth::User, lib: true do ...@@ -377,4 +377,40 @@ describe Gitlab::OAuth::User, lib: true do
end end
end end
end end
describe 'updating email' do
let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') }
before do
stub_omniauth_config(sync_email_from_provider: 'my-provider')
end
context "when provider sets an email" do
it "updates the user email" do
expect(gl_user.email).to eq(info_hash[:email])
end
it "has external_email set to true" do
expect(gl_user.external_email?).to be(true)
end
it "has email_provider set to provider" do
expect(gl_user.email_provider).to eql 'my-provider'
end
end
context "when provider doesn't set an email" do
before do
info_hash.delete(:email)
end
it "does not update the user email" do
expect(gl_user.email).not_to eq(info_hash[:email])
end
it "has external_email set to false" do
expect(gl_user.external_email?).to be(false)
end
end
end
end end
require 'spec_helper'
describe IssueLink do
describe 'Associations' do
it { is_expected.to belong_to(:source).class_name('Issue') }
it { is_expected.to belong_to(:target).class_name('Issue') }
end
describe 'Validation' do
subject { create :issue_link }
it { is_expected.to validate_presence_of(:source) }
it { is_expected.to validate_presence_of(:target) }
it do
is_expected.to validate_uniqueness_of(:source)
.scoped_to(:target_id)
.with_message(/already related/)
end
context 'self relation' do
let(:issue) { create :issue }
context 'cannot be validated' do
it 'does not invalidate object with self relation error' do
issue_link = build :issue_link, source: issue, target: nil
issue_link.valid?
expect(issue_link.errors[:source]).to be_empty
end
end
context 'can be invalidated' do
it 'invalidates object' do
issue_link = build :issue_link, source: issue, target: issue
expect(issue_link).to be_invalid
expect(issue_link.errors[:source]).to include('cannot be related to itself')
end
end
end
end
end
...@@ -10,14 +10,10 @@ describe ProjectPolicy, models: true do ...@@ -10,14 +10,10 @@ describe ProjectPolicy, models: true do
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
let(:project) { create(:empty_project, :public, namespace: owner.namespace) } let(:project) { create(:empty_project, :public, namespace: owner.namespace) }
before do
allow_any_instance_of(License).to receive(:feature_available?) { true }
end
let(:guest_permissions) do let(:guest_permissions) do
%i[ %i[
read_project read_board read_list read_wiki read_issue read_label read_project read_board read_list read_wiki read_issue read_label
read_issue_link read_milestone read_project_snippet read_project_member read_milestone read_project_snippet read_project_member
read_note create_project create_issue create_note read_note create_project create_issue create_note
upload_file upload_file
] ]
...@@ -26,7 +22,7 @@ describe ProjectPolicy, models: true do ...@@ -26,7 +22,7 @@ describe ProjectPolicy, models: true do
let(:reporter_permissions) do let(:reporter_permissions) do
%i[ %i[
download_code fork_project create_project_snippet update_issue download_code fork_project create_project_snippet update_issue
admin_issue admin_label admin_issue_link admin_list read_commit_status read_build admin_issue admin_label admin_list read_commit_status read_build
read_container_image read_pipeline read_environment read_deployment read_container_image read_pipeline read_environment read_deployment
read_merge_request download_wiki_code read_merge_request download_wiki_code
] ]
...@@ -75,7 +71,7 @@ describe ProjectPolicy, models: true do ...@@ -75,7 +71,7 @@ describe ProjectPolicy, models: true do
let(:auditor_permissions) do let(:auditor_permissions) do
%i[ %i[
download_code download_wiki_code read_project read_board read_list download_code download_wiki_code read_project read_board read_list
read_wiki read_issue read_label read_issue_link read_milestone read_project_snippet read_wiki read_issue read_label read_milestone read_project_snippet
read_project_member read_note read_cycle_analytics read_pipeline read_project_member read_note read_cycle_analytics read_pipeline
read_build read_commit_status read_container_image read_environment read_build read_commit_status read_container_image read_environment
read_deployment read_merge_request read_pages read_deployment read_merge_request read_pages
......
require 'rails_helper'
describe Projects::IssueLinksController do
let(:user) { create :user }
let(:project) { create(:project_empty_repo) }
let(:issue) { create :issue, project: project }
before do
allow_any_instance_of(License).to receive(:feature_available?) { false }
allow_any_instance_of(License).to receive(:feature_available?).with(:related_issues) { true }
end
describe 'GET /*namespace_id/:project_id/issues/:issue_id/links' do
let(:issue_b) { create :issue, project: project }
let!(:issue_link) { create :issue_link, source: issue, target: issue_b }
before do
project.team << [user, :guest]
login_as user
end
it 'returns JSON response' do
list_service_response = IssueLinks::ListService.new(issue, user).execute
get namespace_project_issue_links_path(issue_links_params)
expect(response).to have_http_status(200)
expect(json_response).to eq(list_service_response.as_json)
end
end
describe 'POST /*namespace_id/:project_id/issues/:issue_id/links' do
let(:issue_b) { create :issue, project: project }
before do
project.team << [user, user_role]
login_as user
end
context 'with success' do
let(:user_role) { :developer }
let(:issue_references) { [issue_b.to_reference] }
it 'returns success JSON' do
post namespace_project_issue_links_path(issue_links_params(issue_references: issue_references))
list_service_response = IssueLinks::ListService.new(issue, user).execute
expect(response).to have_http_status(200)
expect(json_response).to eq('message' => nil,
'issues' => list_service_response.as_json)
end
end
context 'with failure' do
context 'when unauthorized' do
let(:user_role) { :guest }
let(:issue_references) { [issue_b.to_reference] }
it 'returns 403' do
post namespace_project_issue_links_path(issue_links_params(issue_references: issue_references))
expect(response).to have_http_status(403)
end
end
context 'when failing service result' do
let(:user_role) { :developer }
let(:issue_references) { ['#999'] }
it 'returns failure JSON' do
post namespace_project_issue_links_path(issue_links_params(issue_references: issue_references))
list_service_response = IssueLinks::ListService.new(issue, user).execute
expect(response).to have_http_status(401)
expect(json_response).to eq('message' => 'No Issue found for given reference', 'issues' => list_service_response.as_json)
end
end
end
end
describe 'DELETE /*namespace_id/:project_id/issues/:issue_id/link/:id' do
let(:issue_link) { create :issue_link, target: referenced_issue }
before do
project.team << [user, user_role]
login_as user
end
context 'when unauthorized' do
context 'when no authorization on current project' do
let(:referenced_issue) { create :issue, project: project }
let(:user_role) { :guest }
it 'returns 403' do
delete namespace_project_issue_link_path(issue_links_params(id: issue_link.id))
expect(response).to have_http_status(403)
end
end
context 'when no authorization on the related issue project' do
# unauthorized project issue
let(:referenced_issue) { create :issue }
let(:user_role) { :developer }
it 'returns 403' do
delete namespace_project_issue_link_path(issue_links_params(id: issue_link.id))
expect(response).to have_http_status(403)
end
end
end
context 'when authorized' do
let(:referenced_issue) { create :issue, project: project }
let(:user_role) { :developer }
it 'returns success JSON' do
delete namespace_project_issue_link_path(issue_links_params(id: issue_link.id))
list_service_response = IssueLinks::ListService.new(issue, user).execute
expect(json_response).to eq('issues' => list_service_response.as_json)
end
end
end
def issue_links_params(opts = {})
opts.reverse_merge(namespace_id: issue.project.namespace,
project_id: issue.project,
issue_id: issue,
format: :json)
end
end
require 'spec_helper'
describe IssueLinks::CreateService, service: true do
describe '#execute' do
let(:namespace) { create :namespace }
let(:project) { create :empty_project, namespace: namespace }
let(:issue) { create :issue, project: project }
let(:user) { create :user }
let(:params) do
{}
end
before do
allow_any_instance_of(License).to receive(:feature_available?) { false }
allow_any_instance_of(License).to receive(:feature_available?).with(:related_issues) { true }
project.team << [user, :developer]
end
subject { described_class.new(issue, user, params).execute }
context 'when the reference list is empty' do
let(:params) do
{ issue_references: [] }
end
it 'returns error' do
is_expected.to eq(message: 'No Issue found for given reference', status: :error, http_status: 401)
end
end
context 'when Issue not found' do
let(:params) do
{ issue_references: ['#999'] }
end
it 'returns error' do
is_expected.to eq(message: 'No Issue found for given reference', status: :error, http_status: 401)
end
it 'no relationship is created' do
expect { subject }.not_to change(IssueLink, :count)
end
end
context 'when user has no permission to target project Issue' do
let(:target_issue) { create :issue }
let(:params) do
{ issue_references: [target_issue.to_reference(project)] }
end
it 'returns error' do
target_issue.project.add_guest(user)
is_expected.to eq(message: 'No Issue found for given reference', status: :error, http_status: 401)
end
it 'no relationship is created' do
expect { subject }.not_to change(IssueLink, :count)
end
end
context 'when there is an issue to relate' do
let(:issue_a) { create :issue, project: project }
let(:another_project) { create :empty_project, namespace: project.namespace }
let(:another_project_issue) { create :issue, project: another_project }
let(:issue_a_ref) { issue_a.to_reference }
let(:another_project_issue_ref) { another_project_issue.to_reference(project) }
let(:params) do
{ issue_references: [issue_a_ref, another_project_issue_ref] }
end
before do
another_project.team << [user, :developer]
end
it 'creates relationships' do
expect { subject }.to change(IssueLink, :count).from(0).to(2)
expect(IssueLink.find_by!(target: issue_a)).to have_attributes(source: issue)
expect(IssueLink.find_by!(target: another_project_issue)).to have_attributes(source: issue)
end
it 'returns success status' do
is_expected.to eq(status: :success)
end
it 'creates notes' do
# First two-way relation notes
expect(SystemNoteService).to receive(:relate_issue)
.with(issue, issue_a, user)
expect(SystemNoteService).to receive(:relate_issue)
.with(issue_a, issue, user)
# Second two-way relation notes
expect(SystemNoteService).to receive(:relate_issue)
.with(issue, another_project_issue, user)
expect(SystemNoteService).to receive(:relate_issue)
.with(another_project_issue, issue, user)
subject
end
end
context 'when reference of any already related issue is present' do
let(:issue_a) { create :issue, project: project }
let(:issue_b) { create :issue, project: project }
before do
create :issue_link, source: issue, target: issue_a
end
let(:params) do
{ issue_references: [issue_b.to_reference, issue_a.to_reference] }
end
it 'returns success status' do
is_expected.to eq(status: :success)
end
it 'valid relations are created' do
expect { subject }.to change(IssueLink, :count).from(1).to(2)
expect(IssueLink.find_by!(target: issue_b)).to have_attributes(source: issue)
end
end
end
end
require 'spec_helper'
describe IssueLinks::DestroyService, service: true do
describe '#execute' do
let(:user) { create :user }
let!(:issue_link) { create :issue_link }
subject { described_class.new(issue_link, user).execute }
it 'removes related issue' do
expect { subject }.to change(IssueLink, :count).from(1).to(0)
end
it 'creates notes' do
# Two-way notes creation
expect(SystemNoteService).to receive(:unrelate_issue)
.with(issue_link.source, issue_link.target, user)
expect(SystemNoteService).to receive(:unrelate_issue)
.with(issue_link.target, issue_link.source, user)
subject
end
it 'returns success message' do
is_expected.to eq(message: 'Relation was removed', status: :success)
end
end
end
require 'spec_helper'
describe IssueLinks::ListService, service: true do
let(:user) { create :user }
let(:project) { create(:project_empty_repo, :private) }
let(:issue) { create :issue, project: project }
let(:user_role) { :developer }
before do
allow_any_instance_of(License).to receive(:feature_available?) { false }
allow_any_instance_of(License).to receive(:feature_available?).with(:related_issues) { true }
project.team << [user, user_role]
end
describe '#execute' do
subject { described_class.new(issue, user).execute }
context 'user can see all issues' do
let(:issue_b) { create :issue, project: project }
let(:issue_c) { create :issue, project: project }
let(:issue_d) { create :issue, project: project }
let!(:issue_link_c) do
create(:issue_link, source: issue_d,
target: issue)
end
let!(:issue_link_b) do
create(:issue_link, source: issue,
target: issue_c)
end
let!(:issue_link_a) do
create(:issue_link, source: issue,
target: issue_b)
end
it 'ensures no N+1 queries are made' do
control_count = ActiveRecord::QueryRecorder.new { subject }.count
project = create :empty_project, :public
issue_x = create :issue, project: project
issue_y = create :issue, project: project
issue_z = create :issue, project: project
create :issue_link, source: issue_x, target: issue_y
create :issue_link, source: issue_x, target: issue_z
create :issue_link, source: issue_y, target: issue_z
expect { subject }.not_to exceed_query_limit(control_count)
end
it 'returns related issues JSON' do
expect(subject.size).to eq(3)
expect(subject).to include(include(id: issue_b.id,
iid: issue_b.iid,
title: issue_b.title,
state: issue_b.state,
path: "/#{project.full_path}/issues/#{issue_b.iid}",
project_path: issue_b.project.path,
namespace_full_path: issue_b.project.namespace.full_path,
destroy_relation_path: "/#{project.full_path}/issues/#{issue.iid}/links/#{issue_link_a.id}"))
expect(subject).to include(include(id: issue_c.id,
iid: issue_c.iid,
title: issue_c.title,
state: issue_c.state,
path: "/#{project.full_path}/issues/#{issue_c.iid}",
project_path: issue_c.project.path,
namespace_full_path: issue_c.project.namespace.full_path,
destroy_relation_path: "/#{project.full_path}/issues/#{issue.iid}/links/#{issue_link_b.id}"))
expect(subject).to include(include(id: issue_d.id,
iid: issue_d.iid,
title: issue_d.title,
state: issue_d.state,
path: "/#{project.full_path}/issues/#{issue_d.iid}",
project_path: issue_d.project.path,
namespace_full_path: issue_d.project.namespace.full_path,
destroy_relation_path: "/#{project.full_path}/issues/#{issue.iid}/links/#{issue_link_c.id}"))
end
end
context 'referencing a public project issue' do
let(:public_project) { create :empty_project, :public }
let(:issue_b) { create :issue, project: public_project }
let!(:issue_link) do
create(:issue_link, source: issue, target: issue_b)
end
it 'presents issue' do
expect(subject.size).to eq(1)
end
end
context 'referencing issue with removed relationships' do
context 'when referenced a deleted issue' do
let(:issue_b) { create :issue, project: project }
let!(:issue_link) do
create(:issue_link, source: issue, target: issue_b)
end
it 'ignores issue' do
issue_b.destroy!
is_expected.to eq([])
end
end
context 'when referenced an issue with deleted project' do
let(:issue_b) { create :issue, project: project }
let!(:issue_link) do
create(:issue_link, source: issue, target: issue_b)
end
it 'ignores issue' do
project.destroy!
is_expected.to eq([])
end
end
context 'when referenced an issue with deleted namespace' do
let(:issue_b) { create :issue, project: project }
let!(:issue_link) do
create(:issue_link, source: issue, target: issue_b)
end
it 'ignores issue' do
project.namespace.destroy!
is_expected.to eq([])
end
end
end
context 'user cannot see relations' do
context 'when user cannot see the referenced issue' do
let!(:issue_link) do
create(:issue_link, source: issue)
end
it 'returns an empty list' do
is_expected.to eq([])
end
end
context 'when user cannot see the issue that referenced' do
let!(:issue_link) do
create(:issue_link, target: issue)
end
it 'returns an empty list' do
is_expected.to eq([])
end
end
end
context 'remove relations' do
let!(:issue_link) do
create(:issue_link, source: issue, target: referenced_issue)
end
context 'user can admin related issues just on target project' do
let(:user_role) { :guest }
let(:target_project) { create :empty_project }
let(:referenced_issue) { create :issue, project: target_project }
it 'returns no destroy relation path' do
target_project.add_developer(user)
expect(subject.first[:destroy_relation_path]).to be_nil
end
end
context 'user can admin related issues just on source project' do
let(:user_role) { :developer }
let(:target_project) { create :empty_project }
let(:referenced_issue) { create :issue, project: target_project }
it 'returns no destroy relation path' do
target_project.add_guest(user)
expect(subject.first[:destroy_relation_path]).to be_nil
end
end
context 'when user can admin related issues on both projects' do
let(:referenced_issue) { create :issue, project: project }
it 'returns related issue destroy relation path' do
expect(subject.first[:destroy_relation_path])
.to eq("/#{project.full_path}/issues/#{issue.iid}/links/#{issue_link.id}")
end
end
end
end
end
...@@ -139,7 +139,7 @@ describe Projects::CreateService, '#execute', services: true do ...@@ -139,7 +139,7 @@ describe Projects::CreateService, '#execute', services: true do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
opts.merge!( opts.merge!(
visibility_level: Gitlab::VisibilityLevel.options['Public'] visibility_level: Gitlab::VisibilityLevel::PUBLIC
) )
end end
......
...@@ -899,38 +899,6 @@ describe SystemNoteService, services: true do ...@@ -899,38 +899,6 @@ describe SystemNoteService, services: true do
end end
end end
describe '.relate_issue' do
let(:noteable_ref) { create(:issue) }
subject { described_class.relate_issue(noteable, noteable_ref, author) }
it_behaves_like 'a system note' do
let(:action) { 'relate' }
end
context 'when issue marks another as related' do
it 'sets the note text' do
expect(subject.note).to eq "marked this issue as related to #{noteable_ref.to_reference(project)}"
end
end
end
describe '.unrelate_issue' do
let(:noteable_ref) { create(:issue) }
subject { described_class.unrelate_issue(noteable, noteable_ref, author) }
it_behaves_like 'a system note' do
let(:action) { 'unrelate' }
end
context 'when issue relation is removed' do
it 'sets the note text' do
expect(subject.note).to eq "removed the relation with #{noteable_ref.to_reference(project)}"
end
end
end
describe '.approve_mr' do describe '.approve_mr' do
let(:noteable) { create(:merge_request, source_project: project) } let(:noteable) { create(:merge_request, source_project: project) }
subject { described_class.approve_mr(noteable, author) } subject { described_class.approve_mr(noteable, author) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment