Skip to content

Fixes #38905 - Add ACS for Deb Repositories#11567

Merged
m-bucher merged 1 commit intoKatello:masterfrom
ATIX-AG:add-debian-acs
Apr 23, 2026
Merged

Fixes #38905 - Add ACS for Deb Repositories#11567
m-bucher merged 1 commit intoKatello:masterfrom
ATIX-AG:add-debian-acs

Conversation

@hstct
Copy link
Copy Markdown
Contributor

@hstct hstct commented Nov 14, 2025

What are the changes introduced in this pull request?

  1. Extends Alternate Content Sources with Debian Content
  2. Updates the UI and Creation Wizard to include Debian
  3. Add tests

Considerations taken when implementing this change?

  • Debian Remotes require a distributions parameter. So it has been added to the creation process.
  • components and architectures fields have been included to match sync.
  • The ACS provides a subpaths parameter and is not used by debian ACS.
    • It's not showing up in the UI for debian.
    • There is no validation however, because it's validated directly in pulp.

What are the testing steps for this pull request?

  • Create a new ACS with debian content
  • (more to come)

Summary by Sourcery

Add full Debian content support for Alternate Content Sources by extending the database schema, model validations, API, UI wizard, and Pulp3 orchestration workflows, accompanied by extensive test coverage.

New Features:

  • Add Debian support to Alternate Content Sources including custom and simplified deb types
  • Enhance the ACS creation wizard and finish step UI to configure Debian distributions, components, and architectures
  • Implement Pulp3 backend service support for creating, updating, refreshing, and deleting Debian ACS remotes

Enhancements:

  • Add model validations, normalization, and Rails migration for deb-specific fields (distributions, components, architectures)
  • Extend API controller and parameter preprocessing to handle Debian fields
  • Update smart proxy cleanup logic to include deb ACS deletion

Tests:

  • Add comprehensive tests covering controller actions, orchestration workflows, model validations, UI wizard interactions, and content view deb filters and rules
  • Add integration test for apt sync with Debian ACS

Summary by CodeRabbit

  • New Features

    • Full Debian/APT ACS support in UI and API: create wizard, review/edit dialogs, details show Distributions/Components/Architectures; backend sync/cleanup for Debian ACS enabled.
  • Bug Fixes / Validation

    • Server- and client-side validation added for Debian fields; invalid mixes return clear 422 errors and block create/update.
  • Chores

    • Database schema extended to store Debian selector fields.
  • Tests

    • Extensive Debian-focused unit/integration tests and HTTP fixtures added.

Comment thread app/controllers/katello/api/v2/alternate_content_sources_controller.rb Outdated
@quba42
Copy link
Copy Markdown
Contributor

quba42 commented Nov 26, 2025

Just adding some ToDo reminders for ourselves:

  • hammer-cli-katello PR
  • foreman-documentation PR
  • pulp_deb side feature: Part of pulp_deb 3.8.0, requires pulpcore>=3.75.0,<3.100, pulpcore 3.85 is part of Katello 4.19
    • foreman-packaging PR (rubygem client)
    • pulpcore-packaging PR

@hstct
Copy link
Copy Markdown
Contributor Author

hstct commented Nov 26, 2025

once pulp_deb 3.8.0 is available in foreman-packaging we need to re-record the vcr tests also

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @hstct, your pull request is larger than the review limit of 150000 diff characters

@hstct hstct force-pushed the add-debian-acs branch 3 times, most recently from c33ef52 to d81e9e5 Compare January 28, 2026 15:05
Comment thread katello.gemspec
Comment thread webpack/scenes/AlternateContentSources/helpers.js Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds Debian (DEB) alternate content source support across backend and frontend: new DEB fields, model predicates/validations, controller pre-validation, Pulp3 service/API mappings, DB migration, frontend form/state/helpers, orchestration logic, VCR fixtures, and expanded tests.

Changes

Cohort / File(s) Summary
API Controller
app/controllers/katello/api/v2/alternate_content_sources_controller.rb
Add before_action :validate_acs_params! for create/update; permit :deb_releases, :deb_components, :deb_architectures; implement pre-validation returning 422 on invalid ACS.
Model
app/models/katello/alternate_content_source.rb
Add deb to CONTENT_TYPES, add deb? predicate; add deb_constraints and deb_fields_xor_subpaths validations; include deb_* in absence validations; restrict path validator for non-deb custom sources.
Pulp3 Service & API
app/services/katello/pulp3/alternate_content_source.rb, app/services/katello/pulp3/api/apt.rb, app/services/katello/pulp3/smart_proxy_mirror_repository.rb
Add helpers join_space_or_nil and join_space_required!; include DEB-specific distributions (required) and optional components/architectures in remote payload; add Apt alternate_content_source API/client methods; extend orphan deletion to handle deb.
Views / Serialization
app/views/katello/api/v2/alternate_content_sources/base.json.rabl
Expose deb_releases, deb_components, deb_architectures in custom/RHUI ACS JSON output.
DB Migration
db/migrate/20251110000001_add_deb_fields_to_acs.rb
Add string columns deb_releases, deb_components, deb_architectures to katello_alternate_content_sources.
Frontend — Create/Edit UI & Helpers
webpack/scenes/AlternateContentSources/... (ACSCreateWizard.js, ACSCreateFinish.js, ACSReview.js, AcsUrlPaths.js, SelectSource.js, ACSExpandableDetails.js, Details/EditModals/ACSEditURLPaths.js, helpers.js, etc.)
Introduce deb* context/state and helpers (toList, spaceSepOrUndef, spaceSepOrEmpty); render DEB-specific inputs (releases/components/architectures) replacing subpaths in DEB mode; add validation (require releases for custom) and include DEB fields in submit payloads.
Frontend Tests
webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
Add Jest test that drives the Add-source wizard end-to-end for DEB with network stubs.
Orchestration / Integration Tests
test/actions/pulp3/orchestration/*_alternate_content_source_*.rb, test/actions/pulp3/orchestration/deb_sync_test.rb
Add/extend orchestration tests for DEB create/update/refresh/delete and repository sync; update setup/teardown to persist/remove DEB ACS fixtures and smart-proxy links.
Controller & Model Tests
test/controllers/api/v2/alternate_content_sources_controller_test.rb, test/models/katello/alternate_content_source_test.rb
Add API tests for DEB create/update/simplified flows, negative validation test; add model tests covering DEB validations and search inclusion.
Fixtures — Models, Repos & VCR
test/fixtures/models/katello_alternate_content_sources.yml, test/fixtures/models/katello_repositories.yml, test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_*/deb_*.yml
Add DEB ACS fixtures (full and simplified), adjust Debian repo content_id, and add multiple DEB VCR cassettes for create/update/refresh/delete and proxy scenarios.
Misc Tests / Teardown
various test/... files listed in diff
Extend many test setups/teardowns and add DEB-specific assertions across unit/integration/orchestration suites.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client/User
    participant API as API Controller
    participant Model as AlternateContentSource Model
    participant Service as Pulp3 Service
    participant Pulp as Pulp3 API

    Client->>API: POST /api/v2/alternate_content_sources (deb params)
    API->>API: permit params, run validate_acs_params!
    API->>Model: build ACS from params (excluding proxy/product ids)
    Model->>Model: run deb? validations (deb_constraints, deb_fields_xor_subpaths)
    alt validation fails
        Model-->>API: errors (message, errors, full_messages)
        API-->>Client: 422 Unprocessable Entity
    else validation passes
        API->>Service: build remote_options(acs)
        Service->>Service: join_space_required!(distributions)
        Service->>Service: join_space_or_nil(components/architectures)
        Service->>Pulp: POST /pulp/api/v3/remotes/deb/apt/ (create remote)
        Pulp-->>Service: remote href
        Service->>Pulp: POST /pulp/api/v3/acs/deb/deb/ (create ACS)
        Pulp-->>Service: ACS href / task
        Service-->>API: task/href
        API-->>Client: 201 Created (ACS resource / task)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Fixes #38905 - Add ACS for Deb Repositories' directly and clearly describes the main objective of the changeset: adding Alternate Content Source (ACS) support for Debian repositories, as confirmed by the comprehensive changes across models, controllers, services, UI components, and test files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/services/katello/pulp3/smart_proxy_mirror_repository.rb (1)

140-167: ⚠️ Potential issue | 🟡 Minor

Missing return statement for tasks array.

The delete_orphan_alternate_content_sources method populates the tasks array but doesn't return it. Other similar methods in this file (e.g., delete_orphan_repositories, delete_orphan_distributions, delete_orphan_remotes) return their tasks array. This may cause issues if the caller expects task references for monitoring.

🐛 Proposed fix
         if RepositoryTypeManager.enabled_repository_types['deb']
           deb_acs_api = ::Katello::Pulp3::Repository.api(smart_proxy, 'deb').alternate_content_source_api
           orphan_deb_acs_hrefs = deb_acs_api.list.results.map(&:pulp_href) - known_acs_hrefs
           orphan_deb_acs_hrefs.each do |orphan_deb_acs_href|
             tasks << deb_acs_api.delete(orphan_deb_acs_href)
           end
         end
+        tasks
       end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/services/katello/pulp3/smart_proxy_mirror_repository.rb` around lines 140
- 167, The method delete_orphan_alternate_content_sources builds a local tasks
array but never returns it; update delete_orphan_alternate_content_sources to
return the tasks array (same behavior as delete_orphan_repositories /
delete_orphan_distributions / delete_orphan_remotes) so callers can receive the
created task references from the file_acs_api/yum_acs_api/deb_acs_api delete
calls.
🧹 Nitpick comments (6)
webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js (2)

102-105: The useSelector mock placement may be fragile.

Setting up the useSelector mock mid-test after some interactions have already occurred could lead to inconsistent behavior. Consider moving the mock setup before rendering or using a more predictable pattern for providing test data.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js`
around lines 102 - 105, The test sets up the reactRedux.useSelector mock
(useSelectorMock) after interactions, which is fragile; move the
jest.spyOn(reactRedux, 'useSelector') and its
mockReturnValueOnce(smartProxyResult).mockReturnValue(contentCredentialResult.results)
setup to run before rendering or user interactions (e.g., at the start of the
test or in a beforeEach) so useSelector returns predictable values during render
and subsequent actions; ensure the ordering of mockReturnValueOnce then
mockReturnValue is preserved to match the component's selector call sequence.

54-54: Consider using async/await instead of the done callback pattern.

The test uses the older done callback pattern. Modern Jest best practices recommend using async/await for async tests, which provides cleaner error handling and more readable code.

♻️ Suggested refactor
-test('Can display create wizard and create custom Deb ACS', async (done) => {
+test('Can display create wizard and create custom Deb ACS', async () => {

And at the end of the test:

-  act(done);
+  // assertions complete
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js`
at line 54, The test "Can display create wizard and create custom Deb ACS"
currently uses the done callback; refactor it to use async/await by removing the
done parameter, awaiting all asynchronous calls (e.g., any render, userEvent,
fetch/mocked API calls, or waitFor calls) and avoiding calling done() — ensure
the test function signature is "test(..., async () => { ... })", replace any
done() usages with awaited promises or await expect(...) assertions, and keep
any cleanup/assertion logic after the awaited operations to preserve behavior.
test/actions/pulp3/orchestration/alternate_content_source_create_test.rb (1)

63-70: Assert the DEB PRNs too.

The YUM and file cases verify both *_href and *_prn, but this new DEB case only checks the href prefixes. A regression in DEB PRN extraction would still pass here.

Suggested assertions
     assert_equal 1, `@deb_acs.smart_proxy_alternate_content_sources.count`
     assert `@deb_acs.smart_proxy_alternate_content_sources.first.remote_href.start_with`?('/pulp/api/v3/remotes/deb/apt/')
     assert `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_href.start_with`?('/pulp/api/v3/acs/deb/deb/')
+    assert_not_nil `@deb_acs.smart_proxy_alternate_content_sources.first.remote_prn`
+    assert_match(/^prn:deb\.aptremote:[0-9a-f\-]+$/, `@deb_acs.smart_proxy_alternate_content_sources.first.remote_prn`)
+    assert_not_nil `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_prn`
+    assert_match(/^prn:deb\.aptalternatecontentsource:[0-9a-f\-]+$/, `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_prn`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/alternate_content_source_create_test.rb`
around lines 63 - 70, The DEB test (test_deb_create) currently only asserts href
prefixes; add assertions for the PRN fields on the created
smart_proxy_alternate_content_sources to match the YUM/file tests. After
creating smart_proxy_acs and syncing (in test_deb_create), assert that
smart_proxy_alternate_content_sources.first.remote_href_prn starts_with the
expected DEB remote PRN prefix and that
smart_proxy_alternate_content_sources.first.alternate_content_source_prn
starts_with the expected DEB ACS PRN prefix, using the same object references
(`@deb_acs` and the smart_proxy_alternate_content_sources collection) as in the
test.
test/actions/pulp3/orchestration/alternate_content_source_update_test.rb (1)

187-189: Inconsistent assertion argument order.

The assertion order here (expected, actual) differs from similar tests in this file (Lines 115-117, 134-136) which use (actual, expected). While both work, consistency improves readability.

♻️ Optional fix for consistency
-      assert_equal proxy.url, remote_options[:proxy_url]
-      assert_equal proxy.username, remote_options[:proxy_username]
-      assert_equal proxy.password, remote_options[:proxy_password]
+      assert_equal remote_options[:proxy_url], proxy.url
+      assert_equal remote_options[:proxy_username], proxy.username
+      assert_equal remote_options[:proxy_password], proxy.password
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`
around lines 187 - 189, The three assertions comparing proxy fields to
remote_options use (expected, actual) while the rest of the file uses (actual,
expected); update the assertions that reference proxy.url/username/password and
remote_options[:proxy_url]/[:proxy_username]/[:proxy_password] to use the same
argument order as the other tests (i.e., swap the arguments so
remote_options[...] is the first arg and proxy.* is the second) to keep
assertion ordering consistent.
test/models/katello/alternate_content_source_test.rb (1)

211-216: Redundant save! call.

The fixture is already loaded and persisted via katello_alternate_content_sources in the setup block (Lines 167-170). The explicit save! on Line 213 is unnecessary.

♻️ Optional cleanup
 def test_search_content_type_deb
   deb_acs = katello_alternate_content_sources(:deb_alternate_content_source)
-  deb_acs.save!
   acss = AlternateContentSource.search_for('content_type = "deb"')
   assert_includes acss, deb_acs
 end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/models/katello/alternate_content_source_test.rb` around lines 211 - 216,
The test method test_search_content_type_deb contains a redundant call to save!
on the fixture object
katello_alternate_content_sources(:deb_alternate_content_source); remove the
unnecessary deb_acs.save! invocation so the test simply retrieves the fixture
and asserts it is included in AlternateContentSource.search_for('content_type =
"deb"') without re-persisting the fixture.
test/actions/pulp3/orchestration/deb_sync_test.rb (1)

28-35: Prefer scoped teardown cleanup here.

destroy_all on the whole Katello::SmartProxyAlternateContentSource table is broader than this test needs. Scoping cleanup to @deb_acs keeps the teardown local and easier to reason about.

🧹 Safer cleanup
-      ::Katello::SmartProxyAlternateContentSource.destroy_all
+      ::Katello::SmartProxyAlternateContentSource.where(
+        alternate_content_source_id: `@deb_acs.id`,
+        smart_proxy_id: `@primary.id`
+      ).destroy_all
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/deb_sync_test.rb` around lines 28 - 35, The
teardown is calling ::Katello::SmartProxyAlternateContentSource.destroy_all
which clears the whole table; change it to only remove records related to this
test by scoping to `@deb_acs` (e.g., call something like `@deb_acs.each` { |sma|
sma.destroy } or ::Katello::SmartProxyAlternateContentSource.where(id:
`@deb_acs.map`(&:id)).destroy_all) so the cleanup only affects the
AlternateContentSource records created for this test; update the teardown method
(the list iteration and final destroy_all) to use the scoped destroy based on
`@deb_acs/its` ids.
🤖 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/models/katello/alternate_content_source.rb`:
- Around line 181-186: In deb_constraints, the validation currently uses
deb_releases.to_s.strip.blank? which accepts separator-only strings like ",";
change the check to split deb_releases on commas, strip each element and reject
blank entries, and add the error when the resulting array is empty (e.g. use
deb_releases.to_s.split(',').map(&:strip).reject(&:blank?).empty?); update the
validation in the deb_constraints method (and the errors.add(:deb_releases, ...)
call) so separator-only values are rejected for custom? && deb?.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`:
- Around line 38-41: The teardown loop deleting
smart_proxy_alternate_content_sources for `@deb_acs` does not refresh the `@deb_acs`
associations afterward; after calling
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Delete,
smart_proxy_acs) for each smart_proxy_acs, call `@deb_acs.reload` to refresh
associations (matching other ACS cleanup blocks) so subsequent assertions
operate on the updated state.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb`:
- Around line 320-337: The test_update_deb currently doesn't include
DEB-specific params so it won't detect if deb_releases, deb_components or
deb_architectures stop being permitted; update the PUT request in
test_update_deb to explicitly pass `@deb_acs.deb_releases`,
`@deb_acs.deb_components` and `@deb_acs.deb_architectures` in params (e.g.
deb_releases: ..., deb_components: ..., deb_architectures: ...) and keep the
surrounding assert_sync_task(::Actions::Katello::AlternateContentSource::Update)
and response/template assertions unchanged so the test will fail if those
attributes are not allowed through the controller.

In `@webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js`:
- Around line 62-66: The urlAndPathsValid function currently includes
subPathValidated in baseOk even when subpaths are hidden in DEB custom mode,
which can block the wizard; change the logic so subPathValidated is only
required when subpaths are visible. Concretely, inside urlAndPathsValid compute
a subPathOk that is true when subpaths are not shown (e.g., when contentType ===
'deb' && acsType === 'custom') and otherwise check subPathValidated !== 'error';
then set baseOk to use url !== '' && urlValidated !== 'error' && subPathOk so
hidden subpaths no longer block validation.

In `@webpack/scenes/AlternateContentSources/helpers.js`:
- Around line 30-33: The function declaration for spaceSep is missing a trailing
semicolon; update the end of the spaceSep declaration (the function that calls
toList and returns arr.join(' ') or emptyValue) to include a semicolon after the
closing brace to match the file's semicolon style and maintain consistent
formatting.

---

Outside diff comments:
In `@app/services/katello/pulp3/smart_proxy_mirror_repository.rb`:
- Around line 140-167: The method delete_orphan_alternate_content_sources builds
a local tasks array but never returns it; update
delete_orphan_alternate_content_sources to return the tasks array (same behavior
as delete_orphan_repositories / delete_orphan_distributions /
delete_orphan_remotes) so callers can receive the created task references from
the file_acs_api/yum_acs_api/deb_acs_api delete calls.

---

Nitpick comments:
In `@test/actions/pulp3/orchestration/alternate_content_source_create_test.rb`:
- Around line 63-70: The DEB test (test_deb_create) currently only asserts href
prefixes; add assertions for the PRN fields on the created
smart_proxy_alternate_content_sources to match the YUM/file tests. After
creating smart_proxy_acs and syncing (in test_deb_create), assert that
smart_proxy_alternate_content_sources.first.remote_href_prn starts_with the
expected DEB remote PRN prefix and that
smart_proxy_alternate_content_sources.first.alternate_content_source_prn
starts_with the expected DEB ACS PRN prefix, using the same object references
(`@deb_acs` and the smart_proxy_alternate_content_sources collection) as in the
test.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`:
- Around line 187-189: The three assertions comparing proxy fields to
remote_options use (expected, actual) while the rest of the file uses (actual,
expected); update the assertions that reference proxy.url/username/password and
remote_options[:proxy_url]/[:proxy_username]/[:proxy_password] to use the same
argument order as the other tests (i.e., swap the arguments so
remote_options[...] is the first arg and proxy.* is the second) to keep
assertion ordering consistent.

In `@test/actions/pulp3/orchestration/deb_sync_test.rb`:
- Around line 28-35: The teardown is calling
::Katello::SmartProxyAlternateContentSource.destroy_all which clears the whole
table; change it to only remove records related to this test by scoping to
`@deb_acs` (e.g., call something like `@deb_acs.each` { |sma| sma.destroy } or
::Katello::SmartProxyAlternateContentSource.where(id:
`@deb_acs.map`(&:id)).destroy_all) so the cleanup only affects the
AlternateContentSource records created for this test; update the teardown method
(the list iteration and final destroy_all) to use the scoped destroy based on
`@deb_acs/its` ids.

In `@test/models/katello/alternate_content_source_test.rb`:
- Around line 211-216: The test method test_search_content_type_deb contains a
redundant call to save! on the fixture object
katello_alternate_content_sources(:deb_alternate_content_source); remove the
unnecessary deb_acs.save! invocation so the test simply retrieves the fixture
and asserts it is included in AlternateContentSource.search_for('content_type =
"deb"') without re-persisting the fixture.

In
`@webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js`:
- Around line 102-105: The test sets up the reactRedux.useSelector mock
(useSelectorMock) after interactions, which is fragile; move the
jest.spyOn(reactRedux, 'useSelector') and its
mockReturnValueOnce(smartProxyResult).mockReturnValue(contentCredentialResult.results)
setup to run before rendering or user interactions (e.g., at the start of the
test or in a beforeEach) so useSelector returns predictable values during render
and subsequent actions; ensure the ordering of mockReturnValueOnce then
mockReturnValue is preserved to match the component's selector call sequence.
- Line 54: The test "Can display create wizard and create custom Deb ACS"
currently uses the done callback; refactor it to use async/await by removing the
done parameter, awaiting all asynchronous calls (e.g., any render, userEvent,
fetch/mocked API calls, or waitFor calls) and avoiding calling done() — ensure
the test function signature is "test(..., async () => { ... })", replace any
done() usages with awaited promises or await expect(...) assertions, and keep
any cleanup/assertion logic after the awaited operations to preserve behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 62180d4f-b071-4ca7-b9c6-853d5e8f8036

📥 Commits

Reviewing files that changed from the base of the PR and between 2b1e044 and 78cc158.

📒 Files selected for processing (32)
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb
  • app/services/katello/pulp3/alternate_content_source.rb
  • app/services/katello/pulp3/api/apt.rb
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/actions/pulp3/orchestration/alternate_content_source_create_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/deb_sync_test.rb
  • test/controllers/api/v2/alternate_content_sources_controller_test.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/apt_sync/sync_with_deb_acs.yml
  • test/models/katello/alternate_content_source_test.rb
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js
  • webpack/scenes/AlternateContentSources/helpers.js

Comment thread app/models/katello/alternate_content_source.rb
Comment on lines +38 to +41
@deb_acs.smart_proxy_alternate_content_sources.each do |smart_proxy_acs|
ForemanTasks.sync_task(
::Actions::Pulp3::Orchestration::AlternateContentSource::Delete, smart_proxy_acs)
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing @deb_acs.reload after teardown cleanup.

Other ACS cleanup blocks in teardown call reload to refresh associations (e.g., Lines 30, 36, 47, 53). This block is missing that call for consistency.

🔧 Proposed fix
       `@deb_acs.smart_proxy_alternate_content_sources.each` do |smart_proxy_acs|
         ForemanTasks.sync_task(
           ::Actions::Pulp3::Orchestration::AlternateContentSource::Delete, smart_proxy_acs)
       end
+      `@deb_acs.reload`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@deb_acs.smart_proxy_alternate_content_sources.each do |smart_proxy_acs|
ForemanTasks.sync_task(
::Actions::Pulp3::Orchestration::AlternateContentSource::Delete, smart_proxy_acs)
end
`@deb_acs.smart_proxy_alternate_content_sources.each` do |smart_proxy_acs|
ForemanTasks.sync_task(
::Actions::Pulp3::Orchestration::AlternateContentSource::Delete, smart_proxy_acs)
end
`@deb_acs.reload`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`
around lines 38 - 41, The teardown loop deleting
smart_proxy_alternate_content_sources for `@deb_acs` does not refresh the `@deb_acs`
associations afterward; after calling
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Delete,
smart_proxy_acs) for each smart_proxy_acs, call `@deb_acs.reload` to refresh
associations (matching other ACS cleanup blocks) so subsequent assertions
operate on the updated state.

Comment on lines +320 to +337
def test_update_deb
assert_sync_task(::Actions::Katello::AlternateContentSource::Update) do |acs, smart_proxies|
assert_equal acs.attributes.except('id', 'label'), @deb_acs.attributes.except('id', 'label')
assert_equal [@smart_proxy.id], smart_proxies.pluck(:id)
end

put :update, params: {
id: @deb_acs.id,
name: @deb_acs.name,
smart_proxy_ids: [@smart_proxy.id],
content_type: @deb_acs.content_type,
base_url: @deb_acs.base_url,
subpaths: @deb_acs.subpaths,
alternate_content_source_type: @deb_acs.alternate_content_source_type,
verify_ssl: @deb_acs.verify_ssl,
}
assert_response :success
assert_template 'api/v2/alternate_content_sources/show'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Exercise the DEB fields in the update request.

Because @deb_acs is already persisted with the Debian attributes, this assertion still passes even if update stops permitting deb_releases, deb_components, or deb_architectures. The request needs to touch those fields explicitly.

🔧 Suggested test adjustment
       put :update, params: {
         id: `@deb_acs.id`,
         name: `@deb_acs.name`,
         smart_proxy_ids: [`@smart_proxy.id`],
         content_type: `@deb_acs.content_type`,
         base_url: `@deb_acs.base_url`,
         subpaths: `@deb_acs.subpaths`,
+        deb_releases: `@deb_acs.deb_releases`,
+        deb_components: `@deb_acs.deb_components`,
+        deb_architectures: `@deb_acs.deb_architectures`,
         alternate_content_source_type: `@deb_acs.alternate_content_source_type`,
         verify_ssl: `@deb_acs.verify_ssl`,
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_update_deb
assert_sync_task(::Actions::Katello::AlternateContentSource::Update) do |acs, smart_proxies|
assert_equal acs.attributes.except('id', 'label'), @deb_acs.attributes.except('id', 'label')
assert_equal [@smart_proxy.id], smart_proxies.pluck(:id)
end
put :update, params: {
id: @deb_acs.id,
name: @deb_acs.name,
smart_proxy_ids: [@smart_proxy.id],
content_type: @deb_acs.content_type,
base_url: @deb_acs.base_url,
subpaths: @deb_acs.subpaths,
alternate_content_source_type: @deb_acs.alternate_content_source_type,
verify_ssl: @deb_acs.verify_ssl,
}
assert_response :success
assert_template 'api/v2/alternate_content_sources/show'
def test_update_deb
assert_sync_task(::Actions::Katello::AlternateContentSource::Update) do |acs, smart_proxies|
assert_equal acs.attributes.except('id', 'label'), `@deb_acs.attributes.except`('id', 'label')
assert_equal [`@smart_proxy.id`], smart_proxies.pluck(:id)
end
put :update, params: {
id: `@deb_acs.id`,
name: `@deb_acs.name`,
smart_proxy_ids: [`@smart_proxy.id`],
content_type: `@deb_acs.content_type`,
base_url: `@deb_acs.base_url`,
subpaths: `@deb_acs.subpaths`,
deb_releases: `@deb_acs.deb_releases`,
deb_components: `@deb_acs.deb_components`,
deb_architectures: `@deb_acs.deb_architectures`,
alternate_content_source_type: `@deb_acs.alternate_content_source_type`,
verify_ssl: `@deb_acs.verify_ssl`,
}
assert_response :success
assert_template 'api/v2/alternate_content_sources/show'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb` around
lines 320 - 337, The test_update_deb currently doesn't include DEB-specific
params so it won't detect if deb_releases, deb_components or deb_architectures
stop being permitted; update the PUT request in test_update_deb to explicitly
pass `@deb_acs.deb_releases`, `@deb_acs.deb_components` and
`@deb_acs.deb_architectures` in params (e.g. deb_releases: ..., deb_components:
..., deb_architectures: ...) and keep the surrounding
assert_sync_task(::Actions::Katello::AlternateContentSource::Update) and
response/template assertions unchanged so the test will fail if those attributes
are not allowed through the controller.

Comment thread webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
Comment thread webpack/scenes/AlternateContentSources/helpers.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/controllers/katello/api/v2/alternate_content_sources_controller.rb (1)

41-49: ⚠️ Potential issue | 🔴 Critical

Lines 41-49 reference undefined @acs variable, causing NoMethodError on CSV export.

The index action references @acs.custom?, @acs.rhui?, and @acs.simplified? at lines 41 and 45, but @acs is never assigned. The find_authorized_katello_resource before_action (line 7) explicitly excludes the index action, so there's no initialization. This will raise NoMethodError when attempting to export to CSV.

Additionally, the logic appears flawed: the code retrieves a collection of alternate_content_sources (multiple records) but then checks properties of a single undefined @acs object. The conditional logic needs redesign—either filter the collection before export, or iterate through records checking each one's type individually.

♻️ Duplicate comments (3)
webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js (1)

62-67: ⚠️ Potential issue | 🟡 Minor

Subpath validation still blocks wizard in DEB mode when subpaths are hidden.

The urlAndPathsValid() function includes subPathValidated !== 'error' in baseOk unconditionally. If a user enters invalid subpaths in a non-DEB flow and then switches to DEB (where subpaths are not shown), the wizard can remain blocked on a field that is no longer visible or editable.

Suggested fix
 const urlAndPathsValid = () => {
-  const baseOk = url !== '' && urlValidated !== 'error' && subPathValidated !== 'error';
+  const subpathsOk = contentType === 'deb' || subPathValidated !== 'error';
+  const baseOk = url !== '' && urlValidated !== 'error' && subpathsOk;
   const isDebCustom = contentType === 'deb' && acsType === 'custom';
   const hasReleases = (debReleases || '').trim().split(/[,\s]+/).filter(Boolean).length > 0;
   return baseOk && (!isDebCustom || hasReleases);
 };
app/models/katello/alternate_content_source.rb (1)

184-185: ⚠️ Potential issue | 🟠 Major

Reject separator-only deb_releases values.

The current blank check allows values like "," / " , " to pass validation, which can persist invalid DEB ACS definitions and fail later in orchestration.

🔧 Proposed fix
-      if custom? && deb_releases.to_s.strip.blank?
+      releases = deb_releases.to_s.split(',').map(&:strip).reject(&:blank?)
+      if custom? && releases.empty?
         errors.add(:deb_releases, 'must be provided for deb alternate content sources')
       end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/models/katello/alternate_content_source.rb` around lines 184 - 185, The
validation for deb_releases currently only checks blank? which lets
separator-only strings like "," pass; update the condition in the validation
block (the custom? check that calls errors.add on :deb_releases) to treat
comma-separated values with only whitespace/empty entries as blank by splitting
deb_releases on "," then mapping strip and rejecting blank entries, and add the
error if the resulting array is empty (i.e. no real release tokens).
test/controllers/api/v2/alternate_content_sources_controller_test.rb (1)

326-335: ⚠️ Potential issue | 🟡 Minor

Pass the DEB fields in the update request.

This still passes if deb_releases, deb_components, or deb_architectures stop being permitted, because the expectation compares against the already-persisted fixture. Include them in the PUT payload so the controller whitelist is actually exercised.

🔧 Suggested test adjustment
       put :update, params: {
         id: `@deb_acs.id`,
         name: `@deb_acs.name`,
         smart_proxy_ids: [`@smart_proxy.id`],
         content_type: `@deb_acs.content_type`,
         base_url: `@deb_acs.base_url`,
         subpaths: `@deb_acs.subpaths`,
+        deb_releases: `@deb_acs.deb_releases`,
+        deb_components: `@deb_acs.deb_components`,
+        deb_architectures: `@deb_acs.deb_architectures`,
         alternate_content_source_type: `@deb_acs.alternate_content_source_type`,
         verify_ssl: `@deb_acs.verify_ssl`,
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb` around
lines 326 - 335, The test sends an update via put :update for `@deb_acs` but
doesn't include the DEB-specific fields, so the controller's strong-parameter
whitelist isn't exercised; update the params in the put :update call (in
test/controllers/api/v2/alternate_content_sources_controller_test.rb, the put
:update block that references `@deb_acs`) to include deb_releases, deb_components,
and deb_architectures (populated from `@deb_acs.deb_releases`,
`@deb_acs.deb_components`, `@deb_acs.deb_architectures`) so the request payload
actually contains those attributes and will fail if they are no longer
permitted.
🧹 Nitpick comments (2)
db/migrate/20251110000001_add_deb_fields_to_acs.rb (1)

3-5: Consider adding limit: 255 to match the existing deb fields migration, or use :text for consistency across both tables.

The existing migration for deb fields in katello_repositories (20170720142145) uses :string, limit: 255 for deb_releases, deb_components, and deb_architectures. The new ACS migration should either match that pattern with an explicit limit or adopt :text universally. Test data shows no values approaching 255 characters, but clarifying the intended field size strategy is important to avoid future truncation risks.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@db/migrate/20251110000001_add_deb_fields_to_acs.rb` around lines 3 - 5, The
new migration adds deb_releases, deb_components, and deb_architectures to
katello_alternate_content_sources without a size specification; update the three
add_column calls to either add limit: 255 (to match the existing
katello_repositories migration) like add_column
:katello_alternate_content_sources, :deb_releases, :string, limit: 255 (and same
for deb_components and deb_architectures) or change the column type to :text for
all three for consistency across tables—pick one approach and apply it
consistently to the three add_column lines.
webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js (1)

362-404: Consider defensive check for subpaths before calling .join().

Line 371 calls subpaths.join() without a null check. While subpaths should be an array from the API for custom/rhui types, a defensive check would prevent runtime errors if the API returns unexpected data.

Suggested fix
                   <TextListItem
                     aria-label="subpaths_text_value"
                     component={TextListItemVariants.dd}
                   >
-                    {subpaths.join()}
+                    {subpaths?.join() || <InactiveText text="N/A" />}
                   </TextListItem>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js`
around lines 362 - 404, subpaths may be null/undefined before calling .join() in
the ACSExpandableDetails component where subpaths.join() is rendered; update the
rendering logic to defensively check that subpaths is an array (e.g., using
Array.isArray(subpaths)) and only call .join() when true, otherwise render a
fallback such as <InactiveText text="N/A" /> or an empty string; ensure the
change targets the TextListItem with aria-label="subpaths_text_value" so other
debMode branches are untouched.
🤖 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/services/katello/pulp3/smart_proxy_mirror_repository.rb`:
- Around line 160-167: The method delete_orphan_alternate_content_sources
currently may return nil when the deb branch is not executed; ensure it always
returns the accumulated tasks array by adding an explicit tasks return at the
end of the method. Locate the delete_orphan_alternate_content_sources method and
append a final expression returning tasks (matching the behavior of
delete_orphan_remotes) so callers consistently receive the tasks array even when
RepositoryTypeManager.enabled_repository_types['deb'] is false.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`:
- Around line 82-92: The test_deb_update currently only mutates and asserts
deb_releases; update the test (test_deb_update) to also mutate deb_components
and deb_architectures on `@deb_acs` before calling ForemanTasks.sync_task for
Actions::Pulp3::Orchestration::AlternateContentSource::Update, then fetch
pulp_remote via `@deb_acs.backend_service`(`@primary`).get_remote and add assertions
that pulp_remote.components matches the new deb_components and
pulp_remote.architectures matches the new deb_architectures (alongside the
existing assertions for base_url and distributions) to ensure all DEB remote
fields are covered.

In `@test/actions/pulp3/orchestration/deb_sync_test.rb`:
- Around line 7-8: The test's setup mutates global User.current to users(:admin)
but never restores it; modify setup to save the prior user (e.g., previous_user
= User.current) and then update teardown to restore User.current = previous_user
before performing the rest of teardown cleanup so later tests don't inherit
admin context; reference the setup and teardown methods and the User.current
assignment when making the change.

In
`@test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml`:
- Around line 8-247: This cassette contains secret material (embedded certs/keys
and upstream credentials) inside fields such as base64_string (which decodes to
ca_cert and client_key), client_key, ca_cert, proxy_username, proxy_password and
the Authorization header; update the VCR/filtering logic to replace those values
with placeholders (e.g. <REDACTED_CA_CERT>, <REDACTED_CLIENT_KEY>,
<REDACTED_PROXY_USER>, <REDACTED_PROXY_PASS>, <REDACTED_AUTH>) when recording
(look for the vcr config or filter hooks used for these fixtures and the code
that writes/reads this cassette), then rerecord the cassette so the committed
YAML contains the placeholders instead of real secrets.

In
`@test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml`:
- Around line 72-116: The cassette contains sensitive fields (hidden_fields
array values like "client_key", "username", "password") stored in base64; update
the test VCR setup to add filter_sensitive_data rules that mask these fields
before recording (e.g., add VCR.filter_sensitive_data for client_key, username,
password and any tcls_validation token) and re-record the cassette so the
recorded payload has placeholders instead of real credentials; target the test
helper that configures VCR (look for VCR.configure / filter_sensitive_data
usage) and add filters for the base64-encoded RSA key and credentials then
re-run the tests to regenerate the cassette.

In
`@webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js`:
- Around line 54-55: The test "Can display create wizard and create custom Deb
ACS" mixes callback and promise styles: remove the done parameter from the test
function signature and eliminate any act(done) calls (and any other calls to
done) inside the test so the async function relies on returned Promises/await;
replace act(done) with await act(...) or await when resolving effects so the
async test uses only async/await semantics (look for the test string and any
act(done) occurrences to update).

In
`@webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js`:
- Around line 56-63: The current debMode branch sets params.subpaths to an empty
array which wipes hidden Debian subpaths; instead, remove the explicit subpaths:
[] assignment so that when debMode is true the params object does not include
subpaths and the server retains existing values—update the block building params
(the code referencing debMode, params,
deb_releases/deb_components/deb_architectures and spaceSepOrEmpty) to omit
subpaths rather than set it to [].

---

Duplicate comments:
In `@app/models/katello/alternate_content_source.rb`:
- Around line 184-185: The validation for deb_releases currently only checks
blank? which lets separator-only strings like "," pass; update the condition in
the validation block (the custom? check that calls errors.add on :deb_releases)
to treat comma-separated values with only whitespace/empty entries as blank by
splitting deb_releases on "," then mapping strip and rejecting blank entries,
and add the error if the resulting array is empty (i.e. no real release tokens).

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb`:
- Around line 326-335: The test sends an update via put :update for `@deb_acs` but
doesn't include the DEB-specific fields, so the controller's strong-parameter
whitelist isn't exercised; update the params in the put :update call (in
test/controllers/api/v2/alternate_content_sources_controller_test.rb, the put
:update block that references `@deb_acs`) to include deb_releases, deb_components,
and deb_architectures (populated from `@deb_acs.deb_releases`,
`@deb_acs.deb_components`, `@deb_acs.deb_architectures`) so the request payload
actually contains those attributes and will fail if they are no longer
permitted.

---

Nitpick comments:
In `@db/migrate/20251110000001_add_deb_fields_to_acs.rb`:
- Around line 3-5: The new migration adds deb_releases, deb_components, and
deb_architectures to katello_alternate_content_sources without a size
specification; update the three add_column calls to either add limit: 255 (to
match the existing katello_repositories migration) like add_column
:katello_alternate_content_sources, :deb_releases, :string, limit: 255 (and same
for deb_components and deb_architectures) or change the column type to :text for
all three for consistency across tables—pick one approach and apply it
consistently to the three add_column lines.

In `@webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js`:
- Around line 362-404: subpaths may be null/undefined before calling .join() in
the ACSExpandableDetails component where subpaths.join() is rendered; update the
rendering logic to defensively check that subpaths is an array (e.g., using
Array.isArray(subpaths)) and only call .join() when true, otherwise render a
fallback such as <InactiveText text="N/A" /> or an empty string; ensure the
change targets the TextListItem with aria-label="subpaths_text_value" so other
debMode branches are untouched.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 073ec419-cf1d-4770-a0f9-7819150c3d70

📥 Commits

Reviewing files that changed from the base of the PR and between 2b1e044 and 5e306ef.

📒 Files selected for processing (32)
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb
  • app/services/katello/pulp3/alternate_content_source.rb
  • app/services/katello/pulp3/api/apt.rb
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/actions/pulp3/orchestration/alternate_content_source_create_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/deb_sync_test.rb
  • test/controllers/api/v2/alternate_content_sources_controller_test.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/apt_sync/sync_with_deb_acs.yml
  • test/models/katello/alternate_content_source_test.rb
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js
  • webpack/scenes/AlternateContentSources/helpers.js

Comment thread app/services/katello/pulp3/smart_proxy_mirror_repository.rb
Comment on lines +82 to +92
def test_deb_update
::Katello::Pulp3::AlternateContentSource.any_instance.stubs(:generate_backend_object_name).returns(@deb_acs.name)
smart_proxy_acs = ::Katello::SmartProxyAlternateContentSource.create(alternate_content_source_id: @deb_acs.id, smart_proxy_id: @primary.id)
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Create, smart_proxy_acs)
@deb_acs.update(base_url: 'https://fixtures.pulpproject.org/debian/', deb_releases: 'ragnarok ginnungagap')
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Update, smart_proxy_acs)

pulp_remote = @deb_acs.backend_service(@primary).get_remote
assert_equal @deb_acs.base_url, pulp_remote.url
assert_equal 'ragnarok ginnungagap', pulp_remote.distributions
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Cover all DEB remote fields in the update test.

This only mutates/asserts deb_releases, so a regression in deb_components or deb_architectures mapping would still pass here.

🔧 Suggested test expansion
-      `@deb_acs.update`(base_url: 'https://fixtures.pulpproject.org/debian/', deb_releases: 'ragnarok ginnungagap')
+      `@deb_acs.update`!(
+        base_url: 'https://fixtures.pulpproject.org/debian/',
+        deb_releases: 'ragnarok ginnungagap',
+        deb_components: 'main contrib',
+        deb_architectures: 'amd64 arm64'
+      )
       ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Update, smart_proxy_acs)

       pulp_remote = `@deb_acs.backend_service`(`@primary`).get_remote
       assert_equal `@deb_acs.base_url`, pulp_remote.url
-      assert_equal 'ragnarok ginnungagap', pulp_remote.distributions
+      assert_equal `@deb_acs.deb_releases`, pulp_remote.distributions
+      assert_equal `@deb_acs.deb_components`, pulp_remote.components
+      assert_equal `@deb_acs.deb_architectures`, pulp_remote.architectures
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_deb_update
::Katello::Pulp3::AlternateContentSource.any_instance.stubs(:generate_backend_object_name).returns(@deb_acs.name)
smart_proxy_acs = ::Katello::SmartProxyAlternateContentSource.create(alternate_content_source_id: @deb_acs.id, smart_proxy_id: @primary.id)
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Create, smart_proxy_acs)
@deb_acs.update(base_url: 'https://fixtures.pulpproject.org/debian/', deb_releases: 'ragnarok ginnungagap')
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Update, smart_proxy_acs)
pulp_remote = @deb_acs.backend_service(@primary).get_remote
assert_equal @deb_acs.base_url, pulp_remote.url
assert_equal 'ragnarok ginnungagap', pulp_remote.distributions
end
def test_deb_update
::Katello::Pulp3::AlternateContentSource.any_instance.stubs(:generate_backend_object_name).returns(`@deb_acs.name`)
smart_proxy_acs = ::Katello::SmartProxyAlternateContentSource.create(alternate_content_source_id: `@deb_acs.id`, smart_proxy_id: `@primary.id`)
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Create, smart_proxy_acs)
`@deb_acs.update`!(
base_url: 'https://fixtures.pulpproject.org/debian/',
deb_releases: 'ragnarok ginnungagap',
deb_components: 'main contrib',
deb_architectures: 'amd64 arm64'
)
ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Update, smart_proxy_acs)
pulp_remote = `@deb_acs.backend_service`(`@primary`).get_remote
assert_equal `@deb_acs.base_url`, pulp_remote.url
assert_equal `@deb_acs.deb_releases`, pulp_remote.distributions
assert_equal `@deb_acs.deb_components`, pulp_remote.components
assert_equal `@deb_acs.deb_architectures`, pulp_remote.architectures
end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/alternate_content_source_update_test.rb`
around lines 82 - 92, The test_deb_update currently only mutates and asserts
deb_releases; update the test (test_deb_update) to also mutate deb_components
and deb_architectures on `@deb_acs` before calling ForemanTasks.sync_task for
Actions::Pulp3::Orchestration::AlternateContentSource::Update, then fetch
pulp_remote via `@deb_acs.backend_service`(`@primary`).get_remote and add assertions
that pulp_remote.components matches the new deb_components and
pulp_remote.architectures matches the new deb_architectures (alongside the
existing assertions for base_url and distributions) to ensure all DEB remote
fields are covered.

Comment thread test/actions/pulp3/orchestration/deb_sync_test.rb
@aidenfine
Copy link
Copy Markdown
Contributor

I went through these code rabbit reviews and left some comments on the ones I think we should fix. Can you take a look at the proposed fixes?

Copy link
Copy Markdown
Member

@ianballou ianballou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handling some code rabbit reviews:

Comment thread app/services/katello/pulp3/smart_proxy_mirror_repository.rb
@ianballou
Copy link
Copy Markdown
Member

We should be able to merge this after the small tasks comment is dealt with above. This change is looking great.

@quba42
Copy link
Copy Markdown
Contributor

quba42 commented Apr 13, 2026

FYI: We decided we should add some more validation on the API controller, right now it will let me set subpaths via the API for a deb ACS so long as I don't set any smart proxies. If I then try to add a smart proxy to actually use it later the update action will fail, because Katello now tries to create the Pulp object with subpaths and Pulp will say nope. This is not a great user experience. It should simply fail on the Katello API validation, thus forcing me to create something sensible to begin with.

@ianballou
Copy link
Copy Markdown
Member

FYI: We decided we should add some more validation on the API controller, right now it will let me set subpaths via the API for a deb ACS so long as I don't set any smart proxies. If I then try to add a smart proxy to actually use it later the update action will fail, because Katello now tries to create the Pulp object with subpaths and Pulp will say nope. This is not a great user experience. It should simply fail on the Katello API validation, thus forcing me to create something sensible to begin with.

Sounds good to me, thanks for testing it, I didn't realize the subpaths would propagate in so far.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
test/controllers/api/v2/alternate_content_sources_controller_test.rb (1)

326-335: ⚠️ Potential issue | 🟡 Minor

Pass the DEB fields through test_update_deb.

@deb_acs already has deb_releases, deb_components, and deb_architectures persisted, so this request still passes if update stops permitting those params. Include them in the PUT payload so the test covers the new controller surface.

Suggested fix
       put :update, params: {
         id: `@deb_acs.id`,
         name: `@deb_acs.name`,
         smart_proxy_ids: [`@smart_proxy.id`],
         content_type: `@deb_acs.content_type`,
         base_url: `@deb_acs.base_url`,
         subpaths: `@deb_acs.subpaths`,
+        deb_releases: `@deb_acs.deb_releases`,
+        deb_components: `@deb_acs.deb_components`,
+        deb_architectures: `@deb_acs.deb_architectures`,
         alternate_content_source_type: `@deb_acs.alternate_content_source_type`,
         verify_ssl: `@deb_acs.verify_ssl`,
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb` around
lines 326 - 335, The test_update_deb case's PUT request is missing explicit DEB
params so it doesn't exercise the controller's new param handling; modify the
params in the put :update call (inside test_update_deb) to include deb_releases,
deb_components, and deb_architectures (e.g. pass `@deb_acs.deb_releases`,
`@deb_acs.deb_components`, `@deb_acs.deb_architectures`) so the request payload
covers the full DEB fields surface the controller now accepts.
webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js (1)

62-66: ⚠️ Potential issue | 🟠 Major

Don't let hidden subpaths block the DEB flow.

Line 63 still folds subPathValidated into baseOk even when the subpaths field is hidden. If someone enters invalid subpaths before switching to a DEB custom ACS, step 5 can stay blocked with no visible field to correct.

Suggested fix
   const urlAndPathsValid = () => {
-    const baseOk = url !== '' && urlValidated !== 'error' && subPathValidated !== 'error';
+    const subpathsOk = contentType === 'deb' || subPathValidated !== 'error';
+    const baseOk = url !== '' && urlValidated !== 'error' && subpathsOk;
     const isDebCustom = contentType === 'deb' && acsType === 'custom';
     const hasReleases = (debReleases || '').trim().split(/[,\s]+/).filter(Boolean).length > 0;
     return baseOk && (!isDebCustom || hasReleases);
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js` around
lines 62 - 66, The validation currently treats subPathValidated as required even
when the subpaths field is hidden; update urlAndPathsValid so baseOk only checks
subPathValidated when the subpaths field is visible. Concretely, change the
baseOk expression in urlAndPathsValid to use a visibility check (e.g. const
subpathsVisible = !(contentType === 'deb' && acsType === 'custom')) and require
subPathValidated !== 'error' only when subpathsVisible; keep the existing checks
for url and urlValidated and leave the DEB custom release logic (isDebCustom /
hasReleases) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js`:
- Around line 69-70: The code currently does raw subpaths.split(',') which can
leave leading/trailing spaces and empty strings; update the ACSCreateFinish.js
branch that builds acsParams so that instead of using subpaths.split(',') it
normalizes tokens the same way ACSEditURLPaths.js does: split on commas, trim
each token, and filter out empty strings before assigning to acsParams
(reference the acsParams variable and the subpaths handling logic).

---

Duplicate comments:
In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb`:
- Around line 326-335: The test_update_deb case's PUT request is missing
explicit DEB params so it doesn't exercise the controller's new param handling;
modify the params in the put :update call (inside test_update_deb) to include
deb_releases, deb_components, and deb_architectures (e.g. pass
`@deb_acs.deb_releases`, `@deb_acs.deb_components`, `@deb_acs.deb_architectures`) so
the request payload covers the full DEB fields surface the controller now
accepts.

In `@webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js`:
- Around line 62-66: The validation currently treats subPathValidated as
required even when the subpaths field is hidden; update urlAndPathsValid so
baseOk only checks subPathValidated when the subpaths field is visible.
Concretely, change the baseOk expression in urlAndPathsValid to use a visibility
check (e.g. const subpathsVisible = !(contentType === 'deb' && acsType ===
'custom')) and require subPathValidated !== 'error' only when subpathsVisible;
keep the existing checks for url and urlValidated and leave the DEB custom
release logic (isDebCustom / hasReleases) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 35fbd9ec-a705-470c-870b-43701468a9cc

📥 Commits

Reviewing files that changed from the base of the PR and between 5e306ef and 30a7068.

📒 Files selected for processing (32)
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb
  • app/services/katello/pulp3/alternate_content_source.rb
  • app/services/katello/pulp3/api/apt.rb
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/actions/pulp3/orchestration/alternate_content_source_create_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/deb_sync_test.rb
  • test/controllers/api/v2/alternate_content_sources_controller_test.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/apt_sync/sync_with_deb_acs.yml
  • test/models/katello/alternate_content_source_test.rb
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js
  • webpack/scenes/AlternateContentSources/helpers.js
✅ Files skipped from review due to trivial changes (14)
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • app/models/katello/alternate_content_source.rb
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • test/actions/pulp3/orchestration/deb_sync_test.rb
🚧 Files skipped from review as they are similar to previous changes (8)
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/services/katello/pulp3/api/apt.rb
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/helpers.js
  • app/services/katello/pulp3/alternate_content_source.rb
  • webpack/scenes/AlternateContentSources/Create/tests/acsCreateDeb.test.js
  • test/models/katello/alternate_content_source_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb

Comment thread webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js Outdated
@hstct hstct force-pushed the add-debian-acs branch 2 times, most recently from 97da682 to 615491b Compare April 16, 2026 15:06
@hstct
Copy link
Copy Markdown
Contributor Author

hstct commented Apr 16, 2026

ugh, I'll fix those tests asap

@aidenfine
Copy link
Copy Markdown
Contributor

ugh, I'll fix those tests asap

Thank you I think once those tests are fixed we can get this merged. @ianballou does that sound right?

@ianballou
Copy link
Copy Markdown
Member

ugh, I'll fix those tests asap

Thank you I think once those tests are fixed we can get this merged. @ianballou does that sound right?

I think it's worth briefly verifying what happens when you pass subpaths in now, but assuming that looks fine, yep, this can merge then.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js (1)

62-66: ⚠️ Potential issue | 🟠 Major

Don’t gate Debian creation on hidden subpath validation.

Line 63 still requires subPathValidated !== 'error', so a user can enter invalid subpaths in a non-Debian flow, switch to Debian, and be blocked by a hidden field. Skip subpath validation when contentType === 'deb'.

Proposed fix
 const urlAndPathsValid = () => {
-  const baseOk = url !== '' && urlValidated !== 'error' && subPathValidated !== 'error';
+  const subpathsOk = contentType === 'deb' || subPathValidated !== 'error';
+  const baseOk = url !== '' && urlValidated !== 'error' && subpathsOk;
   const isDebCustom = contentType === 'deb' && acsType === 'custom';
   const hasReleases = (debReleases || '').trim().split(/[,\s]+/).filter(Boolean).length > 0;
   return baseOk && (!isDebCustom || hasReleases);
 };

Based on learnings, when in Debian (deb) ACS mode, subpaths are intentionally cleared because Debian ACSs do not use subpaths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js` around
lines 62 - 66, The urlAndPathsValid function currently requires subPathValidated
!== 'error' for all content types, which incorrectly blocks Debian ACS creation
when subpaths are intentionally cleared; update the logic in urlAndPathsValid to
skip subPathValidated checks when contentType === 'deb' (i.e., treat subpath
validation as not required for Debian), keeping the existing checks for url and
urlValidated and preserving the deb-specific logic using acsType === 'custom'
and debReleases to determine whether releases are present.
test/controllers/api/v2/alternate_content_sources_controller_test.rb (1)

345-360: ⚠️ Potential issue | 🟡 Minor

Exercise the Debian-specific fields in the update request.

test_update_deb still passes even if the controller stops permitting deb_releases, deb_components, or deb_architectures, because @deb_acs already has those persisted values. Include them in the PUT params so the test covers the update whitelist.

Proposed test adjustment
       put :update, params: {
         id: `@deb_acs.id`,
         name: `@deb_acs.name`,
         smart_proxy_ids: [`@smart_proxy.id`],
         content_type: `@deb_acs.content_type`,
         base_url: `@deb_acs.base_url`,
         subpaths: `@deb_acs.subpaths`,
+        deb_releases: `@deb_acs.deb_releases`,
+        deb_components: `@deb_acs.deb_components`,
+        deb_architectures: `@deb_acs.deb_architectures`,
         alternate_content_source_type: `@deb_acs.alternate_content_source_type`,
         verify_ssl: `@deb_acs.verify_ssl`,
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb` around
lines 345 - 360, The test_update_deb currently omits Debian-specific params so
it doesn't exercise the controller's strong-params whitelist; update the PUT
:update call in test_update_deb to include `@deb_acs.deb_releases`,
`@deb_acs.deb_components`, and `@deb_acs.deb_architectures` (using the same keys
deb_releases, deb_components, deb_architectures) alongside the existing params
so the controller's Update action (and the assert_sync_task for
::Actions::Katello::AlternateContentSource::Update) actually verifies those
fields are permitted and sent in the request.
🤖 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/models/katello/alternate_content_source.rb`:
- Around line 70-72: The :if option currently uses invalid Ruby syntax ("{
:custom? && !deb? }"); replace it with a Proc/lambda that evaluates the
predicate on the model instance (e.g. use a Proc or ->(r) { r.custom? && !r.deb?
}) so the validator Validators::AlternateContentSourcePathValidator on the model
(the validates_with call for attributes :base_url and :subpaths) only runs when
record.custom? && !record.deb?.

In `@app/services/katello/pulp3/alternate_content_source.rb`:
- Around line 18-20: The join_space_or_nil method currently treats the entire
input as a single value so inputs like "trixie, bookworm" remain
comma-separated; change its normalization to split string inputs on commas and
whitespace (e.g. using a regexp like /[,\s]+/), then map to strings, strip,
reject blank and join with a single space, returning nil for empty result; apply
the same fix to the analogous normalization function present around lines 70-73
so both places produce space-separated tokens sent to Pulp.

In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb`:
- Line 154: Remove the trailing whitespace on the blank line that RuboCop
flagged in the alternate_content_sources_controller_test test file; open
test/controllers/api/v2/alternate_content_sources_controller_test.rb, locate the
empty line around the failing test block and delete any stray spaces so the line
is truly empty (no spaces or tabs), then save and re-run RuboCop.

---

Duplicate comments:
In `@test/controllers/api/v2/alternate_content_sources_controller_test.rb`:
- Around line 345-360: The test_update_deb currently omits Debian-specific
params so it doesn't exercise the controller's strong-params whitelist; update
the PUT :update call in test_update_deb to include `@deb_acs.deb_releases`,
`@deb_acs.deb_components`, and `@deb_acs.deb_architectures` (using the same keys
deb_releases, deb_components, deb_architectures) alongside the existing params
so the controller's Update action (and the assert_sync_task for
::Actions::Katello::AlternateContentSource::Update) actually verifies those
fields are permitted and sent in the request.

In `@webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js`:
- Around line 62-66: The urlAndPathsValid function currently requires
subPathValidated !== 'error' for all content types, which incorrectly blocks
Debian ACS creation when subpaths are intentionally cleared; update the logic in
urlAndPathsValid to skip subPathValidated checks when contentType === 'deb'
(i.e., treat subpath validation as not required for Debian), keeping the
existing checks for url and urlValidated and preserving the deb-specific logic
using acsType === 'custom' and debReleases to determine whether releases are
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ac4aeca-7f25-4dfc-a759-6762072c8e9a

📥 Commits

Reviewing files that changed from the base of the PR and between 30a7068 and af1f5aa.

📒 Files selected for processing (32)
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb
  • app/services/katello/pulp3/alternate_content_source.rb
  • app/services/katello/pulp3/api/apt.rb
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/actions/pulp3/orchestration/alternate_content_source_create_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/deb_sync_test.rb
  • test/controllers/api/v2/alternate_content_sources_controller_test.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/apt_sync/sync_with_deb_acs.yml
  • test/models/katello/alternate_content_source_test.rb
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js
  • webpack/scenes/AlternateContentSources/helpers.js
✅ Files skipped from review due to trivial changes (13)
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • test/fixtures/models/katello_repositories.yml
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/tests/acsCreateDeb.test.js
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
🚧 Files skipped from review as they are similar to previous changes (8)
  • webpack/scenes/AlternateContentSources/helpers.js
  • test/fixtures/models/katello_alternate_content_sources.yml
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/services/katello/pulp3/api/apt.rb
  • test/models/katello/alternate_content_source_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb

Comment thread app/models/katello/alternate_content_source.rb Outdated
Comment thread app/services/katello/pulp3/alternate_content_source.rb
Comment thread test/controllers/api/v2/alternate_content_sources_controller_test.rb Outdated
@hstct
Copy link
Copy Markdown
Contributor Author

hstct commented Apr 20, 2026

alright should hopefully be good to go now

Copy link
Copy Markdown
Member

@ianballou ianballou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one issue, but otherwise this is working well! I think fixing it is optional for now, but should be taken care of down the road, ideally before this release gets out. Stabilization is in a couple of weeks. Let me know if you'd prefer to do it now or later. If later, then I'll finalize my review.

I've tested the feature via API and UI, covering the general CRUD operations that users would run through, and some corner cases around simplified ACSs and repo deletion.

Automated testing report for the curious: https://gist.github.com/ianballou/6171febdbb3f285a2a956696a2a5df80
I also hand-tested the feature via the UI.

Comment thread app/models/katello/alternate_content_source.rb Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/actions/pulp3/orchestration/alternate_content_source_create_test.rb (1)

63-70: Optional: add DEB PRN assertions for parity with yum/file tests.

test_yum_create and test_file_create verify both remote_prn and alternate_content_source_prn are present and match the expected prn:<type>:<uuid> shape. Adding the DEB equivalents would make this test equally effective at catching PRN regressions in the new Pulp v3 DEB path.

♻️ Proposed assertions
     def test_deb_create
       ::Katello::Pulp3::AlternateContentSource.any_instance.stubs(:generate_backend_object_name).returns(`@deb_acs.name`)
       smart_proxy_acs = ::Katello::SmartProxyAlternateContentSource.create(alternate_content_source_id: `@deb_acs.id`, smart_proxy_id: `@primary.id`)
       ForemanTasks.sync_task(::Actions::Pulp3::Orchestration::AlternateContentSource::Create, smart_proxy_acs)
       assert_equal 1, `@deb_acs.smart_proxy_alternate_content_sources.count`
       assert `@deb_acs.smart_proxy_alternate_content_sources.first.remote_href.start_with`?('/pulp/api/v3/remotes/deb/apt/')
       assert `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_href.start_with`?('/pulp/api/v3/acs/deb/deb/')
+      assert_not_nil `@deb_acs.smart_proxy_alternate_content_sources.first.remote_prn`
+      assert_match(/^prn:deb\.aptremote:[0-9a-f\-]+$/, `@deb_acs.smart_proxy_alternate_content_sources.first.remote_prn`)
+      assert_not_nil `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_prn`
+      assert_match(/^prn:deb\.aptalternatecontentsource:[0-9a-f\-]+$/, `@deb_acs.smart_proxy_alternate_content_sources.first.alternate_content_source_prn`)
     end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/actions/pulp3/orchestration/alternate_content_source_create_test.rb`
around lines 63 - 70, Update test_deb_create to also assert the DEB PRNs like
the yum/file tests: after creating smart_proxy_acs and syncing, fetch the
created record via `@deb_acs.smart_proxy_alternate_content_sources.first` and add
assertions that its remote_prn and alternate_content_source_prn are present and
match the expected "prn:<type>:<uuid>" shape (use a regex similar to the other
tests, e.g. /^prn:[a-z]+:[0-9a-f-]+$/), referencing the test method
test_deb_create, the `@deb_acs` fixture and smart_proxy_alternate_content_sources
to locate where to add the checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/actions/pulp3/orchestration/alternate_content_source_create_test.rb`:
- Around line 63-70: Update test_deb_create to also assert the DEB PRNs like the
yum/file tests: after creating smart_proxy_acs and syncing, fetch the created
record via `@deb_acs.smart_proxy_alternate_content_sources.first` and add
assertions that its remote_prn and alternate_content_source_prn are present and
match the expected "prn:<type>:<uuid>" shape (use a regex similar to the other
tests, e.g. /^prn:[a-z]+:[0-9a-f-]+$/), referencing the test method
test_deb_create, the `@deb_acs` fixture and smart_proxy_alternate_content_sources
to locate where to add the checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 204b66eb-f524-4250-980c-020747e9c702

📥 Commits

Reviewing files that changed from the base of the PR and between af1f5aa and 456b3d9.

📒 Files selected for processing (32)
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb
  • app/services/katello/pulp3/alternate_content_source.rb
  • app/services/katello/pulp3/api/apt.rb
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/actions/pulp3/orchestration/alternate_content_source_create_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_delete_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/deb_sync_test.rb
  • test/controllers/api/v2/alternate_content_sources_controller_test.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/models/katello_repositories.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/apt_sync/sync_with_deb_acs.yml
  • test/models/katello/alternate_content_source_test.rb
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js
  • webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateDeb.test.js
  • webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js
  • webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js
  • webpack/scenes/AlternateContentSources/helpers.js
✅ Files skipped from review due to trivial changes (10)
  • test/fixtures/models/katello_repositories.yml
  • app/views/katello/api/v2/alternate_content_sources/base.json.rabl
  • db/migrate/20251110000001_add_deb_fields_to_acs.rb
  • test/fixtures/models/katello_alternate_content_sources.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/http_proxy_url_update_deb_acs.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_delete/deb_delete.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh_updates_remote.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_create/deb_create.yml
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_refresh/deb_refresh.yml
  • test/models/katello/alternate_content_source_test.rb
🚧 Files skipped from review as they are similar to previous changes (10)
  • webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js
  • webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js
  • app/services/katello/pulp3/smart_proxy_mirror_repository.rb
  • webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js
  • test/actions/pulp3/orchestration/alternate_content_source_update_test.rb
  • test/actions/pulp3/orchestration/alternate_content_source_refresh_test.rb
  • webpack/scenes/AlternateContentSources/Create/tests/acsCreateDeb.test.js
  • test/fixtures/vcr_cassettes/actions/pulp3/alternate_content_source_update/deb_update.yml
  • app/controllers/katello/api/v2/alternate_content_sources_controller.rb
  • app/models/katello/alternate_content_source.rb

Copy link
Copy Markdown
Member

@ianballou ianballou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ship this! Thanks!

Copy link
Copy Markdown
Contributor

@aidenfine aidenfine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good!

@m-bucher m-bucher merged commit 7a7d984 into Katello:master Apr 23, 2026
21 of 23 checks passed
@m-bucher m-bucher deleted the add-debian-acs branch April 23, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants