OpenLiberty / ci.maven

Maven plugins for managing Liberty profile servers #devops
Apache License 2.0
130 stars 91 forks source link

Enhance Liberty Maven Plugin for CI integration #739

Open scottkurz opened 4 years ago

scottkurz commented 4 years ago

Outside of dev mode, atm, it isn't straightforward to use the Liberty Maven Plugin to package up what is needed or run tests whether locally or automatically integrated with a CI pipeline. See examples below.

Need to look at ways to improve this so it becomes straightforward to package up what you need and run tests using Liberty Maven Plugin for integrating with a CI pipeline.

There are different potential solutions e.g. an all-in-one goal or a new option for dev mode. The ultimate solution should be natural to Maven users and easy for developers to use.


Consider potential for all-in-one goal for users without LMP goals bound for test build, Docker build

The user who does not inherit from the LMP parent POM or even bind the LMP goals into the build lifecycle (e.g. the "ideal POM" user) has to use several goals in order to run integration tests.

Two examples:

  1. The appsody java-openliberty stack here uses a command like:

    mvn clean liberty:create pre-integration-test liberty:install-feature liberty:start liberty:deploy failsafe:integration-test liberty:stop failsafe:verify

  2. The containerize guide WIP here from @gkwan-ibm has a similar sequence.

(A difference between the two is that the first example also copies dependencies into place - see #705, and also calls any goals bound to pre-integration-test).

Perhaps the "create" goal could do the part it does now (install server, create server and copy config over) plus the install-feature and deploy? Or maybe there are other ideas?

Note there's overlap between this and issues: https://github.com/OpenLiberty/ci.maven/issues/685 https://github.com/OpenLiberty/ci.maven/issues/667 (maybe we only need one, but I thought it was still helpful to write up the problem like this now.)

yeekangc commented 4 years ago

This issue should cover what is noted in #809 particularly the self-contained creation of a runnable jar.

scottkurz commented 4 years ago

One point on the command:

mvn clean liberty:create pre-integration-test liberty:install-feature liberty:start liberty:deploy failsafe:integration-test liberty:stop failsafe:verify

The reason for throwing the "pre-integration-test" phase in the middle of all those other goals is to reflect the fact that there might be some IT setup that our all-in-one-goals won't know about, because they require some type of app-specific setup, e.g. DB creation and population. This gives a phase to bind user-specific goals to.

I'm not saying this comment makes the solution any easier, just explaining the problem statement better.

scottkurz commented 4 years ago

@yeekangc @gkwan-ibm - what if we were to view this not as a whole separate goal but as a configuration of dev mode? E.g. what if I did: mvn -DquickTest liberty:dev which caused the whole dev mode sequence to get executed, generate UT and IT reports, and stop the server, and then propagate back the IT exit status (0 vs. non-0)?

gkwan-ibm commented 4 years ago

I remember liberty:dev already support -DhotTests but not exit the dev mode. Technically, I think it is not difficult for LMP to support, either mvn -DquickTest liberty:dev, mvn -DquickTest liberty:run, mvn liberty:verify, or whatever interface. I prefer the interface should be obvious and simple to users.

scottkurz commented 4 years ago

It's not just the command-line interface that should be simple, though, but also the goal binding to the "lifecycle" created by all-in-one goals.

This is not just an implementation detail. These goals are configured by users, so they are part of the "POM interface", so to speak. We already have an all-in-one goal in the 'run' goal and a different one in the 'dev' goal impl. So I'm suggesting maybe keep this number from growing if possible and re-use the existing dev goal, to make the plugin behavior easier to understand.

cherylking commented 4 years ago

I agree with @scottkurz. If we can achieve this through the existing dev goal, that is better than adding another all-in-one goal.

gkwan-ibm commented 4 years ago

As I am a user, I do not consider how the implementation will be, but I concern how the CLI make sense to me and what really be tested (the real packaged war at the apps directory or loose app app.war.xml, which make sense to the users?)

gkwan-ibm commented 4 years ago

if MST, use different approach

scottkurz commented 4 years ago

If you have a framework like MST/Testcontainers where you don't need a local install because you're running against Open Liberty in a container, you already have a simple approach (the most standard one): mvn verify. I don't think it's worth trying to squeeze both this use case and an all-in-one test use case into one invocation... ultimately this will still require understanding from users and I thinking adding one more abstraction would be yet one more new invention to understand.

gkwan-ibm commented 4 years ago

Yep, we studied MST and analyzed before. We agreed MST will use different approach. No need to consider MST in this issue.

yeekangc commented 3 years ago

@ericglau @sdaschner, any thoughts on the suggestion above to consider an option for dev mode to run tests in "headless" manner? To facilitate integration with automated test setup or CI pipeline. Even as a short hand for local runs.

yeekangc commented 3 years ago

Updated description to reflect the problems we want to solve per discussion with @NottyCode @gcharters.

Any solution should be natural to Maven users and should take into considerations what is typical/expected for a usual Maven lifecycle (e.g. mvn verify).

Additional user feedback on what is needed or will work will be useful too.

sdaschner commented 3 years ago

Hi there,

I like the approach of adding a "shortcut" of doing everything Liberty needs to do to run my app in one shot (I think we talked about this in the past).

From a cli perspective, I'd prefer a separate goal, simply because the lifecycle behaves differently to :dev (stops Liberty again), and if I understand it correctly, it also doesn't really run as "dev mode" (listen to live code changes and reload) from a user perspective. Probably not much difference implementation-wise, but I think it makes more sense when you read the commands.

scottkurz commented 3 years ago

From a cli perspective, I'd prefer a separate goal, simply because the lifecycle behaves differently to :dev (stops Liberty again), and if I understand it correctly, it also doesn't really run as "dev mode" (listen to live code changes and reload)

To keep the number of all-in-one goals to two, we could also add an option to the 'run' goal, e.g: mvn -DtestRun liberty:run

ericglau commented 3 years ago

Currently liberty:run and liberty:dev have two things in common: they are all-in-one goals, AND they keep the server running. If we introduce a flag that stops the server after tests are run, this seems to break the latter convention. Hence I think it makes more sense to have a separate goal.

scottkurz commented 3 years ago

If we think of these all-in-one goals as defining their own lifecycles (without defining a whole new packaging type or more advanced extension techniques), then my point is let's not create a third.

This design goal could be satisfied via a new liberty:test where a new TestMojo extends RunMojo, and we refrain from proliferating with yet another all-in-one-style "lifecycle". If that seems to be a better UI, I guess I'm OK with that.

I do think we should document more clearly exactly which goals are called in each of 'dev' and 'run/test' more clearly in our doc. You can tease out this info from the dev mode doc but it should be documented like a Maven lifecycle is documented.

It's worth noting too I think that this really isn't about what's "natural" to Maven users.. . a more advanced Maven user at least knows how to construct the correct binding of goals to phases along with the right command line to do something like this. It's really the non-power-user that needs this simplified experience more. The all-in-one goals aren't really useful within a lifecycle. It could be confusing to have a mix of lifecycle-friendly goals and non-lifecycle, all-in-one goals, in one plugin. (One more reason I like to limit the number).

gas-stocktrader commented 3 years ago

Currently to run integration tests in the CI mode I use the following Liberty plugin configuration: It allows me just do all (create server, install features, deploy app and run test) in one go via: mvn clean verify

           <!-- Enable liberty-maven plugin -->
            <plugin>
                <groupId>io.openliberty.tools</groupId>
                <artifactId>liberty-maven-plugin</artifactId>
                <version>3.3.4</version>
                <executions>
                  <execution>
                    <id>install-feature</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>create</goal>                        
                        <goal>install-feature</goal>
                    </goals>
                </execution>     
                <execution>
                    <id>start-server</id>
                    <phase>pre-integration-test</phase>
                    <goals> 
                        <goal>test-start</goal>
                        <goal>deploy</goal>
                    </goals>
                  </execution>
                  <execution>
                    <id>stop-server</id>
                    <phase>post-integration-test</phase>
                    <goals> <goal>test-stop</goal> </goals>
                  </execution>
                    </executions>
                    <configuration>
                        <stripVersion>true</stripVersion>
                    </configuration>                      
            </plugin>            
scottkurz commented 3 years ago

Another use case overlapping this one is if I just wanted to build a runnable JAR out of a WAR packaged project (for some reason).

I'd have to do something like:

mvn package liberty:create liberty:install-feature liberty:deploy liberty:package -Dinclude=runnable

Perhaps that's enough of a special case it shouldn't get lumped into this issue but possibly worth considering.

scottkurz commented 9 months ago

I think we should reconsider the idea of a "skipServerStart" parameter flag for the 'run' goal.

This has been open for 4 years now without progress, and this would be a trivial change to implement. It is a bit weird conceptually "do a run without the server start" ... like "hamburger, hold the meat" :) But IMOH, it seems more maintainable to parameterize the existing 'run' goal vs. creating yet another (third) all-in-one goal.

Though this is a bit of a tangent on an already somewhat long and complicated discussion, let me note that the more all-in-one goals we have too, the harder it is to maintain consistency. E.g. when we recently added the new 'skipInstallFeature' behavior to dev mode, we didn't add the same to 'run'. We probably discussed it at the time, but now a few months removed, I don't see why it should be any different and why it wouldn't apply the same to 'run'.

scottkurz commented 9 months ago

DXDI 2024-01-31 UPDATE:

In the meeting a modest preference was expressed for defining a third goal but as a very thin extension of the 'run' goal. This would allow reuse of the implementation and would be simple to understand (the doc could, e.g. largely just link to the 'run' goal).

Perhaps 'liberty:bootstrap' ? I'm sure we could consider other names.

The next step is probably just to prototype this.

dougbreaux commented 2 months ago

I so far can't find an incantation of this that works from my GitHub Actions build.

 mvn package liberty:install-feature liberty:deploy liberty:run liberty:package -Dinclude=runnable
...
Downloaded from central: https://repo.maven.apache.org/maven2/io/openliberty/openliberty-kernel/24.0.0.7/openliberty-kernel-24.0.0.7.zip (15 MB at 50 MB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.238 s
[INFO] Finished at: 2024-08-06T16:08:21Z
[INFO] ------------------------------------------------------------------------
Error:  Failed to execute goal io.openliberty.tools:liberty-maven-plugin:3.10.3:install-feature (default-cli) on project WebTest: CWWKM2121E: Missing pre-installed assembly directory: /runner/_work/saz-max-proxy-web-test/saz-max-proxy-web-test/target/liberty/wlp.

And

mvn liberty:run liberty:package -Dinclude=runnable

Seems to have never come back. I had to kill the job. I guess that makes sense, it started in the foreground...

Anyway, for now, I'm just looking for some sequence that will do the trick from GitHub Actions.

scottkurz commented 2 months ago

I so far can't find an incantation of this that works from my GitHub Actions build.

It looks like you missed the 'create' goal, so maybe:

mvn package liberty:create liberty:install-feature liberty:deploy liberty:package -Dinclude=runnable

dougbreaux commented 2 months ago

That seems to have done the trick, thanks.