diff --git a/CHANGELOG b/CHANGELOG index 1c6e24bc10..8159d3258a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,7 @@ v 8.8.0 (unreleased) - Updated search UI - Display informative message when new milestone is created - Sanitize milestones and labels titles + - Support multi-line tag messages. !3833 (Calin Seciu) - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) - Added button to toggle whitespaces changes on diff view - Backport GitHub Enterprise import support from EE diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 0442b33958..9f1424aecc 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -27,7 +27,6 @@ %pre.body = strip_gpg_signature(@tag.message) - .append-bottom-default.prepend-top-default - if @release.description.present? .description diff --git a/features/project/commits/tags.feature b/features/project/commits/tags.feature deleted file mode 100644 index a4be39b2d4..0000000000 --- a/features/project/commits/tags.feature +++ /dev/null @@ -1,46 +0,0 @@ -@project_commits -Feature: Project Commits Tags - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project tags page - - Scenario: I can see all git tags - Then I should see "Shop" all tags list - - Scenario: I create a tag - And I click new tag link - 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 - Then I should see new an error that tag is invalid - - Scenario: I create a tag with invalid reference - And I click new tag link - And I submit new tag form with invalid reference - Then I should see new an error that tag ref is invalid - - Scenario: I create a tag that already exists - And I click new tag link - And I submit new tag form with tag that already exists - Then I should see new an error that tag already exists - - 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' - - 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 diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb deleted file mode 100644 index 912ba580ef..0000000000 --- a/features/steps/project/commits/tags.rb +++ /dev/null @@ -1,90 +0,0 @@ -class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see "Shop" all tags list' do - expect(page).to have_content "Tags" - expect(page).to have_content "v1.0.0" - end - - step 'I click new tag link' do - click_link 'New tag' - end - - step 'I submit new tag form' do - fill_in 'tag_name', with: 'v7.0' - fill_in 'ref', with: 'master' - 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' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid reference' do - fill_in 'tag_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create tag' - end - - step 'I submit new tag form with tag that already exists' do - fill_in 'tag_name', with: 'v1.0.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I should see new tag created' do - expect(page).to have_content 'v7.0' - end - - step 'I should see new an error that tag is invalid' do - expect(page).to have_content 'Tag name invalid' - end - - step 'I should see new an error that tag ref is invalid' do - expect(page).to have_content 'Target foo is invalid' - end - - step 'I should see new an error that tag already exists' do - expect(page).to have_content 'Tag v1.0.0 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('.content') do - first('.btn-remove').click - end - end - - step "I should not see tag 'v1.1.0'" do - page.within '.tags' do - expect(page).not_to have_link 'v1.1.0' - end - end - - step 'I click edit tag link' do - click_link 'Edit release notes' - end - - step 'I should see tag release notes' do - expect(page).to have_content 'Awesome release notes' - end -end diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb new file mode 100644 index 0000000000..08a97085a9 --- /dev/null +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +feature 'Master creates tag', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + project.team << [user, :master] + login_with(user) + visit namespace_project_tags_path(project.namespace, project) + end + + scenario 'with an invalid name displays an error' do + create_tag_in_form(tag: 'v 1.0', ref: 'master') + + expect(page).to have_content 'Tag name invalid' + end + + scenario 'with an invalid reference displays an error' do + create_tag_in_form(tag: 'v2.0', ref: 'foo') + + expect(page).to have_content 'Target foo is invalid' + end + + scenario 'that already exists displays an error' do + create_tag_in_form(tag: 'v1.1.0', ref: 'master') + + expect(page).to have_content 'Tag v1.1.0 already exists' + end + + scenario 'with multiline message displays the message in a
block' do
+ create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v3.0'))
+ expect(page).to have_content 'v3.0'
+ page.within 'pre.body' do
+ expect(page).to have_content "Awesome tag message\n\n- hello\n- world"
+ end
+ end
+
+ scenario 'with multiline release notes parses the release note as Markdown' do
+ create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v4.0'))
+ expect(page).to have_content 'v4.0'
+ page.within '.description' do
+ expect(page).to have_content 'Awesome release notes'
+ expect(page).to have_selector('ul li', count: 2)
+ end
+ end
+
+ def create_tag_in_form(tag:, ref:, message: nil, desc: nil)
+ click_link 'New tag'
+ fill_in 'tag_name', with: tag
+ fill_in 'ref', with: ref
+ fill_in 'message', with: message unless message.nil?
+ fill_in 'release_description', with: desc unless desc.nil?
+ click_button 'Create tag'
+ end
+end
diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb
new file mode 100644
index 0000000000..f0990118e3
--- /dev/null
+++ b/spec/features/tags/master_deletes_tag_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+feature 'Master deletes tag', feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ before do
+ project.team << [user, :master]
+ login_with(user)
+ visit namespace_project_tags_path(project.namespace, project)
+ end
+
+ context 'from the tags list page' do
+ scenario 'deletes the tag' do
+ expect(page).to have_content 'v1.1.0'
+
+ page.within('.content') do
+ first('.btn-remove').click
+ end
+
+ expect(current_path).to eq(
+ namespace_project_tags_path(project.namespace, project))
+ expect(page).not_to have_content 'v1.1.0'
+ end
+
+ end
+
+ context 'from a specific tag page' do
+ scenario 'deletes the tag' do
+ click_on 'v1.0.0'
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
+
+ click_on 'Delete tag'
+
+ expect(current_path).to eq(
+ namespace_project_tags_path(project.namespace, project))
+ expect(page).not_to have_content 'v1.0.0'
+ end
+ end
+end
diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb
new file mode 100644
index 0000000000..c926e9841f
--- /dev/null
+++ b/spec/features/tags/master_updates_tag_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+
+feature 'Master updates tag', feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ before do
+ project.team << [user, :master]
+ login_with(user)
+ visit namespace_project_tags_path(project.namespace, project)
+ end
+
+ context 'from the tags list page' do
+ scenario 'updates the release notes' do
+ page.within(first('.controls')) do
+ click_link 'Edit release notes'
+ end
+
+ fill_in 'release_description', with: 'Awesome release notes'
+ click_button 'Save changes'
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.1.0'))
+ expect(page).to have_content 'v1.1.0'
+ expect(page).to have_content 'Awesome release notes'
+ end
+ end
+
+ context 'from a specific tag page' do
+ scenario 'updates the release notes' do
+ click_on 'v1.1.0'
+ click_link 'Edit release notes'
+ fill_in 'release_description', with: 'Awesome release notes'
+ click_button 'Save changes'
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.1.0'))
+ expect(page).to have_content 'v1.1.0'
+ expect(page).to have_content 'Awesome release notes'
+ end
+ end
+end
diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb
new file mode 100644
index 0000000000..29d2c24472
--- /dev/null
+++ b/spec/features/tags/master_views_tags_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+feature 'Master views tags', feature: true do
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_with(user)
+ end
+
+ context 'when project has no tags' do
+ let(:project) { create(:project_empty_repo) }
+ before do
+ visit namespace_project_path(project.namespace, project)
+ click_on 'README'
+ fill_in :commit_message, with: 'Add a README file', visible: true
+ # Remove pre-receive hook so we can push without auth
+ FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive'))
+ click_button 'Commit Changes'
+ visit namespace_project_tags_path(project.namespace, project)
+ end
+
+ scenario 'displays a specific message' do
+ expect(page).to have_content 'Repository has no tags yet.'
+ end
+ end
+
+ context 'when project has tags' do
+ let(:project) { create(:project, namespace: user.namespace) }
+ before do
+ visit namespace_project_tags_path(project.namespace, project)
+ end
+
+ scenario 'views the tags list page' do
+ expect(page).to have_content 'v1.0.0'
+ end
+
+ scenario 'views a specific tag page' do
+ click_on 'v1.0.0'
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
+ expect(page).to have_content 'v1.0.0'
+ expect(page).to have_content 'This tag has no release notes.'
+ end
+
+ describe 'links on the tag page' do
+ scenario 'has a button to browse files' do
+ click_on 'v1.0.0'
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
+
+ click_on 'Browse files'
+
+ expect(current_path).to eq(
+ namespace_project_tree_path(project.namespace, project, 'v1.0.0'))
+ end
+
+ scenario 'has a button to browse commits' do
+ click_on 'v1.0.0'
+
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
+
+ click_on 'Browse commits'
+
+ expect(current_path).to eq(
+ namespace_project_commits_path(project.namespace, project, 'v1.0.0'))
+ end
+ end
+ end
+end