POST Statuses API 500 Error when a Tag/Branch with the same exists
Summary
When statuses are posted to a pipeline which maps to a branch that shares a name with a tag then the statuses API returns a 500 error and does not create the external status.
In my example repo, I created a branch and a tag with the name some-tag
:
When I post a status to a pipeline on the some-tag
branch a 500 error will occur because there's a duplicate ref. Another thing I noticed is the "external" stage gets created, but the job isn't created.
Steps to reproduce
- Copy my pipeline yaml: https://gitlab.com/Seth10001/pipeline-status-on-ref-with-tag-and-branch/-/blob/main/.gitlab-ci.yml?ref_type=heads
- Generate a personal token and add it to your pipeline variables as
GITLAB_PRIVATE_TOKEN
- Create a branch called "some-tag"
- Create a tag called "some-tag"
- Run a pipeline on the "some-tag" branch
Example Project
Example pipeline: https://gitlab.com/Seth10001/pipeline-status-on-ref-with-tag-and-branch/-/pipelines/967511717
Project: https://gitlab.com/Seth10001/pipeline-status-on-ref-with-tag-and-branch
What is the current bug behavior?
It does not create the external job
What is the expected correct behavior?
Create the external job
Relevant logs and/or screenshots
exception.backtrace: [ [-]
app/models/project.rb:2483:in `protected_for?'
lib/api/commit_statuses.rb:126:in `block (2 levels) in <class:CommitStatuses>'
ee/lib/gitlab/middleware/ip_restrictor.rb:14:in `block in call'
ee/lib/gitlab/ip_address_state.rb:10:in `with'
ee/lib/gitlab/middleware/ip_restrictor.rb:13:in `call'
lib/api/api_guard.rb:222:in `call'
lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'
lib/gitlab/middleware/memory_report.rb:13:in `call'
lib/gitlab/middleware/speedscope.rb:13:in `call'
lib/gitlab/database/load_balancing/rack_middleware.rb:23:in `call'
lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'
lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'
lib/gitlab/metrics/web_transaction.rb:46:in `run'
lib/gitlab/metrics/rack_middleware.rb:16:in `call'
lib/gitlab/jira/middleware.rb:19:in `call'
lib/gitlab/middleware/go.rb:20:in `call'
lib/gitlab/etag_caching/middleware.rb:21:in `call'
lib/gitlab/middleware/query_analyzer.rb:11:in `block in call'
lib/gitlab/database/query_analyzer.rb:37:in `within'
lib/gitlab/middleware/query_analyzer.rb:11:in `call'
lib/gitlab/middleware/multipart.rb:173:in `call'
lib/gitlab/middleware/read_only/controller.rb:50:in `call'
lib/gitlab/middleware/read_only.rb:18:in `call'
lib/gitlab/middleware/same_site_cookies.rb:27:in `call'
lib/gitlab/middleware/basic_health_check.rb:25:in `call'
lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'
lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'
lib/gitlab/middleware/request_context.rb:21:in `call'
lib/gitlab/middleware/webhook_recursion_detection.rb:15:in `call'
config/initializers/fix_local_cache_middleware.rb:11:in `call'
lib/gitlab/middleware/compressed_json.rb:37:in `call'
lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'
lib/gitlab/middleware/sidekiq_web_static.rb:20:in `call'
lib/gitlab/metrics/requests_rack_middleware.rb:79:in `call'
lib/gitlab/middleware/release_env.rb:13:in `call'
]
exception.class: Repository::AmbiguousRefError
exception.message: Repository::AmbiguousRefError
Possible fixes
The error is rooted here: https://gitlab.com/gitlab-org/gitlab/-/blob/540e62918ddc27f2450f0b5724a44fc100b97190/lib/api/commit_statuses.rb#L126
When it's looking up whether the ref is protected it errors because that's how it was designed. There are tests that verify this here: https://gitlab.com/gitlab-org/gitlab/-/blob/540e62918ddc27f2450f0b5724a44fc100b97190/spec/models/project_spec.rb#L4404-4416
The error gets raised here: https://gitlab.com/gitlab-org/gitlab/-/blob/540e62918ddc27f2450f0b5724a44fc100b97190/app/models/project.rb#L2530
Unsure how to fix this... maybe look up the branch/tag that's related to the pipeline and check if that's protected instead of using a ref