Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit 677863a

Browse files
authored
Merge pull request cloudfoundry#1611 from cloudfoundry/171637275_add_deployable_revisions
Add deployable property to revisions endpoints.
2 parents 9b8083e + 9accf60 commit 677863a

9 files changed

Lines changed: 81 additions & 8 deletions

File tree

app/fetchers/app_revisions_fetcher.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
module VCAP::CloudController
22
class AppRevisionsFetcher
33
def self.fetch(app, message)
4-
dataset = RevisionModel.where(app_guid: app.guid)
4+
dataset = RevisionModel.where(Sequel[:revisions][:app_guid] => app.guid)
55

66
if message.requested?(:versions)
7-
dataset = dataset.where(app_guid: app.guid, version: message.versions)
7+
dataset = dataset.where(Sequel[:revisions][:app_guid] => app.guid, version: message.versions)
8+
end
9+
10+
if message.requested?(:deployable)
11+
dataset = dataset.join(:droplets, guid: :droplet_guid).where(Sequel[:revisions][:app_guid] => app.guid, Sequel[:droplets][:state] => DropletModel::STAGED_STATE)
812
end
913

1014
if message.requested?(:label_selector)

app/messages/app_revisions_list_message.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ module VCAP::CloudController
44
class AppRevisionsListMessage < MetadataListMessage
55
register_allowed_keys [
66
:versions,
7+
:deployable,
78
]
89

910
validates_with NoAdditionalParamsValidator
1011

1112
validates :versions, array: true, allow_nil: true
13+
validates :deployable,
14+
inclusion: { in: [true, false], message: 'must be a boolean' },
15+
allow_nil: true
1216

1317
def self.from_params(params)
1418
super(params, %w(versions))

app/presenters/v3/revision_presenter.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def to_hash
3030
metadata: {
3131
labels: hashified_labels(revision.labels),
3232
annotations: hashified_annotations(revision.annotations),
33-
}
33+
},
34+
deployable: deployable
35+
3436
}
3537
end
3638

@@ -68,6 +70,10 @@ def sidecars
6870
}
6971
end
7072
end
73+
74+
def deployable
75+
revision.droplet.staged?
76+
end
7177
end
7278
end
7379
end

docs/v3/source/includes/api_resources/_revisions.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
}
2020
],
2121
"description": "Initial revision.",
22+
"deployable": true,
2223
"relationships": {
2324
"app": {
2425
"data": {
@@ -81,6 +82,7 @@
8182
}
8283
],
8384
"description": "Initial revision.",
85+
"deployable": true,
8486
"relationships": {
8587
"app": {
8688
"data": {

docs/v3/source/includes/experimental_resources/revisions/_object.md.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Name | Type | Description
1717
**created_at** | _datetime_ | The time with zone when the object was created.
1818
**updated_at** | _datetime_ | The time with zone when the object was last updated.
1919
**description** | _string_ | A short description of the reason for revision.
20+
**deployable** _(experimental)_ | _boolean_ | Indicates if the revision's droplet is staged and the revision can be used to [create a deployment](#create-a-deployment).
2021
**relationships.app** | [_to-one relationship_](#to-one-relationships) | The app the revision is associated with.
2122
**metadata.labels** | [_label object_](#labels) | Labels applied to the revision.
2223
**metadata.annotations** | [_annotation object_](#annotations) | Annotations applied to the revision.

spec/request/revisions_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
'command' => 'run-sidecar',
7070
'process_types' => ['web'],
7171
'memory_in_mb' => 300,
72-
}]
72+
}],
73+
'deployable' => true
7374
}
7475
)
7576
end
@@ -146,6 +147,7 @@
146147
},
147148
},
148149
'sidecars' => [],
150+
'deployable' => true
149151
},
150152
{
151153
'guid' => revision2.guid,
@@ -181,6 +183,7 @@
181183
},
182184
},
183185
'sidecars' => [],
186+
'deployable' => true
184187
}
185188
]
186189
}
@@ -244,6 +247,7 @@
244247
},
245248
},
246249
'sidecars' => [],
250+
'deployable' => true
247251
},
248252
{
249253
'guid' => revision3.guid,
@@ -279,6 +283,7 @@
279283
},
280284
},
281285
'sidecars' => [],
286+
'deployable' => true
282287
}
283288
]
284289
}
@@ -367,6 +372,7 @@
367372
},
368373
},
369374
'sidecars' => [],
375+
'deployable' => true
370376
}
371377
)
372378
end
@@ -461,6 +467,7 @@
461467
},
462468
},
463469
'sidecars' => [],
470+
'deployable' => true
464471
},
465472
{
466473
'guid' => revision2.guid,
@@ -496,6 +503,7 @@
496503
},
497504
},
498505
'sidecars' => [],
506+
'deployable' => true
499507
}
500508
]
501509
}

spec/unit/fetchers/app_revisions_fetcher_spec.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ module VCAP::CloudController
55
RSpec.describe AppRevisionsFetcher do
66
let(:fetcher) { AppRevisionsFetcher }
77
let!(:app) { AppModel.make }
8-
let!(:revision1) { RevisionModel.make(version: 21, app: app) }
9-
let!(:revision2) { RevisionModel.make(version: 34, app: app) }
8+
9+
let(:expired_droplet) { DropletModel.make(:droplet, app: app, state: DropletModel::EXPIRED_STATE) }
10+
let(:staged_droplet) { DropletModel.make(:droplet, app: app, state: DropletModel::STAGED_STATE) }
11+
12+
let!(:revision1) { RevisionModel.make(version: 21, droplet_guid: staged_droplet.guid, app: app) }
13+
let!(:revision2) { RevisionModel.make(version: 34, droplet_guid: expired_droplet.guid, app: app) }
1014

1115
describe '#fetch' do
1216
let(:message) { AppRevisionsListMessage.from_params(filters) }
@@ -20,7 +24,7 @@ module VCAP::CloudController
2024
end
2125
end
2226

23-
context 'when the revisions are filtered' do
27+
context 'when the revisions are filtered on version' do
2428
let(:filters) { { versions: [revision1.version] } }
2529

2630
it 'returns all of the desired revisions' do
@@ -29,6 +33,15 @@ module VCAP::CloudController
2933
end
3034
end
3135

36+
context 'when the revisions are filtered on deployable' do
37+
let(:filters) { { deployable: true } }
38+
39+
it 'returns all of the desired revisions' do
40+
expect(subject).to include(revision1)
41+
expect(subject).to_not include(revision2)
42+
end
43+
end
44+
3245
context 'when a label_selector is provided' do
3346
let(:message) { AppRevisionsListMessage.from_params({ 'label_selector' => 'key=value' }) }
3447
let!(:revision1label) { RevisionLabelModel.make(key_name: 'key', value: 'value', revision: revision1) }

spec/unit/messages/app_revisions_list_message_spec.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module VCAP::CloudController
1010
'page' => 1,
1111
'per_page' => 5,
1212
'label_selector' => 'key=value',
13+
'deployable' => true
1314
}
1415
end
1516

@@ -20,6 +21,7 @@ module VCAP::CloudController
2021
expect(message.page).to eq(1)
2122
expect(message.per_page).to eq(5)
2223
expect(message.versions).to eq(['1', '3'])
24+
expect(message.deployable).to eq(true)
2325
expect(message.label_selector).to eq('key=value')
2426
end
2527

@@ -29,6 +31,7 @@ module VCAP::CloudController
2931
expect(message.requested?(:page)).to be_truthy
3032
expect(message.requested?(:per_page)).to be_truthy
3133
expect(message.requested?(:versions)).to be_truthy
34+
expect(message.requested?(:deployable)).to be_truthy
3235
expect(message.requested?(:label_selector)).to be_truthy
3336
end
3437
end
@@ -55,7 +58,8 @@ module VCAP::CloudController
5558
AppRevisionsListMessage.from_params({
5659
page: 1,
5760
per_page: 5,
58-
versions: ['1'],
61+
versions: ['1'],
62+
deployable: true,
5963
label_selector: 'key=value',
6064
})
6165
}.not_to raise_error
@@ -88,6 +92,19 @@ module VCAP::CloudController
8892
end
8993
end
9094

95+
context 'deployable' do
96+
it 'validates deployable to be a boolean' do
97+
message = AppRevisionsListMessage.from_params(deployable: 'not a boolean')
98+
expect(message).to be_invalid
99+
expect(message.errors[:deployable]).to include('must be a boolean')
100+
end
101+
102+
it 'allows deployable to be nil' do
103+
message = AppRevisionsListMessage.from_params(deployable: nil)
104+
expect(message).to be_valid
105+
end
106+
end
107+
91108
it 'validates metadata requirements' do
92109
message = AppRevisionsListMessage.from_params('label_selector' => '')
93110

spec/unit/presenters/v3/revision_presenter_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ module VCAP::CloudController::Presenters::V3
9696
expect(result[:sidecars][0][:memory_in_mb]).to eq(300)
9797
expect(result[:sidecars][0][:process_types]).to eq(['web'])
9898
expect(result[:description]).to eq('Initial revision')
99+
expect(result[:deployable]).to eq(true)
100+
end
101+
102+
context 'when the droplet is not staged' do
103+
let(:droplet) do
104+
VCAP::CloudController::DropletModel.make(
105+
app: app_model,
106+
state: VCAP::CloudController::DropletModel::EXPIRED_STATE,
107+
process_types: {
108+
'web' => 'droplet_web_command',
109+
'worker' => 'droplet_worker_command',
110+
})
111+
end
112+
113+
it 'returns deployable is false' do
114+
result = RevisionPresenter.new(revision).to_hash
115+
expect(result[:deployable]).to eq(false)
116+
end
99117
end
100118
end
101119
end

0 commit comments

Comments
 (0)