Skip to content

Conversation

@VGoncharova
Copy link
Contributor

No description provided.

…n and restoration logic, refine handling of plugin and non-plugin samples
@coderabbitai
Copy link

coderabbitai bot commented Oct 30, 2025

Walkthrough

Introduces EapRepositoryConfig and replaces inline EAP repository/settings generation with generated content; refactors sample settings helpers to createEAPSampleSettings/restoreEAPSampleSettings, updates buildEAPGradleSample/buildEAPGradlePluginSample to use new flows, and adds env-driven Ktor Gradle plugin handling in the init script.

Changes

Cohort / File(s) Summary
EAP sample build & settings refactor
\.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt
Added public object EapRepositoryConfig (constants KTOR_EAP_URL, COMPOSE_DEV_URL and generators: generateGradleRepositories, generateGradlePluginRepositories, generateMavenRepository, generateSettingsContent). Reworked init script to use generated repo blocks and to optionally fetch/use KTOR_GRADLE_PLUGIN_VERSION via USE_LATEST_KTOR_GRADLE_PLUGIN.
Settings create/restore API
\.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt
Replaced createPluginSampleSettings/restorePluginSampleSettings with createEAPSampleSettings(samplePath: String, isPluginSample: Boolean) and restoreEAPSampleSettings(samplePath: String). Settings now written atomically to samplePath/settings.gradle.kts and restored from backups when present.
Build step wiring & call sites
\.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt
Updated buildEAPGradleSample and buildEAPGradlePluginSample to compute samplePath/wrapperPath, set workingDir and gradleWrapperPath, and to call createEAPSampleSettings(..., isPluginSample) and restoreEAPSampleSettings(...) conditionally (standalone vs non-standalone). Updated logging/messages and removed legacy plugin/sample setting references.
Maven/EAP repo injection
\.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt
Maven EAP sample repository content now produced via EapRepositoryConfig.generateMavenRepository() rather than inline literals.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify new public EapRepositoryConfig functions for correct generated strings (repositories, pluginManagement, settings).
  • Check all updated call sites for correct samplePath/wrapperPath computation and isPluginSample flag usage.
  • Review atomic write/restore logic for settings files and backup cleanup.
  • Inspect init-script changes that set/use KTOR_GRADLE_PLUGIN_VERSION and logging.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive No pull request description was provided by the author, making it impossible to evaluate whether the description is related to, unrelated to, or vague about the changeset. The check instructions do not explicitly address how to handle missing descriptions, and while they specify the check is "very lenient," they also require that descriptions be "related in some way to the changeset" for a pass. Without any description content to evaluate against these criteria, a definitive assessment cannot be made.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "update Ktor EAP trigger settings: consolidate sample settings creation and restoration logic, refine handling of plugin and non-plugin samples" directly relates to the main changes in the changeset. The title accurately captures the primary objectives: consolidating and refining the sample settings creation and restoration logic, which aligns with the introduction of the EapRepositoryConfig object, the refactored function signatures (createEAPSampleSettings, restoreEAPSampleSettings), and the updated build step logic for handling both plugin and non-plugin samples. The title is clear, specific, and concise enough to communicate the main change to reviewers scanning the history.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch vgoncharova/ktor-train

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5d13f0 and 50302f2.

📒 Files selected for processing (1)
  • .teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (4 hunks)
🔇 Additional comments (7)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (7)

18-83: Excellent abstraction of EAP repository configuration.

The EapRepositoryConfig object provides a clean, centralized way to generate repository and settings content. The conditional plugin resolution strategy (lines 66-77) appropriately handles the io.ktor.plugin version override for plugin samples while keeping non-plugin samples simpler.


90-159: Well-integrated init script with proper error handling.

The init script correctly uses EapRepositoryConfig.generateGradleRepositories() and includes robust plugin version fetching with timeouts, retries, and fallbacks. The logging statements provide good visibility into the EAP configuration being applied.


161-205: Robust atomic file operations with proper error handling.

The function uses a solid atomic write pattern with temporary files, backups, and rollback on failure. The process-ID-based naming (line 169) ensures uniqueness across concurrent builds.

Minor observation: The trap cleanup at line 174 attempts to remove files that may have already been moved, but since rm -f doesn't error on missing files, this is safe and provides defense-in-depth cleanup.


207-240: Defensive restore logic handles multiple backup scenarios.

The two-tier backup search (process-specific first at line 219, then generic at line 226) provides resilience across different execution contexts. The fallback to removing temporary settings when no backup exists (line 235) correctly handles new file creation scenarios.


242-262: Clean integration with new settings management functions.

The path computation logic (lines 244-245) correctly handles standalone vs. non-standalone samples, and the conditional calls to createEAPSampleSettings and restoreEAPSampleSettings ensure settings are only manipulated when necessary.


264-284: Correct plugin sample handling with appropriate path structure.

The function properly computes paths for plugin samples (line 266: samples/$relativeDir) and passes isPluginSample=true (line 269) to enable the Gradle plugin version resolution strategy in the generated settings.


286-321: Consistent Maven integration with EapRepositoryConfig.

The function correctly uses EapRepositoryConfig.generateMavenRepository() to generate the Maven repository configuration, maintaining consistency with the Gradle-based sample handling.


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

@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: 2

🧹 Nitpick comments (1)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (1)

146-206: Consider refactoring duplicated pluginManagement blocks.

The pluginManagement repository configuration is nearly identical between plugin samples (lines 146-170) and regular samples (lines 193-206), with the only difference being the resolutionStrategy block for plugin samples. This duplication increases maintenance burden.

Consider extracting the common repository configuration into a variable or function to reduce duplication:

+            # Common plugin management repos
+            PLUGIN_REPOS='
+    repositories {
+        maven {
+            name = "KtorEAP"  
+            url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
+            content {
+                includeGroup("io.ktor")
+            }
+        }
+        gradlePluginPortal()
+        mavenCentral()
+        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
+    }'
+            
             # Create settings based on sample type
             if [ "$isPluginSample" = "true" ]; then
                 # Plugin samples need build-logic and plugin includes
                 cat > "${'$'}{SETTINGS_FILE}" << 'EOF'
 ...
 pluginManagement {
-    repositories {
-        maven {
-            name = "KtorEAP"  
-            url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
-            content {
-                includeGroup("io.ktor")
-            }
-        }
-        gradlePluginPortal()
-        mavenCentral()
-        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-    }
+EOF
+                echo "$PLUGIN_REPOS" >> "${'$'}{SETTINGS_FILE}"
+                cat >> "${'$'}{SETTINGS_FILE}" << 'EOF'
     
     resolutionStrategy {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89bb7b9 and 4499426.

📒 Files selected for processing (1)
  • .teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (5 hunks)
🔇 Additional comments (5)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (5)

24-103: LGTM! Robust version fetching with proper fallbacks.

The init script creation handles plugin version fetching with appropriate error handling, timeouts, and a sed fallback when jq is unavailable. The Gradle init script properly enforces EAP versions and provides clear logging.


215-236: LGTM! Clean restoration logic.

The backup restoration logic is simple and correct, properly handling both the backup-exists and no-backup cases.


264-288: LGTM! Correct path handling for plugin samples.

The function correctly adjusts paths for the plugin sample directory structure (adding "samples/" prefix and using "../.." for wrapper path). The same empty string concern from buildEAPGradleSample applies here for standalone mode.


105-288: Well-structured refactoring improves clarity.

The consolidation from separate plugin-specific functions to parameterized EAP functions with the isPluginSample flag is a clean design that reduces code duplication while maintaining clear separation between plugin and regular sample configurations. The removal of the standalone parameter from restoreEAPSampleSettings is appropriate since the path information is sufficient for restoration.


241-253: No issue found — code is correct.

TeamCity's Kotlin DSL accepts empty strings for workingDir and gradleWrapperPath—an empty workingDir uses the default/checkout directory, and an empty gradleWrapperPath uses standard wrapper behavior. The code in lines 241-253 correctly leverages this behavior when standalone=true, so no changes are needed.

Copy link

@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: 0

Caution

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

⚠️ Outside diff range comments (1)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (1)

105-204: Consider consolidating the duplicated settings generation logic.

The plugin and regular sample branches generate nearly identical settings.gradle.kts content. The only difference is the plugin resolution strategy block (lines 154-163). This duplication means repository configurations must be maintained in two places, increasing the risk of inconsistency.

Consider refactoring to generate the common parts once, then conditionally append the plugin-specific resolution strategy:

-            # Create settings based on sample type
-            if [ "$isPluginSample" = "true" ]; then
-                # Plugin samples need build-logic and plugin includes
-                cat > "${'$'}{SETTINGS_FILE}" << 'EOF'
+            # Create base settings content
+            cat > "${'$'}{SETTINGS_FILE}" << 'EOF'
 dependencyResolutionManagement {
     repositories {
         maven {
             name = "KtorEAP"
             url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
             content {
                 includeGroup("io.ktor")
             }
         }
         google()
         mavenCentral()
         maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
     }
 }
 
 pluginManagement {
     repositories {
         maven {
             name = "KtorEAP"  
             url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
             content {
                 includeGroup("io.ktor")
             }
         }
         gradlePluginPortal()
         mavenCentral()
         maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
     }
-    
+EOF
+            
+            # Add plugin-specific resolution strategy if needed
+            if [ "$isPluginSample" = "true" ]; then
+                cat >> "${'$'}{SETTINGS_FILE}" << 'EOF'
+    
     resolutionStrategy {
         eachPlugin {
             if (requested.id.id == "io.ktor.plugin") {
                 val pluginVersion = System.getenv("KTOR_GRADLE_PLUGIN_VERSION")
                 if (pluginVersion != null && pluginVersion.isNotEmpty()) {
                     useVersion(pluginVersion)
                 }
             }
         }
     }
-}
 EOF
-            else
-                # Regular samples - simpler setup
-                cat > "${'$'}{SETTINGS_FILE}" << 'EOF'
-dependencyResolutionManagement {
-    repositories {
-        maven {
-            name = "KtorEAP"
-            url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
-            content {
-                includeGroup("io.ktor")
-            }
-        }
-        google()
-        mavenCentral()
-        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-    }
-}
-
-pluginManagement {
-    repositories {
-        maven {
-            name = "KtorEAP"  
-            url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
-            content {
-                includeGroup("io.ktor")
-            }
-        }
-        gradlePluginPortal()
-        mavenCentral()
-        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-    }
+            fi
+            
+            # Close pluginManagement block
+            cat >> "${'$'}{SETTINGS_FILE}" << 'EOF'
 }
 EOF
-            fi
🧹 Nitpick comments (2)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (2)

229-253: Consider clarifying the empty string assignments for standalone builds.

When standalone is true, both samplePath and wrapperPath are set to empty strings. While this likely relies on TeamCity's default behavior (empty workingDir uses checkout root, empty gradleWrapperPath uses default wrapper), the intent could be made more explicit with a brief comment.

Consider adding a comment to document the intended behavior:

     val samplePath = if (!standalone) relativeDir else ""
     val wrapperPath = if (!standalone) ".." else ""
+    // For standalone builds, empty strings tell TeamCity to use checkout root and default wrapper location

255-279: Consider clarifying the empty string assignments for standalone builds.

Similar to buildEAPGradleSample, when standalone is true, both samplePath and wrapperPath are set to empty strings. A clarifying comment would make the intent explicit.

Consider adding the same documentation as suggested for buildEAPGradleSample:

     val samplePath = if (!standalone) "samples/$relativeDir" else ""
     val wrapperPath = if (!standalone) "../.." else ""
+    // For standalone builds, empty strings tell TeamCity to use checkout root and default wrapper location
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad934aa and d5d13f0.

📒 Files selected for processing (1)
  • .teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (4 hunks)
🔇 Additional comments (2)
.teamcity/src/subprojects/train/TriggerProjectSamplesOnEAP.kt (2)

24-103: LGTM! Well-structured init script with proper error handling.

The function correctly handles fetching the latest Ktor Gradle Plugin version with appropriate timeouts and retries, and the init script properly forces EAP versions with clear error messages when KTOR_VERSION is missing.


206-227: LGTM! Clean restoration logic.

The function properly handles both scenarios (restoring from backup or removing temporary file) with clear logging.

…on logic and streamline sample settings creation
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.

2 participants