diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 058c35fc2b0df096967082645f1092ac071f9379..28fdd674aa45c4a703ee3d0e61c4ae2567ba6de1 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -197,7 +197,11 @@ class CommitStatus < Ci::ApplicationRecord commit_status.failure_reason = reason.failure_reason_enum commit_status.allow_failure = true if reason.force_allow_failure? - commit_status.exit_code = reason.exit_code if Feature.enabled?(:ci_retry_on_exit_codes, Feature.current_request) + # Windows exit codes can reach a max value of 32-bit unsigned integer + # We only allow a smallint for exit_code in the db, hence the added limit of 32767 + if reason.exit_code && Feature.enabled?(:ci_retry_on_exit_codes, Feature.current_request) + commit_status.exit_code = reason.exit_code % 32768 + end end before_transition [:skipped, :manual] => :created do |commit_status, transition| diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index f5f29109c10bf8b068f3e104b4d376df8eb001de..72b59d848210e3f50ae64aefc0cfcff4869cbd0b 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -5257,6 +5257,15 @@ def run_job_without_exception end end end + + context 'when exit code is greater than 32767' do + let(:exit_code) { 32770 } + + it 'wraps around to max size of a signed smallint' do + expect { drop_with_exit_code } + .to change { build.reload.metadata&.exit_code }.from(nil).to(2) + end + end end describe '#exit_codes_defined?' do