Skip to content

Commit 9de99eb

Browse files
Merge pull request #2698 from coreinfrastructure/fix_automation_bugs
Fix automation bugs
2 parents 64a566d + 0ed623d commit 9de99eb

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

app/controllers/projects_controller.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,18 +1733,17 @@ def get_justification_for_status(status_field_name)
17331733
@project.public_send(justification_field)
17341734
end
17351735

1736-
# Detect if a criteria justification field was automated (changed value)
1737-
# URL proposals always count as automated when they change a field
1736+
# Detect if a criteria justification field was automated (changed value).
1737+
# Any actual change to justification counts as automation — Chief already
1738+
# prevents overwriting non-empty justifications when the status is
1739+
# unchanged, so only legitimate changes reach this point.
17381740
# @param field_name [Symbol] The justification field name
17391741
# @param old_value [String] Original justification
17401742
# @param new_value [String] Current justification
17411743
# @return [Hash, nil] Field info if automated, nil otherwise
17421744
def detect_criteria_justification_automation(field_name, old_value, new_value)
1743-
# Any change to justification counts as automation
1744-
# (typically from URL proposal or Chief detective)
17451745
return if old_value == new_value
17461746

1747-
# Get the corresponding status field to track as parent
17481747
status_field = field_name.to_s.sub('_justification', '_status').to_sym
17491748
{ field: status_field, new_value: new_value, explanation: new_value }
17501749
end

app/lib/chief.rb

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,20 +295,21 @@ def apply_changes(project, changes)
295295
next if ALLOWED_FIELDS.exclude?(key)
296296
next unless update_value?(project, key, data)
297297

298-
# Store change:
298+
old_value = project.attribute_present?(key) ? project[key] : nil
299299
project[key] = data[:value]
300-
# Now add the explanation, if we can.
300+
# Set justification if the status actually changed, or if the
301+
# justification is empty. If the status is unchanged and there's
302+
# already a justification, leave it alone — the user's rationale
303+
# should not be modified when no status change occurred.
301304
next unless key.to_s.end_with?('_status') && data.key?(:explanation)
302305

306+
status_changed = old_value != data[:value]
303307
justification_key = (key.to_s.chomp('_status') + '_justification').to_sym
304-
if project.attribute_present?(justification_key)
305-
unless project[justification_key].end_with?(data[:explanation])
306-
project[justification_key] =
307-
project[justification_key] + ' ' + data[:explanation]
308-
end
309-
else
310-
project[justification_key] = data[:explanation]
311-
end
308+
existing = project.attribute_present?(justification_key) &&
309+
project[justification_key]
310+
next if !status_changed && existing.present?
311+
312+
project[justification_key] = data[:explanation]
312313
end
313314
end
314315
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright the OpenSSF Best Practices badge contributors
4+
# SPDX-License-Identifier: MIT
5+
6+
# Backfill baseline_N_saved flags using badge_percentage_baseline_N.
7+
# The original backfill in AddLevelSavedFlags had two bugs:
8+
# 1. Symbol/String mismatch in criteria name intersection (always empty)
9+
# 2. Compared integer status columns to string '?' instead of integer 0
10+
# As a result, baseline saved flags were never set for existing projects.
11+
# This migration uses the same badge_percentage > 10 approach that works
12+
# correctly for metal levels.
13+
class BackfillBaselineSavedFlags < ActiveRecord::Migration[8.1]
14+
# rubocop:disable Rails/SkipsModelValidations
15+
def up
16+
Project.where('badge_percentage_baseline_1 > ?', 10)
17+
.update_all(baseline_1_saved: true)
18+
Project.where('badge_percentage_baseline_2 > ?', 10)
19+
.update_all(baseline_2_saved: true)
20+
Project.where('badge_percentage_baseline_3 > ?', 10)
21+
.update_all(baseline_3_saved: true)
22+
end
23+
# rubocop:enable Rails/SkipsModelValidations
24+
25+
def down
26+
# No-op: we can't distinguish which flags were set by this migration
27+
# vs. set by normal user edits since the original migration ran.
28+
end
29+
end

db/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[8.1].define(version: 2026_02_12_174356) do
13+
ActiveRecord::Schema[8.1].define(version: 2026_02_12_221406) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "citext"
1616
enable_extension "pg_catalog.plpgsql"

0 commit comments

Comments
 (0)