gnodet-bot commented on code in PR #13775:
URL: https://github.com/apache/maven/pull/13775#discussion_r4443108012


##########
src/site/markdown/aggregator-migration.md:
##########
@@ -0,0 +1,306 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Migrating Aggregator Mojos to Lifecycle Ordering
+
+This guide helps Maven plugin authors evaluate whether a Mojo using
+`aggregator = true` or lifecycle forking should migrate to lifecycle
+ordering with `@After` and phases such as `after:all`.
+
+**Important:** `aggregator = true`, lifecycle forking, and lifecycle ordering
+serve different purposes. They are not interchangeable. Choose the migration
+based on the behavior the plugin requires.
+
+> **Warning:** The Maven 4 APIs discussed in this guide, including
+> `@Mojo`, `@After`, `@Resolution`, and `@Execute`, are marked
+> `@Experimental`. Their contracts may change or the APIs may be
+> removed without notice. Plugin authors should take this into
+> account before adopting them in production plugins.
+
+## 1. Understand the existing behavior
+
+A legacy Mojo may declare itself as an aggregator:
+
+```java
+import org.apache.maven.plugins.annotations.Mojo;
+
+@Mojo(name = "report", aggregator = true)
+public class ReportMojo {
+    // ...
+}
+```
+
+Aggregator status affects how a goal operates in a multi-project build.
+It does not, by itself, express a precise ordering dependency on another
+lifecycle phase.
+
+Some legacy Mojos also use `@Execute` to request execution of another
+goal or lifecycle phase. This introduces lifecycle-forking behavior that
+must be considered separately when migrating.
+
+Before changing an annotation, identify whether the Mojo needs to:
+
+- Run once for a multi-project build rather than once per project.
+- Run after a particular lifecycle phase has completed.
+- Access information or dependencies from other projects.
+- Fork another lifecycle or goal before executing its own work.
+
+These requirements are distinct and may require different solutions.
+
+### Direct migration to the Maven 4 `@Mojo` annotation
+
+Maven 4 provides its own `@Mojo` annotation in
+`org.apache.maven.api.plugin.annotations`. It retains the
+`aggregator` attribute.
+
+If a plugin needs to preserve its existing aggregator behavior while
+adopting the Maven 4 annotation, it can retain `aggregator = true`:
+
+```java
+import org.apache.maven.api.plugin.annotations.Mojo;
+
+@Mojo(name = "report", aggregator = true)
+public class ReportMojo {
+    // ...
+}
+```
+
+This is the direct annotation migration path. The Maven 4 `aggregator`
+attribute identifies a Mojo that uses the Maven project and its
+subprojects.
+
+However, retaining `aggregator = true` does not express a specific
+lifecycle-ordering relationship. If the plugin requires execution
+after a particular phase or after the entire reactor, consider the
+lifecycle-ordering mechanisms described below.
+
+## 2. Express lifecycle ordering with `@After`
+
+The Maven API provides the `@After` annotation to express that a Mojo
+must run after a specified lifecycle phase.
+
+For example:
+
+```java
+import org.apache.maven.api.plugin.annotations.After;
+import org.apache.maven.api.plugin.annotations.Mojo;
+
+@Mojo(name = "report")
+@After(phase = "resources")
+public class ReportMojo {
+    // ...
+}
+```
+
+This declares an ordering constraint relative to the `resources` phase.
+It does not, on its own, make the Mojo an aggregator or guarantee that it
+runs only once for the entire reactor.
+
+The `@After` annotation is repeatable. A Mojo can declare multiple
+ordering constraints when it must run after more than one phase:
+
+```java
+@Mojo(name = "report")
+@After(phase = "compile")
+@After(phase = "test-compile")
+public class ReportMojo {
+    // ...
+}
+```
+
+The annotation also supports an ordering type:
+
+```java
+@After(phase = "package", type = After.Type.PROJECT)
+```
+
+The available types are:
+
+- `PROJECT`: expresses an ordering relationship for a project.
+- `DEPENDENCIES`: expresses an ordering relationship involving dependencies.
+- `CHILDREN`: expresses an ordering relationship involving child projects.
+
+For dependency ordering, `scope` can further describe the dependency scope:
+
+```java
+@After(
+    phase = "ready",
+    type = After.Type.DEPENDENCIES,
+    scope = "compile"
+)
+```
+
+Use the actual phases and relationship required by your plugin. Verify the
+supported phase names and ordering semantics against the Maven version
+your plugin targets.
+
+## 3. Run a Mojo after the entire reactor with `after:all`
+
+Maven 4 introduces additional lifecycle phases, including `all`,
+`each`, `before:all`, `after:all`, `before:each`, and `after:each`.
+
+The `after:all` phase runs at the end of a project's build. In a
+multi-project build, the `after:all` phases of child projects run
+before the `after:all` phase of their parent project.
+
+This allows a goal bound to `after:all` in the root project to execute
+after the child projects have completed their builds.
+
+For example, bind a goal to `after:all` in the root POM:
+
+```xml
+<plugin>
+  <groupId>org.example</groupId>
+  <artifactId>example-maven-plugin</artifactId>
+  <version>1.0.0</version>
+  <inherited>false</inherited>
+  <executions>
+    <execution>
+      <id>final-report</id>
+      <phase>after:all</phase>
+      <goals>
+        <goal>report</goal>
+      </goals>
+    </execution>
+  </executions>
+</plugin>
+```
+
+Replace the plugin coordinates and goal name with the actual values
+for your plugin.
+
+The `<inherited>false</inherited>` setting prevents the plugin
+configuration from being inherited by child projects. When the
+execution is declared only in the root POM, this allows the goal to
+run at the root project's `after:all` phase after the child projects
+have completed.
+
+Do not assume that binding a goal to `after:all` automatically
+preserves every behavior of a legacy aggregator Mojo. Check how the
+goal is scheduled, how often it executes, and what project and session
+information it receives.
+
+Also distinguish `after:all` from `after:<phase>`. Use `after:all`
+when the goal needs to run after the complete project hierarchy has
+finished its build. Use a phase-specific ordering constraint when
+the goal only needs to wait for a particular phase.
+
+## 4. Review dependency resolution
+
+Maven provides the experimental `@Resolution` annotation for declaring
+dependency resolution requirements on a Mojo field. It has been available
+since Maven 4.0.0.
+
+For example, a Mojo that needs resolved dependency paths can declare:
+
+```java
+import java.nio.file.Path;
+import java.util.List;
+
+import org.apache.maven.api.plugin.annotations.Resolution;
+
+@Resolution(
+    pathScope = "compile",

Review Comment:
   ❌ **Bug: invalid `pathScope` value.**
   
   `"compile"` is not a registered `PathScope` ID. The only valid IDs are:
   - `"main-compile"` (`PathScope.MAIN_COMPILE`)
   - `"main-runtime"` (`PathScope.MAIN_RUNTIME`)
   - `"test-compile"` (`PathScope.TEST_COMPILE`)
   - `"test-runtime"` (`PathScope.TEST_RUNTIME`)
   
   At runtime, `DefaultMavenPluginManager` calls 
`PathScopeRegistry.require(pathScope)`, which throws on an unrecognised ID. 
Plugin authors who copy-paste this example will get a hard runtime error.
   
   ```suggestion
       pathScope = "main-compile",
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to