summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-01-14 19:45:43 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2016-01-14 19:45:55 +0100
commitac652d82f17d378e485dcef15a8fabdcf9bad76b (patch)
tree722e6afd2ea63a43b15886b890138c3def3d5885
parentba42b03348056e511df8484a8b342c7a2129c4f4 (diff)
downloadgitlab-ce-ci/build_dependencies.tar.gz
Let the CI runner know about builds that this build depends onci/build_dependencies
This allows us to implement artifacts passing: runner will download artifacts from all prior builds
-rw-r--r--CHANGELOG1
-rw-r--r--app/models/ci/build.rb8
-rw-r--r--app/uploaders/artifact_uploader.rb4
-rw-r--r--doc/ci/api/builds.md64
-rw-r--r--lib/ci/api/builds.rb4
-rw-r--r--lib/ci/api/entities.rb19
-rw-r--r--spec/models/build_spec.rb24
-rw-r--r--spec/requests/ci/api/builds_spec.rb12
-rw-r--r--spec/support/gitlab_stubs/gitlab_ci.yml8
9 files changed, 125 insertions, 19 deletions
diff --git a/CHANGELOG b/CHANGELOG
index d613249356b..6f634ee81b9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@ v 8.4.0 (unreleased)
- Don't notify users twice if they are both project watchers and subscribers (Stan Hu)
- Implement new UI for group page
- Implement search inside emoji picker
+ - Let the CI runner know about builds that this build depends on
- Add API support for looking up a user by username (Stan Hu)
- Add project permissions to all project API endpoints (Stan Hu)
- Link to milestone in "Milestone changed" system note
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 6cc26abce66..16a5b03f591 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -128,6 +128,14 @@ module Ci
!self.commit.latest_builds_for_ref(self.ref).include?(self)
end
+ def depends_on_builds
+ # Get builds of the same type
+ latest_builds = self.commit.builds.similar(self).latest
+
+ # Return builds from previous stages
+ latest_builds.where('stage_idx < ?', stage_idx)
+ end
+
def trace_html
html = Ci::Ansi2html::convert(trace) if trace.present?
html || ''
diff --git a/app/uploaders/artifact_uploader.rb b/app/uploaders/artifact_uploader.rb
index 1b0ae6c0056..1cd93263c9f 100644
--- a/app/uploaders/artifact_uploader.rb
+++ b/app/uploaders/artifact_uploader.rb
@@ -32,6 +32,10 @@ class ArtifactUploader < CarrierWave::Uploader::Base
self.class.storage == CarrierWave::Storage::File
end
+ def filename
+ file.try(:filename)
+ end
+
def exists?
file.try(:exists?)
end
diff --git a/doc/ci/api/builds.md b/doc/ci/api/builds.md
index 3b5008ccdb4..3e2fb804731 100644
--- a/doc/ci/api/builds.md
+++ b/doc/ci/api/builds.md
@@ -18,18 +18,64 @@ Returns:
```json
{
- "id" : 79,
- "commands" : "",
- "path" : "",
- "ref" : "",
- "sha" : "",
- "project_id" : 6,
- "repo_url" : "git@demo.gitlab.com:gitlab/gitlab-shell.git",
- "before_sha" : ""
+ "id": 48584,
+ "ref": "0.1.1",
+ "tag": true,
+ "sha": "d63117656af6ff57d99e50cc270f854691f335ad",
+ "status": "success",
+ "name": "pages",
+ "token": "9dd60b4f1a439d1765357446c1084c",
+ "stage": "test",
+ "project_id": 479,
+ "project_name": "test",
+ "commands": "echo commands",
+ "repo_url": "http://gitlab-ci-token:token@gitlab.example/group/test.git",
+ "before_sha": "0000000000000000000000000000000000000000",
+ "allow_git_fetch": false,
+ "options": {
+ "image": "docker:image",
+ "artifacts": {
+ "paths": [
+ "public"
+ ]
+ },
+ "cache": {
+ "paths": [
+ "vendor"
+ ]
+ }
+ },
+ "timeout": 3600,
+ "variables": [
+ {
+ "key": "CI_BUILD_TAG",
+ "value": "0.1.1",
+ "public": true
+ }
+ ],
+ "dependencies": {
+ "builds": [
+ {
+ "id": 48584,
+ "ref": "0.1.1",
+ "tag": true,
+ "sha": "d63117656af6ff57d99e50cc270f854691f335ad",
+ "status": "success",
+ "name": "build",
+ "token": "9dd60b4f1a439d1765357446c1084c",
+ "stage": "build",
+ "project_id": 479,
+ "project_name": "test",
+ "artifacts_file": {
+ "filename": "artifacts.zip",
+ "size": 0
+ }
+ }
+ ]
+ }
}
```
-
### Update details of an existing build
PUT /ci/builds/:id
diff --git a/lib/ci/api/builds.rb b/lib/ci/api/builds.rb
index fb87637b94f..690bbf97a89 100644
--- a/lib/ci/api/builds.rb
+++ b/lib/ci/api/builds.rb
@@ -20,7 +20,7 @@ module Ci
if build
update_runner_info
- present build, with: Entities::Build
+ present build, with: Entities::BuildDetails
else
not_found!
end
@@ -111,7 +111,7 @@ module Ci
build.artifacts_metadata = metadata
if build.save
- present(build, with: Entities::Build)
+ present(build, with: Entities::BuildDetails)
else
render_validation_error!(build)
end
diff --git a/lib/ci/api/entities.rb b/lib/ci/api/entities.rb
index e4ac0545ea2..835f8c97021 100644
--- a/lib/ci/api/entities.rb
+++ b/lib/ci/api/entities.rb
@@ -16,10 +16,19 @@ module Ci
end
class Build < Grape::Entity
- expose :id, :commands, :ref, :sha, :status, :project_id, :repo_url,
- :before_sha, :allow_git_fetch, :project_name
-
+ expose :id, :ref, :tag, :sha, :status
expose :name, :token, :stage
+ expose :project_id
+ expose :project_name
+ expose :artifacts_file, using: ArtifactFile, if: lambda { |build, opts| build.artifacts_file.exists? }
+ end
+
+ class BuildDetails < Build
+ expose :commands
+ expose :repo_url
+ expose :before_sha
+ expose :allow_git_fetch
+ expose :token
expose :options do |model|
model.options
@@ -30,7 +39,9 @@ module Ci
end
expose :variables
- expose :artifacts_file, using: ArtifactFile
+ expose :dependencies do
+ expose :depends_on_builds, as: :builds, using: Build
+ end
end
class Runner < Grape::Entity
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index 0e13456723d..d12b9e65c82 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -426,6 +426,30 @@ describe Ci::Build, models: true do
it { is_expected.to include(project.web_url[7..-1]) }
end
+ describe :depends_on_builds do
+ let!(:build) { FactoryGirl.create :ci_build, commit: commit, name: 'build', stage_idx: 0, stage: 'build' }
+ let!(:rspec_test) { FactoryGirl.create :ci_build, commit: commit, name: 'rspec', stage_idx: 1, stage: 'test' }
+ let!(:rubocop_test) { FactoryGirl.create :ci_build, commit: commit, name: 'rubocop', stage_idx: 1, stage: 'test' }
+ let!(:staging) { FactoryGirl.create :ci_build, commit: commit, name: 'staging', stage_idx: 2, stage: 'deploy' }
+
+ it 'to have no dependents if this is first build' do
+ expect(build.depends_on_builds).to be_empty
+ end
+
+ it 'to have one dependent if this is test' do
+ expect(rspec_test.depends_on_builds.map(&:id)).to contain_exactly(build.id)
+ end
+
+ it 'to have all builds from build and test stage if this is last' do
+ expect(staging.depends_on_builds.map(&:id)).to contain_exactly(build.id, rspec_test.id, rubocop_test.id)
+ end
+
+ it 'to have retried builds instead the original ones' do
+ retried_rspec = Ci::Build.retry(rspec_test)
+ expect(staging.depends_on_builds.map(&:id)).to contain_exactly(build.id, retried_rspec.id, rubocop_test.id)
+ end
+ end
+
def create_mr(build, commit, factory: :merge_request, created_at: Time.now)
FactoryGirl.create(factory,
source_project_id: commit.gl_project_id,
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index 648ea0d5f50..1c3e27abb9f 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -101,6 +101,18 @@ describe Ci::API::API do
{ "key" => "TRIGGER_KEY", "value" => "TRIGGER_VALUE", "public" => false },
])
end
+
+ it "returns dependent builds" do
+ commit = FactoryGirl.create(:ci_commit, project: project)
+ commit.create_builds('master', false, nil, nil)
+ commit.builds.where(stage: 'test').each(&:success)
+
+ post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
+
+ expect(response.status).to eq(201)
+ expect(json_response["dependencies"]["builds"].count).to eq(2)
+ expect(json_response["dependencies"]["builds"][0]["name"]).to eq("rspec")
+ end
end
describe "PUT /builds/:id" do
diff --git a/spec/support/gitlab_stubs/gitlab_ci.yml b/spec/support/gitlab_stubs/gitlab_ci.yml
index 3482145404e..a5b256bd3ec 100644
--- a/spec/support/gitlab_stubs/gitlab_ci.yml
+++ b/spec/support/gitlab_stubs/gitlab_ci.yml
@@ -36,8 +36,8 @@ staging:
script: "cap deploy stating"
type: deploy
tags:
- - capistrano
- - debian
+ - ruby
+ - mysql
except:
- stable
@@ -47,8 +47,8 @@ production:
- cap deploy production
- cap notify
tags:
- - capistrano
- - debian
+ - ruby
+ - mysql
only:
- master
- /^deploy-.*$/