mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-18 17:16:08 +10:00
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into ce-to-ee
# Conflicts: # README.md # app/controllers/projects_controller.rb # db/schema.rb # doc/workflow/README.md # lib/gitlab/satellite/merge_action.rb
This commit is contained in:
@@ -1,6 +1,24 @@
|
||||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 7.14.0 (unreleased)
|
||||
- Fix full screen mode for snippet comments (Daniel Gerhardt)
|
||||
- Fix 404 error in files view after deleting the last file in a repository (Stan Hu)
|
||||
- Fix label read access for unauthenticated users (Daniel Gerhardt)
|
||||
- Fix access to disabled features for unauthenticated users (Daniel Gerhardt)
|
||||
- Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu)
|
||||
- Fix file upload dialog for comment editing (Daniel Gerhardt)
|
||||
- Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu)
|
||||
- Expire Rails cache entries after two weeks to prevent endless Redis growth
|
||||
- Add support for destroying project milestones (Stan Hu)
|
||||
- Add fetch command to the MR page.
|
||||
- Fix bug causing "Remove source-branch" option not to work for merge requests from the same project.
|
||||
|
||||
v 7.13.1
|
||||
- Revert issue caching
|
||||
- Reverted cache for events
|
||||
|
||||
v 7.13.0 (unreleased)
|
||||
- Remove repository graph log to fix slow cache updates after push event (Stan Hu)
|
||||
- Only enable HSTS header for HTTPS and port 443 (Stan Hu)
|
||||
- Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu)
|
||||
- Fix redirection to home page URL for unauthorized users (Daniel Gerhardt)
|
||||
@@ -15,7 +33,6 @@ v 7.13.0 (unreleased)
|
||||
- Add `two_factor_enabled` field to admin user API (Stan Hu)
|
||||
- Fix invalid timestamps in RSS feeds (Rowan Wookey)
|
||||
- Fix downloading of patches on public merge requests when user logged out (Stan Hu)
|
||||
- The password for the default administrator (root) account has been changed from "5iveL!fe" to "password".
|
||||
- Fix Error 500 when relative submodule resolves to a namespace that has a different name from its path (Stan Hu)
|
||||
- Extract the longest-matching ref from a commit path when multiple matches occur (Stan Hu)
|
||||
- Update maintenance documentation to explain no need to recompile asssets for omnibus installations (Stan Hu)
|
||||
@@ -47,6 +64,8 @@ v 7.13.0 (unreleased)
|
||||
- Faster code search in repository and wiki. Fixes search page timeout for big repositories
|
||||
- Allow administrators to disable 2FA for a specific user
|
||||
- Add error message for SSH key linebreaks
|
||||
- Store commits count in database (will populate with valid values only after first push)
|
||||
- Rebuild cache after push to repository in background job
|
||||
|
||||
v 7.12.2
|
||||
- Correctly show anonymous authorized applications under Profile > Applications.
|
||||
@@ -122,6 +141,7 @@ v 7.12.0
|
||||
- Improve group removing logic
|
||||
- Trigger create-hooks on backup restore task
|
||||
- Add option to automatically link omniauth and LDAP identities
|
||||
- Allow special character in users bio. I.e.: I <3 GitLab
|
||||
|
||||
v 7.11.4
|
||||
- Fix missing bullets when creating lists
|
||||
@@ -140,9 +160,6 @@ v 7.11.1
|
||||
v 7.11.0
|
||||
- Fall back to Plaintext when Syntaxhighlighting doesn't work. Fixes some buggy lexers (Hannes Rosenögger)
|
||||
- Get editing comments to work in Chrome 43 again.
|
||||
- Allow special character in users bio. I.e.: I <3 GitLab
|
||||
|
||||
v 7.11.0
|
||||
- Fix broken view when viewing history of a file that includes a path that used to be another file (Stan Hu)
|
||||
- Don't show duplicate deploy keys
|
||||
- Fix commit time being displayed in the wrong timezone in some cases (Hannes Rosenögger)
|
||||
|
||||
@@ -46,7 +46,7 @@ gem "gitlab_git", '~> 7.2.5'
|
||||
gem 'gitlab-grack', '~> 2.0.2', require: 'grack'
|
||||
|
||||
# LDAP Auth
|
||||
# GitLab fork with several improvements to original library. For full list of changes
|
||||
# GitLab fork with several improvements to original library. For full list of changes
|
||||
# see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master
|
||||
gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
|
||||
gem 'net-ldap'
|
||||
@@ -55,9 +55,9 @@ gem 'net-ldap'
|
||||
gem 'gollum-lib', '~> 4.0.2'
|
||||
|
||||
# Language detection
|
||||
# GitLab fork of linguist does not require pygments/python dependency.
|
||||
# New version of original gem also dropped pygments support but it has strict
|
||||
# dependency to unstable rugged version. We have internal issue for replacing
|
||||
# GitLab fork of linguist does not require pygments/python dependency.
|
||||
# New version of original gem also dropped pygments support but it has strict
|
||||
# dependency to unstable rugged version. We have internal issue for replacing
|
||||
# fork with original gem when we meet on same rugged version - https://dev.gitlab.org/gitlab/gitlabhq/issues/2052.
|
||||
gem "gitlab-linguist", "~> 3.0.1", require: "linguist"
|
||||
|
||||
@@ -230,7 +230,7 @@ end
|
||||
|
||||
group :development, :test do
|
||||
gem 'awesome_print'
|
||||
gem 'byebug'
|
||||
gem 'byebug', platform: :mri
|
||||
gem 'fuubar', '~> 2.0.0'
|
||||
gem 'pry-rails'
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# GitLab
|
||||
|
||||
[](https://ci.gitlab.com/projects/1?ref=master)
|
||||
[](https://semaphoreapp.com/gitlabhq/gitlabhq)
|
||||
[](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
|
||||
|
||||
## Canonical source
|
||||
|
||||
The source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible.
|
||||
@@ -41,21 +48,12 @@ To see how GitLab looks please see the [features page on our website](https://ab
|
||||
|
||||
## Editions
|
||||
|
||||
There are two editions of GitLab.
|
||||
*GitLab [Community Edition](https://about.gitlab.com/features/) (CE)* is available without any costs under an MIT license.
|
||||
There are two editions of GitLab:
|
||||
|
||||
*GitLab Enterprise Edition (EE)* includes [extra features](https://about.gitlab.com/features/#compare) that are most useful for organizations with more than 100 users.
|
||||
To use EE and get official support please [become a subscriber](https://about.gitlab.com/pricing/).
|
||||
- GitLab Community Edition (CE) is available freely under the MIT Expat license.
|
||||
- GitLab Enterprise Edition (EE) includes [extra features](https://about.gitlab.com/features/#compare) that are more useful for organizations with more than 100 users. To use EE and get official support please [become a subscriber](https://about.gitlab.com/pricing/).
|
||||
|
||||
## Code status
|
||||
|
||||
- [](https://ci.gitlab.com/projects/1?ref=master) on ci.gitlab.com (master branch)
|
||||
|
||||
- [](https://semaphoreapp.com/gitlabhq/gitlabhq)
|
||||
|
||||
- [](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
|
||||
- [](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
|
||||
Included with the GitLab Omnibus Packages is [GitLab CI](https://about.gitlab.com/gitlab-ci/) that can easily build, test and deploy code.
|
||||
|
||||
## Website
|
||||
|
||||
@@ -70,7 +68,31 @@ On [about.gitlab.com](https://about.gitlab.com/) you can find more information a
|
||||
|
||||
## Requirements
|
||||
|
||||
GitLab requires the following software:
|
||||
Please see the [requirements documentation](doc/install/requirements.md) for system requirements and more information about the supported operating systems.
|
||||
|
||||
## Installation
|
||||
|
||||
The recommended way to install GitLab is with the [Omnibus packages](https://about.gitlab.com/downloads/) on our package server.
|
||||
Compared to an installation from source, this is faster and less error prone.
|
||||
Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager.
|
||||
|
||||
There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information.
|
||||
|
||||
You can access a new installation with the login **`root`** and password **`5iveL!fe`**, after login you are required to set a unique password.
|
||||
|
||||
## Install a development environment
|
||||
|
||||
To work on GitLab itself, we recommend setting up your development environment with [the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit).
|
||||
If you do not use the GitLab Development Kit you need to install and setup all the dependencies yourself, this is a lot of work and error prone.
|
||||
One small thing you also have to do when installing it yourself is to copy the example development unicorn configuration file:
|
||||
|
||||
cp config/unicorn.rb.example.development config/unicorn.rb
|
||||
|
||||
Instructions on how to start GitLab and how to run the tests can be found in the [development section of the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit#development).
|
||||
|
||||
## Software stack
|
||||
|
||||
GitLab is a Ruby on Rails application that runs on the following software:
|
||||
|
||||
- Ubuntu/Debian/CentOS/RHEL
|
||||
- Ruby (MRI) 2.0 or 2.1
|
||||
@@ -78,15 +100,7 @@ GitLab requires the following software:
|
||||
- Redis 2.0+
|
||||
- MySQL or PostgreSQL
|
||||
|
||||
Please see the [requirements documentation](doc/install/requirements.md) for system requirements and more information about the supported operating systems.
|
||||
|
||||
## Installation
|
||||
|
||||
The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to an installation from source, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager.
|
||||
|
||||
There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information.
|
||||
|
||||
You can access a new installation with the login **`root`** and password **`password`**, after login you are required to set a unique password.
|
||||
For more information please see the [architecture documentation](http://doc.gitlab.com/ce/development/architecture.html).
|
||||
|
||||
## Third-party applications
|
||||
|
||||
@@ -100,16 +114,6 @@ Since 2011 a minor or major version of GitLab is released on the 22nd of every m
|
||||
|
||||
For upgrading information please see our [update page](https://about.gitlab.com/update/).
|
||||
|
||||
## Install a development environment
|
||||
|
||||
To work on GitLab itself, we recommend setting up your development environment with [the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit).
|
||||
If you do not use the GitLab Development Kit you need to install and setup all the dependencies yourself, this is a lot of work and error prone.
|
||||
One small thing you also have to do when installing it yourself is to copy the example development unicorn configuration file:
|
||||
|
||||
cp config/unicorn.rb.example.development config/unicorn.rb
|
||||
|
||||
Instructions on how to start GitLab and how to run the tests can be found in the [development section of the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit#development).
|
||||
|
||||
## Documentation
|
||||
|
||||
All documentation can be found on [doc.gitlab.com/ee/](http://doc.gitlab.com/ee/).
|
||||
@@ -125,4 +129,4 @@ Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on
|
||||
## Is it awesome?
|
||||
|
||||
Thanks for [asking this question](https://twitter.com/supersloth/status/489462789384056832) Joshua.
|
||||
[These people](https://twitter.com/gitlab/favorites) seem to like it.
|
||||
[These people](https://twitter.com/gitlab/favorites) seem to like it.
|
||||
|
||||
@@ -132,7 +132,10 @@ class Dispatcher
|
||||
shortcut_handler = new ShortcutsNavigation()
|
||||
new ZenMode()
|
||||
new DropzoneInput($('.wiki-form'))
|
||||
when 'snippets', 'labels', 'graphs'
|
||||
when 'snippets'
|
||||
shortcut_handler = new ShortcutsNavigation()
|
||||
new ZenMode() if path[2] == 'show'
|
||||
when 'labels', 'graphs'
|
||||
shortcut_handler = new ShortcutsNavigation()
|
||||
when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches'
|
||||
shortcut_handler = new ShortcutsNavigation()
|
||||
|
||||
@@ -70,7 +70,7 @@ class @LineHighlighter
|
||||
|
||||
@clearHighlight()
|
||||
|
||||
lineNumber = $(event.target).data('line-number')
|
||||
lineNumber = $(event.target).closest('a').data('line-number')
|
||||
current = @hashToRange(@_hash)
|
||||
|
||||
unless current[0] && event.shiftKey
|
||||
|
||||
@@ -15,9 +15,7 @@ class @MergeRequest
|
||||
this.$('.show-all-commits').on 'click', =>
|
||||
this.showAllCommits()
|
||||
|
||||
# `MergeRequests#new` has no tab-persisting or lazy-loading behavior
|
||||
unless @opts.action == 'new'
|
||||
new MergeRequestTabs(@opts)
|
||||
@initTabs()
|
||||
|
||||
# Prevent duplicate event bindings
|
||||
@disableTaskList()
|
||||
@@ -29,6 +27,14 @@ class @MergeRequest
|
||||
$: (selector) ->
|
||||
this.$el.find(selector)
|
||||
|
||||
initTabs: ->
|
||||
if @opts.action != 'new'
|
||||
# `MergeRequests#new` has no tab-persisting or lazy-loading behavior
|
||||
new MergeRequestTabs(@opts)
|
||||
else
|
||||
# Show the first tab (Commits)
|
||||
$('.merge-request-tabs a[data-toggle="tab"]:first').tab('show')
|
||||
|
||||
showAllCommits: ->
|
||||
this.$('.first-commits').remove()
|
||||
this.$('.all-commits').removeClass 'hide'
|
||||
|
||||
@@ -298,7 +298,7 @@ class @Notes
|
||||
note.find(".note-header").hide()
|
||||
base_form = note.find(".note-edit-form")
|
||||
form = base_form.clone().insertAfter(base_form)
|
||||
form.addClass('current-note-edit-form')
|
||||
form.addClass('current-note-edit-form gfm-form')
|
||||
form.find('.div-dropzone').remove()
|
||||
|
||||
# Show the attachment delete link
|
||||
|
||||
@@ -64,7 +64,12 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def destroy
|
||||
return access_denied! unless can?(current_user, :admin_milestone, @milestone)
|
||||
return access_denied! unless can?(current_user, :admin_milestone, @project)
|
||||
|
||||
update_params = { milestone: nil }
|
||||
@milestone.issues.each do |issue|
|
||||
Issues::UpdateService.new(@project, current_user, update_params).execute(issue)
|
||||
end
|
||||
|
||||
@milestone.destroy
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ class Projects::TreeController < Projects::ApplicationController
|
||||
before_action :authorize_download_code!
|
||||
|
||||
def show
|
||||
return not_found! unless @repository.commit(@ref)
|
||||
|
||||
if tree.entries.empty?
|
||||
if @repository.blob_at(@commit.id, @path)
|
||||
redirect_to(
|
||||
namespace_project_blob_path(@project.namespace, @project,
|
||||
File.join(@ref, @path))
|
||||
) and return
|
||||
else
|
||||
elsif @path.present?
|
||||
return not_found!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class ProjectsController < ApplicationController
|
||||
prepend_before_action :render_go_import, only: [:show]
|
||||
skip_before_action :authenticate_user!, only: [:show]
|
||||
prepend_before_filter :render_go_import, only: [:show]
|
||||
skip_before_action :authenticate_user!, only: [:show, :activity]
|
||||
before_action :project, except: [:new, :create]
|
||||
before_action :repository, except: [:new, :create]
|
||||
|
||||
|
||||
@@ -131,8 +131,12 @@ module ProjectsHelper
|
||||
nav_tabs << :snippets
|
||||
end
|
||||
|
||||
if can?(current_user, :read_label, project)
|
||||
nav_tabs << :labels
|
||||
end
|
||||
|
||||
if can?(current_user, :read_milestone, project)
|
||||
nav_tabs << [:milestones, :labels]
|
||||
nav_tabs << :milestones
|
||||
end
|
||||
|
||||
nav_tabs.flatten
|
||||
@@ -284,4 +288,18 @@ module ProjectsHelper
|
||||
def readme_cache_key
|
||||
[@project.id, @project.commit.sha, "readme"].join('-')
|
||||
end
|
||||
|
||||
def round_commit_count(project)
|
||||
count = project.commit_count
|
||||
|
||||
if count > 10000
|
||||
'10000+'
|
||||
elsif count > 5000
|
||||
'5000+'
|
||||
elsif count > 1000
|
||||
'1000+'
|
||||
else
|
||||
count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+32
-23
@@ -47,10 +47,11 @@ class Ability
|
||||
end
|
||||
|
||||
if project && project.public?
|
||||
[
|
||||
rules = [
|
||||
:read_project,
|
||||
:read_wiki,
|
||||
:read_issue,
|
||||
:read_label,
|
||||
:read_milestone,
|
||||
:read_project_snippet,
|
||||
:read_project_member,
|
||||
@@ -58,6 +59,8 @@ class Ability
|
||||
:read_note,
|
||||
:download_code
|
||||
]
|
||||
|
||||
rules - project_disabled_features_rules(project)
|
||||
else
|
||||
group = if subject.kind_of?(Group)
|
||||
subject
|
||||
@@ -118,28 +121,7 @@ class Ability
|
||||
rules -= project_archived_rules
|
||||
end
|
||||
|
||||
unless project.issues_enabled
|
||||
rules -= named_abilities('issue')
|
||||
end
|
||||
|
||||
unless project.merge_requests_enabled
|
||||
rules -= named_abilities('merge_request')
|
||||
end
|
||||
|
||||
unless project.issues_enabled or project.merge_requests_enabled
|
||||
rules -= named_abilities('label')
|
||||
rules -= named_abilities('milestone')
|
||||
end
|
||||
|
||||
unless project.snippets_enabled
|
||||
rules -= named_abilities('project_snippet')
|
||||
end
|
||||
|
||||
unless project.wiki_enabled
|
||||
rules -= named_abilities('wiki')
|
||||
end
|
||||
|
||||
rules
|
||||
rules - project_disabled_features_rules(project)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -221,6 +203,33 @@ class Ability
|
||||
]
|
||||
end
|
||||
|
||||
def project_disabled_features_rules(project)
|
||||
rules = []
|
||||
|
||||
unless project.issues_enabled
|
||||
rules += named_abilities('issue')
|
||||
end
|
||||
|
||||
unless project.merge_requests_enabled
|
||||
rules += named_abilities('merge_request')
|
||||
end
|
||||
|
||||
unless project.issues_enabled or project.merge_requests_enabled
|
||||
rules += named_abilities('label')
|
||||
rules += named_abilities('milestone')
|
||||
end
|
||||
|
||||
unless project.snippets_enabled
|
||||
rules += named_abilities('project_snippet')
|
||||
end
|
||||
|
||||
unless project.wiki_enabled
|
||||
rules += named_abilities('wiki')
|
||||
end
|
||||
|
||||
rules
|
||||
end
|
||||
|
||||
def group_abilities(user, group)
|
||||
rules = []
|
||||
|
||||
|
||||
@@ -240,6 +240,10 @@ class MergeRequest < ActiveRecord::Base
|
||||
execute(self, commit_message)
|
||||
end
|
||||
|
||||
def remove_source_branch?
|
||||
self.should_remove_source_branch && !self.source_project.root_ref?(self.source_branch) && !self.for_fork?
|
||||
end
|
||||
|
||||
def open?
|
||||
opened? || reopened?
|
||||
end
|
||||
|
||||
@@ -703,6 +703,10 @@ class Project < ActiveRecord::Base
|
||||
update_attribute(:repository_size, repository.size)
|
||||
end
|
||||
|
||||
def update_commit_count
|
||||
update_attribute(:commit_count, repository.commit_count)
|
||||
end
|
||||
|
||||
def forks_count
|
||||
ForkedProjectLink.where(forked_from_project_id: self.id).count
|
||||
end
|
||||
|
||||
@@ -22,8 +22,12 @@ class GitlabCiService < CiService
|
||||
API_PREFIX = "api/v1"
|
||||
|
||||
prop_accessor :project_url, :token
|
||||
validates :project_url, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
validates :project_url,
|
||||
presence: true,
|
||||
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
|
||||
validates :token,
|
||||
presence: true,
|
||||
format: { with: /\A([A-Za-z0-9]+)\z/ }, if: :activated?
|
||||
|
||||
after_save :compose_service_hook, if: :activated?
|
||||
|
||||
|
||||
+23
-35
@@ -94,18 +94,6 @@ class Repository
|
||||
gitlab_shell.rm_tag(path_with_namespace, tag_name)
|
||||
end
|
||||
|
||||
def round_commit_count
|
||||
if commit_count > 10000
|
||||
'10000+'
|
||||
elsif commit_count > 5000
|
||||
'5000+'
|
||||
elsif commit_count > 1000
|
||||
'1000+'
|
||||
else
|
||||
commit_count
|
||||
end
|
||||
end
|
||||
|
||||
def branch_names
|
||||
cache.fetch(:branch_names) { raw_repository.branch_names }
|
||||
end
|
||||
@@ -130,28 +118,29 @@ class Repository
|
||||
cache.fetch(:size) { raw_repository.size }
|
||||
end
|
||||
|
||||
def cache_keys
|
||||
%i(size branch_names tag_names commit_count
|
||||
readme version contribution_guide changelog license)
|
||||
end
|
||||
|
||||
def build_cache
|
||||
cache_keys.each do |key|
|
||||
unless cache.exist?(key)
|
||||
send(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def expire_cache
|
||||
%i(size branch_names tag_names commit_count graph_log
|
||||
readme version contribution_guide changelog license).each do |key|
|
||||
cache_keys.each do |key|
|
||||
cache.expire(key)
|
||||
end
|
||||
end
|
||||
|
||||
def graph_log
|
||||
cache.fetch(:graph_log) do
|
||||
commits = raw_repository.log(limit: 6000, skip_merges: true,
|
||||
ref: root_ref)
|
||||
|
||||
commits.map do |rugged_commit|
|
||||
commit = Gitlab::Git::Commit.new(rugged_commit)
|
||||
|
||||
{
|
||||
author_name: commit.author_name,
|
||||
author_email: commit.author_email,
|
||||
additions: commit.stats.additions,
|
||||
deletions: commit.stats.deletions,
|
||||
}
|
||||
end
|
||||
def rebuild_cache
|
||||
cache_keys.each do |key|
|
||||
cache.expire(key)
|
||||
send(key)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -442,8 +431,7 @@ class Repository
|
||||
filename = nil
|
||||
startline = 0
|
||||
|
||||
lines = result.lines
|
||||
lines.each_with_index do |line, index|
|
||||
result.each_line.each_with_index do |line, index|
|
||||
if line =~ /^.*:.*:\d+:/
|
||||
ref, filename, startline = line.split(':')
|
||||
startline = startline.to_i - index
|
||||
@@ -451,11 +439,11 @@ class Repository
|
||||
end
|
||||
end
|
||||
|
||||
data = lines.map do |line|
|
||||
line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '')
|
||||
end
|
||||
data = ""
|
||||
|
||||
data = data.join("")
|
||||
result.each_line do |line|
|
||||
data << line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '')
|
||||
end
|
||||
|
||||
OpenStruct.new(
|
||||
filename: filename,
|
||||
|
||||
@@ -43,7 +43,7 @@ module Files
|
||||
|
||||
def after_commit(sha, branch)
|
||||
commit = repository.commit(sha)
|
||||
full_ref = 'refs/heads/' + branch
|
||||
full_ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch}"
|
||||
old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
|
||||
GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
|
||||
end
|
||||
|
||||
@@ -21,7 +21,6 @@ class GitPushService
|
||||
|
||||
project.ensure_satellite_exists
|
||||
project.repository.expire_cache
|
||||
project.update_repository_size
|
||||
|
||||
if push_remove_branch?(ref, newrev)
|
||||
@push_commits = []
|
||||
@@ -61,6 +60,7 @@ class GitPushService
|
||||
EventCreateService.new.push(project, user, @push_data)
|
||||
project.execute_hooks(@push_data.dup, :push_hooks)
|
||||
project.execute_services(@push_data.dup, :push_hooks)
|
||||
ProjectCacheWorker.perform_async(project.id)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
@@ -2,15 +2,15 @@ class GitTagPushService
|
||||
attr_accessor :project, :user, :push_data
|
||||
|
||||
def execute(project, user, oldrev, newrev, ref)
|
||||
@project, @user = project, user
|
||||
project.repository.expire_cache
|
||||
|
||||
@project, @user = project, user
|
||||
@push_data = build_push_data(oldrev, newrev, ref)
|
||||
|
||||
EventCreateService.new.push(project, user, @push_data)
|
||||
project.execute_hooks(@push_data.dup, :tag_push_hooks)
|
||||
project.execute_services(@push_data.dup, :tag_push_hooks)
|
||||
|
||||
project.repository.expire_cache
|
||||
ProjectCacheWorker.perform_async(project.id)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
@@ -37,6 +37,14 @@ module MergeRequests
|
||||
# Merge local branches using rugged instead of satellites
|
||||
if sha = commit
|
||||
after_commit(sha, merge_request.target_branch)
|
||||
|
||||
if merge_request.remove_source_branch?
|
||||
DeleteBranchService.new(merge_request.source_project, current_user).execute(merge_request.source_branch)
|
||||
end
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -55,7 +63,7 @@ module MergeRequests
|
||||
|
||||
def after_commit(sha, branch)
|
||||
commit = repository.commit(sha)
|
||||
full_ref = 'refs/heads/' + branch
|
||||
full_ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch}"
|
||||
old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
|
||||
GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
|
||||
end
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
|
||||
= render "events/event/created_project", event: event
|
||||
- else
|
||||
= cache event do
|
||||
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
|
||||
- if event.push?
|
||||
= render "events/event/push", event: event
|
||||
- elsif event.commented?
|
||||
= render "events/event/note", event: event
|
||||
- else
|
||||
= render "events/event/common", event: event
|
||||
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
|
||||
- if event.push?
|
||||
= render "events/event/push", event: event
|
||||
- elsif event.commented?
|
||||
= render "events/event/note", event: event
|
||||
- else
|
||||
= render "events/event/common", event: event
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
.repo-info
|
||||
- unless project.empty_repo?
|
||||
= link_to pluralize(project.repository.round_commit_count, 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
|
||||
= link_to pluralize(round_commit_count(project), 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
|
||||
·
|
||||
= link_to pluralize(project.repository.branch_names.count, 'branch'), namespace_project_branches_path(project.namespace, project)
|
||||
·
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Download the Google Authenticator application from App Store for iOS or Google
|
||||
Play for Android and scan this code.
|
||||
|
||||
More information is available in the #{link_to('documentation', help_page_path('workflow', 'two_factor_authentication'))}.
|
||||
More information is available in the #{link_to('documentation', help_page_path('profile', 'two_factor_authentication'))}.
|
||||
|
||||
%hr
|
||||
|
||||
|
||||
@@ -3,43 +3,42 @@
|
||||
.issue-check
|
||||
= check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
|
||||
|
||||
= cache issue do
|
||||
.issue-title
|
||||
%span.issue-title-text
|
||||
= link_to_gfm issue.title, issue_path(issue), class: "row_title"
|
||||
.issue-labels
|
||||
- issue.labels.each do |label|
|
||||
= link_to_label(label, project: issue.project)
|
||||
.pull-right.light
|
||||
- if issue.closed?
|
||||
%span
|
||||
CLOSED
|
||||
- if issue.assignee
|
||||
= link_to_member(@project, issue.assignee, name: false)
|
||||
- note_count = issue.notes.user.count
|
||||
- if note_count > 0
|
||||
|
||||
%span
|
||||
%i.fa.fa-comments
|
||||
= note_count
|
||||
- else
|
||||
|
||||
%span.issue-no-comments
|
||||
%i.fa.fa-comments
|
||||
= 0
|
||||
|
||||
.issue-info
|
||||
= "#{issue.to_reference} opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')} by #{link_to_member(@project, issue.author, avatar: false)}".html_safe
|
||||
- if issue.votes_count > 0
|
||||
= render 'votes/votes_inline', votable: issue
|
||||
- if issue.milestone
|
||||
.issue-title
|
||||
%span.issue-title-text
|
||||
= link_to_gfm issue.title, issue_path(issue), class: "row_title"
|
||||
.issue-labels
|
||||
- issue.labels.each do |label|
|
||||
= link_to_label(label, project: issue.project)
|
||||
.pull-right.light
|
||||
- if issue.closed?
|
||||
%span
|
||||
CLOSED
|
||||
- if issue.assignee
|
||||
= link_to_member(@project, issue.assignee, name: false)
|
||||
- note_count = issue.notes.user.count
|
||||
- if note_count > 0
|
||||
|
||||
%span
|
||||
%i.fa.fa-clock-o
|
||||
= issue.milestone.title
|
||||
- if issue.tasks?
|
||||
%span.task-status
|
||||
= issue.task_status
|
||||
%i.fa.fa-comments
|
||||
= note_count
|
||||
- else
|
||||
|
||||
%span.issue-no-comments
|
||||
%i.fa.fa-comments
|
||||
= 0
|
||||
|
||||
.pull-right.issue-updated-at
|
||||
%small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
|
||||
.issue-info
|
||||
= "#{issue.to_reference} opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')} by #{link_to_member(@project, issue.author, avatar: false)}".html_safe
|
||||
- if issue.votes_count > 0
|
||||
= render 'votes/votes_inline', votable: issue
|
||||
- if issue.milestone
|
||||
|
||||
%span
|
||||
%i.fa.fa-clock-o
|
||||
= issue.milestone.title
|
||||
- if issue.tasks?
|
||||
%span.task-status
|
||||
= issue.task_status
|
||||
|
||||
.pull-right.issue-updated-at
|
||||
%small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
%li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
|
||||
%li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
|
||||
|
||||
- if @merge_request.open? and @merge_request.source_branch_exists?
|
||||
.append-bottom-20
|
||||
.slead
|
||||
%span
|
||||
Fetch the branch with
|
||||
%strong.label-branch<
|
||||
git fetch
|
||||
\ #{@merge_request.source_project.http_url_to_repo}
|
||||
\ #{@merge_request.source_branch}
|
||||
|
||||
= render "projects/merge_requests/show/how_to_merge"
|
||||
= render "projects/merge_requests/widget/show.html.haml"
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
:plain
|
||||
$(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}");
|
||||
$('.js-timeago').timeago()
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
:plain
|
||||
$(".mr_target_commit").html("#{commit_to_html(@commit, @target_project, false)}");
|
||||
$('.js-timeago').timeago()
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
%i.fa.fa-pencil-square-o
|
||||
Edit
|
||||
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close"
|
||||
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-sm btn-remove" do
|
||||
%i.fa.fa-trash-o
|
||||
Remove
|
||||
|
||||
%h4
|
||||
= link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone)
|
||||
- if milestone.expired? and not milestone.closed?
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-grouped"
|
||||
- else
|
||||
= link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-grouped"
|
||||
= link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-remove" do
|
||||
%i.fa.fa-trash-o
|
||||
Remove
|
||||
|
||||
%hr
|
||||
- if @milestone.issues.any? && @milestone.can_be_closed?
|
||||
|
||||
@@ -56,10 +56,9 @@
|
||||
|
||||
|
||||
.note-body{class: note_editable?(note) ? 'js-task-list-container' : ''}
|
||||
= cache [note, 'markdown'] do
|
||||
.note-text
|
||||
= preserve do
|
||||
= markdown(note.note, {no_header_anchors: true})
|
||||
.note-text
|
||||
= preserve do
|
||||
= markdown(note.note, {no_header_anchors: true})
|
||||
= render 'projects/notes/edit_form', note: note
|
||||
|
||||
- if note.attachment.url
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
= render 'shared/no_ssh'
|
||||
= render 'shared/no_password'
|
||||
|
||||
= render 'projects/last_push'
|
||||
- if prefer_readme?
|
||||
= render 'projects/last_push'
|
||||
|
||||
= render "home_panel"
|
||||
|
||||
.project-stats
|
||||
%ul.nav.nav-pills
|
||||
%li
|
||||
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do
|
||||
= pluralize(number_with_delimiter(@repository.commit_count), 'commit')
|
||||
= pluralize(number_with_delimiter(@project.commit_count), 'commit')
|
||||
%li
|
||||
= link_to namespace_project_branches_path(@project.namespace, @project) do
|
||||
= pluralize(number_with_delimiter(@repository.branch_names.count), 'branch')
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- else
|
||||
none
|
||||
.issuable-context-selectbox
|
||||
- if can?(current_user, :admin_issue, @project)
|
||||
- if can?(current_user, :"admin_#{issuable.class.to_s.underscore}", @project)
|
||||
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true)
|
||||
|
||||
%div.prepend-top-20.clearfix
|
||||
@@ -24,7 +24,7 @@
|
||||
- else
|
||||
none
|
||||
.issuable-context-selectbox
|
||||
- if can?(current_user, :admin_issue, @project)
|
||||
- if can?(current_user, :"admin_#{issuable.class.to_s.underscore}", @project)
|
||||
= f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
|
||||
= hidden_field_tag :issuable_context
|
||||
= f.submit class: 'btn hide'
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
class ProjectCacheWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
sidekiq_options queue: :default
|
||||
|
||||
def perform(project_id)
|
||||
project = Project.find(project_id)
|
||||
project.update_repository_size
|
||||
project.update_commit_count
|
||||
|
||||
if project.repository.root_ref
|
||||
project.repository.build_cache
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,7 +28,7 @@ class RepositoryImportWorker
|
||||
project.import_finish
|
||||
project.save
|
||||
project.satellite.create unless project.satellite.exists?
|
||||
project.update_repository_size
|
||||
ProjectCacheWorker.perform_async(project.id)
|
||||
Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -96,6 +96,7 @@ module Gitlab
|
||||
end
|
||||
|
||||
redis_config_hash[:namespace] = 'cache:gitlab'
|
||||
redis_config_hash[:expires_in] = 2.weeks # Cache should not grow forever
|
||||
config.cache_store = :redis_store, redis_config_hash
|
||||
|
||||
# This is needed for gitlab-shell
|
||||
|
||||
@@ -14,6 +14,7 @@ if Gitlab::LDAP::Config.enabled?
|
||||
end
|
||||
end
|
||||
|
||||
OmniAuth.config.full_host = Settings.gitlab['url']
|
||||
OmniAuth.config.allowed_request_methods = [:post]
|
||||
#In case of auto sign-in, the GET method is used (users don't get to click on a button)
|
||||
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
|
||||
|
||||
@@ -6,7 +6,8 @@ Doorkeeper.configure do
|
||||
# This block will be called to check whether the resource owner is authenticated or not.
|
||||
resource_owner_authenticator do
|
||||
# Put your resource owner authentication logic here.
|
||||
# Example implementation:
|
||||
# Ensure user is redirected to redirect_uri after login
|
||||
session[:user_return_to] = request.fullpath
|
||||
current_user || redirect_to(new_user_session_url)
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -520,7 +520,7 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do
|
||||
resources :milestones, constraints: { id: /\d+/ } do
|
||||
member do
|
||||
put :sort_issues
|
||||
put :sort_merge_requests
|
||||
|
||||
@@ -5,7 +5,7 @@ Gitlab::Seeder.quiet do
|
||||
s.email = 'admin@example.com'
|
||||
s.notification_email = 'admin@example.com'
|
||||
s.username = 'root'
|
||||
s.password = 'password'
|
||||
s.password = '5iveL!fe'
|
||||
s.admin = true
|
||||
s.projects_limit = 100
|
||||
s.confirmed_at = DateTime.now
|
||||
|
||||
@@ -11,9 +11,42 @@ Sidekiq::Testing.inline! do
|
||||
'https://github.com/twitter/flight.git',
|
||||
'https://github.com/twitter/typeahead.js.git',
|
||||
'https://github.com/h5bp/html5-boilerplate.git',
|
||||
'https://github.com/google/material-design-lite.git',
|
||||
'https://github.com/jlevy/the-art-of-command-line.git',
|
||||
'https://github.com/FreeCodeCamp/freecodecamp.git',
|
||||
'https://github.com/google/deepdream.git',
|
||||
'https://github.com/jtleek/datasharing.git',
|
||||
'https://github.com/WebAssembly/design.git',
|
||||
'https://github.com/airbnb/javascript.git',
|
||||
'https://github.com/tessalt/echo-chamber-js.git',
|
||||
'https://github.com/atom/atom.git',
|
||||
'https://github.com/ipselon/react-ui-builder.git',
|
||||
'https://github.com/mattermost/platform.git',
|
||||
'https://github.com/purifycss/purifycss.git',
|
||||
'https://github.com/facebook/nuclide.git',
|
||||
'https://github.com/wbkd/awesome-d3.git',
|
||||
'https://github.com/kilimchoi/engineering-blogs.git',
|
||||
'https://github.com/gilbarbara/logos.git',
|
||||
'https://github.com/gaearon/redux.git',
|
||||
'https://github.com/awslabs/s2n.git',
|
||||
'https://github.com/arkency/reactjs_koans.git',
|
||||
'https://github.com/twbs/bootstrap.git',
|
||||
'https://github.com/chjj/ttystudio.git',
|
||||
'https://github.com/DrBoolean/mostly-adequate-guide.git',
|
||||
'https://github.com/octocat/Spoon-Knife.git',
|
||||
'https://github.com/opencontainers/runc.git',
|
||||
'https://github.com/googlesamples/android-topeka.git'
|
||||
]
|
||||
|
||||
project_urls.each_with_index do |url, i|
|
||||
# You can specify how many projects you need during seed execution
|
||||
size = if ENV['SIZE'].present?
|
||||
ENV['SIZE'].to_i
|
||||
else
|
||||
8
|
||||
end
|
||||
|
||||
|
||||
project_urls.first(size).each_with_index do |url, i|
|
||||
group_path, project_path = url.split('/')[-2..-1]
|
||||
|
||||
group = Group.find_by(path: group_path)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
if ENV['GITLAB_ROOT_PASSWORD'].blank?
|
||||
password = 'password'
|
||||
password = '5iveL!fe'
|
||||
expire_time = Time.now
|
||||
else
|
||||
password = ENV['GITLAB_ROOT_PASSWORD']
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class AddSessionExpireDelayForApplicationSettings < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :application_settings, :session_expire_delay, :integer, default: 10080, null: false
|
||||
unless column_exists?(:application_settings, :session_expire_delay)
|
||||
add_column :application_settings, :session_expire_delay, :integer, default: 10080, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddCommitsCountToProject < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :projects, :commit_count, :integer, default: 0
|
||||
end
|
||||
end
|
||||
@@ -455,6 +455,7 @@ ActiveRecord::Schema.define(version: 20150717155058) do
|
||||
t.boolean "merge_requests_rebase_default", default: true
|
||||
t.integer "approvals_before_merge", default: 0, null: false
|
||||
t.boolean "reset_approvals_on_push", default: true
|
||||
t.integer "commit_count", default: 0
|
||||
end
|
||||
|
||||
add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree
|
||||
|
||||
@@ -49,7 +49,8 @@ Parameters:
|
||||
"state": "active",
|
||||
"created_at": "2012-04-29T08:46:00Z"
|
||||
},
|
||||
"description":"fixed login page css paddings"
|
||||
"description":"fixed login page css paddings",
|
||||
"work_in_progress": false
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -94,7 +95,8 @@ Parameters:
|
||||
"state": "active",
|
||||
"created_at": "2012-04-29T08:46:00Z"
|
||||
},
|
||||
"description":"fixed login page css paddings"
|
||||
"description":"fixed login page css paddings",
|
||||
"work_in_progress": false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -118,6 +120,7 @@ Parameters:
|
||||
"project_id": 4,
|
||||
"title": "Blanditiis beatae suscipit hic assumenda et molestias nisi asperiores repellat et.",
|
||||
"description": "Qui voluptatibus placeat ipsa alias quasi. Deleniti rem ut sint. Optio velit qui distinctio.",
|
||||
"work_in_progress": false,
|
||||
"state": "reopened",
|
||||
"created_at": "2015-02-02T19:49:39.159Z",
|
||||
"updated_at": "2015-02-02T20:08:49.959Z",
|
||||
@@ -336,14 +339,6 @@ Parameters:
|
||||
|
||||
```json
|
||||
{
|
||||
"author": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"email": "admin@example.com",
|
||||
"name": "Administrator",
|
||||
"blocked": false,
|
||||
"created_at": "2012-04-29T08:46:00Z"
|
||||
},
|
||||
"note": "text1"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -13,3 +13,7 @@ Step-by-step guides on the basics of working with Git and GitLab.
|
||||
* [Create a project](create-project.md)
|
||||
|
||||
* [Create a group](create-group.md)
|
||||
|
||||
* [Create a branch](create-branch.md)
|
||||
|
||||
* [Fork a project](fork-project.md)
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
# Basic Git commands
|
||||
|
||||
* Go to the master branch to pull the latest changes from there
|
||||
### Go to the master branch to pull the latest changes from there
|
||||
```
|
||||
git checkout master
|
||||
```
|
||||
|
||||
* Download the latest changes in the project, so that you work on an up-to-date copy (this is important to do every time you work on a project), while you setup tracking branches
|
||||
### Download the latest changes in the project
|
||||
This is for you to work on an up-to-date copy (it is important to do every time you work on a project), while you setup tracking branches.
|
||||
```
|
||||
git pull REMOTE NAME-OF-BRANCH -u
|
||||
```
|
||||
(REMOTE: origin) (NAME-OF-BRANCH: could be "master" or an existing branch)
|
||||
|
||||
* Create a branch (remember that spaces won't be recognized, you need to use a hyphen or underscore)
|
||||
### Create a branch
|
||||
Spaces won't be recognized, so you need to use a hyphen or underscore.
|
||||
```
|
||||
git checkout -b NAME-OF-BRANCH
|
||||
```
|
||||
|
||||
* Work on a branch that has already been created
|
||||
### Work on a branch that has already been created
|
||||
```
|
||||
git checkout NAME-OF-BRANCH
|
||||
```
|
||||
|
||||
* To see the changes you've made (it's important to be aware of what's happening and what's the status of your changes)
|
||||
### View the changes you've made
|
||||
It's important to be aware of what's happening and what's the status of your changes.
|
||||
```
|
||||
git status
|
||||
```
|
||||
|
||||
* Add changes to commit (you'll be able to see your changes in red when you type "git status")
|
||||
### Add changes to commit
|
||||
You'll see your changes in red when you type "git status".
|
||||
```
|
||||
git add CHANGES IN RED
|
||||
git commit -m "DESCRIBE THE INTENTION OF THE COMMIT"
|
||||
```
|
||||
|
||||
* Send changes to gitlab.com
|
||||
### Send changes to gitlab.com
|
||||
```
|
||||
git push origin NAME-OF-BRANCH
|
||||
git push REMOTE NAME-OF-BRANCH
|
||||
```
|
||||
|
||||
* Throw away all changes in the Git repository, but leave unstaged things
|
||||
### Delete all changes in the Git repository, but leave unstaged things
|
||||
```
|
||||
git checkout .
|
||||
```
|
||||
|
||||
* Delete all changes in the Git repository, including untracked files
|
||||
### Delete all changes in the Git repository, including untracked files
|
||||
```
|
||||
git clean -f
|
||||
```
|
||||
|
||||
* Remove all the changes that you don't want to send to gitlab.com
|
||||
```
|
||||
git add NAME-OF-FILE -all
|
||||
```
|
||||
|
||||
* Merge created branch with master branch. You need to be in the created branch
|
||||
### Merge created branch with master branch
|
||||
You need to be in the created branch.
|
||||
```
|
||||
git checkout NAME-OF-BRANCH
|
||||
git merge master
|
||||
|
||||
@@ -2,46 +2,47 @@
|
||||
|
||||
## Start working on your project
|
||||
|
||||
* In Git, when you copy a project you say you "clone" it. To work on a git project locally (from your own computer), you will need to clone it. To do this, sign in to [GitLab.com](https://gitlab.com)
|
||||
In Git, when you copy a project you say you "clone" it. To work on a git project locally (from your own computer), you will need to clone it. To do this, sign in to [GitLab.com](https://gitlab.com).
|
||||
|
||||
* When you are on your Dashboard, click on the project that you'd like to clone, which you'll find at the right side of your screen
|
||||
When you are on your Dashboard, click on the project that you'd like to clone, which you'll find at the right side of your screen.
|
||||
|
||||

|
||||
|
||||
* To work in the project, you can copy a link to the Git repository through a SSH or a HTTPS protocol. SSH is easier to use after it's been [setup](create-your-ssh-keys.md). When you're in the project, click on the HTTPS or SSH button at the right side of your screen. Then copy the link (you'll have to paste it on your shell in the next step)
|
||||
To work in the project, you can copy a link to the Git repository through a SSH or a HTTPS protocol. SSH is easier to use after it's been [setup](create-your-ssh-keys.md). When you're in the project, click on the HTTPS or SSH button at the right side of your screen. Then copy the link (you'll have to paste it on your shell in the next step).
|
||||
|
||||

|
||||
|
||||
## On the command line
|
||||
|
||||
* To clone your project, go to your computer's shell and type the following command
|
||||
### Clone your project
|
||||
Go to your computer's shell and type the following command:
|
||||
```
|
||||
git clone PASTE HTTPS OR SSH HERE
|
||||
```
|
||||
|
||||
* A clone of the project will be created in your computer
|
||||
A clone of the project will be created in your computer.
|
||||
|
||||
* Go into a project, directory or file to work in it
|
||||
### Go into a project, directory or file to work in it
|
||||
```
|
||||
cd NAME-OF-PROJECT-OR-FILE
|
||||
```
|
||||
|
||||
* Go back one directory or file
|
||||
### Go back one directory or file
|
||||
```
|
||||
cd ../
|
||||
```
|
||||
|
||||
* To see what’s in the directory that you are in
|
||||
### View what’s in the directory that you are in
|
||||
```
|
||||
ls
|
||||
```
|
||||
|
||||
* Create a directory
|
||||
### Create a directory
|
||||
```
|
||||
mkdir NAME-OF-YOUR-DIRECTORY
|
||||
```
|
||||
|
||||
* Create a README.md or file in directory
|
||||
### Create a README.md or file in directory
|
||||
```
|
||||
touch README.md
|
||||
nano README.md
|
||||
@@ -51,22 +52,23 @@ nano README.md
|
||||
#### Press: enter
|
||||
```
|
||||
|
||||
* Remove a file
|
||||
### Remove a file
|
||||
```
|
||||
rm NAME-OF-FILE
|
||||
```
|
||||
|
||||
* Remove a directory and all of its contents
|
||||
### Remove a directory and all of its contents
|
||||
```
|
||||
rm -rf NAME-OF-DIRECTORY
|
||||
```
|
||||
|
||||
* View history in the command line
|
||||
### View history in the command line
|
||||
```
|
||||
history
|
||||
```
|
||||
|
||||
* Carry out commands for which the account you are using lacks authority. (You will be asked for an administrator’s password)
|
||||
### Carry out commands for which the account you are using lacks authority
|
||||
You will be asked for an administrator’s password.
|
||||
```
|
||||
sudo
|
||||
```
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# How to create a branch
|
||||
|
||||
A branch is an independent line of development.
|
||||
|
||||
New commits are recorded in the history for the current branch, which results in taking the source from someone’s repository (the place where the history of your work is stored) at certain point in time, and apply your own changes to it in the history of the project.
|
||||
|
||||
To add changes to your GitLab project, you should create a branch. You can do it in your [shell](basic-git-commands.md) or in GitLab.
|
||||
|
||||
To create a new branch in GitLab, sign in and then select a project on the right side of your screen:
|
||||
|
||||

|
||||
|
||||
Click on "commits" on the menu on the left side of your screen:
|
||||
|
||||

|
||||
|
||||
Click on the "branches" tab:
|
||||
|
||||

|
||||
|
||||
Click on the "new branch" button on the right side of the screen:
|
||||
|
||||

|
||||
|
||||
Fill out the information required:
|
||||
|
||||
1. Add a name for your new branch (you can't add spaces, so you can use hyphens or underscores)
|
||||
|
||||
1. On the "create from" space, add the the name of the branch you want to branch off from
|
||||
|
||||
1. Click on the button "create branch"
|
||||
|
||||

|
||||
|
||||
### Note:
|
||||
|
||||
You will be able to find and select the name of your branch in the white box next to a project's name:
|
||||
|
||||

|
||||
@@ -1,14 +1,12 @@
|
||||
# How to create a project in GitLab
|
||||
|
||||
## Create a project
|
||||
To create a new project, sign in to [GitLab.com](https://gitlab.com).
|
||||
|
||||
* Sign in to [GitLab.com](https://gitlab.com)
|
||||
|
||||
* Go to your Dashboard and click on "new project" on the right side of your screen
|
||||
Go to your Dashboard and click on "new project" on the right side of your screen.
|
||||
|
||||

|
||||
|
||||
* Fill out the required information
|
||||
Fill out the required information:
|
||||
|
||||
1. Project path or the name of your project (you can't add spaces, so you can use hyphens or underscores)
|
||||
|
||||
|
||||
@@ -4,34 +4,34 @@ You need to connect your computer to your GitLab account through SSH Keys. They
|
||||
|
||||
## Generate your SSH Key
|
||||
|
||||
* Create an account on GitLab. Sign up and check your email for your confirmation link
|
||||
Create an account on GitLab. Sign up and check your email for your confirmation link.
|
||||
|
||||
* After you confirm, go to [GitLab.com](https://about.gitlab.com/) and sign in to your account
|
||||
After you confirm, go to [GitLab.com](https://about.gitlab.com/) and sign in to your account.
|
||||
|
||||
## Add your SSH Key
|
||||
|
||||
* At the top right corner, click on "profile settings"
|
||||
At the top right corner, click on "profile settings":
|
||||
|
||||

|
||||
|
||||
* On the left side menu click on "SSH Keys"
|
||||
On the left side menu click on "SSH Keys":
|
||||
|
||||

|
||||
|
||||
* Then click on the green button "Add SSH Key"
|
||||
Then click on the green button "Add SSH Key":
|
||||
|
||||

|
||||
|
||||
* There, you should paste the SSH Key that your commandline will generate for you. Below you'll find the steps to generate it
|
||||
There, you should paste the SSH Key that your command line will generate for you. Below you'll find the steps to generate it:
|
||||
|
||||

|
||||
|
||||
## To generate an SSH Key on your commandline
|
||||
## To generate an SSH Key on your command line
|
||||
|
||||
* Go to your [commandline](start-using-git.md) and follow the [instructions](https://gitlab.com/help/ssh/README) to generate it
|
||||
Go to your [command line](start-using-git.md) and follow the [instructions](../ssh/README.md) to generate it.
|
||||
|
||||
* Copy the SSH Key that your commandline created and paste it on the "Key" box on the GitLab page. The title will be added automatically
|
||||
Copy the SSH Key that your command line created and paste it on the "Key" box on the GitLab page. The title will be added automatically.
|
||||
|
||||

|
||||
|
||||
* Now, you'll be able to use Git over SSH, instead of Git over HTTP.
|
||||
Now, you'll be able to use Git over SSH, instead of Git over HTTP.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# How to fork a project
|
||||
|
||||
A fork is a copy of an original repository that you can put somewhere else
|
||||
or where you can experiment and apply changes that you can later decide if
|
||||
publishing or not, without affecting your original project.
|
||||
|
||||
It takes just a few steps to fork a project in GitLab.
|
||||
|
||||
Sign in to [gitlab.com](https://gitlab.com).
|
||||
|
||||
Select a project on the right side of your screen:
|
||||
|
||||

|
||||
|
||||
Click on the "fork" button on the right side of your screen:
|
||||
|
||||

|
||||
|
||||
Click on the user or group to where you'd like to add the forked project.
|
||||
@@ -1,10 +1,10 @@
|
||||
# Start using Git on the commandline
|
||||
# Start using Git on the command line
|
||||
|
||||
If you want to start using a Git and GitLab, make sure that you have created an account on [GitLab.com](https://about.gitlab.com/)
|
||||
If you want to start using a Git and GitLab, make sure that you have created an account on [GitLab.com](https://about.gitlab.com/).
|
||||
|
||||
## Open a shell
|
||||
|
||||
* Depending on your operating system, find the shell of your preference. Here are some suggestions
|
||||
Depending on your operating system, find the shell of your preference. Here are some suggestions.
|
||||
|
||||
- [Terminal](http://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line) on Mac OSX
|
||||
|
||||
@@ -14,54 +14,48 @@ If you want to start using a Git and GitLab, make sure that you have created an
|
||||
|
||||
## Check if Git has already been installed
|
||||
|
||||
* Git is usually preinstalled on Mac and Linux
|
||||
|
||||
* Type the following command and then press enter
|
||||
Git is usually preinstalled on Mac and Linux.
|
||||
|
||||
Type the following command and then press enter:
|
||||
```
|
||||
git --version
|
||||
```
|
||||
|
||||
* You should receive a message that will tell you which Git version you have in your computer. If you don’t receive a "Git version" message, it means that you need to [download Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
You should receive a message that will tell you which Git version you have in your computer. If you don’t receive a "Git version" message, it means that you need to [download Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
|
||||
|
||||
* If Git doesn't automatically download, there's an option on the website to [download manually](https://git-scm.com/downloads). Then follow the steps on the installation window
|
||||
If Git doesn't automatically download, there's an option on the website to [download manually](https://git-scm.com/downloads). Then follow the steps on the installation window.
|
||||
|
||||
* After you finished installing, open a new shell and type "git --version" again to verify that it was correctly installed
|
||||
After you finished installing, open a new shell and type "git --version" again to verify that it was correctly installed.
|
||||
|
||||
## Add your Git username and set your email
|
||||
|
||||
* It is important because every Git commit that you create will use this information
|
||||
|
||||
* On your shell, type the following command to add your username
|
||||
It is important because every Git commit that you create will use this information.
|
||||
|
||||
On your shell, type the following command to add your username:
|
||||
```
|
||||
git config --global user.name ADD YOUR USERNAME
|
||||
```
|
||||
|
||||
* Then verify that you have the correct username
|
||||
|
||||
Then verify that you have the correct username:
|
||||
```
|
||||
git config --global user.name
|
||||
```
|
||||
|
||||
* To set your email address, type the following command
|
||||
|
||||
To set your email address, type the following command:
|
||||
```
|
||||
git config --global user.email ADD YOUR EMAIL
|
||||
```
|
||||
|
||||
* To verify that you entered your email correctly, type
|
||||
|
||||
To verify that you entered your email correctly, type:
|
||||
```
|
||||
git config --global user.email
|
||||
```
|
||||
|
||||
* You'll need to do this only once because you are using the "--global" option. It tells Git to always use this information for anything you do on that system. If you want to override this with a different username or email address for specific projects, you can run the command without the "--global" option when you’re in that project
|
||||
You'll need to do this only once because you are using the "--global" option. It tells Git to always use this information for anything you do on that system. If you want to override this with a different username or email address for specific projects, you can run the command without the "--global" option when you’re in that project.
|
||||
|
||||
## Check your information
|
||||
|
||||
* To view the information that you entered, type
|
||||
|
||||
To view the information that you entered, type:
|
||||
```
|
||||
git config --global --list
|
||||
```
|
||||
|
||||
@@ -404,7 +404,7 @@ NOTE: Supply `SANITIZE=true` environment variable to `gitlab:check` to omit proj
|
||||
Visit YOUR_SERVER in your web browser for your first GitLab login. The setup has created a default admin account for you. You can use it to log in:
|
||||
|
||||
root
|
||||
password
|
||||
5iveL!fe
|
||||
|
||||
**Important Note:** On login you'll be prompted to change the password.
|
||||
|
||||
|
||||
@@ -63,5 +63,10 @@ your phone's application or a recovery code to log in.
|
||||
1. Go to **Account**.
|
||||
1. Click **Disable Two-factor Authentication**.
|
||||
|
||||
## Note to GitLab administrators
|
||||
|
||||
You need to take special care to that 2FA keeps working after
|
||||
[restoring a GitLab backup](../raketasks/backup_restore.md).
|
||||
|
||||
[Google Authenticator]: https://support.google.com/accounts/answer/1066447?hl=en
|
||||
[FreeOTP]: https://fedorahosted.org/freeotp/
|
||||
|
||||
@@ -9,6 +9,13 @@ This archive will be saved in backup_path (see `config/gitlab.yml`).
|
||||
The filename will be `[TIMESTAMP]_gitlab_backup.tar`. This timestamp can be used to restore an specific backup.
|
||||
You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1.
|
||||
|
||||
You need to keep a separate copy of `/etc/gitlab/gitlab-secrets.json`
|
||||
(for omnibus packages) or `/home/git/gitlab/.secret` (for installations
|
||||
from source). This file contains the database encryption key used
|
||||
for two-factor authentication. If you restore a GitLab backup without
|
||||
restoring the database encryption key, users who have two-factor
|
||||
authentication enabled will loose access to your GitLab server.
|
||||
|
||||
If you are interested in GitLab CI backup please follow to the [CI backup documentation](https://gitlab.com/gitlab-org/gitlab-ci/blob/master/doc/raketasks/backup_restore.md)*
|
||||
|
||||
```
|
||||
@@ -143,15 +150,39 @@ with the name of your bucket:
|
||||
|
||||
## Storing configuration files
|
||||
|
||||
Please be informed that a backup does not store your configuration files.
|
||||
Please be informed that a backup does not store your configuration
|
||||
files. One reason for this is that your database contains encrypted
|
||||
information for two-factor authentication. Storing encrypted
|
||||
information along with its key in the same place defeats the purpose
|
||||
of using encryption in the first place!
|
||||
|
||||
If you use an Omnibus package please see the [instructions in the readme to backup your configuration](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#backup-and-restore-omnibus-gitlab-configuration).
|
||||
If you have a cookbook installation there should be a copy of your configuration in Chef.
|
||||
If you have an installation from source, please consider backing up your `gitlab.yml` file, any SSL keys and certificates, and your [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079).
|
||||
If you have an installation from source, please consider backing up your `.secret` file, `gitlab.yml` file, any SSL keys and certificates, and your [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079).
|
||||
|
||||
At the very **minimum** you should backup `/etc/gitlab/gitlab-secrets.json`
|
||||
(Omnibus) or `/home/git/gitlab/.secret` (source) to preserve your
|
||||
database encryption key.
|
||||
|
||||
## Restore a previously created backup
|
||||
|
||||
You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
You need to have a working GitLab installation before you can perform
|
||||
a restore. This is mainly because the system user performing the
|
||||
restore actions ('git') is usually not allowed to create or delete
|
||||
the SQL database it needs to import data into ('gitlabhq_production').
|
||||
All existing data will be either erased (SQL) or moved to a separate
|
||||
directory (repositories, uploads).
|
||||
|
||||
If some or all of your GitLab users are using two-factor authentication
|
||||
(2FA) then you must also make sure to restore
|
||||
`/etc/gitlab/gitlab-secrets.json` (Omnibus) or `/home/git/gitlab/.secret`
|
||||
(installations from source). Note that you need to run `gitlab-ctl
|
||||
reconfigure` after changing `gitlab-secrets.json`.
|
||||
|
||||
### Installation from source
|
||||
|
||||
```
|
||||
|
||||
@@ -6,6 +6,7 @@ It starts 7 working days before the release.
|
||||
The release manager doesn't have to perform all the work but must ensure someone is assigned.
|
||||
The current release manager must schedule the appointment of the next release manager.
|
||||
The new release manager should create overall issue to track the progress.
|
||||
The release manager should be the only person pushing/merging commits to the x-y-stable branches.
|
||||
|
||||
## Release Manager
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
- [Labels](labels.md)
|
||||
- [Manage large binaries with git annex](git_annex.md)
|
||||
- [Merge Request Approvals](merge_request_approvals.md)
|
||||
- [Notifications](notifications.md)
|
||||
- [Notification emails](notifications.md)
|
||||
- [Project Features](project_features.md)
|
||||
- [Project forking workflow](forking_workflow.md)
|
||||
- [Protected branches](protected_branches.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# GitLab Notifications
|
||||
# GitLab Notification Emails
|
||||
|
||||
GitLab has notifications system in place to notify a user of events important for the workflow.
|
||||
GitLab has a notification system in place to notify a user of events that are important for the workflow.
|
||||
|
||||
## Notification settings
|
||||
|
||||
@@ -67,5 +67,3 @@ Below is the table of events users can be notified of:
|
||||
| Reopen merge request | Project members [1] | [1] higher than participating |
|
||||
| Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
|
||||
| New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
|
||||
|
||||
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ RUN ( \
|
||||
echo "" && \
|
||||
echo "# Docker options" && \
|
||||
echo "# Prevent Postgres from trying to allocate 25% of total memory" && \
|
||||
echo "postgresql['shared_buffers'] = '1MB'" ) >> /etc/gitlab/gitlab.rb
|
||||
echo "postgresql['shared_buffers'] = '1MB'" ) >> /etc/gitlab/gitlab.rb && \
|
||||
mkdir -p /assets/ && \
|
||||
cp /etc/gitlab/gitlab.rb /assets/gitlab.rb
|
||||
|
||||
# Expose web & ssh
|
||||
EXPOSE 443 80 22
|
||||
|
||||
+3
-1
@@ -10,7 +10,7 @@ It might take a while before the docker container is responding to queries.
|
||||
|
||||
You can check the status with something like `sudo docker logs -f gitlab`.
|
||||
|
||||
You can login to the web interface with username `root` and password `password`.
|
||||
You can login to the web interface with username `root` and password `5iveL!fe`.
|
||||
|
||||
Next time, you can just use docker start and stop to run the container.
|
||||
|
||||
@@ -165,3 +165,5 @@ sudo docker push gitlab/gitlab-ce:latest
|
||||
Please see the [troubleshooting](troubleshooting.md) file in this directory.
|
||||
|
||||
Note: We use `fig.yml` to have compatibility with fig and because docker-compose also supports it.
|
||||
|
||||
Our docker image runs chef at every start to generate GitLab configuration.
|
||||
|
||||
@@ -13,4 +13,9 @@ function entrypoint() {
|
||||
gitlab-ctl tail # tail all logs
|
||||
}
|
||||
|
||||
if [[ ! -e /etc/gitlab/gitlab.rb ]]; then
|
||||
cp /assets/gitlab.rb /etc/gitlab/gitlab.rb
|
||||
chmod 0600 /etc/gitlab/gitlab.rb
|
||||
fi
|
||||
|
||||
entrypoint
|
||||
|
||||
@@ -17,6 +17,10 @@ Feature: Project Issues Milestones
|
||||
And I submit new milestone "v2.3"
|
||||
Then I should see milestone "v2.3"
|
||||
|
||||
Scenario: I delete new milestone
|
||||
Given I click link to remove milestone "v2.2"
|
||||
And I should see no milestones
|
||||
|
||||
@javascript
|
||||
Scenario: Listing closed issues
|
||||
Given the milestone has open and closed issues
|
||||
|
||||
@@ -56,4 +56,12 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
|
||||
step 'I should see 3 issues' do
|
||||
expect(page).to have_selector('#tab-issues li.issue-row', count: 4)
|
||||
end
|
||||
|
||||
step 'I click link to remove milestone "v2.2"' do
|
||||
click_link 'Remove'
|
||||
end
|
||||
|
||||
step 'I should see no milestones' do
|
||||
expect(page).to have_content('No milestones to show')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -181,6 +181,7 @@ module API
|
||||
expose :source_project_id, :target_project_id
|
||||
expose :label_names, as: :labels
|
||||
expose :description
|
||||
expose :work_in_progress?, as: :work_in_progress
|
||||
expose :milestone, using: Entities::Milestone
|
||||
end
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ module Backup
|
||||
abort 'Backup failed' unless success
|
||||
|
||||
$progress.print 'Compressing database ... '
|
||||
FileUtils.rm_f db_file_name_gz
|
||||
success = system('gzip', db_file_name)
|
||||
report_success(success)
|
||||
abort 'Backup failed: compress error' unless success
|
||||
|
||||
@@ -327,7 +327,7 @@ module Gitlab
|
||||
link = "https://storage.googleapis.com/google-code-attachments/#{@repo.name}/issue-#{issue_id}/comment-#{comment_id}/#{filename}"
|
||||
|
||||
text = "[#{filename}](#{link})"
|
||||
text = "!#{text}" if filename =~ /\.(png|jpg|jpeg|gif|bmp|tiff)\z/
|
||||
text = "!#{text}" if filename =~ /\.(png|jpg|jpeg|gif|bmp|tiff)\z/i
|
||||
text
|
||||
end.compact
|
||||
end
|
||||
|
||||
@@ -187,7 +187,7 @@ module Gitlab
|
||||
end
|
||||
|
||||
def remove_source_branch(repo)
|
||||
if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch) && !merge_request.for_fork?
|
||||
if merge_request.remove_source_branch?
|
||||
# will raise CommandFailed when push fails
|
||||
repo.git.push(default_options, :origin, ":#{merge_request.source_branch}")
|
||||
end
|
||||
|
||||
@@ -18,4 +18,12 @@ class RepositoryCache
|
||||
def fetch(key, &block)
|
||||
backend.fetch(cache_key(key), &block)
|
||||
end
|
||||
|
||||
def exist?(key)
|
||||
backend.exist?(cache_key(key))
|
||||
end
|
||||
|
||||
def read(key)
|
||||
backend.read(cache_key(key))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ shell_path="/bin/bash"
|
||||
test -f /etc/default/gitlab && . /etc/default/gitlab
|
||||
|
||||
# Switch to the app_user if it is not he/she who is running the script.
|
||||
if [ "$USER" != "$app_user" ]; then
|
||||
if [ `whoami` != "$app_user" ]; then
|
||||
eval su - "$app_user" -s $shell_path -c $(echo \")$0 "$@"$(echo \"); exit;
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Projects::MilestonesController do
|
||||
let(:project) { create(:project) }
|
||||
let(:user) { create(:user) }
|
||||
let(:milestone) { create(:milestone, project: project) }
|
||||
let(:issue) { create(:issue, project: project, milestone: milestone) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
project.team << [user, :master]
|
||||
controller.instance_variable_set(:@project, project)
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
it "should remove milestone" do
|
||||
expect(issue.milestone_id).to eq(milestone.id)
|
||||
delete :destroy, namespace_id: project.namespace.id, project_id: project.id, id: milestone.id, format: :js
|
||||
expect(response).to be_success
|
||||
expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound)
|
||||
issue.reload
|
||||
expect(issue.milestone_id).to eq(nil)
|
||||
# Check system note left for milestone removal
|
||||
last_note = project.issues.find(issue.id).notes[-1].note
|
||||
expect(last_note).to eq('Milestone removed')
|
||||
end
|
||||
end
|
||||
end
|
||||
+26
-3
@@ -8,9 +8,6 @@ describe Projects::TreeController do
|
||||
sign_in(user)
|
||||
|
||||
project.team << [user, :master]
|
||||
|
||||
allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz'])
|
||||
allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0'])
|
||||
controller.instance_variable_set(:@project, project)
|
||||
end
|
||||
|
||||
@@ -44,6 +41,32 @@ describe Projects::TreeController do
|
||||
let(:id) { 'invalid-branch/encoding/' }
|
||||
it { is_expected.to respond_with(:not_found) }
|
||||
end
|
||||
|
||||
context "valid empty branch, invalid path" do
|
||||
let(:id) { 'empty-branch/invalid-path/' }
|
||||
it { is_expected.to respond_with(:not_found) }
|
||||
end
|
||||
|
||||
context "valid empty branch" do
|
||||
let(:id) { 'empty-branch' }
|
||||
it { is_expected.to respond_with(:success) }
|
||||
end
|
||||
|
||||
context "invalid SHA commit ID" do
|
||||
let(:id) { 'ff39438/.gitignore' }
|
||||
it { is_expected.to respond_with(:not_found) }
|
||||
end
|
||||
|
||||
context "valid SHA commit ID" do
|
||||
let(:id) { '6d39438' }
|
||||
it { is_expected.to respond_with(:success) }
|
||||
end
|
||||
|
||||
context "valid SHA commit ID with path" do
|
||||
let(:id) { '6d39438/.gitignore' }
|
||||
it { expect(response.status).to eq(302) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'GET show with blob path' do
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Admin::Projects", feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
describe "GET /admin/projects" do
|
||||
subject { admin_namespaces_projects_path }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Dashboard access", feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
describe "GET /dashboard" do
|
||||
subject { dashboard_path }
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Group access", feature: true do
|
||||
describe "GET /projects/new" do
|
||||
it { expect(new_group_path).to be_allowed_for :admin }
|
||||
it { expect(new_group_path).to be_allowed_for :user }
|
||||
it { expect(new_group_path).to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "Group" do
|
||||
let(:group) { create(:group) }
|
||||
|
||||
let(:owner) { create(:owner) }
|
||||
let(:master) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:nonmember) { create(:user) }
|
||||
|
||||
before do
|
||||
group.add_user(owner, Gitlab::Access::OWNER)
|
||||
group.add_user(master, Gitlab::Access::MASTER)
|
||||
group.add_user(reporter, Gitlab::Access::REPORTER)
|
||||
group.add_user(guest, Gitlab::Access::GUEST)
|
||||
end
|
||||
|
||||
describe "GET /groups/:path" do
|
||||
subject { group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/issues" do
|
||||
subject { issues_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/merge_requests" do
|
||||
subject { merge_requests_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/group_members" do
|
||||
subject { group_group_members_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/edit" do
|
||||
subject { edit_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_denied_for master }
|
||||
it { is_expected.to be_denied_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/projects" do
|
||||
subject { projects_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_denied_for master }
|
||||
it { is_expected.to be_denied_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,82 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Group with internal project access", feature: true do
|
||||
describe "Group" do
|
||||
let(:group) { create(:group) }
|
||||
|
||||
let(:owner) { create(:owner) }
|
||||
let(:master) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:nonmember) { create(:user) }
|
||||
|
||||
before do
|
||||
group.add_user(owner, Gitlab::Access::OWNER)
|
||||
group.add_user(master, Gitlab::Access::MASTER)
|
||||
group.add_user(reporter, Gitlab::Access::REPORTER)
|
||||
group.add_user(guest, Gitlab::Access::GUEST)
|
||||
|
||||
create(:project, :internal, group: group)
|
||||
end
|
||||
|
||||
describe "GET /groups/:path" do
|
||||
subject { group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/issues" do
|
||||
subject { issues_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/merge_requests" do
|
||||
subject { merge_requests_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/group_members" do
|
||||
subject { group_group_members_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/edit" do
|
||||
subject { edit_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_denied_for master }
|
||||
it { is_expected.to be_denied_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,83 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Group access", feature: true do
|
||||
describe "Group" do
|
||||
let(:group) { create(:group) }
|
||||
|
||||
let(:owner) { create(:owner) }
|
||||
let(:master) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:nonmember) { create(:user) }
|
||||
|
||||
before do
|
||||
group.add_user(owner, Gitlab::Access::OWNER)
|
||||
group.add_user(master, Gitlab::Access::MASTER)
|
||||
group.add_user(reporter, Gitlab::Access::REPORTER)
|
||||
group.add_user(guest, Gitlab::Access::GUEST)
|
||||
|
||||
create(:project, :internal, path: "internal_project", group: group)
|
||||
create(:project, :public, path: "public_project", group: group)
|
||||
end
|
||||
|
||||
describe "GET /groups/:path" do
|
||||
subject { group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/issues" do
|
||||
subject { issues_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/merge_requests" do
|
||||
subject { merge_requests_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/group_members" do
|
||||
subject { group_group_members_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/edit" do
|
||||
subject { edit_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_denied_for master }
|
||||
it { is_expected.to be_denied_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,82 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Group with public project access", feature: true do
|
||||
describe "Group" do
|
||||
let(:group) { create(:group) }
|
||||
|
||||
let(:owner) { create(:owner) }
|
||||
let(:master) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:nonmember) { create(:user) }
|
||||
|
||||
before do
|
||||
group.add_user(owner, Gitlab::Access::OWNER)
|
||||
group.add_user(master, Gitlab::Access::MASTER)
|
||||
group.add_user(reporter, Gitlab::Access::REPORTER)
|
||||
group.add_user(guest, Gitlab::Access::GUEST)
|
||||
|
||||
create(:project, :public, group: group)
|
||||
end
|
||||
|
||||
describe "GET /groups/:path" do
|
||||
subject { group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/issues" do
|
||||
subject { issues_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/merge_requests" do
|
||||
subject { merge_requests_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/group_members" do
|
||||
subject { group_group_members_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /groups/:path/edit" do
|
||||
subject { edit_group_path(group) }
|
||||
|
||||
it { is_expected.to be_allowed_for owner }
|
||||
it { is_expected.to be_denied_for master }
|
||||
it { is_expected.to be_denied_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,284 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Group access', feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
def group
|
||||
@group ||= create(:group)
|
||||
end
|
||||
|
||||
def create_project(access_level)
|
||||
if access_level == :mixed
|
||||
create(:empty_project, :public, group: group)
|
||||
create(:empty_project, :internal, group: group)
|
||||
else
|
||||
create(:empty_project, access_level, group: group)
|
||||
end
|
||||
end
|
||||
|
||||
def group_member(access_level, group = group)
|
||||
level = Object.const_get("Gitlab::Access::#{access_level.upcase}")
|
||||
|
||||
create(:user).tap do |user|
|
||||
group.add_user(user, level)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /groups/new' do
|
||||
subject { new_group_path }
|
||||
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe 'GET /groups/:path' do
|
||||
subject { group_path(group) }
|
||||
|
||||
context 'with public projects' do
|
||||
before(:all) { create_project(:public) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with mixed projects' do
|
||||
before(:all) { create_project(:mixed) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with internal projects' do
|
||||
before(:all) { create_project(:internal) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with no projects' do
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /groups/:path/issues' do
|
||||
subject { issues_group_path(group) }
|
||||
|
||||
context 'with public projects' do
|
||||
before(:all) { create_project(:public) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with mixed projects' do
|
||||
before(:all) { create_project(:mixed) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with internal projects' do
|
||||
before(:all) { create_project(:internal) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with no projects' do
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /groups/:path/merge_requests' do
|
||||
subject { merge_requests_group_path(group) }
|
||||
|
||||
context 'with public projects' do
|
||||
before(:all) { create_project(:public) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with mixed projects' do
|
||||
before(:all) { create_project(:mixed) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with internal projects' do
|
||||
before(:all) { create_project(:internal) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with no projects' do
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /groups/:path/group_members' do
|
||||
subject { group_group_members_path(group) }
|
||||
|
||||
context 'with public projects' do
|
||||
before(:all) { create_project(:public) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with mixed projects' do
|
||||
before(:all) { create_project(:mixed) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
context 'with internal projects' do
|
||||
before(:all) { create_project(:internal) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with no projects' do
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_allowed_for group_member(:master) }
|
||||
it { is_expected.to be_allowed_for group_member(:reporter) }
|
||||
it { is_expected.to be_allowed_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /groups/:path/edit' do
|
||||
subject { edit_group_path(group) }
|
||||
|
||||
context 'with public projects' do
|
||||
before(:all) { create_project(:public) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_denied_for group_member(:master) }
|
||||
it { is_expected.to be_denied_for group_member(:reporter) }
|
||||
it { is_expected.to be_denied_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with mixed projects' do
|
||||
before(:all) { create_project(:mixed) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_denied_for group_member(:master) }
|
||||
it { is_expected.to be_denied_for group_member(:reporter) }
|
||||
it { is_expected.to be_denied_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with internal projects' do
|
||||
before(:all) { create_project(:internal) }
|
||||
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_denied_for group_member(:master) }
|
||||
it { is_expected.to be_denied_for group_member(:reporter) }
|
||||
it { is_expected.to be_denied_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
context 'with no projects' do
|
||||
it { is_expected.to be_allowed_for group_member(:owner) }
|
||||
it { is_expected.to be_denied_for group_member(:master) }
|
||||
it { is_expected.to be_denied_for group_member(:reporter) }
|
||||
it { is_expected.to be_denied_for group_member(:guest) }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,18 +1,11 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Profile access", feature: true do
|
||||
before do
|
||||
@u1 = create(:user)
|
||||
end
|
||||
|
||||
describe "GET /login" do
|
||||
it { expect(new_user_session_path).not_to be_not_found_for :visitor }
|
||||
end
|
||||
include AccessMatchers
|
||||
|
||||
describe "GET /profile/keys" do
|
||||
subject { profile_keys_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
@@ -21,7 +14,6 @@ describe "Profile access", feature: true do
|
||||
describe "GET /profile" do
|
||||
subject { profile_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
@@ -30,7 +22,6 @@ describe "Profile access", feature: true do
|
||||
describe "GET /profile/account" do
|
||||
subject { profile_account_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
@@ -39,7 +30,6 @@ describe "Profile access", feature: true do
|
||||
describe "GET /profile/preferences" do
|
||||
subject { profile_preferences_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
@@ -48,7 +38,6 @@ describe "Profile access", feature: true do
|
||||
describe "GET /profile/audit_log" do
|
||||
subject { audit_log_profile_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
@@ -57,7 +46,6 @@ describe "Profile access", feature: true do
|
||||
describe "GET /profile/notifications" do
|
||||
subject { profile_notifications_path }
|
||||
|
||||
it { is_expected.to be_allowed_for @u1 }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Internal Project Access", feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
let(:project) { create(:project, :internal) }
|
||||
|
||||
let(:master) { create(:user) }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Private Project Access", feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
let(:project) { create(:project) }
|
||||
|
||||
let(:master) { create(:user) }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Public Project Access", feature: true do
|
||||
include AccessMatchers
|
||||
|
||||
let(:project) { create(:project) }
|
||||
|
||||
let(:master) { create(:user) }
|
||||
@@ -17,7 +19,6 @@ describe "Public Project Access", feature: true do
|
||||
|
||||
# readonly
|
||||
project.team << [reporter, :reporter]
|
||||
|
||||
end
|
||||
|
||||
describe "Project should be public" do
|
||||
|
||||
+5
@@ -382,6 +382,11 @@
|
||||
"fileName" : "screenshot.png",
|
||||
"fileSize" : 0,
|
||||
"mimetype" : "image/png"
|
||||
}, {
|
||||
"attachmentId" : "001",
|
||||
"fileName" : "screenshot1.PNG",
|
||||
"fileSize" : 0,
|
||||
"mimetype" : "image/x-png"
|
||||
} ]
|
||||
}, {
|
||||
"id" : 1,
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
.file-content
|
||||
.line-numbers
|
||||
- 1.upto(25) do |i|
|
||||
%a{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i}= i
|
||||
%a{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i}
|
||||
%i.fa.fa-link
|
||||
= i
|
||||
%pre.code.highlight
|
||||
%code
|
||||
- 1.upto(25) do |i|
|
||||
|
||||
@@ -48,6 +48,14 @@ describe 'LineHighlighter', ->
|
||||
clickLine(13)
|
||||
expect(spy).toHaveBeenPrevented()
|
||||
|
||||
it 'handles clicking on a child icon element', ->
|
||||
spy = spyOn(@class, 'setHash').and.callThrough()
|
||||
|
||||
$('#L13 i').mousedown().click()
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(13)
|
||||
expect($('#LC13')).toHaveClass(@css)
|
||||
|
||||
describe 'without shiftKey', ->
|
||||
it 'highlights one line when clicked', ->
|
||||
clickLine(13)
|
||||
|
||||
@@ -65,6 +65,7 @@ describe Gitlab::GoogleCodeImport::Importer do
|
||||
expect(issue.description).to include('all the best!')
|
||||
expect(issue.description).to include('[tint2_task_scrolling.diff](https://storage.googleapis.com/google-code-attachments/tint2/issue-169/comment-0/tint2_task_scrolling.diff)')
|
||||
expect(issue.description).to include('')
|
||||
expect(issue.description).to include('')
|
||||
end
|
||||
|
||||
it "imports issue comments" do
|
||||
|
||||
@@ -26,6 +26,33 @@ describe GitlabCiService do
|
||||
it { is_expected.to have_one(:service_hook) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
context 'active' do
|
||||
before { allow(subject).to receive(:activated?).and_return(true) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:token) }
|
||||
it { is_expected.to validate_presence_of(:project_url) }
|
||||
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
|
||||
it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_url) }
|
||||
it { is_expected.not_to allow_value('token with spaces').for(:token) }
|
||||
it { is_expected.not_to allow_value('token/with%spaces').for(:token) }
|
||||
it { is_expected.not_to allow_value('this is not url').for(:project_url) }
|
||||
it { is_expected.not_to allow_value('http//noturl').for(:project_url) }
|
||||
it { is_expected.not_to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
|
||||
end
|
||||
|
||||
context 'inactive' do
|
||||
before { allow(subject).to receive(:activated?).and_return(false) }
|
||||
|
||||
it { is_expected.not_to validate_presence_of(:token) }
|
||||
it { is_expected.not_to validate_presence_of(:project_url) }
|
||||
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
|
||||
it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_url) }
|
||||
it { is_expected.to allow_value('token with spaces').for(:token) }
|
||||
it { is_expected.to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'commits methods' do
|
||||
before do
|
||||
@service = GitlabCiService.new
|
||||
|
||||
@@ -14,10 +14,13 @@ describe API::API, api: true do
|
||||
|
||||
describe "GET /projects/:id/repository/branches" do
|
||||
it "should return an array of project branches" do
|
||||
project.repository.expire_cache
|
||||
|
||||
get api("/projects/#{project.id}/repository/branches", user)
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.first['name']).to eq(project.repository.branch_names.first)
|
||||
branch_names = json_response.map { |x| x['name'] }
|
||||
expect(branch_names).to match_array(project.repository.branch_names)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ describe API::API, api: true do
|
||||
|
||||
it 'returns projects in the correct order when ci_enabled_first parameter is passed' do
|
||||
[project, project2, project3].each{ |project| project.build_missing_services }
|
||||
project2.gitlab_ci_service.update(active: true, token: "token", project_url: "url")
|
||||
project2.gitlab_ci_service.update(active: true, token: "token", project_url: "http://ci.example.com/projects/1")
|
||||
get api('/projects', user), { ci_enabled_first: 'true' }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
|
||||
@@ -7,7 +7,7 @@ describe API::API, api: true do
|
||||
|
||||
describe "POST /projects/:id/services/gitlab-ci" do
|
||||
it "should update gitlab-ci settings" do
|
||||
put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'secret-token', project_url: "http://ci.example.com/projects/1"
|
||||
put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'secrettoken', project_url: "http://ci.example.com/projects/1"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
@@ -17,6 +17,18 @@ describe API::API, api: true do
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it "should return if the format of token is invalid" do
|
||||
put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'token-with dashes and spaces%', project_url: "http://ci.example.com/projects/1", active: true
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "should return if the format of token is invalid" do
|
||||
put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'token-with dashes and spaces%', project_url: "ftp://ci.example/projects/1", active: true
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /projects/:id/services/gitlab-ci" do
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
RSpec::Matchers.define :be_valid_commit do
|
||||
match do |actual|
|
||||
actual &&
|
||||
actual.id == ValidCommit::ID &&
|
||||
actual.message == ValidCommit::MESSAGE &&
|
||||
actual.author_name == ValidCommit::AUTHOR_FULL_NAME
|
||||
end
|
||||
end
|
||||
|
||||
def emulate_user(user)
|
||||
user = case user
|
||||
when :user then create(:user)
|
||||
when :visitor then nil
|
||||
when :admin then create(:admin)
|
||||
else user
|
||||
end
|
||||
login_with(user) if user
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :be_allowed_for do |user|
|
||||
match do |url|
|
||||
emulate_user(user)
|
||||
visit url
|
||||
status_code != 404 && current_path != new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :be_denied_for do |user|
|
||||
match do |url|
|
||||
emulate_user(user)
|
||||
visit url
|
||||
status_code == 404 || current_path == new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :be_not_found_for do |user|
|
||||
match do |url|
|
||||
emulate_user(user)
|
||||
visit url
|
||||
status_code == 404
|
||||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :include_module do |expected|
|
||||
match do
|
||||
described_class.included_modules.include?(expected)
|
||||
end
|
||||
|
||||
description do
|
||||
"includes the #{expected} module"
|
||||
end
|
||||
|
||||
failure_message do
|
||||
"expected #{described_class} to include the #{expected} module"
|
||||
end
|
||||
end
|
||||
|
||||
# Extend shoulda-matchers
|
||||
module Shoulda::Matchers::ActiveModel
|
||||
class ValidateLengthOfMatcher
|
||||
# Shortcut for is_at_least and is_at_most
|
||||
def is_within(range)
|
||||
is_at_least(range.min) && is_at_most(range.max)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
# AccessMatchers
|
||||
#
|
||||
# The custom matchers contained in this module are used to test a user's access
|
||||
# to a URL by emulating a specific user or type of user account, visiting the
|
||||
# URL, and then checking the response status code and resulting path.
|
||||
module AccessMatchers
|
||||
extend RSpec::Matchers::DSL
|
||||
include Warden::Test::Helpers
|
||||
|
||||
def emulate_user(user)
|
||||
case user
|
||||
when :user
|
||||
login_as(create(:user))
|
||||
when :visitor
|
||||
logout
|
||||
when :admin
|
||||
login_as(create(:admin))
|
||||
when User
|
||||
login_as(user)
|
||||
else
|
||||
raise ArgumentError, "cannot emulate user #{user}"
|
||||
end
|
||||
end
|
||||
|
||||
def description_for(user, type)
|
||||
if user.kind_of?(User)
|
||||
# User#inspect displays too much information for RSpec's description
|
||||
# messages
|
||||
"be #{type} for supplied User"
|
||||
else
|
||||
"be #{type} for #{user}"
|
||||
end
|
||||
end
|
||||
|
||||
matcher :be_allowed_for do |user|
|
||||
match do |url|
|
||||
emulate_user(user)
|
||||
visit url
|
||||
status_code != 404 && current_path != new_user_session_path
|
||||
end
|
||||
|
||||
description { description_for(user, 'allowed') }
|
||||
end
|
||||
|
||||
matcher :be_denied_for do |user|
|
||||
match do |url|
|
||||
emulate_user(user)
|
||||
visit url
|
||||
status_code == 404 || current_path == new_user_session_path
|
||||
end
|
||||
|
||||
description { description_for(user, 'denied') }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
RSpec::Matchers.define :include_module do |expected|
|
||||
match do
|
||||
described_class.included_modules.include?(expected)
|
||||
end
|
||||
|
||||
description do
|
||||
"includes the #{expected} module"
|
||||
end
|
||||
|
||||
failure_message do
|
||||
"expected #{described_class} to include the #{expected} module"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
# Extend shoulda-matchers
|
||||
module Shoulda::Matchers::ActiveModel
|
||||
class ValidateLengthOfMatcher
|
||||
# Shortcut for is_at_least and is_at_most
|
||||
def is_within(range)
|
||||
is_at_least(range.min) && is_at_most(range.max)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,7 @@ module TestEnv
|
||||
|
||||
# When developing the seed repository, comment out the branch you will modify.
|
||||
BRANCH_SHA = {
|
||||
'empty-branch' => '7efb185',
|
||||
'flatten-dir' => 'e56497b',
|
||||
'feature' => '0b4bc9a',
|
||||
'feature_conflict' => 'bb5206f',
|
||||
@@ -14,9 +15,13 @@ module TestEnv
|
||||
'master' => '5937ac0'
|
||||
}
|
||||
|
||||
FORKED_BRANCH_SHA = BRANCH_SHA.merge({
|
||||
'add-submodule-version-bump' => '3f547c08'
|
||||
})
|
||||
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily
|
||||
# need to keep all the branches in sync.
|
||||
# We currently only need a subset of the branches
|
||||
FORKED_BRANCH_SHA = {
|
||||
'add-submodule-version-bump' => '3f547c08',
|
||||
'master' => '5937ac0'
|
||||
}
|
||||
|
||||
# Test environment
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user