Merge remote-tracking branch 'origin/release-notes'
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
This commit is contained in:
commit
354b69dde2
|
@ -32,6 +32,7 @@ v 8.2.0 (unreleased)
|
|||
v 8.1.4
|
||||
- Fix bug where manually merged branches in a MR would end up with an empty diff (Stan Hu)
|
||||
- Prevent redirect loop when home_page_url is set to the root URL
|
||||
- Ability to add release notes (markdown text and attachments) to git tags
|
||||
|
||||
v 8.1.3
|
||||
- Force update refs/merge-requests/X/head upon a push to the source branch of a merge request (Stan Hu)
|
||||
|
|
|
@ -39,6 +39,12 @@ class Dispatcher
|
|||
shortcut_handler = new ShortcutsNavigation()
|
||||
new DropzoneInput($('.merge-request-form'))
|
||||
new IssuableForm($('.merge-request-form'))
|
||||
when 'projects:tags:new'
|
||||
new ZenMode()
|
||||
new DropzoneInput($('.tag-form'))
|
||||
when 'projects:releases:edit'
|
||||
new ZenMode()
|
||||
new DropzoneInput($('.release-form'))
|
||||
when 'projects:merge_requests:show'
|
||||
new Diff()
|
||||
shortcut_handler = new ShortcutsIssuable()
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
.bs-callout {
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
border-left: 3px solid #eee;
|
||||
color: #666;
|
||||
background: #f9f9f9;
|
||||
border-left: 3px solid $border-color;
|
||||
color: $text-color;
|
||||
background: $background-color;
|
||||
}
|
||||
.bs-callout h4 {
|
||||
margin-top: 0;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
.append-bottom-10 { margin-bottom:10px }
|
||||
.append-bottom-15 { margin-bottom:15px }
|
||||
.append-bottom-20 { margin-bottom:20px }
|
||||
.append-bottom-default { margin-bottom: $gl-padding; }
|
||||
.inline { display: inline-block }
|
||||
.center { text-align: center }
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ ul.content-list {
|
|||
}
|
||||
|
||||
.controls {
|
||||
padding-top: 4px;
|
||||
padding-top: 1px;
|
||||
float: right;
|
||||
|
||||
.btn {
|
||||
|
|
|
@ -72,9 +72,10 @@
|
|||
list-style: none;
|
||||
|
||||
> li {
|
||||
@include clearfix;
|
||||
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
|
||||
|
|
|
@ -115,3 +115,10 @@ li.commit {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.branch-commit {
|
||||
color: $gl-gray;
|
||||
.commit-id, .commit-row-message {
|
||||
color: $gl-gray;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
class Projects::ReleasesController < Projects::ApplicationController
|
||||
# Authorize
|
||||
before_action :require_non_empty_project
|
||||
before_action :authorize_download_code!
|
||||
before_action :authorize_push_code!
|
||||
before_action :tag
|
||||
before_action :release
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
release.update_attributes(release_params)
|
||||
|
||||
redirect_to namespace_project_tag_path(@project.namespace, @project, @tag.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag
|
||||
@tag ||= @repository.find_tag(params[:tag_id])
|
||||
end
|
||||
|
||||
def release
|
||||
@release ||= @project.releases.find_or_initialize_by(tag: @tag.name)
|
||||
end
|
||||
|
||||
def release_params
|
||||
params.require(:release).permit(:description)
|
||||
end
|
||||
end
|
|
@ -8,15 +8,23 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
def index
|
||||
sorted = VersionSorter.rsort(@repository.tag_names)
|
||||
@tags = Kaminari.paginate_array(sorted).page(params[:page]).per(PER_PAGE)
|
||||
@releases = project.releases.where(tag: @tags)
|
||||
end
|
||||
|
||||
def show
|
||||
@tag = @repository.find_tag(params[:id])
|
||||
@release = @project.releases.find_or_initialize_by(tag: @tag.name)
|
||||
@commit = @repository.commit(@tag.target)
|
||||
end
|
||||
|
||||
def create
|
||||
result = CreateTagService.new(@project, current_user).
|
||||
execute(params[:tag_name], params[:ref], params[:message])
|
||||
execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
|
||||
|
||||
if result[:status] == :success
|
||||
@tag = result[:tag]
|
||||
redirect_to namespace_project_tags_path(@project.namespace, @project)
|
||||
|
||||
redirect_to namespace_project_tag_path(@project.namespace, @project, @tag.name)
|
||||
else
|
||||
@error = result[:message]
|
||||
render action: 'new'
|
||||
|
@ -26,12 +34,6 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
def destroy
|
||||
DeleteTagService.new(project, current_user).execute(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to namespace_project_tags_path(@project.namespace,
|
||||
@project)
|
||||
end
|
||||
format.js
|
||||
end
|
||||
redirect_to namespace_project_tags_path(@project.namespace, @project)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -122,6 +122,7 @@ class Project < ActiveRecord::Base
|
|||
has_many :starrers, through: :users_star_projects, source: :user
|
||||
has_many :ci_commits, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
|
||||
has_many :ci_builds, through: :ci_commits, source: :builds, dependent: :destroy, class_name: 'Ci::Build'
|
||||
has_many :releases, dependent: :destroy
|
||||
|
||||
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
|
||||
has_one :gitlab_ci_project, dependent: :destroy, class_name: "Ci::Project", foreign_key: :gitlab_id
|
||||
|
@ -248,7 +249,7 @@ class Project < ActiveRecord::Base
|
|||
joins(:namespace).
|
||||
iwhere('namespaces.path' => namespace_path)
|
||||
|
||||
projects.where('projects.path' => project_path).take ||
|
||||
projects.where('projects.path' => project_path).take ||
|
||||
projects.iwhere('projects.path' => project_path).take
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class Release < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
|
||||
validates :description, :project, :tag, presence: true
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
require_relative 'base_service'
|
||||
|
||||
class CreateTagService < BaseService
|
||||
def execute(tag_name, ref, message)
|
||||
def execute(tag_name, ref, message, release_description = nil)
|
||||
valid_tag = Gitlab::GitRefValidator.validate(tag_name)
|
||||
if valid_tag == false
|
||||
return error('Tag name invalid')
|
||||
|
@ -19,8 +19,12 @@ class CreateTagService < BaseService
|
|||
new_tag = repository.find_tag(tag_name)
|
||||
|
||||
if new_tag
|
||||
push_data = create_push_data(project, current_user, new_tag)
|
||||
if release_description
|
||||
release = project.releases.find_or_initialize_by(tag: tag_name)
|
||||
release.update_attributes(description: release_description)
|
||||
end
|
||||
|
||||
push_data = create_push_data(project, current_user, new_tag)
|
||||
EventCreateService.new.push(project, current_user, push_data)
|
||||
project.execute_hooks(push_data.dup, :tag_push_hooks)
|
||||
project.execute_services(push_data.dup, :tag_push_hooks)
|
||||
|
|
|
@ -11,8 +11,10 @@ class DeleteTagService < BaseService
|
|||
end
|
||||
|
||||
if repository.rm_tag(tag_name)
|
||||
release = project.releases.find_by(tag: tag_name)
|
||||
release.destroy if release
|
||||
|
||||
push_data = build_push_data(tag)
|
||||
|
||||
EventCreateService.new.push(project, current_user, push_data)
|
||||
project.execute_hooks(push_data.dup, :tag_push_hooks)
|
||||
project.execute_services(push_data.dup, :tag_push_hooks)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
Files
|
||||
|
||||
- if project_nav_tab? :commits
|
||||
= nav_link(controller: %w(commit commits compare repositories tags branches)) do
|
||||
= nav_link(controller: %w(commit commits compare repositories tags branches releases)) do
|
||||
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do
|
||||
= icon('history fw')
|
||||
%span
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.branch-commit.light
|
||||
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
|
||||
.branch-commit
|
||||
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-id"
|
||||
·
|
||||
%span.str-truncated
|
||||
= link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
Branches
|
||||
%span.badge.js-totalbranch-count= @repository.branches.size
|
||||
|
||||
= nav_link(controller: :tags) do
|
||||
= nav_link(controller: [:tags, :releases]) do
|
||||
= link_to namespace_project_tags_path(@project.namespace, @project) do
|
||||
Tags
|
||||
%span.badge.js-totaltags-count= @repository.tags.length
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
- page_title "Edit", @tag.name, "Tags"
|
||||
= render "projects/commits/header_title"
|
||||
= render "projects/commits/head"
|
||||
|
||||
.gray-content-block
|
||||
.oneline
|
||||
.title
|
||||
Release notes for tag
|
||||
%strong #{@tag.name}
|
||||
|
||||
.prepend-top-default
|
||||
= form_for(@release, method: :put, url: namespace_project_tag_release_path(@project.namespace, @project, @tag.name), html: { class: 'form-horizontal gfm-form release-form' }) do |f|
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
|
||||
= render 'projects/zen', f: f, attr: :description, classes: 'description js-quick-submit'
|
||||
= render 'projects/notes/hints'
|
||||
.error-alert
|
||||
.prepend-top-default
|
||||
= f.submit 'Save changes', class: 'btn btn-save'
|
||||
= link_to "Cancel", namespace_project_tag_path(@project.namespace, @project, @tag.name), class: "btn btn-default btn-cancel"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
%span.btn-group.btn-grouped
|
||||
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), class: 'btn btn-default', rel: 'nofollow' do
|
||||
%i.fa.fa-download
|
||||
%span source code
|
||||
%a.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown' }
|
||||
%span.caret
|
||||
%span.sr-only
|
||||
Select Archive Format
|
||||
%ul.col-xs-10.dropdown-menu{ role: 'menu' }
|
||||
%li
|
||||
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), rel: 'nofollow' do
|
||||
%i.fa.fa-download
|
||||
%span Download zip
|
||||
%li
|
||||
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do
|
||||
%i.fa.fa-download
|
||||
%span Download tar.gz
|
|
@ -1,22 +1,28 @@
|
|||
- commit = @repository.commit(tag.target)
|
||||
- release = @releases.find { |release| release.tag == tag.name }
|
||||
%li
|
||||
%div
|
||||
= link_to namespace_project_commits_path(@project.namespace, @project, tag.name), class: "" do
|
||||
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name) do
|
||||
%strong
|
||||
%i.fa.fa-tag
|
||||
= icon('tag')
|
||||
= tag.name
|
||||
- if tag.message.present?
|
||||
|
||||
= strip_gpg_signature(tag.message)
|
||||
|
||||
.controls
|
||||
= link_to edit_namespace_project_tag_release_path(@project.namespace, @project, tag.name), class: 'btn-grouped btn' do
|
||||
= icon("pencil")
|
||||
- if can? current_user, :download_code, @project
|
||||
= render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'btn-grouped btn-group-xs'
|
||||
- if can?(current_user, :admin_project, @project)
|
||||
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-xs btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do
|
||||
%i.fa.fa-trash-o
|
||||
= render 'projects/tags/download', ref: tag.name, project: @project
|
||||
|
||||
- if commit
|
||||
= render 'projects/branches/commit', commit: commit, project: @project
|
||||
- else
|
||||
%p
|
||||
Cant find HEAD commit for this tag
|
||||
- if release && release.description.present?
|
||||
.description.prepend-top-default
|
||||
.wiki
|
||||
= preserve do
|
||||
= markdown release.description
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
$('.js-totaltags-count').html("#{@repository.tags.size}")
|
||||
- if @repository.tags.size == 0
|
||||
$('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
|
|
@ -5,10 +5,12 @@
|
|||
.alert.alert-danger
|
||||
%button{ type: "button", class: "close", "data-dismiss" => "alert"} ×
|
||||
= @error
|
||||
|
||||
%h3.page-title
|
||||
%i.fa.fa-code-fork
|
||||
New tag
|
||||
= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal" do
|
||||
New git tag
|
||||
%hr
|
||||
|
||||
= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal tag-form" do
|
||||
.form-group
|
||||
= label_tag :tag_name, 'Name for new tag', class: 'control-label'
|
||||
.col-sm-10
|
||||
|
@ -17,12 +19,29 @@
|
|||
= label_tag :ref, 'Create from', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :ref, params[:ref], placeholder: 'master', required: true, tabindex: 2, class: 'form-control'
|
||||
.light Branch name or commit SHA
|
||||
.help-block Branch name or commit SHA
|
||||
.form-group
|
||||
= label_tag :message, 'Message', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control'
|
||||
.light (Optional) Entering a message will create an annotated tag.
|
||||
.help-block (Optional) Entering a message will create an annotated tag.
|
||||
%hr
|
||||
.form-group
|
||||
= label_tag :release_description, 'Release notes', class: 'control-label'
|
||||
.col-sm-10
|
||||
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
|
||||
.zennable
|
||||
%input#zen-toggle-comment.zen-toggle-comment(tabindex="-1" type="checkbox")
|
||||
.zen-backdrop
|
||||
= text_area_tag :release_description, nil, class: 'js-gfm-input markdown-area description js-quick-submit form-control', placeholder: ''
|
||||
%a.zen-enter-link(tabindex="-1" href="#")
|
||||
= icon('expand')
|
||||
Edit in fullscreen
|
||||
%a.zen-leave-link(href="#")
|
||||
= icon('compress')
|
||||
|
||||
= render 'projects/notes/hints'
|
||||
.help-block (Optional) You can add release notes to your tag. It will be stored in the GitLab database and shown on the tags page
|
||||
.form-actions
|
||||
= button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
|
||||
= link_to 'Cancel', namespace_project_tags_path(@project.namespace, @project), class: 'btn btn-cancel'
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
- page_title @tag.name, "Tags"
|
||||
= render "projects/commits/header_title"
|
||||
= render "projects/commits/head"
|
||||
|
||||
.gray-content-block
|
||||
.pull-right
|
||||
- if can?(current_user, :push_code, @project)
|
||||
= link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn-grouped btn', title: 'Edit release notes' do
|
||||
= icon("pencil")
|
||||
= link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped', title: 'Browse source code' do
|
||||
= icon('files-o')
|
||||
= link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped', title: 'Browse commits' do
|
||||
= icon('history')
|
||||
- if can? current_user, :download_code, @project
|
||||
= render 'projects/tags/download', ref: @tag.name, project: @project
|
||||
- if can?(current_user, :admin_project, @project)
|
||||
.pull-right
|
||||
= link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'} do
|
||||
%i.fa.fa-trash-o
|
||||
.title
|
||||
%strong= @tag.name
|
||||
- if @tag.message.present?
|
||||
%span.light
|
||||
|
||||
= strip_gpg_signature(@tag.message)
|
||||
- if @commit
|
||||
= render 'projects/branches/commit', commit: @commit, project: @project
|
||||
- else
|
||||
Cant find HEAD commit for this tag
|
||||
|
||||
|
||||
.append-bottom-default.prepend-top-default
|
||||
- if @release.description.present?
|
||||
.description
|
||||
.wiki
|
||||
= preserve do
|
||||
= markdown @release.description
|
||||
- else
|
||||
This tag has no release notes.
|
|
@ -583,7 +583,10 @@ Gitlab::Application.routes.draw do
|
|||
end
|
||||
|
||||
resources :branches, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex }
|
||||
resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex }
|
||||
resources :tags, only: [:index, :show, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } do
|
||||
resource :release, only: [:edit, :update]
|
||||
end
|
||||
|
||||
resources :protected_branches, only: [:index, :create, :update, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex }
|
||||
resource :variables, only: [:show, :update]
|
||||
resources :triggers, only: [:index, :create, :destroy]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
class CreateReleases < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :releases do |t|
|
||||
t.string :tag
|
||||
t.text :description
|
||||
t.integer :project_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :releases, :project_id
|
||||
add_index :releases, [:project_id, :tag]
|
||||
end
|
||||
end
|
13
db/schema.rb
13
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20151103133339) do
|
||||
ActiveRecord::Schema.define(version: 20151105094515) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -639,6 +639,17 @@ ActiveRecord::Schema.define(version: 20151103133339) do
|
|||
|
||||
add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
|
||||
|
||||
create_table "releases", force: true do |t|
|
||||
t.string "tag"
|
||||
t.text "description"
|
||||
t.integer "project_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
add_index "releases", ["project_id", "tag"], name: "index_releases_on_project_id_and_tag", using: :btree
|
||||
add_index "releases", ["project_id"], name: "index_releases_on_project_id", using: :btree
|
||||
|
||||
create_table "sent_notifications", force: true do |t|
|
||||
t.integer "project_id"
|
||||
t.integer "noteable_id"
|
||||
|
|
|
@ -12,6 +12,12 @@ Feature: Project Commits Tags
|
|||
And I submit new tag form
|
||||
Then I should see new tag created
|
||||
|
||||
Scenario: I create a tag with release notes
|
||||
Given I click new tag link
|
||||
And I submit new tag form with release notes
|
||||
Then I should see new tag created
|
||||
And I should see tag release notes
|
||||
|
||||
Scenario: I create a tag with invalid name
|
||||
And I click new tag link
|
||||
And I submit new tag form with invalid name
|
||||
|
@ -27,15 +33,13 @@ Feature: Project Commits Tags
|
|||
And I submit new tag form with tag that already exists
|
||||
Then I should see new an error that tag already exists
|
||||
|
||||
@javascript
|
||||
Scenario: I delete a tag
|
||||
Given I visit tag 'v1.1.0' page
|
||||
Given I delete tag 'v1.1.0'
|
||||
Then I should not see tag 'v1.1.0'
|
||||
|
||||
@javascript
|
||||
Scenario: I delete all tags and see info message
|
||||
Given I delete all tags
|
||||
Then I should see tags info message
|
||||
|
||||
# @wip
|
||||
# Scenario: I can download project by tag
|
||||
Scenario: I add release notes to the tag
|
||||
Given I visit tag 'v1.1.0' page
|
||||
When I click edit tag link
|
||||
And I fill release notes and submit form
|
||||
Then I should see tag release notes
|
||||
|
|
|
@ -18,6 +18,18 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps
|
|||
click_button 'Create tag'
|
||||
end
|
||||
|
||||
step 'I submit new tag form with release notes' do
|
||||
fill_in 'tag_name', with: 'v7.0'
|
||||
fill_in 'ref', with: 'master'
|
||||
fill_in 'release_description', with: 'Awesome release notes'
|
||||
click_button 'Create tag'
|
||||
end
|
||||
|
||||
step 'I fill release notes and submit form' do
|
||||
fill_in 'release_description', with: 'Awesome release notes'
|
||||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
step 'I submit new tag form with invalid name' do
|
||||
fill_in 'tag_name', with: 'v 1.0'
|
||||
fill_in 'ref', with: 'master'
|
||||
|
@ -52,31 +64,27 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps
|
|||
expect(page).to have_content 'Tag already exists'
|
||||
end
|
||||
|
||||
step "I visit tag 'v1.1.0' page" do
|
||||
click_link 'v1.1.0'
|
||||
end
|
||||
|
||||
step "I delete tag 'v1.1.0'" do
|
||||
page.within '.tags' do
|
||||
page.within('.content') do
|
||||
first('.btn-remove').click
|
||||
sleep 0.05
|
||||
end
|
||||
end
|
||||
|
||||
step "I should not see tag 'v1.1.0'" do
|
||||
page.within '.tags' do
|
||||
expect(page.all(visible: true)).not_to have_content 'v1.1.0'
|
||||
expect(page).not_to have_link 'v1.1.0'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I delete all tags' do
|
||||
page.within '.tags' do
|
||||
page.all('.btn-remove').each do |remove|
|
||||
remove.click
|
||||
sleep 0.05
|
||||
end
|
||||
end
|
||||
step 'I click edit tag link' do
|
||||
click_link 'Edit release notes'
|
||||
end
|
||||
|
||||
step 'I should see tags info message' do
|
||||
page.within '.tags' do
|
||||
expect(page).to have_content 'Repository has no tags yet.'
|
||||
end
|
||||
step 'I should see tag release notes' do
|
||||
expect(page).to have_content 'Awesome release notes'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Read about factories at https://github.com/thoughtbot/factory_girl
|
||||
|
||||
FactoryGirl.define do
|
||||
factory :release do
|
||||
tag "v1.1.0"
|
||||
description "Awesome release"
|
||||
project
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Release, type: :model do
|
||||
let(:release) { create(:release) }
|
||||
|
||||
it { expect(release).to be_valid }
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
it { is_expected.to validate_presence_of(:project) }
|
||||
it { is_expected.to validate_presence_of(:description) }
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue