summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzegorz.bizon@ntsn.pl>2015-12-14 11:46:02 +0100
committerGrzegorz Bizon <grzegorz.bizon@ntsn.pl>2015-12-14 12:26:40 +0100
commit2ec93abed7a1a3aa49b3267342824e0743de0f54 (patch)
tree7d3381dd4bd1f4d73ba234a56742edf491baa515 /lib
parentbc1cfd384f4f972ad887b0501280b9f94d4c94ac (diff)
parentc81023435795766411c5954a4676ebb215af40a6 (diff)
downloadgitlab-ce-2ec93abed7a1a3aa49b3267342824e0743de0f54.tar.gz
Merge branch 'master' into ci/persist-registration-token
* master: (66 commits) Fix runners admin view Fix migrations Rename mention of gitlab-git-http-server to gitlab-workhorse Bump Redis requirement to 2.8 for Sidekiq 4 requirements Fix wording on runner setup page add details on how to change saml button label Fix tests Move awards back to gray panel and few improvements to sidebar Few UI improvements to new sidebar implementation Fix tests for new issuable sidebar Update changelog Implement new sidebar for merge request page Make edit link on issuable sidebar works Redesign issue page for new sidebar Move awards css to separate file Implement issuable sidebar partial Update CHANGELOG Clarify cache behavior Run builds from projects with enabled CI Use Gitlab::Git instead of Ci::Git ... Conflicts: db/schema.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/commit_statuses.rb2
-rw-r--r--lib/api/entities.rb10
-rw-r--r--lib/api/helpers.rb7
-rw-r--r--lib/api/project_hooks.rb2
-rw-r--r--lib/api/projects.rb6
-rw-r--r--lib/api/triggers.rb48
-rw-r--r--lib/award_emoji.rb35
-rw-r--r--lib/ci/api/api.rb2
-rw-r--r--lib/ci/api/commits.rb66
-rw-r--r--lib/ci/api/entities.rb9
-rw-r--r--lib/ci/api/helpers.rb4
-rw-r--r--lib/ci/api/projects.rb195
-rw-r--r--lib/ci/api/runners.rb13
-rw-r--r--lib/ci/api/triggers.rb2
-rw-r--r--lib/ci/charts.rb2
-rw-r--r--lib/ci/current_settings.rb22
-rw-r--r--lib/ci/git.rb5
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb66
-rw-r--r--lib/ci/scheduler.rb16
-rw-r--r--lib/gitlab/backend/grack_auth.rb4
-rw-r--r--lib/gitlab/build_data_builder.rb64
-rw-r--r--lib/gitlab/database.rb18
-rw-r--r--lib/gitlab/email/message/repository_push.rb137
-rw-r--r--lib/tasks/ci/schedule_builds.rake6
-rw-r--r--lib/tasks/gitlab/check.rake2
26 files changed, 368 insertions, 376 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index fe1bf8a4816..7834262d612 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -53,5 +53,6 @@ module API
mount Settings
mount Keys
mount Tags
+ mount Triggers
end
end
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index 2c0596c9dfb..1162271f5fc 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -53,7 +53,7 @@ module API
name = params[:name] || params[:context]
status = GenericCommitStatus.running_or_pending.find_by(commit: ci_commit, name: name, ref: params[:ref])
- status ||= GenericCommitStatus.new(commit: ci_commit, user: current_user)
+ status ||= GenericCommitStatus.new(project: @project, commit: ci_commit, user: current_user)
status.update(attrs)
case params[:state].to_s
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 81bf7a8222b..b1cd80bdf65 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -45,7 +45,8 @@ module API
class ProjectHook < Hook
expose :project_id, :push_events
- expose :issues_events, :merge_requests_events, :tag_push_events, :note_events, :enable_ssl_verification
+ expose :issues_events, :merge_requests_events, :tag_push_events, :note_events, :build_events
+ expose :enable_ssl_verification
end
class ForkedFromProject < Grape::Entity
@@ -63,6 +64,7 @@ module API
expose :name, :name_with_namespace
expose :path, :path_with_namespace
expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :created_at, :last_activity_at
+ expose :shared_runners_enabled
expose :creator_id
expose :namespace
expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? }
@@ -252,7 +254,7 @@ module API
class ProjectService < Grape::Entity
expose :id, :title, :created_at, :updated_at, :active
- expose :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events
+ expose :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events, :build_events
# Expose serialized properties
expose :properties do |service, options|
field_names = service.fields.
@@ -359,5 +361,9 @@ module API
end
end
end
+
+ class TriggerRequest < Grape::Entity
+ expose :id, :variables
+ end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 92540ccf2b1..a4df810e755 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -266,12 +266,7 @@ module API
projects = projects.search(params[:search])
end
- if params[:ci_enabled_first].present?
- projects.includes(:gitlab_ci_service).
- reorder("services.active DESC, projects.#{project_order_by} #{project_sort}")
- else
- projects.reorder(project_order_by => project_sort)
- end
+ projects.reorder(project_order_by => project_sort)
end
def project_order_by
diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb
index 882d1a083ad..cf9938d25a7 100644
--- a/lib/api/project_hooks.rb
+++ b/lib/api/project_hooks.rb
@@ -45,6 +45,7 @@ module API
:merge_requests_events,
:tag_push_events,
:note_events,
+ :build_events,
:enable_ssl_verification
]
@hook = user_project.hooks.new(attrs)
@@ -77,6 +78,7 @@ module API
:merge_requests_events,
:tag_push_events,
:note_events,
+ :build_events,
:enable_ssl_verification
]
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 6928fe0eb9d..bdf4b77596e 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -82,6 +82,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # shared_runners_enabled (optional)
# namespace_id (optional) - defaults to user namespace
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - 0 by default
@@ -98,6 +99,7 @@ module API
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
+ :shared_runners_enabled,
:namespace_id,
:public,
:visibility_level,
@@ -126,6 +128,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # shared_runners_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional)
# import_url (optional)
@@ -142,6 +145,7 @@ module API
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
+ :shared_runners_enabled,
:public,
:visibility_level,
:import_url]
@@ -183,6 +187,7 @@ module API
# builds_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
+ # shared_runners_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - visibility level of a project
# Example Request
@@ -197,6 +202,7 @@ module API
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
+ :shared_runners_enabled,
:public,
:visibility_level]
attrs = map_public_to_visibility_level(attrs)
diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb
new file mode 100644
index 00000000000..2781f1cf191
--- /dev/null
+++ b/lib/api/triggers.rb
@@ -0,0 +1,48 @@
+module API
+ # Triggers API
+ class Triggers < Grape::API
+ resource :projects do
+ # Trigger a GitLab project build
+ #
+ # Parameters:
+ # id (required) - The ID of a CI project
+ # ref (required) - The name of project's branch or tag
+ # token (required) - The uniq token of trigger
+ # variables (optional) - The list of variables to be injected into build
+ # Example Request:
+ # POST /projects/:id/trigger/builds
+ post ":id/trigger/builds" do
+ required_attributes! [:ref, :token]
+
+ project = Project.find_with_namespace(params[:id]) || Project.find_by(id: params[:id])
+ trigger = Ci::Trigger.find_by_token(params[:token].to_s)
+ not_found! unless project && trigger
+ unauthorized! unless trigger.project == project
+
+ # validate variables
+ variables = params[:variables]
+ if variables
+ unless variables.is_a?(Hash)
+ render_api_error!('variables needs to be a hash', 400)
+ end
+
+ unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) }
+ render_api_error!('variables needs to be a map of key-valued strings', 400)
+ end
+
+ # convert variables from Mash to Hash
+ variables = variables.to_h
+ end
+
+ # create request and trigger builds
+ trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref].to_s, variables)
+ if trigger_request
+ present trigger_request, with: Entities::TriggerRequest
+ else
+ errors = 'No builds created'
+ render_api_error!(errors, 400)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/award_emoji.rb b/lib/award_emoji.rb
index d58a196c4ef..4d99164bc33 100644
--- a/lib/award_emoji.rb
+++ b/lib/award_emoji.rb
@@ -6,7 +6,42 @@ class AwardEmoji
"ambulance", "anguished", "two_hearts", "wink"
]
+ ALIASES = {
+ pout: "rage",
+ satisfied: "laughing",
+ hankey: "shit",
+ poop: "shit",
+ collision: "boom",
+ thumbsup: "+1",
+ thumbsdown: "-1",
+ punch: "facepunch",
+ raised_hand: "hand",
+ running: "runner",
+ ng_woman: "no_good",
+ shoe: "mans_shoe",
+ tshirt: "shirt",
+ honeybee: "bee",
+ flipper: "dolphin",
+ paw_prints: "feet",
+ waxing_gibbous_moon: "moon",
+ telephone: "phone",
+ knife: "hocho",
+ envelope: "email",
+ pencil: "memo",
+ open_book: "book",
+ sailboat: "boat",
+ red_car: "car",
+ lantern: "izakaya_lantern",
+ uk: "gb",
+ heavy_exclamation_mark: "exclamation",
+ squirrel: "shipit"
+ }.with_indifferent_access
+
def self.path_to_emoji_image(name)
"emoji/#{Emoji.emoji_filename(name)}.png"
end
+
+ def self.normilize_emoji_name(name)
+ ALIASES[name] || name
+ end
end
diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb
index 07e68216d7f..5c347e432b4 100644
--- a/lib/ci/api/api.rb
+++ b/lib/ci/api/api.rb
@@ -30,9 +30,7 @@ module Ci
helpers Gitlab::CurrentSettings
mount Builds
- mount Commits
mount Runners
- mount Projects
mount Triggers
end
end
diff --git a/lib/ci/api/commits.rb b/lib/ci/api/commits.rb
deleted file mode 100644
index a60769d8305..00000000000
--- a/lib/ci/api/commits.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-module Ci
- module API
- class Commits < Grape::API
- resource :commits do
- # Get list of commits per project
- #
- # Parameters:
- # project_id (required) - The ID of a project
- # project_token (requires) - Project token
- # page (optional)
- # per_page (optional) - items per request (default is 20)
- #
- get do
- required_attributes! [:project_id, :project_token]
- project = Ci::Project.find(params[:project_id])
- authenticate_project_token!(project)
-
- commits = project.commits.page(params[:page]).per(params[:per_page] || 20)
- present commits, with: Entities::CommitWithBuilds
- end
-
- # Create a commit
- #
- # Parameters:
- # project_id (required) - The ID of a project
- # project_token (requires) - Project token
- # data (required) - GitLab push data
- #
- # Sample GitLab push data:
- # {
- # "before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
- # "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
- # "ref": "refs/heads/master",
- # "commits": [
- # {
- # "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
- # "message": "Update Catalan translation to e38cb41.",
- # "timestamp": "2011-12-12T14:27:31+02:00",
- # "url": "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
- # "author": {
- # "name": "Jordi Mallach",
- # "email": "jordi@softcatala.org",
- # }
- # }, .... more commits
- # ]
- # }
- #
- # Example Request:
- # POST /commits
- post do
- required_attributes! [:project_id, :data, :project_token]
- project = Ci::Project.find(params[:project_id])
- authenticate_project_token!(project)
- commit = Ci::CreateCommitService.new.execute(project, current_user, params[:data])
-
- if commit.persisted?
- present commit, with: Entities::CommitWithBuilds
- else
- errors = commit.errors.full_messages.join(", ")
- render_api_error!(errors, 400)
- end
- end
- end
- end
- end
-end
diff --git a/lib/ci/api/entities.rb b/lib/ci/api/entities.rb
index 750f421872d..e4ac0545ea2 100644
--- a/lib/ci/api/entities.rb
+++ b/lib/ci/api/entities.rb
@@ -37,15 +37,6 @@ module Ci
expose :id, :token
end
- class Project < Grape::Entity
- expose :id, :name, :token, :default_ref, :gitlab_url, :path,
- :always_build, :polling_interval, :public, :ssh_url_to_repo, :gitlab_id
-
- expose :timeout do |model|
- model.timeout
- end
- end
-
class RunnerProject < Grape::Entity
expose :id, :project_id, :runner_id
end
diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb
index abd1869efc0..443563c2e4a 100644
--- a/lib/ci/api/helpers.rb
+++ b/lib/ci/api/helpers.rb
@@ -13,10 +13,6 @@ module Ci
forbidden! unless current_runner
end
- def authenticate_project_token!(project)
- forbidden! unless project.valid_token?(params[:project_token])
- end
-
def authenticate_build_token!(build)
token = (params[BUILD_TOKEN_PARAM] || env[BUILD_TOKEN_HEADER]).to_s
forbidden! unless token && build.valid_token?(token)
diff --git a/lib/ci/api/projects.rb b/lib/ci/api/projects.rb
deleted file mode 100644
index d719ad9e8d5..00000000000
--- a/lib/ci/api/projects.rb
+++ /dev/null
@@ -1,195 +0,0 @@
-module Ci
- module API
- # Projects API
- class Projects < Grape::API
- before { authenticate! }
-
- resource :projects do
- # Register new webhook for project
- #
- # Parameters
- # project_id (required) - The ID of a project
- # web_hook (required) - WebHook URL
- # Example Request
- # POST /projects/:project_id/webhooks
- post ":project_id/webhooks" do
- required_attributes! [:web_hook]
-
- project = Ci::Project.find(params[:project_id])
-
- unauthorized! unless can?(current_user, :admin_project, project.gl_project)
-
- web_hook = project.web_hooks.new({ url: params[:web_hook] })
-
- if web_hook.save
- present web_hook, with: Entities::WebHook
- else
- errors = web_hook.errors.full_messages.join(", ")
- render_api_error!(errors, 400)
- end
- end
-
- # Retrieve all Gitlab CI projects that the user has access to
- #
- # Example Request:
- # GET /projects
- get do
- gitlab_projects = current_user.authorized_projects
- gitlab_projects = filter_projects(gitlab_projects)
- gitlab_projects = paginate gitlab_projects
-
- ids = gitlab_projects.map { |project| project.id }
-
- projects = Ci::Project.where("gitlab_id IN (?)", ids).load
- present projects, with: Entities::Project
- end
-
- # Retrieve all Gitlab CI projects that the user owns
- #
- # Example Request:
- # GET /projects/owned
- get "owned" do
- gitlab_projects = current_user.owned_projects
- gitlab_projects = filter_projects(gitlab_projects)
- gitlab_projects = paginate gitlab_projects
-
- ids = gitlab_projects.map { |project| project.id }
-
- projects = Ci::Project.where("gitlab_id IN (?)", ids).load
- present projects, with: Entities::Project
- end
-
- # Retrieve info for a Gitlab CI project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # GET /projects/:id
- get ":id" do
- project = Ci::Project.find(params[:id])
- unauthorized! unless can?(current_user, :read_project, project.gl_project)
-
- present project, with: Entities::Project
- end
-
- # Create Gitlab CI project using Gitlab project info
- #
- # Parameters:
- # gitlab_id (required) - The gitlab id of the project
- # default_ref - The branch to run against (defaults to `master`)
- # Example Request:
- # POST /projects
- post do
- required_attributes! [:gitlab_id]
-
- filtered_params = {
- gitlab_id: params[:gitlab_id],
- # we accept gitlab_url for backward compatibility for a while (added to 7.11)
- default_ref: params[:default_ref] || 'master'
- }
-
- project = Ci::Project.new(filtered_params)
- project.build_missing_services
-
- if project.save
- present project, with: Entities::Project
- else
- errors = project.errors.full_messages.join(", ")
- render_api_error!(errors, 400)
- end
- end
-
- # Update a Gitlab CI project
- #
- # Parameters:
- # id (required) - The ID of a project
- # default_ref - The branch to run against (defaults to `master`)
- # Example Request:
- # PUT /projects/:id
- put ":id" do
- project = Ci::Project.find(params[:id])
-
- unauthorized! unless can?(current_user, :admin_project, project.gl_project)
-
- attrs = attributes_for_keys [:default_ref]
-
- if project.update_attributes(attrs)
- present project, with: Entities::Project
- else
- errors = project.errors.full_messages.join(", ")
- render_api_error!(errors, 400)
- end
- end
-
- # Remove a Gitlab CI project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # DELETE /projects/:id
- delete ":id" do
- project = Ci::Project.find(params[:id])
-
- unauthorized! unless can?(current_user, :admin_project, project.gl_project)
-
- project.destroy
- end
-
- # Link a Gitlab CI project to a runner
- #
- # Parameters:
- # id (required) - The ID of a CI project
- # runner_id (required) - The ID of a runner
- # Example Request:
- # POST /projects/:id/runners/:runner_id
- post ":id/runners/:runner_id" do
- project = Ci::Project.find(params[:id])
- runner = Ci::Runner.find(params[:runner_id])
-
- unauthorized! unless can?(current_user, :admin_project, project.gl_project)
-
- options = {
- project_id: project.id,
- runner_id: runner.id
- }
-
- runner_project = Ci::RunnerProject.new(options)
-
- if runner_project.save
- present runner_project, with: Entities::RunnerProject
- else
- errors = project.errors.full_messages.join(", ")
- render_api_error!(errors, 400)
- end
- end
-
- # Remove a Gitlab CI project from a runner
- #
- # Parameters:
- # id (required) - The ID of a CI project
- # runner_id (required) - The ID of a runner
- # Example Request:
- # DELETE /projects/:id/runners/:runner_id
- delete ":id/runners/:runner_id" do
- project = Ci::Project.find(params[:id])
- runner = Ci::Runner.find(params[:runner_id])
-
- unauthorized! unless can?(current_user, :admin_project, project.gl_project)
-
- options = {
- project_id: project.id,
- runner_id: runner.id
- }
-
- runner_project = Ci::RunnerProject.find_by(options)
-
- if runner_project.present?
- runner_project.destroy
- else
- not_found!
- end
- end
- end
- end
- end
-end
diff --git a/lib/ci/api/runners.rb b/lib/ci/api/runners.rb
index 3edf067f46d..bfc14fe7a6b 100644
--- a/lib/ci/api/runners.rb
+++ b/lib/ci/api/runners.rb
@@ -3,17 +3,6 @@ module Ci
# Runners API
class Runners < Grape::API
resource :runners do
- # Get list of all available runners
- #
- # Example Request:
- # GET /runners
- get do
- authenticate!
- runners = Ci::Runner.all
-
- present runners, with: Entities::Runner
- end
-
# Delete runner
# Parameters:
# token (required) - The unique token of runner
@@ -47,7 +36,7 @@ module Ci
tag_list: params[:tag_list],
is_shared: true
)
- elsif project = Ci::Project.find_by(token: params[:token])
+ elsif project = Project.find_by(runners_token: params[:token])
# Create a specific runner for project.
project.runners.create(
description: params[:description],
diff --git a/lib/ci/api/triggers.rb b/lib/ci/api/triggers.rb
index 40907d6db54..63b42113513 100644
--- a/lib/ci/api/triggers.rb
+++ b/lib/ci/api/triggers.rb
@@ -14,7 +14,7 @@ module Ci
post ":id/refs/:ref/trigger" do
required_attributes! [:token]
- project = Ci::Project.find(params[:id])
+ project = Project.find_by(ci_id: params[:id].to_i)
trigger = Ci::Trigger.find_by_token(params[:token].to_s)
not_found! unless project && trigger
unauthorized! unless trigger.project == project
diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb
index 5ff7407c6fe..d53bdcbd0f2 100644
--- a/lib/ci/charts.rb
+++ b/lib/ci/charts.rb
@@ -60,7 +60,7 @@ module Ci
class BuildTime < Chart
def collect
- commits = project.commits.last(30)
+ commits = project.ci_commits.last(30)
commits.each do |commit|
@labels << commit.short_sha
diff --git a/lib/ci/current_settings.rb b/lib/ci/current_settings.rb
deleted file mode 100644
index fd78b024970..00000000000
--- a/lib/ci/current_settings.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module Ci
- module CurrentSettings
- def current_application_settings
- key = :ci_current_application_settings
-
- RequestStore.store[key] ||= begin
- if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('ci_application_settings')
- Ci::ApplicationSetting.current || Ci::ApplicationSetting.create_from_defaults
- else
- fake_application_settings
- end
- end
- end
-
- def fake_application_settings
- OpenStruct.new(
- all_broken_builds: Ci::Settings.gitlab_ci['all_broken_builds'],
- add_pusher: Ci::Settings.gitlab_ci['add_pusher'],
- )
- end
- end
-end
diff --git a/lib/ci/git.rb b/lib/ci/git.rb
deleted file mode 100644
index 7acc3f38edb..00000000000
--- a/lib/ci/git.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-module Ci
- module Git
- BLANK_SHA = '0' * 40
- end
-end
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index e7fb1b79b7c..bcdfd38d292 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -132,26 +132,36 @@ module Ci
end
def validate_job!(name, job)
+ validate_job_name!(name)
+ validate_job_keys!(name, job)
+ validate_job_types!(name, job)
+
+ validate_job_stage!(name, job) if job[:stage]
+ validate_job_cache!(name, job) if job[:cache]
+ validate_job_artifacts!(name, job) if job[:artifacts]
+ end
+
+ private
+
+ def validate_job_name!(name)
if name.blank? || !validate_string(name)
raise ValidationError, "job name should be non-empty string"
end
+ end
+ def validate_job_keys!(name, job)
job.keys.each do |key|
unless ALLOWED_JOB_KEYS.include? key
raise ValidationError, "#{name} job: unknown parameter #{key}"
end
end
+ end
+ def validate_job_types!(name, job)
if !validate_string(job[:script]) && !validate_array_of_strings(job[:script])
raise ValidationError, "#{name} job: script should be a string or an array of a strings"
end
- if job[:stage]
- unless job[:stage].is_a?(String) && job[:stage].in?(stages)
- raise ValidationError, "#{name} job: stage parameter should be #{stages.join(", ")}"
- end
- end
-
if job[:image] && !validate_string(job[:image])
raise ValidationError, "#{name} job: image should be a string"
end
@@ -172,36 +182,40 @@ module Ci
raise ValidationError, "#{name} job: except parameter should be an array of strings"
end
- if job[:cache]
- if job[:cache][:untracked] && !validate_boolean(job[:cache][:untracked])
- raise ValidationError, "#{name} job: cache:untracked parameter should be an boolean"
- end
-
- if job[:cache][:paths] && !validate_array_of_strings(job[:cache][:paths])
- raise ValidationError, "#{name} job: cache:paths parameter should be an array of strings"
- end
+ if job[:allow_failure] && !validate_boolean(job[:allow_failure])
+ raise ValidationError, "#{name} job: allow_failure parameter should be an boolean"
end
- if job[:artifacts]
- if job[:artifacts][:untracked] && !validate_boolean(job[:artifacts][:untracked])
- raise ValidationError, "#{name} job: artifacts:untracked parameter should be an boolean"
- end
+ if job[:when] && !job[:when].in?(%w(on_success on_failure always))
+ raise ValidationError, "#{name} job: when parameter should be on_success, on_failure or always"
+ end
+ end
- if job[:artifacts][:paths] && !validate_array_of_strings(job[:artifacts][:paths])
- raise ValidationError, "#{name} job: artifacts:paths parameter should be an array of strings"
- end
+ def validate_job_stage!(name, job)
+ unless job[:stage].is_a?(String) && job[:stage].in?(stages)
+ raise ValidationError, "#{name} job: stage parameter should be #{stages.join(", ")}"
end
+ end
- if job[:allow_failure] && !validate_boolean(job[:allow_failure])
- raise ValidationError, "#{name} job: allow_failure parameter should be an boolean"
+ def validate_job_cache!(name, job)
+ if job[:cache][:untracked] && !validate_boolean(job[:cache][:untracked])
+ raise ValidationError, "#{name} job: cache:untracked parameter should be an boolean"
end
- if job[:when] && !job[:when].in?(%w(on_success on_failure always))
- raise ValidationError, "#{name} job: when parameter should be on_success, on_failure or always"
+ if job[:cache][:paths] && !validate_array_of_strings(job[:cache][:paths])
+ raise ValidationError, "#{name} job: cache:paths parameter should be an array of strings"
end
end
- private
+ def validate_job_artifacts!(name, job)
+ if job[:artifacts][:untracked] && !validate_boolean(job[:artifacts][:untracked])
+ raise ValidationError, "#{name} job: artifacts:untracked parameter should be an boolean"
+ end
+
+ if job[:artifacts][:paths] && !validate_array_of_strings(job[:artifacts][:paths])
+ raise ValidationError, "#{name} job: artifacts:paths parameter should be an array of strings"
+ end
+ end
def validate_array_of_strings(values)
values.is_a?(Array) && values.all? { |value| validate_string(value) }
diff --git a/lib/ci/scheduler.rb b/lib/ci/scheduler.rb
deleted file mode 100644
index ee0958f4be1..00000000000
--- a/lib/ci/scheduler.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Ci
- class Scheduler
- def perform
- projects = Ci::Project.where(always_build: true).all
- projects.each do |project|
- last_commit = project.commits.last
- next unless last_commit && last_commit.last_build
-
- interval = project.polling_interval
- if (last_commit.last_build.created_at + interval.hours) < Time.now
- last_commit.retry
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 0d156047ff0..cdcaae8094c 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -77,7 +77,9 @@ module Grack
if project && matched_login.present? && git_cmd == 'git-upload-pack'
underscored_service = matched_login['s'].underscore
- if Service.available_services_names.include?(underscored_service)
+ if underscored_service == 'gitlab_ci'
+ return project && project.valid_build_token?(password)
+ elsif Service.available_services_names.include?(underscored_service)
service_method = "#{underscored_service}_service"
service = project.send(service_method)
diff --git a/lib/gitlab/build_data_builder.rb b/lib/gitlab/build_data_builder.rb
new file mode 100644
index 00000000000..86bfa0a4378
--- /dev/null
+++ b/lib/gitlab/build_data_builder.rb
@@ -0,0 +1,64 @@
+module Gitlab
+ class BuildDataBuilder
+ class << self
+ def build(build)
+ project = build.project
+ commit = build.commit
+ user = build.user
+
+ data = {
+ object_kind: 'build',
+
+ ref: build.ref,
+ tag: build.tag,
+ before_sha: build.before_sha,
+ sha: build.sha,
+
+ # TODO: should this be not prefixed with build_?
+ # Leaving this way to have backward compatibility
+ build_id: build.id,
+ build_name: build.name,
+ build_stage: build.stage,
+ build_status: build.status,
+ build_started_at: build.started_at,
+ build_finished_at: build.finished_at,
+ build_duration: build.duration,
+
+ # TODO: do we still need it?
+ project_id: project.id,
+ project_name: project.name_with_namespace,
+
+ user: {
+ id: user.try(:id),
+ name: user.try(:name),
+ email: user.try(:email),
+ },
+
+ commit: {
+ id: commit.id,
+ sha: commit.sha,
+ message: commit.git_commit_message,
+ author_name: commit.git_author_name,
+ author_email: commit.git_author_email,
+ status: commit.status,
+ duration: commit.duration,
+ started_at: commit.started_at,
+ finished_at: commit.finished_at,
+ },
+
+ repository: {
+ name: project.name,
+ url: project.url_to_repo,
+ description: project.description,
+ homepage: project.web_url,
+ git_http_url: project.http_url_to_repo,
+ git_ssh_url: project.ssh_url_to_repo,
+ visibility_level: project.visibility_level
+ },
+ }
+
+ data
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 71f37f1fef8..de77a6fbff1 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -7,5 +7,23 @@ module Gitlab
def self.postgresql?
ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql'
end
+
+ def true_value
+ case ActiveRecord::Base.connection.adapter_name.downcase
+ when 'postgresql'
+ "'t'"
+ else
+ 1
+ end
+ end
+
+ def false_value
+ case ActiveRecord::Base.connection.adapter_name.downcase
+ when 'postgresql'
+ "'f'"
+ else
+ 0
+ end
+ end
end
end
diff --git a/lib/gitlab/email/message/repository_push.rb b/lib/gitlab/email/message/repository_push.rb
new file mode 100644
index 00000000000..a2eb7a70bd2
--- /dev/null
+++ b/lib/gitlab/email/message/repository_push.rb
@@ -0,0 +1,137 @@
+module Gitlab
+ module Email
+ module Message
+ class RepositoryPush
+ attr_accessor :recipient
+ attr_reader :author_id, :ref, :action
+
+ include Gitlab::Application.routes.url_helpers
+
+ delegate :namespace, :name_with_namespace, to: :project, prefix: :project
+ delegate :name, to: :author, prefix: :author
+
+ def initialize(notify, project_id, recipient, opts = {})
+ raise ArgumentError, 'Missing options: author_id, ref, action' unless
+ opts[:author_id] && opts[:ref] && opts[:action]
+
+ @notify = notify
+ @project_id = project_id
+ @recipient = recipient
+ @opts = opts.dup
+
+ @author_id = @opts.delete(:author_id)
+ @ref = @opts.delete(:ref)
+ @action = @opts.delete(:action)
+ end
+
+ def project
+ @project ||= Project.find(@project_id)
+ end
+
+ def author
+ @author ||= User.find(@author_id)
+ end
+
+ def commits
+ @commits ||= (Commit.decorate(compare.commits, project) if compare)
+ end
+
+ def diffs
+ @diffs ||= (compare.diffs if compare)
+ end
+
+ def diffs_count
+ diffs.count if diffs
+ end
+
+ def compare
+ @opts[:compare]
+ end
+
+ def compare_timeout
+ compare.timeout if compare
+ end
+
+ def reverse_compare?
+ @opts[:reverse_compare] || false
+ end
+
+ def disable_diffs?
+ @opts[:disable_diffs] || false
+ end
+
+ def send_from_committer_email?
+ @opts[:send_from_committer_email] || false
+ end
+
+ def action_name
+ @action_name ||=
+ case @action
+ when :create
+ 'pushed new'
+ when :delete
+ 'deleted'
+ else
+ 'pushed to'
+ end
+ end
+
+ def ref_name
+ @ref_name ||= Gitlab::Git.ref_name(@ref)
+ end
+
+ def ref_type
+ @ref_type ||= Gitlab::Git.tag_ref?(@ref) ? 'tag' : 'branch'
+ end
+
+ def target_url
+ if @action == :push && commits
+ if commits.length > 1
+ namespace_project_compare_url(project_namespace,
+ project,
+ from: Commit.new(compare.base, project),
+ to: Commit.new(compare.head, project))
+ else
+ namespace_project_commit_url(project_namespace,
+ project, commits.first)
+ end
+ else
+ unless @action == :delete
+ namespace_project_tree_url(project_namespace,
+ project, ref_name)
+ end
+ end
+ end
+
+ def reply_to
+ if send_from_committer_email? && @notify.can_send_from_user_email?(author)
+ author.email
+ else
+ Gitlab.config.gitlab.email_reply_to
+ end
+ end
+
+ def subject
+ subject_text = '[Git]'
+ subject_text << "[#{project.path_with_namespace}]"
+ subject_text << "[#{ref_name}]" if @action == :push
+ subject_text << ' '
+
+ if @action == :push && commits
+ if commits.length > 1
+ subject_text << "Deleted " if reverse_compare?
+ subject_text << "#{commits.length} commits: #{commits.first.title}"
+ else
+ subject_text << "Deleted 1 commit: " if reverse_compare?
+ subject_text << commits.first.title
+ end
+ else
+ subject_action = action_name.dup
+ subject_action[0] = subject_action[0].capitalize
+ subject_text << "#{subject_action} #{ref_type} #{ref_name}"
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/tasks/ci/schedule_builds.rake b/lib/tasks/ci/schedule_builds.rake
deleted file mode 100644
index 49435504c67..00000000000
--- a/lib/tasks/ci/schedule_builds.rake
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace :ci do
- desc "GitLab CI | Clean running builds"
- task schedule_builds: :environment do
- Ci::Scheduler.new.perform
- end
-end
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index a25fac62cfc..b5af3d88b4c 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -331,7 +331,7 @@ namespace :gitlab do
end
def check_redis_version
- min_redis_version = "2.4.0"
+ min_redis_version = "2.8.0"
print "Redis version >= #{min_redis_version}? ... "
redis_version = run(%W(redis-cli --version))