Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into spread-runner-last-updated-at

This commit is contained in:
Jacob Vosmaer 2015-11-03 13:48:57 +01:00
commit 2674a14bec
27 changed files with 359 additions and 162 deletions

View File

@ -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

View File

@ -33,6 +33,8 @@
}
li.commit {
list-style: none;
.commit-row-title {
font-size: $list-font-size;
line-height: 20px;

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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')

View File

@ -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')}

View File

@ -0,0 +1,2 @@
.search-result-row
= render 'projects/commits/commit', project: @project, commit: commit

View File

@ -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

View File

@ -23,7 +23,8 @@ Example response:
"content": "IyA9PSBTY2hlbWEgSW5mb3...",
"ref": "master",
"blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
"last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d"
}
```

View File

@ -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)

View File

@ -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:

View File

@ -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:
@ -64,4 +64,4 @@ gitlab-ci-multi-runner register \
With the command above, you create a runner that uses [ruby:2.1](https://registry.hub.docker.com/u/library/ruby/) image and uses [postgres](https://registry.hub.docker.com/u/library/postgres/) database.
To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.
To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.

View File

@ -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

View File

@ -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.

View File

@ -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'

View File

@ -1,3 +1,5 @@
require 'backup/files'
module Backup
class Builds < Files
def initialize

View File

@ -1,3 +1,5 @@
require 'backup/files'
module Backup
class Uploads < Files

View File

@ -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

View File

@ -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

View File

@ -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
@ -33,4 +33,4 @@ def run_commands(cmds)
cmds.each do |cmd|
system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!")
end
end
end

View File

@ -2,7 +2,8 @@ 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({
@ -28,78 +29,218 @@ module Ci
when: "on_success"
})
end
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"] }
})
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, path)
config_processor = GitlabCiYamlProcessor.new(config)
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
end
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(0)
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

View File

@ -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}\)/

View File

@ -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') }

View File

@ -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