Slack notification service links incorrectly formatted when the link text contains square brackets
Summary
GitLab CI job names can contain pairs of square brackets ([ ]) thanks to the parallel:matrix feature. When link text contains a pair of square brackets, the links are not formatted correctly by the Slack notification service.
Steps to reproduce
-
Apply this patch (
git apply patch-file)diff --git a/spec/models/integrations/chat_message/pipeline_message_spec.rb b/spec/models/integrations/chat_message/pipeline_message_spec.rb index a80d13d7f5d..fa3be2b29c9 100644 --- a/spec/models/integrations/chat_message/pipeline_message_spec.rb +++ b/spec/models/integrations/chat_message/pipeline_message_spec.rb @@ -332,6 +332,22 @@ end end + context "when name contains brackets" do + before do + args[:builds] = [ + { id: 1, name: "test: [arg1, arg2]", status: "failed", stage: "test" } + ] + end + + it "correctly formats links" do + expect(subject.attachments.first[:fields][3]).to eq( + title: "Failed jobs", + value: "<http://example.gitlab.com/-/jobs/1|test: [arg1, arg2]>", + short: true + ) + end + end + context "when the CI config file contains a YAML error" do let(:has_yaml_errors) { true } -
Run
bundle exec rspec spec/models/integrations/chat_message/pipeline_message_spec.rb -
Tests fail when they should pass
Failures: 1) Integrations::ChatMessage::PipelineMessage when name contains brackets correctly formats links Failure/Error: expect(subject.attachments.first[:fields][3]).to eq( title: "Failed jobs", value: "<http://example.gitlab.com/-/jobs/1|test: [arg1, arg2]>", short: true ) expected: {:short=>true, :title=>"Failed jobs", :value=>"<http://example.gitlab.com/-/jobs/1|test: [arg1, arg2]>"} got: {:short=>true, :title=>"Failed job", :value=>"[test: [arg1, arg2]](http://example.gitlab.com/-/jobs/1)"} (compared using ==) Diff: @@ -1,4 +1,4 @@ :short => true, -:title => "Failed jobs", -:value => "<http://example.gitlab.com/-/jobs/1|test: [arg1, arg2]>", +:title => "Failed job", +:value => "[test: [arg1, arg2]](http://example.gitlab.com/-/jobs/1)", # ./spec/models/integrations/chat_message/pipeline_message_spec.rb:343:in `block (3 levels) in <top (required)>' # ./spec/spec_helper.rb:406:in `block (3 levels) in <top (required)>' # ./spec/support/sidekiq_middleware.rb:9:in `with_sidekiq_server_middleware' # ./spec/spec_helper.rb:397:in `block (2 levels) in <top (required)>' # ./spec/spec_helper.rb:393:in `block (3 levels) in <top (required)>' # ./lib/gitlab/application_context.rb:31:in `with_raw_context' # ./spec/spec_helper.rb:393:in `block (2 levels) in <top (required)>' # ./spec/support/database/query_analyzer.rb:9:in `block (3 levels) in <main>' # ./lib/gitlab/database/query_analyzer.rb:42:in `within' # ./spec/support/database/query_analyzer.rb:9:in `block (2 levels) in <main>' # ./spec/support/database/prevent_cross_joins.rb:102:in `block (3 levels) in <main>' # ./spec/support/database/prevent_cross_joins.rb:56:in `with_cross_joins_prevented' # ./spec/support/database/prevent_cross_joins.rb:102:in `block (2 levels) in <main>' Finished in 3 minutes 9.7 seconds (files took 1 minute 27.35 seconds to load) 38 examples, 1 failure Failed examples: rspec ./spec/models/integrations/chat_message/pipeline_message_spec.rb:342 # Integrations::ChatMessage::PipelineMessage when name contains brackets correctly formats links
Branch example: https://gitlab.com/gitlab-org/gitlab/-/commits/bwill/slack-brackets-links-example
What is the current bug behavior?
The links are presented in markdown format [text](link)
What is the expected correct behavior?
The links should be presented in Slack link format <link|text>
Possible fixes
We use ::Slack::Messenger::Util::LinkFormatter in order to format these links. In many places in the codebase, we have a link_text and a link which we format into a markdown string like [link_text](link) and then pass it to LinkFormatter#format. This seems very inefficient, since LinkFormatter#format needs to parse out the link_text and link using regex. Instead, we should probable make LinkFormatter#slack_link public, and give it the link_text and link.
