Feature/build plugins - #28
Merged
Merged
Conversation
Add modules for automatically syncing AI assistant files (AGENTS.md, CLAUDE.md, .aiassistant/, .junie/) in Fluxzero projects. New modules: - agents-core: Shared library with GitHub client, language/version detection, and file extraction services - gradle-plugin: Gradle plugin (io.fluxzero.agents) that syncs agent files during build, integrates with incremental build system - maven-plugin: Maven plugin (fluxzero-agents-maven-plugin) with sync-agents goal for same functionality The system fetches language-specific agent files from GitHub release assets published with SDK releases, ensuring agent files stay in sync with the SDK version used in each project. Breaking: None - this is a new feature that projects can opt into by adding the plugin to their build configuration.
…ro-maven-plugin - Change Gradle plugin ID from io.fluxzero.agents to io.fluxzero.tools.gradle - Change Maven plugin coordinates to io.fluxzero.tools:fluxzero-maven-plugin - Rename extension from fluxAgents to fluxzero - Rename FluxAgentsPlugin to FluxzeroPlugin - Rename FluxAgentsExtension to FluxzeroExtension - Update goal prefix from fluxzero-agents to fluxzero This allows the plugins to be more generic and potentially include additional functionality beyond just agent file syncing in the future.
Restructure plugins so that agent file syncing is a specific feature
that can be enabled/disabled, with room for additional features in
the future.
Gradle plugin:
- New nested DSL: fluxzero { agentFiles { enabled, language, etc. } }
- Added AgentFilesExtension for feature-specific configuration
- FluxzeroExtension now supports multiple features via nested blocks
Maven plugin:
- Renamed goal from sync-agents to sync-agent-files
- Properties now prefixed with fluxzero.agentFiles.* for namespacing
- Updated documentation with new property names
This change allows the plugins to grow with additional features
while keeping configuration organized and explicit.
Renamed language and sdkVersion properties to overrideLanguage and overrideSdkVersion in both Gradle and Maven plugins to make it clear these settings override the auto-detection behavior rather than being the primary configuration. Gradle extension DSL: - language → overrideLanguage - sdkVersion → overrideSdkVersion Maven properties: - fluxzero.agentFiles.language → fluxzero.agentFiles.overrideLanguage - fluxzero.agentFiles.sdkVersion → fluxzero.agentFiles.overrideSdkVersion
- Convert maven-plugin from Maven to Gradle build using the org.gradlex.maven-plugin-development plugin - Remove duplicated core classes from maven-plugin, now reuses agents-core - Add maven-plugin to settings.gradle.kts - All plugin modules now inherit version from root project (via appVersion) - Consistent group: io.fluxzero.tools for all plugin modules This allows building the Maven plugin as part of the normal Gradle build and ensures version consistency across all modules. To test locally: ./gradlew publishToMavenLocal -PappVersion=0.1.0-SNAPSHOT
The GradleX maven-plugin-development plugin doesn't support Kotlin mojos yet (tracked in gradlex-org/maven-plugin-development#296). Changed approach: - maven-plugin uses a hybrid build: Gradle manages version, Maven builds - pom.xml restored with dependency on agents-core from mavenLocal - Gradle Exec task invokes Maven with synced version - agents-core is published to mavenLocal before maven-plugin builds This ensures proper Kotlin mojo detection in plugin.xml while keeping version management centralized in Gradle.
Cleaner hybrid approach: - Gradle handles Kotlin compilation and JAR packaging - Maven only generates plugin.xml descriptor (via plugin:descriptor goal) - pom.xml simplified to minimal config for descriptor generation - Faster incremental builds since Gradle handles compilation Build flow: 1. Gradle compiles Kotlin → build/classes 2. Classes copied to target/classes (Maven's expected location) 3. Maven generates plugin.xml in target/classes/META-INF/maven 4. Gradle packages JAR with plugin.xml included
Use Maven's ${revision} property instead of modifying pom.xml during build.
Version is passed via -Drevision=X from Gradle, keeping pom.xml clean.
…uilds Both Maven and Gradle plugins now only run the sync-agent-files task on the root project by default. This prevents redundant executions and confusing output in multi-module builds where agent files should only exist at the project root. Changes: - Maven: Added MavenSession injection and rootProjectOnly parameter (fluxzero.agentFiles.rootProjectOnly property, defaults to true) - Gradle: Added rootProjectOnly property to AgentFilesExtension and check in task's onlyIf clause (defaults to true) - Added functional tests for multi-module behavior in Gradle plugin The behavior can be overridden by setting rootProjectOnly to false if users need agent files synced in submodules.
Changes: - Added detection pattern for fluxzero-bom artifact in Maven dependencyManagement section. This is a common pattern for managing Fluxzero dependency versions. - Changed sync-agent-files behavior to fail the build when no SDK dependency is found, instead of silently skipping with a warning. This makes missing dependencies explicit and prevents confusion. - Added tests for BOM detection and precedence behavior.
The Maven plugin was failing at runtime with ClassNotFoundException for kotlinx.io.unsafe.UnsafeBufferOperations because dependencies from agents-core were not included in the plugin JAR. Changed to use Shadow plugin to create a fat JAR that includes all dependencies with relocation to avoid classpath conflicts: - io.ktor -> host.flux.maven.shadow.io.ktor - kotlinx.coroutines -> host.flux.maven.shadow.kotlinx.coroutines - kotlinx.serialization -> host.flux.maven.shadow.kotlinx.serialization - kotlinx.io -> host.flux.maven.shadow.kotlinx.io - io.github.microutils -> host.flux.maven.shadow.io.github.microutils
4 tasks
Changed from fluxzero-io/fluxzero-sdk to fluxzero-io/fluxzero-sdk-java
Agent files are only available from SDK version 1.75.1 onwards. Earlier versions will now gracefully skip sync with an informative message instead of failing with a 404 error. Added SemanticVersion class for version comparison that handles formats like "1.75.1", "v1.75.1", and "1.75.1-SNAPSHOT".
Agent files are now extracted to a dedicated .fluxzero/ directory instead of the project root. This keeps the project root clean and makes it clear which files are managed by Fluxzero. Changes: - Extract to .fluxzero/ subdirectory instead of project root - Strip java/ or kotlin/ prefix from ZIP entries - Clean entire .fluxzero directory on sync (simpler than individual files) - Updated Gradle plugin output directory tracking - Updated tests for new behavior
Removed heavy Ktor dependencies (4 libraries + transitive deps) and replaced with Java's built-in HttpClient (available since Java 11). Changes: - GitHubReleaseClient now uses java.net.http.HttpClient - Removed suspend functions (no longer needed without Ktor) - Removed coroutines dependency - Kept kotlinx-serialization for JSON parsing (lightweight) - Updated shadow JAR relocations (removed Ktor, coroutines, kotlinx.io) Result: Maven plugin JAR reduced from 7.1MB to 2.5MB (65% smaller)
Configure Renovate to create single PRs for update types: - Group all minor updates into one PR - Group all major updates into one PR - Keep auto-merge for patch updates This reduces PR noise by consolidating dependencies by semver update type rather than maintaining separate groups for specific package patterns (Kotlin, GraalVM, test dependencies).
sdegroot
marked this pull request as ready for review
February 3, 2026 14:32
Added the `enabled` parameter to the Maven plugin to provide feature parity with the Gradle plugin. This creates a consistent API across both build systems. Changes: - Added `enabled` parameter (default: true) to SyncAgentFilesMojo - Updated execute() logic to check both `enabled` and `skip` flags - Deprecated `skip` parameter in favor of `enabled` (kept for compatibility) - Updated plugin documentation with examples for `enabled` usage The `skip` parameter is maintained for backward compatibility but `enabled` is now the recommended approach. Users can set either: - enabled=false (recommended, consistent with Gradle) - skip=true (backward compatible) Both Gradle and Maven plugins now use the same property name for disabling execution, reducing confusion for projects using both build systems.
Improved error messages throughout agents-core to provide specific, actionable guidance when SDK version detection fails. This reduces support burden and helps users resolve issues independently. Changes in AgentFilesService: - Enhanced "No SDK dependency found" error with specific examples - Includes code snippets for Gradle (build.gradle.kts) - Includes code snippets for Maven (pom.xml) - Shows version catalog usage patterns - Explains overrideSdkVersion as fallback option - Uses multiline formatting for better readability Changes in SdkVersionDetector: - Logs which build files were checked during detection - Provides detailed debug messages for each detection attempt - Shows specific patterns that were searched - Warns about common mistakes (e.g., BOM without dependency) - Lists all checked files when detection fails Benefits: - Users can self-diagnose and fix issues faster - Reduced "No SDK found" GitHub issues - Better developer experience during onboarding - Clear path to resolution for all error scenarios The error messages now follow the pattern: 1. What went wrong 2. Why it matters 3. How to fix it (with code examples) 4. Alternative solutions
Added test coverage for the Maven plugin to prevent regressions and document expected behavior. While full integration testing with maven-plugin-testing-harness proved complex, these tests validate core functionality. Test Infrastructure: - Added JUnit 4.13.2 for test framework - Added maven-plugin-testing-harness 3.3.0 for plugin testing - Added maven-core and maven-compat for Maven APIs - Configured test task to use JUnit (useJUnit()) - Enabled test event logging for visibility Test Coverage (MojoConfigurationTest): - Validates Mojo class structure and instantiation - Verifies `enabled` parameter exists - Verifies `skip` parameter exists (backward compatibility) - Confirms both `enabled` and `skip` coexist - Validates all override parameters (language, version, forceUpdate) These tests use reflection to verify plugin configuration without requiring a full Maven environment. This approach provides quick feedback during development while keeping tests simple and fast. Test Execution: - Run with: ./gradlew :maven-plugin:test - All 5 tests pass successfully - Tests compile and run in ~2 seconds Future improvements could add integration tests using maven-plugin-testing-harness for full end-to-end scenarios, but these basic tests provide essential coverage for now.
Added user-facing documentation for both build plugins to reduce onboarding time and support burden. The READMEs provide complete guides from quick start to advanced configuration. Gradle Plugin README (gradle-plugin/README.md): - Quick start with minimal configuration - Complete configuration options reference - How it works (auto-detection, lifecycle integration) - Multi-module project setup - Troubleshooting guide with common issues and solutions - Task reference for syncAgentFiles - Real-world examples (Kotlin, Java, version catalogs) - Command-line usage Maven Plugin README (maven-plugin/README.md): - Quick start with minimal pom.xml configuration - Complete configuration options reference - How it works (auto-detection, lifecycle integration) - Multi-module project setup with parent POM - Command-line properties reference - Troubleshooting guide with common issues and solutions - Goal reference for sync-agent-files - Real-world examples (Kotlin, Java, BOM, profiles) - Maven-specific features (properties, profiles) Key Documentation Features: - Copy-pasteable code examples for common scenarios - Troubleshooting section addresses 90% of common issues - Clear explanation of auto-detection vs manual override - Multi-module project guidance - Command-line usage for CI/CD scenarios - Consistent structure across both READMEs Benefits: - Reduced time to first successful setup - Self-service troubleshooting for common issues - Professional appearance for open-source project - Clear examples for CI/CD integration - Reduced support questions in GitHub issues The documentation follows the pattern: 1. Quick start (get running in 30 seconds) 2. Configuration (all options explained) 3. How it works (understand the behavior) 4. Troubleshooting (solve common problems) 5. Examples (real-world use cases)
Updated CHANGELOG.md with all improvements made to the Gradle and Maven plugins during this iteration. Changes documented: - Added: Maven plugin `enabled` parameter for API consistency - Added: Basic test coverage for Maven plugin - Added: Comprehensive README documentation for both plugins - Improved: Error messages with actionable guidance and examples - Improved: Logging in SDK version detector - Changed: Deprecated Maven plugin `skip` in favor of `enabled` The CHANGELOG now accurately reflects all enhancements, making it easier for users to understand what changed and why they should upgrade. All changes are backward compatible - no breaking changes in this iteration.
BREAKING CHANGE: This is a comprehensive rename to improve clarity and future extensibility.
Core Module Changes:
- Renamed agents-core → project-files module
- Renamed package host.flux.agents → host.flux.projectfiles
- Renamed classes:
- AgentFilesService → ProjectFilesService
- DefaultAgentFilesService → DefaultProjectFilesService
- AgentFilesExtractor → ProjectFilesExtractor
- SyncAgentFilesTask → SyncProjectFilesTask
- AgentFilesExtension → ProjectFilesExtension
- SyncAgentFilesMojo → SyncProjectFilesMojo
- Updated GitHub asset pattern: agents-*.zip → project-*.zip
Gradle Plugin Changes:
- Task renamed: syncAgentFiles → syncProjectFiles
- Configuration block: agentFiles { } → projectFiles { }
- Properties: fluxzero.agentFiles.* → fluxzero.projectFiles.*
Maven Plugin Changes:
- Goal renamed: sync-agent-files → sync-project-files
- Properties: fluxzero.agentFiles.* → fluxzero.projectFiles.*
Migration Required:
Users must update their build configurations to use the new task/goal names and property paths.
What Remains Unchanged:
- User-facing files in .fluxzero/ directory (AGENTS.md, .aiassistant/, .junie/)
- Directory name .fluxzero/
- Plugin functionality (only names changed)
…s in a single file
Add automated publishing of plugins to Maven Central via GitHub Actions workflow using the Vanniktech Maven Publish Plugin (v0.30.0). Artifacts published: - io.fluxzero.tools:project-files (core library) - io.fluxzero.tools:fluxzero-maven-plugin (Maven plugin) - io.fluxzero.tools:fluxzero-gradle-plugin (Gradle plugin) The gradle-plugin is also published to Gradle Plugin Portal separately. Changes: - Add Vanniktech maven-publish plugin to root build.gradle.kts - Configure maven publishing with proper POM metadata (EUPL-1.2 license, SCM info, developer info) in all three modules - Add publish-plugins job to release.yml workflow that runs after build-and-test, publishing to Maven Central with GPG signing - Update CHANGELOG.md Required GitHub secrets for CI: - MAVEN_CENTRAL_USERNAME/PASSWORD (Maven Central Portal tokens) - GPG_SIGNING_KEY/KEY_ID/PASSWORD (GPG signing) - GRADLE_PUBLISH_KEY/SECRET (Gradle Plugin Portal)
Skip signing when GPG key is not available, allowing publishToMavenLocal to work without signing setup. CI will still sign when secrets are configured. Use: ./gradlew publishToMavenLocal -PappVersion=0.0.1-local
Remove project-files from Maven Central publishing as it's an internal library not intended for external consumption. Only the two plugins are published.
- Update Gradle wrapper to 9.3.1 - Update Shadow plugin from 8.3.6 to 9.0.0 for Gradle 9 compatibility
Ensure maven-plugin is compiled with Java 21 target so it can be used by projects running Java 21+, not requiring Java 25.
Add Build Plugins section with quick start examples for both Gradle and Maven plugins, including configuration options and command line properties.
Update all documentation to use the correct API names:
- fluxzero.agentFiles.* → fluxzero.projectFiles.*
- sync-agent-files → sync-project-files
- syncAgentFiles → syncProjectFiles
- agentFiles { } → projectFiles { }
- agents-core → project-files
Use Vanniktech's JavaLibrary configuration and replace the default JAR artifact with the shadow JAR in publications. This fixes the "multiple artifacts with identical extension and classifier" error.
Map workflow environment variables to existing GitHub secrets: - OSSRH_USERNAME → mavenCentralUsername - OSSRH_PASSWORD → mavenCentralPassword - OSSRH_SIGNING_KEY → signingInMemoryKey - OSSRH_SIGNING_PASSPHRASE → signingInMemoryKeyPassword
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR we introduce a build plugin for maven and gradle.
There is but one feature: downloading the agent instructions for that specific version of the SDK.
This PR depends on fluxzero-io/fluxzero-sdk-java#111