Let the CI runner know about builds that this build depends on
This allows us to implement artifacts passing: runner will download artifacts from all prior builds
This commit is contained in:
parent
ba42b03348
commit
ac652d82f1
|
@ -20,6 +20,7 @@ v 8.4.0 (unreleased)
|
||||||
- Don't notify users twice if they are both project watchers and subscribers (Stan Hu)
|
- Don't notify users twice if they are both project watchers and subscribers (Stan Hu)
|
||||||
- Implement new UI for group page
|
- Implement new UI for group page
|
||||||
- Implement search inside emoji picker
|
- 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 API support for looking up a user by username (Stan Hu)
|
||||||
- Add project permissions to all project API endpoints (Stan Hu)
|
- Add project permissions to all project API endpoints (Stan Hu)
|
||||||
- Link to milestone in "Milestone changed" system note
|
- Link to milestone in "Milestone changed" system note
|
||||||
|
|
|
@ -128,6 +128,14 @@ module Ci
|
||||||
!self.commit.latest_builds_for_ref(self.ref).include?(self)
|
!self.commit.latest_builds_for_ref(self.ref).include?(self)
|
||||||
end
|
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
|
def trace_html
|
||||||
html = Ci::Ansi2html::convert(trace) if trace.present?
|
html = Ci::Ansi2html::convert(trace) if trace.present?
|
||||||
html || ''
|
html || ''
|
||||||
|
|
|
@ -32,6 +32,10 @@ class ArtifactUploader < CarrierWave::Uploader::Base
|
||||||
self.class.storage == CarrierWave::Storage::File
|
self.class.storage == CarrierWave::Storage::File
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filename
|
||||||
|
file.try(:filename)
|
||||||
|
end
|
||||||
|
|
||||||
def exists?
|
def exists?
|
||||||
file.try(:exists?)
|
file.try(:exists?)
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,18 +18,64 @@ Returns:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id" : 79,
|
"id": 48584,
|
||||||
"commands" : "",
|
"ref": "0.1.1",
|
||||||
"path" : "",
|
"tag": true,
|
||||||
"ref" : "",
|
"sha": "d63117656af6ff57d99e50cc270f854691f335ad",
|
||||||
"sha" : "",
|
"status": "success",
|
||||||
"project_id" : 6,
|
"name": "pages",
|
||||||
"repo_url" : "git@demo.gitlab.com:gitlab/gitlab-shell.git",
|
"token": "9dd60b4f1a439d1765357446c1084c",
|
||||||
"before_sha" : ""
|
"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
|
### Update details of an existing build
|
||||||
|
|
||||||
PUT /ci/builds/:id
|
PUT /ci/builds/:id
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Ci
|
||||||
|
|
||||||
if build
|
if build
|
||||||
update_runner_info
|
update_runner_info
|
||||||
present build, with: Entities::Build
|
present build, with: Entities::BuildDetails
|
||||||
else
|
else
|
||||||
not_found!
|
not_found!
|
||||||
end
|
end
|
||||||
|
@ -111,7 +111,7 @@ module Ci
|
||||||
build.artifacts_metadata = metadata
|
build.artifacts_metadata = metadata
|
||||||
|
|
||||||
if build.save
|
if build.save
|
||||||
present(build, with: Entities::Build)
|
present(build, with: Entities::BuildDetails)
|
||||||
else
|
else
|
||||||
render_validation_error!(build)
|
render_validation_error!(build)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,10 +16,19 @@ module Ci
|
||||||
end
|
end
|
||||||
|
|
||||||
class Build < Grape::Entity
|
class Build < Grape::Entity
|
||||||
expose :id, :commands, :ref, :sha, :status, :project_id, :repo_url,
|
expose :id, :ref, :tag, :sha, :status
|
||||||
:before_sha, :allow_git_fetch, :project_name
|
|
||||||
|
|
||||||
expose :name, :token, :stage
|
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|
|
expose :options do |model|
|
||||||
model.options
|
model.options
|
||||||
|
@ -30,7 +39,9 @@ module Ci
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :variables
|
expose :variables
|
||||||
expose :artifacts_file, using: ArtifactFile
|
expose :dependencies do
|
||||||
|
expose :depends_on_builds, as: :builds, using: Build
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Runner < Grape::Entity
|
class Runner < Grape::Entity
|
||||||
|
|
|
@ -426,6 +426,30 @@ describe Ci::Build, models: true do
|
||||||
it { is_expected.to include(project.web_url[7..-1]) }
|
it { is_expected.to include(project.web_url[7..-1]) }
|
||||||
end
|
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)
|
def create_mr(build, commit, factory: :merge_request, created_at: Time.now)
|
||||||
FactoryGirl.create(factory,
|
FactoryGirl.create(factory,
|
||||||
source_project_id: commit.gl_project_id,
|
source_project_id: commit.gl_project_id,
|
||||||
|
|
|
@ -101,6 +101,18 @@ describe Ci::API::API do
|
||||||
{ "key" => "TRIGGER_KEY", "value" => "TRIGGER_VALUE", "public" => false },
|
{ "key" => "TRIGGER_KEY", "value" => "TRIGGER_VALUE", "public" => false },
|
||||||
])
|
])
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "PUT /builds/:id" do
|
describe "PUT /builds/:id" do
|
||||||
|
|
|
@ -36,8 +36,8 @@ staging:
|
||||||
script: "cap deploy stating"
|
script: "cap deploy stating"
|
||||||
type: deploy
|
type: deploy
|
||||||
tags:
|
tags:
|
||||||
- capistrano
|
- ruby
|
||||||
- debian
|
- mysql
|
||||||
except:
|
except:
|
||||||
- stable
|
- stable
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ production:
|
||||||
- cap deploy production
|
- cap deploy production
|
||||||
- cap notify
|
- cap notify
|
||||||
tags:
|
tags:
|
||||||
- capistrano
|
- ruby
|
||||||
- debian
|
- mysql
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- /^deploy-.*$/
|
- /^deploy-.*$/
|
||||||
|
|
Loading…
Reference in New Issue