Commit 6e3880e2 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 6d31b8f0
@import 'framework/variables';
// Do not use 3-letter hex codes, bgcolor vs css background-color is problematic in emails
// See https://stackoverflow.com/questions/28551981/why-are-3-digit-hex-color-code-values-interpreted-differently-in-internet-explor
//
// stylelint-disable color-hex-length
$mailer-font: 'Helvetica Neue', Helvetica, Arial, sans-serif;
$mailer-text-color: #333333;
$mailer-bg-color: #fafafa;
$mailer-link-color: #3777b0;
$mailer-link-muted-color: #333333;
$mailer-line-cell-bg-color: #6b4fbb;
$mailer-wrapper-cell-bg-color: #ffffff;
$mailer-wrapper-cell-border-color: #ededed;
$mailer-header-footer-text-color: #5c5c5c;
body {
margin: 0 !important;
background-color: $mailer-bg-color;
padding: 0;
text-align: center;
min-width: 640px;
width: 100%;
height: 100%;
font-family: $mailer-font;
}
table#body {
background-color: $mailer-bg-color;
margin: 0;
padding: 0;
text-align: center;
min-width: 640px;
width: 100%;
}
a {
color: $mailer-link-color;
text-decoration: none;
&.muted {
color: $mailer-link-muted-color;
}
}
.highlight {
font-weight: 500;
}
tr td {
font-family: $mailer-font;
}
tr.line td {
font-family: $mailer-font;
background-color: $mailer-line-cell-bg-color;
height: 4px;
font-size: 4px;
line-height: 4px;
}
tr.header td,
tr.footer td,
td.footer-message {
font-family: $mailer-font;
padding: 25px 0;
font-size: 13px;
line-height: 1.6;
color: $mailer-header-footer-text-color;
}
table.wrapper {
width: 640px;
margin: 0 auto;
border-collapse: separate;
border-spacing: 0;
td.wrapper-cell {
font-family: $mailer-font;
background-color: $mailer-wrapper-cell-bg-color;
text-align: left;
padding: 18px 25px;
border: 1px solid $mailer-wrapper-cell-border-color;
border-radius: 3px;
overflow: hidden;
}
}
table.content {
width: 100%;
border-collapse: separate;
border-spacing: 0;
td.text-content {
font-family: $mailer-font;
color: $mailer-text-color;
font-size: 15px;
font-weight: 400;
line-height: 1.4;
padding: 15px 5px;
text-align: center;
}
}
tr.footer td {
img {
display: block;
margin: 0 auto 1em;
}
.mng-notif-link,
.help-link {
color: $mailer-link-color;
text-decoration: none;
}
}
/* CLIENT-SPECIFIC STYLES */
// These are client-specific rules, ignore some linting rules
//
// stylelint-disable property-no-vendor-prefix, property-no-unknown, length-zero-no-unit
// scss-lint:disable PropertySpelling, ZeroUnit
body,
table,
td,
a {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
-ms-interpolation-mode: bicubic;
}
.hidden {
display: none !important;
visibility: hidden !important;
}
/* iOS BLUE LINKS */
a[x-apple-data-detectors] {
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
/* ANDROID MARGIN HACK */
div[style*='margin: 16px 0'] {
margin: 0 !important;
}
@media only screen and (max-width: 639px) {
body,
#body {
min-width: 320px !important;
}
table.wrapper {
width: 100% !important;
min-width: 320px !important;
}
table.wrapper td.wrapper-cell {
border-left: 0 !important;
border-right: 0 !important;
border-radius: 0 !important;
padding-left: 10px !important;
padding-right: 10px !important;
}
}
......@@ -270,7 +270,7 @@
}
.count-badge,
.btn {
.btn-xs {
height: 24px;
}
......
......@@ -324,6 +324,15 @@ module ApplicationHelper
}
end
def asset_to_string(name)
app = Rails.application
if Rails.configuration.assets.compile
app.assets.find_asset(name).to_s
else
controller.view_context.render(file: File.join('public/assets', app.assets_manifest.assets[name]))
end
end
private
def appearance
......
......@@ -15,16 +15,18 @@ module Emails
user = User.find(recipient_id)
mail(to: user.notification_email_for(notification_group),
subject: subject("Request to join the #{member_source.human_name} #{member_source.model_name.singular}"))
member_email_with_layout(
to: user.notification_email_for(notification_group),
subject: subject("Request to join the #{member_source.human_name} #{member_source.model_name.singular}"))
end
def member_access_granted_email(member_source_type, member_id)
@member_source_type = member_source_type
@member_id = member_id
mail(to: member.user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was granted"))
member_email_with_layout(
to: member.user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was granted"))
end
def member_access_denied_email(member_source_type, source_id, user_id)
......@@ -33,8 +35,9 @@ module Emails
user = User.find(user_id)
mail(to: user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was denied"))
member_email_with_layout(
to: user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was denied"))
end
def member_invited_email(member_source_type, member_id, token)
......@@ -42,8 +45,9 @@ module Emails
@member_id = member_id
@token = token
mail(to: member.invite_email,
subject: subject("Invitation to join the #{member_source.human_name} #{member_source.model_name.singular}"))
member_email_with_layout(
to: member.invite_email,
subject: subject("Invitation to join the #{member_source.human_name} #{member_source.model_name.singular}"))
end
def member_invite_accepted_email(member_source_type, member_id)
......@@ -51,8 +55,9 @@ module Emails
@member_id = member_id
return unless member.created_by
mail(to: member.created_by.notification_email_for(notification_group),
subject: subject('Invitation accepted'))
member_email_with_layout(
to: member.created_by.notification_email_for(notification_group),
subject: subject('Invitation accepted'))
end
def member_invite_declined_email(member_source_type, source_id, invite_email, created_by_id)
......@@ -64,8 +69,9 @@ module Emails
user = User.find(created_by_id)
mail(to: user.notification_email_for(notification_group),
subject: subject('Invitation declined'))
member_email_with_layout(
to: user.notification_email_for(notification_group),
subject: subject('Invitation declined'))
end
def member
......@@ -85,5 +91,12 @@ module Emails
def member_source_class
@member_source_type.classify.constantize
end
def member_email_with_layout(to:, subject:)
mail(to: to, subject: subject) do |format|
format.html { render layout: 'mailer' }
format.text { render layout: 'mailer' }
end
end
end
end
......@@ -18,12 +18,11 @@ module Emails
@merge_request = pipeline.all_merge_requests.first
add_headers
# We use bcc here because we don't want to generate this emails for a
# We use bcc here because we don't want to generate these emails for a
# thousand times. This could be potentially expensive in a loop, and
# recipients would contain all project watchers so it could be a lot.
mail(bcc: recipients,
subject: pipeline_subject(status),
skip_premailer: true) do |format|
subject: pipeline_subject(status)) do |format|
format.html { render layout: 'mailer' }
format.text { render layout: 'mailer' }
end
......
......@@ -21,7 +21,13 @@ module Emails
private
def release_email_subject
release_info = [@release.name, @release.tag].select(&:presence).join(' - ')
release_info =
if @release.name == @release.tag
@release.tag
else
[@release.name, @release.tag].select(&:presence).join(' - ')
end
"New release: #{release_info}"
end
end
......
......@@ -77,7 +77,7 @@ class NotifyPreview < ActionMailer::Preview
end
def import_issues_csv_email
Notify.import_issues_csv_email(user, project, { success: 3, errors: [5, 6, 7], valid_file: true })
Notify.import_issues_csv_email(user.id, project.id, { success: 3, errors: [5, 6, 7], valid_file: true })
end
def closed_merge_request_email
......@@ -109,11 +109,11 @@ class NotifyPreview < ActionMailer::Preview
end
def member_access_requested_email
Notify.member_access_requested_email('group', user.id, user.id).message
Notify.member_access_requested_email(member.source_type, member.id, user.id).message
end
def member_invite_accepted_email
Notify.member_invite_accepted_email('project', user.id).message
Notify.member_invite_accepted_email(member.source_type, member.id).message
end
def member_invite_declined_email
......
......@@ -69,6 +69,10 @@ class Release < ApplicationRecord
released_at.present? && released_at > Time.zone.now
end
def name
self.read_attribute(:name) || tag
end
private
def actual_sha
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
%html{ lang: "en" }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
%meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/
%title= message.subject
:css
/* CLIENT-SPECIFIC STYLES */
body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
img { -ms-interpolation-mode: bicubic; }
.hidden {
display: none !important;
visibility: hidden !important;
}
/* iOS BLUE LINKS */
a[x-apple-data-detectors] {
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
-# Avoid premailer processing of client-specific styles (@media tag not supported)
-# We need to inline the contents here because mail clients (e.g. iOS Mail, Outlook)
-# do not support linked stylesheets.
%style{ type: 'text/css', 'data-premailer': 'ignore' }
= asset_to_string('mailer_client_specific.css').html_safe
/* ANDROID MARGIN HACK */
body { margin:0 !important; }
div[style*="margin: 16px 0"] { margin:0 !important; }
@media only screen and (max-width: 639px) {
body, #body {
min-width: 320px !important;
}
table.wrapper {
width: 100% !important;
min-width: 320px !important;
}
table.wrapper > tbody > tr > td {
border-left: 0 !important;
border-right: 0 !important;
border-radius: 0 !important;
padding-left: 10px !important;
padding-right: 10px !important;
}
}
%body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" }
= stylesheet_link_tag 'mailer.css'
%body
%table#body{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
%tr.line
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }
%td
%tr.header
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
%td
= html_header_message
= header_logo
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" }
%td
%table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
%table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
%td.wrapper-cell
%table.content{ border: "0", cellpadding: "0", cellspacing: "0" }
%tbody
= yield
= render_if_exists 'layouts/mailer/additional_text'
%tr.footer
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
%img{ alt: "GitLab", height: "33", src: image_url('mailers/gitlab_footer_logo.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/
%td
%img{ alt: "GitLab", height: "33", width: "90", src: image_url('mailers/gitlab_footer_logo.gif') }
%div
- manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, style: "color:#3777b0;text-decoration:none;")
- help_link = link_to(_("Help"), help_url, style: "color:#3777b0;text-decoration:none;")
- manage_notifications_link = link_to(_("Manage all notifications"), profile_notifications_url, class: 'mng-notif-link')
- help_link = link_to(_("Help"), help_url, class: 'help-link')
= _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link }
= yield :additional_footer
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
%td.footer-message
= html_footer_message
%p
Your request to join the
#{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}
has been denied.
%tr
%td.text-content
%p
Your request to join the
#{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}
has been #{content_tag :span, 'denied', class: :highlight}.
- link_end = '</a>'.html_safe
- source_type = member_source.model_name.singular
- leave_link = polymorphic_url([member_source], leave: 1)
- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer')
- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer', class: :highlight)
- access_level = content_tag(:span, member.human_access, class: :highlight)
%tr
%td.text-content
%p
= _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: access_level, source_link: source_link, source_type: source_type }
%p
- leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
= _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
%p
= _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: member.human_access, source_link: source_link, source_type: source_type }
%p
- leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
= _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
%p
#{link_to member.user.name, member.user} requested #{member.human_access}
access to the #{link_to member_source.human_name, polymorphic_url([member_source, :members])} #{member_source.model_name.singular}.
%tr
%td.text-content
%p
#{link_to member.user.name, member.user, class: :highlight} requested #{content_tag :span, member.human_access, class: :highlight}
access to the #{link_to member_source.human_name, polymorphic_url([member_source, :members]), class: :highlight} #{member_source.model_name.singular}.
%p
#{member.invite_email}, now known as
#{link_to member.user.name, user_url(member.user)},
has accepted your invitation to join the
#{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
%tr
%td.text-content
%p
#{content_tag :span, member.invite_email, class: :highlight}, now known as
#{link_to member.user.name, user_url(member.user)},
has accepted your invitation to join the
#{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}.
%p
#{@invite_email}
has declined your invitation to join the
#{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
%tr
%td.text-content
%p
#{content_tag :span, @invite_email, class: :highlight}
has #{content_tag :span, 'declined', class: :highlight} your invitation to join the
#{link_to member_source.human_name, member_source.web_url, class: :highlight} #{member_source.model_name.singular}.
%p
You have been invited
- if member.created_by
by
= link_to member.created_by.name, user_url(member.created_by)
to join the
= link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token)
#{member_source.model_name.singular} as #{member.human_access}.
%tr
%td.text-content
%p
You have been invited
- if member.created_by
by
= link_to member.created_by.name, user_url(member.created_by)
to join the
= link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token), class: :highlight
#{member_source.model_name.singular} as #{content_tag :span, member.human_access, class: :highlight}.
%p
= link_to 'Accept invitation', invite_url(@token)
or
= link_to 'decline', decline_invite_url(@token)
%p
= link_to 'Accept invitation', invite_url(@token)
or
= link_to 'decline', decline_invite_url(@token)
......@@ -6,17 +6,18 @@
= render 'projects/blob/viewer_switcher', blob: blob unless blame
.btn-group{ role: "group" }<
= copy_blob_source_button(blob) unless blame
= open_raw_blob_button(blob)
= download_blob_button(blob)
= view_on_environment_button(@commit.sha, @path, @environment) if @environment
.btn-group{ role: "group" }<
= render_if_exists 'projects/blob/header_file_locks_link'
= edit_blob_button
= ide_edit_button
.btn-group{ role: "group" }<
= render_if_exists 'projects/blob/header_file_locks_link'
- if current_user
= replace_blob_link
= delete_blob_link
.btn-group{ role: "group" }<
= copy_blob_source_button(blob) unless blame
= open_raw_blob_button(blob)
= download_blob_button(blob)
= view_on_environment_button(@commit.sha, @path, @environment) if @environment
= render 'projects/fork_suggestion'
= render_if_exists 'projects/blob/header_file_locks', project: @project, path: @path
---
title: Made `name` optional parameter of Release entity
merge_request: 19705
author:
type: changed
---
title: Revert btn-xs styling in projects scss
merge_request: 19640
author:
type: fixed
---
title: Visual design for edit buttons in blob view
merge_request: 19932
author:
type: other
---
title: Unify html email layout for member html emails
merge_request: 17699
author: Diego Louzán
type: added
......@@ -157,6 +157,8 @@ module Gitlab
config.assets.paths << "#{config.root}/vendor/assets/fonts"
config.assets.precompile << "print.css"
config.assets.precompile << "mailer.css"
config.assets.precompile << "mailer_client_specific.css"
config.assets.precompile << "notify.css"
config.assets.precompile << "mailers/*.css"
config.assets.precompile << "page_bundles/ide.css"
......
......@@ -303,7 +303,7 @@ POST /projects/:id/releases
| Attribute | Type | Required | Description |
| -------------------| --------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). |
| `name` | string | yes | The release name. |
| `name` | string | no | The release name. |
| `tag_name` | string | yes | The tag where the release will be created from. |
| `description` | string | yes | The description of the release. You can use [markdown](../../user/markdown.md). |
| `ref` | string | yes, if `tag_name` doesn't exist | If `tag_name` doesn't exist, the release will be created from `ref`. It can be a commit SHA, another tag name, or a branch name. |
......
......@@ -38,7 +38,7 @@ that's tested and deployed on every push to the `master` branch of the [codebase
This will also provide
boilerplate code for starting a browser-based game with the following components:
- Written in [Typescript](https://www.typescriptlang.org/) and [PhaserJs](https://phaser.io)
- Written in [TypeScript](https://www.typescriptlang.org/) and [PhaserJs](https://phaser.io)
- Building, running, and testing with [Gulp](https://gulpjs.com)
- Unit tests with [Chai](https://www.chaijs.com) and [Mocha](https://mochajs.org/)
- CI/CD with GitLab
......@@ -508,7 +508,7 @@ deploy:
## Conclusion
Within the [demo repository](https://gitlab.com/blitzgren/gitlab-game-demo) you can also find a handful of boilerplate code to get
[Typescript](https://www.typescriptlang.org/), [Mocha](https://mochajs.org/), [Gulp](https://gulpjs.com/) and [Phaser](https://phaser.io) all playing
[TypeScript](https://www.typescriptlang.org/), [Mocha](https://mochajs.org/), [Gulp](https://gulpjs.com/) and [Phaser](https://phaser.io) all playing
together nicely with GitLab CI/CD, which is the result of lessons learned while making [Dark Nova](https://www.darknova.io).
Using a combination of free and open source software, we have a full CI/CD pipeline, a game foundation,
and unit tests, all running and deployed at every push to master - with shockingly little code.
......
......@@ -268,7 +268,7 @@ Each issue scheduled for the current milestone should be labeled ~Deliverable
or ~"Stretch". Any open issue for a previous milestone should be labeled
~"Next Patch Release", or otherwise rescheduled to a different milestone.
#### Priority labels
### Priority labels
Priority labels help us define the time a ~bug fix should be completed. Priority determines how quickly the defect turnaround time must be.
If there are multiple defects, the priority decides which defect has to be fixed immediately versus later.
......
......@@ -25,7 +25,7 @@ SAST supports the following official analyzers:
- [`security-code-scan`](https://gitlab.com/gitlab-org/security-products/analyzers/security-code-scan) (Security Code Scan (.NET))
- [`sobelow`](https://gitlab.com/gitlab-org/security-products/analyzers/sobelow) (Sobelow (Elixir Phoenix))
- [`spotbugs`](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) (SpotBugs with the Find Sec Bugs plugin (Ant, Gradle and wrapper, Grails, Maven and wrapper, SBT))
- [`tslint`](https://gitlab.com/gitlab-org/security-products/analyzers/tslint) (TSLint (Typescript))
- [`tslint`](https://gitlab.com/gitlab-org/security-products/analyzers/tslint) (TSLint (TypeScript))
The analyzers are published as Docker images that SAST will use to launch
dedicated containers for each analysis.
......
......@@ -78,7 +78,7 @@ The following table shows which languages, package managers and frameworks are s
| Python ([pip](https://pip.pypa.io/en/stable/)) | [bandit](https://github.com/PyCQA/bandit) | 10.3 |
| Ruby on Rails | [brakeman](https://brakemanscanner.org) | 10.3 |
| Scala ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.0 (SBT) & 11.9 (Ant, Gradle, Maven) |
| Typescript | [TSLint config security](https://github.com/webschik/tslint-config-security/) | 11.9 |
| TypeScript | [TSLint config security](https://github.com/webschik/tslint-config-security/) | 11.9 |
NOTE: **Note:**
The Java analyzers can also be used for variants like the
......
......@@ -1299,7 +1299,9 @@ module API
class Release < Grape::Entity
include ::API::Helpers::Presentable
expose :name
expose :name do |release, _|
can_download_code? ? release.name : "Release-#{release.id}"
end
expose :tag, as: :tag_name, if: ->(_, _) { can_download_code? }
expose :description
expose :description_html do |entity|
......
......@@ -45,7 +45,7 @@ module API
end
params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
requires :name, type: String, desc: 'The name of the release'
optional :name, type: String, desc: 'The name of the release'
requires :description, type: String, desc: 'The release notes'
optional :ref, type: String, desc: 'The commit sha or branch name'
optional :assets, type: Hash do
......
{
"type": "object",
"required": ["name", "tag_name"],
"required": ["tag_name", "description"],
"properties": {
"name": { "type": "string" },
"tag_name": { "type": "string" },
"ref": { "type": "string "},
"description": { "type": "string" },
"description_html": { "type": "string" },
"created_at": { "type": "date" },
......
......@@ -18,6 +18,7 @@ describe Emails::Releases do
context 'when the release has a name' do
it 'shows the correct subject' do
release.name = 'beta-1'
expected_subject = "#{release.project.name} | New release: #{release.name} - #{release.tag}"
is_expected.to have_subject(expected_subject)
end
......
......@@ -27,7 +27,7 @@ describe Evidence do
let(:release) { create(:release, project: project, name: nil) }
it 'creates a valid JSON object' do
expect(release.name).to be_nil
expect(release.name).to eq(release.tag)
expect(summary_json).to match_schema(schema_file)
end
end
......
......@@ -34,7 +34,7 @@ RSpec.describe Release do
expect(existing_release_without_name).to be_valid
expect(existing_release_without_name.description).to eq("change")
expect(existing_release_without_name.name).to be_nil
expect(existing_release_without_name.name).not_to be_nil
end
end
......@@ -129,4 +129,16 @@ RSpec.describe Release do
end
end
end
describe '#name' do
context 'name is nil' do
before do
release.update(name: nil)
end
it 'returns tag' do
expect(release.name).to eq(release.tag)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment