Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into spread-runner-last-updated-at
This commit is contained in:
commit
2674a14bec
27 changed files with 359 additions and 162 deletions
|
@ -13,9 +13,13 @@ v 8.2.0 (unreleased)
|
|||
- Fix: Inability to reply to code comments in the MR view, if the MR comes from a fork
|
||||
- Use git follow flag for commits page when retrieve history for file or directory
|
||||
- Show merge request CI status on merge requests index page
|
||||
- Extend yml syntax for only and except to support specifying repository path
|
||||
- Fix: 500 error returned if destroy request without HTTP referer (Kazuki Shimizu)
|
||||
- Remove deprecated CI events from project settings page
|
||||
- Use issue editor as cross reference comment author when issue is edited with a new mention.
|
||||
- [API] Add ability to fetch the commit ID of the last commit that actually touched a file
|
||||
- Add "New file" link to dropdown on project page
|
||||
- Include commit logs in project search
|
||||
|
||||
v 8.1.3
|
||||
- Spread out runner contacted_at updates
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
}
|
||||
|
||||
li.commit {
|
||||
list-style: none;
|
||||
|
||||
.commit-row-title {
|
||||
font-size: $list-font-size;
|
||||
line-height: 20px;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class ProjectsController < ApplicationController
|
||||
include ExtractsPath
|
||||
|
||||
prepend_before_filter :render_go_import, only: [:show]
|
||||
prepend_before_action :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]
|
||||
|
|
|
@ -23,8 +23,8 @@ class SearchController < ApplicationController
|
|||
|
||||
@search_results =
|
||||
if @project
|
||||
unless %w(blobs notes issues merge_requests milestones wiki_blobs).
|
||||
include?(@scope)
|
||||
unless %w(blobs notes issues merge_requests milestones wiki_blobs
|
||||
commits).include?(@scope)
|
||||
@scope = 'blobs'
|
||||
end
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ module Ci
|
|||
end
|
||||
|
||||
def config_processor
|
||||
@config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file)
|
||||
@config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file, gl_project.path_with_namespace)
|
||||
rescue Ci::GitlabCiYamlProcessor::ValidationError => e
|
||||
save_yaml_error(e.message)
|
||||
nil
|
||||
|
|
|
@ -87,6 +87,15 @@ class Repository
|
|||
commits
|
||||
end
|
||||
|
||||
def find_commits_by_message(query)
|
||||
# Limited to 1000 commits for now, could be parameterized?
|
||||
args = %W(git log --pretty=%H --max-count 1000 --grep=#{query})
|
||||
|
||||
git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:chomp)
|
||||
commits = git_log_results.map { |c| commit(c) }
|
||||
commits
|
||||
end
|
||||
|
||||
def find_branch(name)
|
||||
branches.find { |branch| branch.name == name }
|
||||
end
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
= hidden_field_tag :scope, 'merge_requests'
|
||||
- elsif current_controller?(:wikis)
|
||||
= hidden_field_tag :scope, 'wiki_blobs'
|
||||
- elsif current_controller?(:commits)
|
||||
= hidden_field_tag :scope, 'commits'
|
||||
- else
|
||||
= hidden_field_tag :search_code, true
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
New snippet
|
||||
- if can?(current_user, :push_code, @project)
|
||||
%li.divider
|
||||
%li
|
||||
= link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), title: 'New file' do
|
||||
= icon('file fw')
|
||||
New file
|
||||
%li
|
||||
= link_to new_namespace_project_branch_path(@project.namespace, @project) do
|
||||
= icon('code-fork fw')
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
Wiki
|
||||
%span.badge
|
||||
= @search_results.wiki_blobs_count
|
||||
%li{class: ("active" if @scope == 'commits')}
|
||||
= link_to search_filter_path(scope: 'commits') do
|
||||
= icon('history fw')
|
||||
%span
|
||||
Commits
|
||||
%span.badge
|
||||
= @search_results.commits_count
|
||||
|
||||
- elsif @show_snippets
|
||||
%li{class: ("active" if @scope == 'snippet_blobs')}
|
||||
|
|
2
app/views/search/results/_commit.html.haml
Normal file
2
app/views/search/results/_commit.html.haml
Normal file
|
@ -0,0 +1,2 @@
|
|||
.search-result-row
|
||||
= render 'projects/commits/commit', project: @project, commit: commit
|
|
@ -8,24 +8,3 @@
|
|||
# inflect.irregular 'person', 'people'
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
# Mark "commits" as uncountable.
|
||||
#
|
||||
# Without this change, the routes
|
||||
#
|
||||
# resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
|
||||
# resources :commits, only: [:show], constraints: {id: /.+/}
|
||||
#
|
||||
# would generate identical route helper methods (`project_commit_path`), resulting
|
||||
# in one of them not getting a helper method at all.
|
||||
#
|
||||
# After this change, the helper methods are:
|
||||
#
|
||||
# project_commit_path(@project, @project.commit)
|
||||
# # => "/gitlabhq/commit/bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a
|
||||
#
|
||||
# project_commits_path(@project, 'stable/README.md')
|
||||
# # => "/gitlabhq/commits/stable/README.md"
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.uncountable %w(commits)
|
||||
end
|
||||
|
|
|
@ -23,7 +23,8 @@ Example response:
|
|||
"content": "IyA9PSBTY2hlbWEgSW5mb3...",
|
||||
"ref": "master",
|
||||
"blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
|
||||
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
|
||||
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
|
||||
"last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Build script examples
|
||||
|
||||
+ [Test and deploy Ruby applications to Heroku](test-and-deploy-ruby-application-to-heroku.md)
|
||||
+ [Test and deploy Python applications to Heroku](test-and-deploy-python-application-to-heroku.md)
|
||||
+ [Test Clojure applications](test-clojure-application.md)
|
||||
+ [Test and deploy a Ruby application to Heroku](test-and-deploy-ruby-application-to-heroku.md)
|
||||
+ [Test and deploy a Python application to Heroku](test-and-deploy-python-application-to-heroku.md)
|
||||
+ [Test a Clojure application](test-clojure-application.md)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Test and Deploy a python application
|
||||
This example will guide you how to run tests in your Python application and deploy it automatically as Heroku application.
|
||||
|
||||
You can checkout the example [source](https://gitlab.com/ayufan/python-getting-started) and check [CI status](https://ci.gitlab.com/projects/4080).
|
||||
You can checkout the example [source](https://gitlab.com/ayufan/python-getting-started) and check [CI status](https://gitlab.com/ayufan/python-getting-started/builds?scope=all).
|
||||
|
||||
### Configure project
|
||||
This is what the `.gitlab-ci.yml` file looks like for this project:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Test and Deploy a ruby application
|
||||
This example will guide you how to run tests in your Ruby application and deploy it automatiacally as Heroku application.
|
||||
|
||||
You can checkout the example [source](https://gitlab.com/ayufan/ruby-getting-started) and check [CI status](https://ci.gitlab.com/projects/4050).
|
||||
You can checkout the example [source](https://gitlab.com/ayufan/ruby-getting-started) and check [CI status](https://gitlab.com/ayufan/ruby-getting-started/builds?scope=all).
|
||||
|
||||
### Configure project
|
||||
This is what the `.gitlab-ci.yml` file looks like for this project:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## Test Clojure applications
|
||||
## Test a Clojure application
|
||||
|
||||
This example will guide you how to run tests in your Clojure application.
|
||||
|
||||
You can checkout the example [source](https://gitlab.com/dzaporozhets/clojure-web-application) and check [CI status](https://ci.gitlab.com/projects/6306).
|
||||
You can checkout the example [source](https://gitlab.com/dzaporozhets/clojure-web-application) and check [CI status](https://gitlab.com/dzaporozhets/clojure-web-application/builds?scope=all).
|
||||
|
||||
### Configure project
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ This are two parameters that allow for setting a refs policy to limit when jobs
|
|||
|
||||
There are a few rules that apply to usage of refs policy:
|
||||
|
||||
1. `only` and `except` are exclusive. If both `only` and `except` are defined in job specification only `only` is taken into account.
|
||||
1. `only` and `except` are inclusive. If both `only` and `except` are defined in job specification the ref is filtered by `only` and `except`.
|
||||
1. `only` and `except` allow for using the regexp expressions.
|
||||
1. `only` and `except` allow for using special keywords: `branches` and `tags`.
|
||||
These names can be used for example to exclude all tags and all branches.
|
||||
|
@ -182,6 +182,18 @@ job:
|
|||
- branches # use special keyword
|
||||
```
|
||||
|
||||
1. `only` and `except` allow for specify repository path to filter jobs for forks.
|
||||
The repository path can be used to have jobs executed only for parent repository.
|
||||
|
||||
```yaml
|
||||
job:
|
||||
only:
|
||||
- branches@gitlab-org/gitlab-ce
|
||||
except:
|
||||
- master@gitlab-org/gitlab-ce
|
||||
```
|
||||
The above will run `job` for all branches on `gitlab-org/gitlab-ce`, except master .
|
||||
|
||||
### tags
|
||||
`tags` is used to select specific runners from the list of all runners that are allowed to run this project.
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ module API
|
|||
# "content": "IyA9PSBTY2hlbWEgSW5mb3...",
|
||||
# "ref": "master",
|
||||
# "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
|
||||
# "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
|
||||
# "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
|
||||
# "last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
|
||||
# }
|
||||
#
|
||||
get ":id/repository/files" do
|
||||
|
@ -71,6 +72,7 @@ module API
|
|||
ref: ref,
|
||||
blob_id: blob.id,
|
||||
commit_id: commit.id,
|
||||
last_commit_id: user_project.repository.last_commit_for_path(commit.sha, file_path).id
|
||||
}
|
||||
else
|
||||
not_found! 'File'
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'backup/files'
|
||||
|
||||
module Backup
|
||||
class Builds < Files
|
||||
def initialize
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'backup/files'
|
||||
|
||||
module Backup
|
||||
class Uploads < Files
|
||||
|
||||
|
|
|
@ -7,10 +7,11 @@ module Ci
|
|||
ALLOWED_YAML_KEYS = [:before_script, :image, :services, :types, :stages, :variables]
|
||||
ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, :allow_failure, :type, :stage, :when]
|
||||
|
||||
attr_reader :before_script, :image, :services, :variables
|
||||
attr_reader :before_script, :image, :services, :variables, :path
|
||||
|
||||
def initialize(config)
|
||||
def initialize(config, path = nil)
|
||||
@config = YAML.load(config)
|
||||
@path = path
|
||||
|
||||
unless @config.is_a? Hash
|
||||
raise ValidationError, "YAML should be a hash"
|
||||
|
@ -63,26 +64,6 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def process?(only_params, except_params, ref, tag)
|
||||
return true if only_params.nil? && except_params.nil?
|
||||
|
||||
if only_params
|
||||
return true if tag && only_params.include?("tags")
|
||||
return true if !tag && only_params.include?("branches")
|
||||
|
||||
only_params.find do |pattern|
|
||||
match_ref?(pattern, ref)
|
||||
end
|
||||
else
|
||||
return false if tag && except_params.include?("tags")
|
||||
return false if !tag && except_params.include?("branches")
|
||||
|
||||
except_params.each do |pattern|
|
||||
return false if match_ref?(pattern, ref)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_job(name, job)
|
||||
{
|
||||
stage_idx: stages.index(job[:stage]),
|
||||
|
@ -101,14 +82,6 @@ module Ci
|
|||
}
|
||||
end
|
||||
|
||||
def match_ref?(pattern, ref)
|
||||
if pattern.first == "/" && pattern.last == "/"
|
||||
Regexp.new(pattern[1...-1]) =~ ref
|
||||
else
|
||||
pattern == ref
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_script(script)
|
||||
if script.is_a? Array
|
||||
script.join("\n")
|
||||
|
@ -208,5 +181,36 @@ module Ci
|
|||
def validate_string(value)
|
||||
value.is_a?(String) || value.is_a?(Symbol)
|
||||
end
|
||||
|
||||
def process?(only_params, except_params, ref, tag)
|
||||
if only_params.present?
|
||||
return false unless matching?(only_params, ref, tag)
|
||||
end
|
||||
|
||||
if except_params.present?
|
||||
return false if matching?(except_params, ref, tag)
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def matching?(patterns, ref, tag)
|
||||
patterns.any? do |pattern|
|
||||
match_ref?(pattern, ref, tag)
|
||||
end
|
||||
end
|
||||
|
||||
def match_ref?(pattern, ref, tag)
|
||||
pattern, path = pattern.split('@', 2)
|
||||
return false if path && path != self.path
|
||||
return true if tag && pattern == 'tags'
|
||||
return true if !tag && pattern == 'branches'
|
||||
|
||||
if pattern.first == "/" && pattern.last == "/"
|
||||
Regexp.new(pattern[1...-1]) =~ ref
|
||||
else
|
||||
pattern == ref
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,8 @@ module Gitlab
|
|||
Kaminari.paginate_array(blobs).page(page).per(per_page)
|
||||
when 'wiki_blobs'
|
||||
Kaminari.paginate_array(wiki_blobs).page(page).per(per_page)
|
||||
when 'commits'
|
||||
Kaminari.paginate_array(commits).page(page).per(per_page)
|
||||
else
|
||||
super
|
||||
end
|
||||
|
@ -27,7 +29,7 @@ module Gitlab
|
|||
|
||||
def total_count
|
||||
@total_count ||= issues_count + merge_requests_count + blobs_count +
|
||||
notes_count + wiki_blobs_count
|
||||
notes_count + wiki_blobs_count + commits_count
|
||||
end
|
||||
|
||||
def blobs_count
|
||||
|
@ -42,6 +44,10 @@ module Gitlab
|
|||
@wiki_blobs_count ||= wiki_blobs.count
|
||||
end
|
||||
|
||||
def commits_count
|
||||
@commits_count ||= commits.count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def blobs
|
||||
|
@ -70,6 +76,14 @@ module Gitlab
|
|||
Note.where(project_id: limit_project_ids).user.search(query).order('updated_at DESC')
|
||||
end
|
||||
|
||||
def commits
|
||||
if project.empty_repo? || query.blank?
|
||||
[]
|
||||
else
|
||||
project.repository.find_commits_by_message(query).compact
|
||||
end
|
||||
end
|
||||
|
||||
def limit_project_ids
|
||||
[project.id]
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace :spinach do
|
|||
task :project do
|
||||
cmds = [
|
||||
%W(rake gitlab:setup),
|
||||
%W(spinach --tags ~@admin,~@dashboard,~@profile,~@public,~@snippets),
|
||||
%W(spinach --tags ~@admin,~@dashboard,~@profile,~@public,~@snippets,~@commits),
|
||||
]
|
||||
run_commands(cmds)
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ namespace :spinach do
|
|||
task :other do
|
||||
cmds = [
|
||||
%W(rake gitlab:setup),
|
||||
%W(spinach --tags @admin,@dashboard,@profile,@public,@snippets),
|
||||
%W(spinach --tags @admin,@dashboard,@profile,@public,@snippets,@commits),
|
||||
]
|
||||
run_commands(cmds)
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ require 'spec_helper'
|
|||
|
||||
module Ci
|
||||
describe GitlabCiYamlProcessor do
|
||||
let(:path) { 'path' }
|
||||
|
||||
describe "#builds_for_ref" do
|
||||
let(:type) { 'test' }
|
||||
|
@ -12,7 +13,7 @@ module Ci
|
|||
rspec: { script: "rspec" }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").first).to eq({
|
||||
|
@ -29,77 +30,217 @@ module Ci
|
|||
})
|
||||
end
|
||||
|
||||
it "does not return builds if only has another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["deploy"] }
|
||||
})
|
||||
describe :only do
|
||||
it "does not return builds if only has another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["deploy"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
|
||||
end
|
||||
|
||||
it "does not return builds if only has regexp with another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["/^deploy$/"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns builds if only has specified this branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["master"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
|
||||
end
|
||||
|
||||
it "returns builds if only has a list of branches including specified" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["master", "deploy"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "returns builds if only has a branches keyword specified" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["branches"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "does not return builds if only has a tags keyword" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["tags"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns builds if only has current repository path" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["branches@path"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "does not return builds if only has different repository path" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["branches@fork"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns build only for specified type" do
|
||||
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: "test", only: ["master", "deploy"] },
|
||||
staging: { script: "deploy", type: "deploy", only: ["master", "deploy"] },
|
||||
production: { script: "deploy", type: "deploy", only: ["master@path", "deploy"] },
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, 'fork')
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref("deploy", "deploy").size).to eq(2)
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "deploy").size).to eq(1)
|
||||
expect(config_processor.builds_for_stage_and_ref("deploy", "master").size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not return builds if only has regexp with another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["/^deploy$/"] }
|
||||
})
|
||||
describe :except do
|
||||
it "returns builds if except has another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", except: ["deploy"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
|
||||
end
|
||||
|
||||
it "returns builds if except has regexp with another branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", except: ["/^deploy$/"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
|
||||
end
|
||||
|
||||
it "does not return builds if except has specified this branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", except: ["master"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
|
||||
end
|
||||
|
||||
it "does not return builds if except has a list of branches including specified" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, except: ["master", "deploy"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0)
|
||||
end
|
||||
|
||||
it "does not return builds if except has a branches keyword specified" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, except: ["branches"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns builds if except has a tags keyword" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, except: ["tags"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "does not return builds if except has current repository path" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, except: ["branches@path"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns builds if except has different repository path" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, except: ["branches@fork"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "returns build except specified type" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: "test", except: ["master", "deploy", "test@fork"] },
|
||||
staging: { script: "deploy", type: "deploy", except: ["master"] },
|
||||
production: { script: "deploy", type: "deploy", except: ["master@fork"] },
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config, 'fork')
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref("deploy", "deploy").size).to eq(2)
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "test").size).to eq(0)
|
||||
expect(config_processor.builds_for_stage_and_ref("deploy", "master").size).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns builds if only has specified this branch" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", only: ["master"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
|
||||
end
|
||||
|
||||
it "does not build tags" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", except: ["tags"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "0-1", true).size).to eq(0)
|
||||
end
|
||||
|
||||
it "returns builds if only has a list of branches including specified" do
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
rspec: { script: "rspec", type: type, only: ["master", "deploy"] }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
end
|
||||
|
||||
it "returns build only for specified type" do
|
||||
|
||||
config = YAML.dump({
|
||||
before_script: ["pwd"],
|
||||
build: { script: "build", type: "build", only: ["master", "deploy"] },
|
||||
rspec: { script: "rspec", type: type, only: ["master", "deploy"] },
|
||||
staging: { script: "deploy", type: "deploy", only: ["master", "deploy"] },
|
||||
production: { script: "deploy", type: "deploy", only: ["master", "deploy"] },
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref("production", "deploy").size).to eq(0)
|
||||
expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1)
|
||||
expect(config_processor.builds_for_stage_and_ref("deploy", "deploy").size).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Image and service handling" do
|
||||
|
@ -111,7 +252,7 @@ module Ci
|
|||
rspec: { script: "rspec" }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({
|
||||
|
@ -139,7 +280,7 @@ module Ci
|
|||
rspec: { image: "ruby:2.5", services: ["postgresql"], script: "rspec" }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
|
||||
expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({
|
||||
|
@ -172,7 +313,7 @@ module Ci
|
|||
rspec: { script: "rspec" }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
expect(config_processor.variables).to eq(variables)
|
||||
end
|
||||
end
|
||||
|
@ -184,7 +325,7 @@ module Ci
|
|||
rspec: { script: "rspec", when: when_state }
|
||||
})
|
||||
|
||||
config_processor = GitlabCiYamlProcessor.new(config)
|
||||
config_processor = GitlabCiYamlProcessor.new(config, path)
|
||||
builds = config_processor.builds_for_stage_and_ref("test", "master")
|
||||
expect(builds.size).to eq(1)
|
||||
expect(builds.first[:when]).to eq(when_state)
|
||||
|
@ -200,154 +341,154 @@ module Ci
|
|||
it "returns errors if tags parameter is invalid" do
|
||||
config = YAML.dump({ rspec: { script: "test", tags: "mysql" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: tags parameter should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if before_script parameter is invalid" do
|
||||
config = YAML.dump({ before_script: "bundle update", rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "before_script should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if image parameter is invalid" do
|
||||
config = YAML.dump({ image: ["test"], rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "image should be a string")
|
||||
end
|
||||
|
||||
it "returns errors if job name is blank" do
|
||||
config = YAML.dump({ '' => { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "job name should be non-empty string")
|
||||
end
|
||||
|
||||
it "returns errors if job name is non-string" do
|
||||
config = YAML.dump({ 10 => { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "job name should be non-empty string")
|
||||
end
|
||||
|
||||
it "returns errors if job image parameter is invalid" do
|
||||
config = YAML.dump({ rspec: { script: "test", image: ["test"] } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: image should be a string")
|
||||
end
|
||||
|
||||
it "returns errors if services parameter is not an array" do
|
||||
config = YAML.dump({ services: "test", rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if services parameter is not an array of strings" do
|
||||
config = YAML.dump({ services: [10, "test"], rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "services should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if job services parameter is not an array" do
|
||||
config = YAML.dump({ rspec: { script: "test", services: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: services should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if job services parameter is not an array of strings" do
|
||||
config = YAML.dump({ rspec: { script: "test", services: [10, "test"] } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: services should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if there are unknown parameters" do
|
||||
config = YAML.dump({ extra: "bundle update" })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Unknown parameter: extra")
|
||||
end
|
||||
|
||||
it "returns errors if there are unknown parameters that are hashes, but doesn't have a script" do
|
||||
config = YAML.dump({ extra: { services: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Unknown parameter: extra")
|
||||
end
|
||||
|
||||
it "returns errors if there is no any jobs defined" do
|
||||
config = YAML.dump({ before_script: ["bundle update"] })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Please define at least one job")
|
||||
end
|
||||
|
||||
it "returns errors if job allow_failure parameter is not an boolean" do
|
||||
config = YAML.dump({ rspec: { script: "test", allow_failure: "string" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: allow_failure parameter should be an boolean")
|
||||
end
|
||||
|
||||
it "returns errors if job stage is not a string" do
|
||||
config = YAML.dump({ rspec: { script: "test", type: 1, allow_failure: "string" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test, deploy")
|
||||
end
|
||||
|
||||
it "returns errors if job stage is not a pre-defined stage" do
|
||||
config = YAML.dump({ rspec: { script: "test", type: "acceptance", allow_failure: "string" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test, deploy")
|
||||
end
|
||||
|
||||
it "returns errors if job stage is not a defined stage" do
|
||||
config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", type: "acceptance", allow_failure: "string" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test")
|
||||
end
|
||||
|
||||
it "returns errors if stages is not an array" do
|
||||
config = YAML.dump({ types: "test", rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if stages is not an array of strings" do
|
||||
config = YAML.dump({ types: [true, "test"], rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings")
|
||||
end
|
||||
|
||||
it "returns errors if variables is not a map" do
|
||||
config = YAML.dump({ variables: "test", rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-valued strings")
|
||||
end
|
||||
|
||||
it "returns errors if variables is not a map of key-valued strings" do
|
||||
config = YAML.dump({ variables: { test: false }, rspec: { script: "test" } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-valued strings")
|
||||
end
|
||||
|
||||
it "returns errors if job when is not on_success, on_failure or always" do
|
||||
config = YAML.dump({ rspec: { script: "test", when: 1 } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config)
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure or always")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -468,7 +468,7 @@ describe Notify do
|
|||
subject { Notify.note_commit_email(recipient.id, note.id) }
|
||||
|
||||
it_behaves_like 'a note email'
|
||||
it_behaves_like 'an answer to an existing thread', 'commits'
|
||||
it_behaves_like 'an answer to an existing thread', 'commit'
|
||||
|
||||
it 'has the correct subject' do
|
||||
is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/
|
||||
|
|
|
@ -26,6 +26,15 @@ describe Repository do
|
|||
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
|
||||
end
|
||||
|
||||
describe :find_commits_by_message do
|
||||
subject { repository.find_commits_by_message('submodule').map{ |k| k.id } }
|
||||
|
||||
it { is_expected.to include('5937ac0a7beb003549fc5fd26fc247adbce4a52e') }
|
||||
it { is_expected.to include('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') }
|
||||
it { is_expected.to include('cfe32cf61b73a0d5e9f13e774abde7ff789b1660') }
|
||||
it { is_expected.not_to include('913c66a37b4a45b9769037c55c2d238bd0942d2e') }
|
||||
end
|
||||
|
||||
describe :blob_at do
|
||||
context 'blank sha' do
|
||||
subject { repository.blob_at(Gitlab::Git::BLANK_SHA, '.gitignore') }
|
||||
|
|
|
@ -19,6 +19,7 @@ describe API::API, api: true do
|
|||
expect(response.status).to eq(200)
|
||||
expect(json_response['file_path']).to eq(file_path)
|
||||
expect(json_response['file_name']).to eq('popen.rb')
|
||||
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
|
||||
expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue