Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
ed36e359
Commit
ed36e359
authored
Nov 22, 2019
by
Lee Tickett
Committed by
Martin Wortschack
Nov 22, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add badge name field
parent
ed00cd2e
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
100 additions
and
33 deletions
+100
-33
app/assets/javascripts/badges/components/badge.vue
app/assets/javascripts/badges/components/badge.vue
+5
-0
app/assets/javascripts/badges/components/badge_form.vue
app/assets/javascripts/badges/components/badge_form.vue
+19
-1
app/assets/javascripts/badges/components/badge_list_row.vue
app/assets/javascripts/badges/components/badge_list_row.vue
+5
-4
app/assets/javascripts/badges/empty_badge.js
app/assets/javascripts/badges/empty_badge.js
+1
-0
app/assets/javascripts/badges/store/actions.js
app/assets/javascripts/badges/store/actions.js
+4
-6
app/models/badge.rb
app/models/badge.rb
+2
-0
changelogs/unreleased/add-badge-name-field.yml
changelogs/unreleased/add-badge-name-field.yml
+5
-0
db/migrate/20190606202100_add_name_to_badges.rb
db/migrate/20190606202100_add_name_to_badges.rb
+11
-0
db/schema.rb
db/schema.rb
+1
-0
doc/api/group_badges.md
doc/api/group_badges.md
+4
-10
doc/api/project_badges.md
doc/api/project_badges.md
+3
-0
lib/api/badges.rb
lib/api/badges.rb
+7
-1
lib/api/entities.rb
lib/api/entities.rb
+1
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/javascripts/badges/components/badge_form_spec.js
spec/javascripts/badges/components/badge_form_spec.js
+4
-2
spec/javascripts/badges/components/badge_list_row_spec.js
spec/javascripts/badges/components/badge_list_row_spec.js
+4
-0
spec/javascripts/badges/dummy_badge.js
spec/javascripts/badges/dummy_badge.js
+2
-0
spec/javascripts/badges/store/actions_spec.js
spec/javascripts/badges/store/actions_spec.js
+4
-0
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+1
-0
spec/requests/api/badges_spec.rb
spec/requests/api/badges_spec.rb
+14
-9
No files found.
app/assets/javascripts/badges/components/badge.vue
View file @
ed36e359
...
...
@@ -14,6 +14,11 @@ export default {
GlTooltip
:
GlTooltipDirective
,
},
props
:
{
name
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
imageUrl
:
{
type
:
String
,
required
:
true
,
...
...
app/assets/javascripts/badges/components/badge_form.vue
View file @
ed36e359
...
...
@@ -4,7 +4,7 @@ import { mapActions, mapState } from 'vuex';
import
createFlash
from
'
~/flash
'
;
import
{
s__
,
sprintf
}
from
'
~/locale
'
;
import
LoadingButton
from
'
~/vue_shared/components/loading_button.vue
'
;
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
GlLoadingIcon
,
GlFormInput
,
GlFormGroup
}
from
'
@gitlab/ui
'
;
import
createEmptyBadge
from
'
../empty_badge
'
;
import
Badge
from
'
./badge.vue
'
;
...
...
@@ -16,6 +16,8 @@ export default {
Badge
,
LoadingButton
,
GlLoadingIcon
,
GlFormInput
,
GlFormGroup
,
},
props
:
{
isEditing
:
{
...
...
@@ -64,6 +66,18 @@ export default {
renderedLinkUrl
()
{
return
this
.
renderedBadge
?
this
.
renderedBadge
.
renderedLinkUrl
:
''
;
},
name
:
{
get
()
{
return
this
.
badge
?
this
.
badge
.
name
:
''
;
},
set
(
name
)
{
const
badge
=
this
.
badge
||
createEmptyBadge
();
this
.
updateBadgeInForm
({
...
badge
,
name
,
});
},
},
imageUrl
:
{
get
()
{
return
this
.
badge
?
this
.
badge
.
imageUrl
:
''
;
...
...
@@ -154,6 +168,10 @@ export default {
novalidate
@submit.prevent.stop="onSubmit"
>
<gl-form-group
:label=
"s__('Badges|Name')"
label-for=
"badge-name"
>
<gl-form-input
id=
"badge-name"
v-model=
"name"
/>
</gl-form-group>
<div
class=
"form-group"
>
<label
for=
"badge-link-url"
class=
"label-bold"
>
{{
s__
(
'
Badges|Link
'
)
}}
</label>
<p
v-html=
"helpText"
></p>
...
...
app/assets/javascripts/badges/components/badge_list_row.vue
View file @
ed36e359
...
...
@@ -43,13 +43,14 @@ export default {
<badge
:image-url=
"badge.renderedImageUrl"
:link-url=
"badge.renderedLinkUrl"
class=
"table-section section-
4
0"
class=
"table-section section-
3
0"
/>
<
span
class=
"table-section section-30 str-truncated"
>
{{
badge
.
linkUrl
}}
</span
>
<div
class=
"table-section section-15"
>
<
div
class=
"table-section section-30"
>
<label
class=
"label-bold str-truncated mb-0"
>
{{
badge
.
name
}}
</label
>
<span
class=
"badge badge-pill"
>
{{
badgeKindText
}}
</span>
</div>
<div
class=
"table-section section-15 table-button-footer"
>
<span
class=
"table-section section-30 str-truncated"
>
{{
badge
.
linkUrl
}}
</span>
<div
class=
"table-section section-10 table-button-footer"
>
<div
v-if=
"canEditBadge"
class=
"table-action-buttons"
>
<button
:disabled=
"badge.isDeleting"
...
...
app/assets/javascripts/badges/empty_badge.js
View file @
ed36e359
export
default
()
=>
({
name
:
''
,
imageUrl
:
''
,
isDeleting
:
false
,
linkUrl
:
''
,
...
...
app/assets/javascripts/badges/store/actions.js
View file @
ed36e359
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
types
from
'
./mutation_types
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
export
const
transformBackendBadge
=
badge
=>
({
id
:
badge
.
id
,
imageUrl
:
badge
.
image_url
,
kind
:
badge
.
kind
,
linkUrl
:
badge
.
link_url
,
renderedImageUrl
:
badge
.
rendered_image_url
,
renderedLinkUrl
:
badge
.
rendered_link_url
,
...
convertObjectPropsToCamelCase
(
badge
,
true
),
isDeleting
:
false
,
});
...
...
@@ -27,6 +23,7 @@ export default {
dispatch
(
'
requestNewBadge
'
);
return
axios
.
post
(
endpoint
,
{
name
:
newBadge
.
name
,
image_url
:
newBadge
.
imageUrl
,
link_url
:
newBadge
.
linkUrl
,
})
...
...
@@ -141,6 +138,7 @@ export default {
dispatch
(
'
requestUpdatedBadge
'
);
return
axios
.
put
(
endpoint
,
{
name
:
badge
.
name
,
image_url
:
badge
.
imageUrl
,
link_url
:
badge
.
linkUrl
,
})
...
...
app/models/badge.rb
View file @
ed36e359
...
...
@@ -22,6 +22,8 @@ class Badge < ApplicationRecord
scope
:order_created_at_asc
,
->
{
reorder
(
created_at: :asc
)
}
scope
:with_name
,
->
(
name
)
{
where
(
name:
name
)
}
validates
:link_url
,
:image_url
,
addressable_url:
true
validates
:type
,
presence:
true
...
...
changelogs/unreleased/add-badge-name-field.yml
0 → 100644
View file @
ed36e359
---
title
:
Add badge name field
merge_request
:
16998
author
:
Lee Tickett
type
:
added
db/migrate/20190606202100_add_name_to_badges.rb
0 → 100644
View file @
ed36e359
# frozen_string_literal: true
class
AddNameToBadges
<
ActiveRecord
::
Migration
[
5.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:badges
,
:name
,
:string
,
null:
true
,
limit:
255
end
end
db/schema.rb
View file @
ed36e359
...
...
@@ -498,6 +498,7 @@ ActiveRecord::Schema.define(version: 2019_11_19_023952) do
t
.
integer
"project_id"
t
.
integer
"group_id"
t
.
string
"type"
,
null:
false
t
.
string
"name"
,
limit:
255
t
.
datetime_with_timezone
"created_at"
,
null:
false
t
.
datetime_with_timezone
"updated_at"
,
null:
false
t
.
index
[
"group_id"
],
name:
"index_badges_on_group_id"
...
...
doc/api/group_badges.md
View file @
ed36e359
...
...
@@ -26,9 +26,10 @@ GET /groups/:id/badges
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer/string | yes | The ID or
[
URL-encoded path of the group
](
README.md#namespaced-path-encoding
)
owned by the authenticated user |
|
`name`
| string | no | Name of the badges to return (case-sensitive). |
```
bash
curl
--header
"PRIVATE-TOKEN: <your_access_token>"
https://gitlab.example.com/api/v4/groups/:id/badges
curl
--header
"PRIVATE-TOKEN: <your_access_token>"
https://gitlab.example.com/api/v4/groups/:id/badges
?name
=
Coverage
```
Example response:
...
...
@@ -36,21 +37,14 @@ Example response:
```
json
[
{
"name"
:
"Coverage"
,
"id"
:
1
,
"link_url"
:
"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}"
,
"image_url"
:
"https://shields.io/my/badge"
,
"rendered_link_url"
:
"http://example.com/ci_status.svg?project=example-org/example-project&ref=master"
,
"rendered_image_url"
:
"https://shields.io/my/badge"
,
"kind"
:
"group"
},
{
"id"
:
2
,
"link_url"
:
"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}"
,
"image_url"
:
"https://shields.io/my/badge"
,
"rendered_link_url"
:
"http://example.com/ci_status.svg?project=example-org/example-project&ref=master"
,
"rendered_image_url"
:
"https://shields.io/my/badge"
,
"kind"
:
"group"
},
}
]
```
...
...
doc/api/project_badges.md
View file @
ed36e359
...
...
@@ -23,6 +23,7 @@ GET /projects/:id/badges
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer/string | yes | The ID or
[
URL-encoded path of the project
](
README.md#namespaced-path-encoding
)
owned by the authenticated user |
|
`name`
| string | no | Name of the badges to return (case-sensitive). |
```
bash
curl
--header
"PRIVATE-TOKEN: <your_access_token>"
https://gitlab.example.com/api/v4/projects/:id/badges
...
...
@@ -33,6 +34,7 @@ Example response:
```
json
[
{
"name"
:
"Coverage"
,
"id"
:
1
,
"link_url"
:
"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}"
,
"image_url"
:
"https://shields.io/my/badge"
,
...
...
@@ -41,6 +43,7 @@ Example response:
"kind"
:
"project"
},
{
"name"
:
"Pipeline"
,
"id"
:
2
,
"link_url"
:
"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}"
,
"image_url"
:
"https://shields.io/my/badge"
,
...
...
lib/api/badges.rb
View file @
ed36e359
...
...
@@ -33,7 +33,11 @@ module API
get
":id/badges"
do
source
=
find_source
(
source_type
,
params
[
:id
])
present_badges
(
source
,
paginate
(
source
.
badges
))
badges
=
source
.
badges
name
=
params
[
:name
]
badges
=
badges
.
with_name
(
name
)
if
name
present_badges
(
source
,
paginate
(
badges
))
end
desc
"Preview a badge from a
#{
source_type
}
."
do
...
...
@@ -80,6 +84,7 @@ module API
params
do
requires
:link_url
,
type:
String
,
desc:
'URL of the badge link'
requires
:image_url
,
type:
String
,
desc:
'URL of the badge image'
optional
:name
,
type:
String
,
desc:
'Name for the badge'
end
post
":id/badges"
do
source
=
find_source_if_admin
(
source_type
)
...
...
@@ -100,6 +105,7 @@ module API
params
do
optional
:link_url
,
type:
String
,
desc:
'URL of the badge link'
optional
:image_url
,
type:
String
,
desc:
'URL of the badge image'
optional
:name
,
type:
String
,
desc:
'Name for the badge'
end
put
":id/badges/:badge_id"
do
source
=
find_source_if_admin
(
source_type
)
...
...
lib/api/entities.rb
View file @
ed36e359
...
...
@@ -1736,6 +1736,7 @@ module API
end
class
BasicBadgeDetails
<
Grape
::
Entity
expose
:name
expose
:link_url
expose
:image_url
expose
:rendered_link_url
do
|
badge
,
options
|
...
...
locale/gitlab.pot
View file @
ed36e359
...
...
@@ -2386,6 +2386,9 @@ msgstr ""
msgid "Badges|Link"
msgstr ""
msgid "Badges|Name"
msgstr ""
msgid "Badges|No badge image"
msgstr ""
...
...
spec/javascripts/badges/components/badge_form_spec.js
View file @
ed36e359
...
...
@@ -51,13 +51,14 @@ describe('BadgeForm component', () => {
});
const
sharedSubmitTests
=
submitAction
=>
{
const
nameSelector
=
'
#badge-name
'
;
const
imageUrlSelector
=
'
#badge-image-url
'
;
const
findImageUrlElement
=
()
=>
vm
.
$el
.
querySelector
(
imageUrlSelector
);
const
linkUrlSelector
=
'
#badge-link-url
'
;
const
findLinkUrlElement
=
()
=>
vm
.
$el
.
querySelector
(
linkUrlSelector
);
const
setValue
=
(
inputElementSelector
,
url
)
=>
{
const
setValue
=
(
inputElementSelector
,
value
)
=>
{
const
inputElement
=
vm
.
$el
.
querySelector
(
inputElementSelector
);
inputElement
.
value
=
url
;
inputElement
.
value
=
value
;
inputElement
.
dispatchEvent
(
new
Event
(
'
input
'
));
};
const
submitForm
=
()
=>
{
...
...
@@ -82,6 +83,7 @@ describe('BadgeForm component', () => {
isSaving
:
false
,
});
setValue
(
nameSelector
,
'
TestBadge
'
);
setValue
(
linkUrlSelector
,
`
${
TEST_HOST
}
/link/url`
);
setValue
(
imageUrlSelector
,
`
${
window
.
location
.
origin
}${
DUMMY_IMAGE_URL
}
`
);
});
...
...
spec/javascripts/badges/components/badge_list_row_spec.js
View file @
ed36e359
...
...
@@ -39,6 +39,10 @@ describe('BadgeListRow component', () => {
expect
(
badgeElement
.
getAttribute
(
'
src
'
)).
toBe
(
badge
.
renderedImageUrl
);
});
it
(
'
renders the badge name
'
,
()
=>
{
expect
(
vm
.
$el
).
toContainText
(
badge
.
name
);
});
it
(
'
renders the badge link
'
,
()
=>
{
expect
(
vm
.
$el
).
toContainText
(
badge
.
linkUrl
);
});
...
...
spec/javascripts/badges/dummy_badge.js
View file @
ed36e359
...
...
@@ -6,6 +6,7 @@ export const createDummyBadge = () => {
const
id
=
_
.
uniqueId
();
return
{
id
,
name
:
'
TestBadge
'
,
imageUrl
:
`
${
TEST_HOST
}
/badges/
${
id
}
/image/url`
,
isDeleting
:
false
,
linkUrl
:
`
${
TEST_HOST
}
/badges/
${
id
}
/link/url`
,
...
...
@@ -16,6 +17,7 @@ export const createDummyBadge = () => {
};
export
const
createDummyBadgeResponse
=
()
=>
({
name
:
'
TestBadge
'
,
image_url
:
`
${
TEST_HOST
}
/badge/image/url`
,
link_url
:
`
${
TEST_HOST
}
/badge/link/url`
,
kind
:
PROJECT_BADGE
,
...
...
spec/javascripts/badges/store/actions_spec.js
View file @
ed36e359
...
...
@@ -90,6 +90,7 @@ describe('Badges store actions', () => {
endpointMock
.
replyOnce
(
req
=>
{
expect
(
req
.
data
).
toBe
(
JSON
.
stringify
({
name
:
'
TestBadge
'
,
image_url
:
badgeInAddForm
.
imageUrl
,
link_url
:
badgeInAddForm
.
linkUrl
,
}),
...
...
@@ -114,6 +115,7 @@ describe('Badges store actions', () => {
endpointMock
.
replyOnce
(
req
=>
{
expect
(
req
.
data
).
toBe
(
JSON
.
stringify
({
name
:
'
TestBadge
'
,
image_url
:
badgeInAddForm
.
imageUrl
,
link_url
:
badgeInAddForm
.
linkUrl
,
}),
...
...
@@ -526,6 +528,7 @@ describe('Badges store actions', () => {
endpointMock
.
replyOnce
(
req
=>
{
expect
(
req
.
data
).
toBe
(
JSON
.
stringify
({
name
:
'
TestBadge
'
,
image_url
:
badgeInEditForm
.
imageUrl
,
link_url
:
badgeInEditForm
.
linkUrl
,
}),
...
...
@@ -550,6 +553,7 @@ describe('Badges store actions', () => {
endpointMock
.
replyOnce
(
req
=>
{
expect
(
req
.
data
).
toBe
(
JSON
.
stringify
({
name
:
'
TestBadge
'
,
image_url
:
badgeInEditForm
.
imageUrl
,
link_url
:
badgeInEditForm
.
linkUrl
,
}),
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
ed36e359
...
...
@@ -651,6 +651,7 @@ PrometheusAlert:
-
prometheus_metric_id
Badge
:
-
id
-
name
-
link_url
-
image_url
-
project_id
...
...
spec/requests/api/badges_spec.rb
View file @
ed36e359
...
...
@@ -81,6 +81,7 @@ describe API::Badges do
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/badges/
#{
badge
.
id
}
"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
[
'name'
]).
to
eq
(
badge
.
name
)
expect
(
json_response
[
'id'
]).
to
eq
(
badge
.
id
)
expect
(
json_response
[
'link_url'
]).
to
eq
(
badge
.
link_url
)
expect
(
json_response
[
'rendered_link_url'
]).
to
eq
(
badge
.
rendered_link_url
)
...
...
@@ -98,6 +99,7 @@ describe API::Badges do
include_context
'source helpers'
let
(
:source
)
{
get_source
(
source_type
)
}
let
(
:example_name
)
{
'BadgeName'
}
let
(
:example_url
)
{
'http://www.example.com'
}
let
(
:example_url2
)
{
'http://www.example1.com'
}
...
...
@@ -105,7 +107,7 @@ describe API::Badges do
it_behaves_like
'a 404 response when source is private'
do
let
(
:route
)
do
post
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/badges"
,
stranger
),
params:
{
link_url:
example_url
,
image_url:
example_url2
}
params:
{
name:
example_name
,
link_url:
example_url
,
image_url:
example_url2
}
end
end
...
...
@@ -128,11 +130,12 @@ describe API::Badges do
it
'creates a new badge'
do
expect
do
post
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/badges"
,
maintainer
),
params:
{
link_url:
example_url
,
image_url:
example_url2
}
params:
{
name:
example_name
,
link_url:
example_url
,
image_url:
example_url2
}
expect
(
response
).
to
have_gitlab_http_status
(
201
)
end
.
to
change
{
source
.
badges
.
count
}.
by
(
1
)
expect
(
json_response
[
'name'
]).
to
eq
(
example_name
)
expect
(
json_response
[
'link_url'
]).
to
eq
(
example_url
)
expect
(
json_response
[
'image_url'
]).
to
eq
(
example_url2
)
expect
(
json_response
[
'kind'
]).
to
eq
source_type
...
...
@@ -169,6 +172,7 @@ describe API::Badges do
context
"with :sources ==
#{
source_type
.
pluralize
}
"
do
let
(
:badge
)
{
source
.
badges
.
first
}
let
(
:example_name
)
{
'BadgeName'
}
let
(
:example_url
)
{
'http://www.example.com'
}
let
(
:example_url2
)
{
'http://www.example1.com'
}
...
...
@@ -197,9 +201,10 @@ describe API::Badges do
context
'when authenticated as a maintainer/owner'
do
it
'updates the member'
,
:quarantine
do
put
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/badges/
#{
badge
.
id
}
"
,
maintainer
),
params:
{
link_url:
example_url
,
image_url:
example_url2
}
params:
{
name:
example_name
,
link_url:
example_url
,
image_url:
example_url2
}
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
[
'name'
]).
to
eq
(
example_name
)
expect
(
json_response
[
'link_url'
]).
to
eq
(
example_url
)
expect
(
json_response
[
'image_url'
]).
to
eq
(
example_url2
)
expect
(
json_response
[
'kind'
]).
to
eq
source_type
...
...
@@ -297,7 +302,7 @@ describe API::Badges do
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
.
keys
).
to
contain_exactly
(
'link_url'
,
'rendered_link_url'
,
'image_url'
,
'rendered_image_url'
)
expect
(
json_response
.
keys
).
to
contain_exactly
(
'
name'
,
'
link_url'
,
'rendered_link_url'
,
'image_url'
,
'rendered_image_url'
)
expect
(
json_response
[
'link_url'
]).
to
eq
(
example_url
)
expect
(
json_response
[
'image_url'
]).
to
eq
(
example_url2
)
expect
(
json_response
[
'rendered_link_url'
]).
to
eq
(
example_url
)
...
...
@@ -351,9 +356,9 @@ describe API::Badges do
project
.
add_developer
(
developer
)
project
.
add_maintainer
(
maintainer
)
project
.
request_access
(
access_requester
)
project
.
project_badges
<<
build
(
:project_badge
,
project:
project
)
project
.
project_badges
<<
build
(
:project_badge
,
project:
project
)
project_group
.
badges
<<
build
(
:group_badge
,
group:
group
)
project
.
project_badges
<<
build
(
:project_badge
,
project:
project
,
name:
'ExampleBadge1'
)
project
.
project_badges
<<
build
(
:project_badge
,
project:
project
,
name:
'ExampleBadge2'
)
project_group
.
badges
<<
build
(
:group_badge
,
group:
group
,
name:
'ExampleBadge3'
)
end
end
...
...
@@ -362,8 +367,8 @@ describe API::Badges do
group
.
add_developer
(
developer
)
group
.
add_owner
(
maintainer
)
group
.
request_access
(
access_requester
)
group
.
badges
<<
build
(
:group_badge
,
group:
group
)
group
.
badges
<<
build
(
:group_badge
,
group:
group
)
group
.
badges
<<
build
(
:group_badge
,
group:
group
,
name:
'ExampleBadge4'
)
group
.
badges
<<
build
(
:group_badge
,
group:
group
,
name:
'ExampleBadge5'
)
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment