Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add goal that works with Maven CI Friendly Versions and set property (revision) based on git tag #1071

Open
jimisola opened this issue Apr 24, 2024 · 9 comments

Comments

@jimisola
Copy link

jimisola commented Apr 24, 2024

Maven supports Maven CI Friendly Versions since version 3.5.

It allows the user to set a placeholder

<version>${revision}</version>

that can be replaced from command line using:

e.g.

mvn -Drevision=1.0.0-SNAPSHOT clean package
Our use-case is that you want this revision property (can be configurable) to be set by a Maven plugin using tag information from the scm (typically, git).

The revision property should be set as follows:

note: will be set to variants of nr of commits

  1. if no tags in repo: set to 0.0.1- (e.g. 0.0.1-23) (left-padded due to Maven bug comparing qualifer as a string)
  2. if tags exist
    1. if latest commit is tagged (assume a release): set revision to tag (e.g. 1.0.1)
    2. if it is a previous tag: use the tag, bump patch level, set build number to and add <-SNAPSHOT> (e.g. 0.5.1 -> 0.5.2--SNAPSHOT

That is the basics. I was contemplating writing a plugin for it, but we'll rather so it incorporated in into this plugin.

Build number will be handled correctly by Maven as can be seen here:

java -jar ${MAVEN_HOME}/lib/maven-artifact-3.9.6.jar 1.1 1.2.1-1 1.2.1-1-SNAPSHOT 1.2.1-9 1.3
Display parameters as parsed by Maven (in canonical form and as a list of tokens) and comparison result:
1. 1.1 -> 1.1; tokens: [1, 1]
   1.1 < 1.2.1-1
2. 1.2.1-1 -> 1.2.1-1; tokens: [1, 2, 1, [1]]
   1.2.1-1 > 1.2.1-1-SNAPSHOT
3. 1.2.1-1-SNAPSHOT -> 1.2.1-1-snapshot; tokens: [1, 2, 1, [1, [snapshot]]]
   1.2.1-1-SNAPSHOT < 1.2.1-9
4. 1.2.1-9 -> 1.2.1-9; tokens: [1, 2, 1, [9]]
   1.2.1-9 < 1.3
5. 1.3 -> 1.3; tokens: [1, 3]
@lfvjimisola
Copy link

Would you approve a PR with this functionality?

@olamy
Copy link
Member

olamy commented May 14, 2024

maybe you should use an extension for this rather than a plugin.

https://maven.apache.org/examples/maven-3-lifecycle-extensions.html

@lfvjimisola
Copy link

Ended up creating our own plugin. Could use Maven SCM API and it did feel right to add the JGit dependency.

We haven't published it yet, so we could potentially provide it as an extension but probably need some guidance then.

Also, we are in need of this now really and I'm not sure how long it would take for a PR and a release to happen.

@slawekjaranowski
Copy link
Member

Ended up creating our own plugin. Could use Maven SCM API and it did feel right to add the JGit dependency.

Your code with JGit looks simple, Maven SCM Api add support for others tools - I will try with it.
But if it will be complicated we can start with JGit 😄

We haven't published it yet, so we could potentially provide it as an extension but probably need some guidance then.

As next goal will be easier than extension.

Also, we are in need of this now really and I'm not sure how long it would take for a PR and a release to happen.

Release can happen in a few days after merge.

I watch a repository and when we have new feature or bug fix I will simply release.
Now we have for next release: https://github.com/mojohaus/versions/milestone/17?closed=1
Last release was in November ... so it will be good time for next one.

@lfvjimisola
Copy link

lfvjimisola commented May 16, 2024

@slawekjaranowski I tried with Maven SCM API, but it seemed like it was to simple for this use-case. Could be that I missed out on something. I reckon it might will be configurable later on how the git repo should be traversed from the starting commit (branch only etc), so for flexibility I'd prefer JGit.

You wrote "I will try with it". Was that as in you or a suggestion for me?

As next goal will be easier than extension.

Not following here either.
What do you mean with as next goal? Do you mean that creating a goal is favorable over an extension?
It seems to me that a new regular goal is a better option.

We would rather see this feature incorporated in the Versions Maven plugin as it involves versioning of POMs but with another angle, i.e. instead of changing the actual POM.xml once uses CI/CD and tags.

I'm a bit stressed for time now (3 weeks since I wrote here) and we need this feature asap.
That said, I'm willing to provide an initial PR if I can get some help to get it through 🙏
E.g. I'm not sure what would be the best way to write tests since we need a git repostory for that (would git-bundle be an option?).

As for our code we will donate it without any copyright claims or what not.

However, the plugin contains a modified (VersionInformation) of code that is copyrighted by Karl Heinz Marbaise under MIT License for mojohaus. Is there a solution to this (licenses are MIT for build-helper and Apache 2.0 for Versions)?

@slawekjaranowski
Copy link
Member

@slawekjaranowski I tried with Maven SCM API, but it seemed like it was to simple for this use-case. Could be that I missed out on something. I reckon it might will be configurable later on how the git repo should be traversed from the starting commit (branch only etc), so for flexibility I'd prefer JGit.

You wrote "I will try with it". Was that as in you or a suggestion for me?

Suggestion for you 😄

As next goal will be easier than extension.

Not following here either. What do you mean with as next goal? Do you mean that creating a goal is favorable over an extension? It seems to me that a new regular goal is a better option.

I think about new goal.

We would rather see this feature incorporated in the Versions Maven plugin as it involves versioning of POMs but with another angle, i.e. instead of changing the actual POM.xml once uses CI/CD and tags.

I'm a bit stressed for time now (3 weeks since I wrote here) and we need this feature asap.

It is open source project maintained by volunteers in their free time, so I can not give you any promise about timelines.

That said, I'm willing to provide an initial PR if I can get some help to get it through 🙏 E.g. I'm not sure what would be the best way to write tests since we need a git repostory for that (would git-bundle be an option?).

We use maven-invoker-plugin for IT test, there are possibility to use pre - setup and post - verify script
I suggest to try preparing testing repo in pre script

As for our code we will donate it without any copyright claims or what not.

However, the plugin contains a modified (VersionInformation) of code that is copyrighted by Karl Heinz Marbaise under MIT License for mojohaus. Is there a solution to this (licenses are MIT for build-helper and Apache 2.0 for Versions)?

We can copy as is with preserving license header .... or change @khmarbaise what do you think

@lfvjimisola
Copy link

lfvjimisola commented May 17, 2024

  1. Ok. Suggestion understood ;)
  2. A new goal it is.
  3. I did not imply that we expected some else to get this feature asap. I'm simply stating that we have a plugin that will work for us for now. I've been involved off and on in open source for 20 years or so and fully understand the volunteer aspect. We all do what we can with the time that we have. I've seen how active you are in the Maven community.
  4. Ok. When I have the time I'll look into maven-invoker-plugin for IT then. Thanks.

@lfvjimisola
Copy link

lfvjimisola commented May 23, 2024

@slawekjaranowski Would it be possible to elaborate a little moe on how to use the maven invoker plugin for testing with git repos?

I'm looking at e.g. it-823-ranges-update-report-001 and it-set-scm-tag-004 but it's not clear to me how I use maven invoker plugin to either use a pre-set git repository or to create on of the fly. This in order to have test data.

I'm thinking that I need to use JGit to setup and then regular JUnit.

I honestly think that testing Maven plugin is a mess. Shall I use the maven-plugin-testing-harness even?

@slawekjaranowski
Copy link
Member

With invoker, create a file: selector.groovy with content like:

try {
    // smoke test if we have a needed tools
    def gitVersion = "git --version".execute()
    gitVersion.consumeProcessOutput(System.out, System.out)
    gitVersion.waitFor()
    return gitVersion.exitValue() == 0
} catch (Exception e) {
    // some error occurs - we skip a test
    return false
}

if git will not available on system test will be skipped

next you create: setup.groovy, with content like:

void exec(String command) {
    def proc = command.execute(null, basedir)
    proc.consumeProcessOutput(System.out, System.out)
    proc.waitFor()
    assert proc.exitValue() == 0 : "command '${command}' return status: " + proc.exitValue()
}

def testFile = new File(basedir, 'test.txt')
testFile << 'content'

exec('git init')
exec('git add test.txt')
exec('git status')
exec('git commit -m first-commit')
exec('git tag first-tag')

and finally create a verify.groovy to check result

you can execute only one test by:

mvn verify -P run-its -pl versions-maven-plugin -DskipTests -Dinvoker.test=test-name

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

No branches or pull requests

4 participants