feat: Allow editing description and keywords for iOS Releases#917
feat: Allow editing description and keywords for iOS Releases#917Animesh-Ghosh wants to merge 14 commits intomainfrom
description and keywords for iOS Releases#917Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughReplaces partial-based size-limited textareas with a new Form::SizeLimitedTextareaComponent and updates live release metadata views to use it; adds draft_keywords (string array) and draft_description (text) with a migration; introduces iOS limits/constants (description ≤ 4000, keywords total ≤ 100), validations, and keywords_joined; controller now permits and parses description and keywords; App Store submission payload includes description and keywords; tests and anonymization rules updated. Sequence Diagram(s)sequenceDiagram
actor User
participant UI as LiveRelease::MetadataComponent
participant Component as Form::SizeLimitedTextareaComponent
participant Ctrl as ReleaseMetadataController
participant Model as ReleaseMetadata
participant DB as Database
participant AppStore as AppStoreIntegration
User->>UI: Edit description / keywords
UI->>Component: Render textarea with live counter
alt Submit published metadata
UI->>Ctrl: POST update_all (description, keywords, ...)
Ctrl->>Ctrl: Permit & parse params (keywords CSV -> Array)
Ctrl->>Model: update_and_clear_drafts!(attrs)
Model->>Model: Validate lengths & compute keywords_joined
Model->>DB: Persist attributes, clear draft_* fields
Ctrl->>AppStore: prepare_release(..., metadata_with_description_and_keywords)
else Save draft
UI->>Ctrl: Save draft request
Ctrl->>Model: save_draft(draft_attrs)
Model->>DB: Persist draft_description & draft_keywords
end
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
d17f764 to
f13623f
Compare
3627684 to
00d35da
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/controllers/release_metadata_controller.rb`:
- Around line 20-23: The iOS keywords parsing in release_metadata_controller
(inside the block that checks rm_params.key?(:ios)) calls
ios_params[:keywords].split unguarded and can raise NoMethodError; update the
ios_params assignment to handle nil by converting keywords to a string or
checking presence before split, split on "," then map(&:strip) and remove blank
entries (e.g. use to_s or presence and then
.split(",").map(&:strip).reject(&:blank?)) so missing or empty keywords do not
cause a 500.
In `@app/models/release_metadata.rb`:
- Around line 69-71: keywords_joined can call join on nil for unsaved
ReleaseMetadata instances; change its implementation to guard against nil by
using the same pattern as elsewhere (e.g., Array(attrs[:keywords'])) so replace
the direct keywords.join(",") with a nil-safe conversion like
Array(keywords).join(",") inside the ReleaseMetadata#keywords_joined method;
this aligns behavior with the keywords_length validator (triggered on ios?) and
prevents NoMethodError during validation.
In `@db/schema.rb`:
- Around line 723-724: Add the new user-content columns draft_keywords and
draft_description to the anonymization task by updating the anonymize list in
lib/tasks/anonymize.rake: locate the array or method that enumerates columns to
scrub (e.g., the list named anonymize_columns, USER_CONTENT_COLUMNS, or the
method anonymize_user_content) and append "draft_keywords" and
"draft_description" so they are included in the anonymization pass; ensure array
type handling for draft_keywords (array of strings) is preserved consistent with
existing array-column handling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e8b86ee8-ade7-436d-8c2a-1d1623f1da8a
📒 Files selected for processing (10)
app/components/live_release/metadata_component.html.erbapp/components/live_release/metadata_component.rbapp/controllers/release_metadata_controller.rbapp/models/app_store_submission.rbapp/models/release_metadata.rbapp/views/shared/_size_limited_textarea.html.erbdb/migrate/20260225190552_add_draft_keywords_and_description_to_release_metadata.rbdb/schema.rbspec/models/app_store_submission_spec.rbspec/models/release_metadata_spec.rb
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/components/live_release/metadata_component.html.erb (1)
90-94: Consider usinglabel_type: :basefor Android release notes for visual consistency.The iOS fields all use
label_type: :base, but the Android release notes field uses the default (:default). This may cause visual inconsistency between platform sections.♻️ Suggested change for consistency
<%= render Form::SizeLimitedTextareaComponent.new(form: aF, obj_method: :release_notes, label_text: "Release Notes", max_length: android_max_length, - existing_value: android_metadata.release_notes) %> + existing_value: android_metadata.release_notes, + label_type: :base) %>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/components/live_release/metadata_component.html.erb` around lines 90 - 94, The Android release notes field uses the default label type causing visual inconsistency; update the Form::SizeLimitedTextareaComponent invocation (the one with form: aF, obj_method: :release_notes, label_text: "Release Notes", max_length: android_max_length, existing_value: android_metadata.release_notes) to include label_type: :base so it matches the iOS fields' styling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/components/live_release/metadata_component.html.erb`:
- Around line 90-94: The Android release notes field uses the default label type
causing visual inconsistency; update the Form::SizeLimitedTextareaComponent
invocation (the one with form: aF, obj_method: :release_notes, label_text:
"Release Notes", max_length: android_max_length, existing_value:
android_metadata.release_notes) to include label_type: :base so it matches the
iOS fields' styling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2ecdc33d-8f74-47df-ab18-4dce0638c35b
📒 Files selected for processing (4)
app/components/form/size_limited_textarea_component.html.erbapp/components/form/size_limited_textarea_component.rbapp/components/live_release/metadata_component.html.erbapp/views/shared/_size_limited_textarea.html.erb
💤 Files with no reviewable changes (1)
- app/views/shared/_size_limited_textarea.html.erb
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/controllers/release_metadata_controller.rb`:
- Line 22: Replace the call to reject(&:blank?) in the assignment to
ios_params[:keywords] with compact_blank to satisfy RuboCop's Rails/CompactBlank
rule while preserving behavior; specifically update the expression that sets
ios_params[:keywords] (the line using ios_params[:keywords] =
ios_params[:keywords].split(",").map(&:strip).reject(&:blank?)) to use
compact_blank instead of reject(&:blank?).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 39052dc3-7500-44c5-999f-dfec23e36823
📒 Files selected for processing (2)
app/controllers/release_metadata_controller.rblib/tasks/anonymize.rake
d07a264 to
ec14bce
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/models/release_metadata.rb (1)
118-122:⚠️ Potential issue | 🟡 MinorAdd nil guard to
notes_lengthvalidation.The
release_notescolumn is nullable (schema shows nonull: falseand no default), and there's no presence validation to prevent nil values. Ifrelease_notesis nil, calling.lengthon line 119 will raiseNoMethodError.Suggested fix
def notes_length + return if release_notes.blank? if release_notes.length > notes_max_length errors.add(:release_notes, :too_long, max_length: notes_max_length, platform: release_platform_run.platform) end end🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/models/release_metadata.rb` around lines 118 - 122, The notes_length validation calls release_notes.length and will crash if release_notes is nil; update the notes_length method to guard against nil by either returning early when release_notes is nil (e.g., return if release_notes.nil?) or by using a safe string conversion (e.g., release_notes.to_s.length) before comparing to notes_max_length, then keep the errors.add call unchanged (referencing notes_length, release_notes, notes_max_length, and errors.add(:release_notes,...)).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@app/models/release_metadata.rb`:
- Around line 118-122: The notes_length validation calls release_notes.length
and will crash if release_notes is nil; update the notes_length method to guard
against nil by either returning early when release_notes is nil (e.g., return if
release_notes.nil?) or by using a safe string conversion (e.g.,
release_notes.to_s.length) before comparing to notes_max_length, then keep the
errors.add call unchanged (referencing notes_length, release_notes,
notes_max_length, and errors.add(:release_notes,...)).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 02ea2442-85fd-419c-a13d-94dce7d12f55
📒 Files selected for processing (13)
app/components/form/size_limited_textarea_component.html.erbapp/components/form/size_limited_textarea_component.rbapp/components/live_release/metadata_component.html.erbapp/components/live_release/metadata_component.rbapp/controllers/release_metadata_controller.rbapp/models/app_store_submission.rbapp/models/release_metadata.rbapp/views/shared/_size_limited_textarea.html.erbdb/migrate/20260225190552_add_draft_keywords_and_description_to_release_metadata.rbdb/schema.rblib/tasks/anonymize.rakespec/models/app_store_submission_spec.rbspec/models/release_metadata_spec.rb
💤 Files with no reviewable changes (1)
- app/views/shared/_size_limited_textarea.html.erb
🚧 Files skipped from review as they are similar to previous changes (5)
- spec/models/release_metadata_spec.rb
- spec/models/app_store_submission_spec.rb
- app/models/app_store_submission.rb
- db/schema.rb
- app/controllers/release_metadata_controller.rb
81b590d to
5c65c8f
Compare
Allow `AppStoreSubmission#prepare_for_release!` to send the `description` and `keywords` param to applelink to update the iOS Release's metadata.
Render a size-limited textarea on the Release Notes UI.
Add `ReleaseMetadata#keywords_joined`. Follow component convention in `LiveRelease::MetadataComponent`.
5c65c8f to
e166e79
Compare
Closes: https://github.com/orgs/tramlinehq/projects/5?pane=issue&itemId=94582410
NOTE: Getting tramlinehq/applelink#41 merged is a pre-condition for merging this PR.
Why
We want to allow updating the
descriptionandkeywordsmetadata for App Store releases.This addresses
Allowing the iOS release's description and keywords metadata to be updated from the UI.
We also do a length validation for the release's keywords and description and show an helpful info icon for the keywords field, which links to a Apple developer page on "Choose accurate keywords that resonate".
We also store the draft versions of the invalid keywords and descriptions.
Locale-updates, before initiating production deployment
Scenarios tested
Summary by CodeRabbit
New Features
Chores
Tests