Skip to content

Simplify Gradle build logic for making releases. #700

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

blackwinter
Copy link
Member

@blackwinter blackwinter commented Jun 24, 2025

Resolves #684.

Release and release candidate builds require a clean working directory and a matching tag: Create a tag for the release version first, then execute whatever build target you need with the corresponding version specified as project property (-PpublishVersion=A.B.C or -PpublishVersion=A.B.C-rcN). Release builds additionally enforce signing of the generated artifacts.

Ad hoc builds from branches (including master) or arbitrary "version" designators always result in SNAPSHOT builds and don't require a clean working directory or a matching tag: Specify the desired "version" as project property (-PpublishVersion=A-B-C-SNAPSHOT) or simply omit it (will then use the current branch name).

Behavioural changes:

  • Release candidates use tags instead of branches, just like regular releases.
  • Release candidates require a clean working directory, just like regular releases.
  • Publish version must be passed explicitly, it's no longer inferred from repository state and/or tags.
  • Ad hoc builds ignore tags altogether (no need to fake a dirty working directory in order to work around the previous build logic).
  • Branch names don't carry any meaning (previously releases/* for release builds and *-rc* for release candidates).
  • Aborts the build instead of warning/skipping if any preconditions aren't met (i.e. working directory state, matching tag).

Release and release candidate builds require a clean working directory and a matching tag: Create a tag for the release version first, then execute whatever build target you need with the corresponding version specified as project property (`-PpublishVersion=A.B.C` or `-PpublishVersion=A.B.C-rcN`). Release builds additionally enforce signing of the generated artifacts.

Ad hoc builds from branches (including `master`) or arbitrary "version" designators always result in SNAPSHOT builds and don't require a clean working directory or a matching tag: Specify the desired "version" as project property (`-PpublishVersion=A-B-C-SNAPSHOT`) or simply omit it (will then use the current branch name).
@blackwinter blackwinter force-pushed the 684-simplifyGradleBuildLogic branch from dfee37c to ab7f368 Compare June 25, 2025 09:26
Copy link
Member

@dr0i dr0i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides he empty line I think this is good 👍

@dr0i dr0i removed their assignment Jul 1, 2025
@dr0i dr0i removed their assignment Jul 1, 2025
@TobiasNx
Copy link
Contributor

@blackwinter can you help me how to review this? what should I try to run?

@TobiasNx TobiasNx assigned blackwinter and unassigned TobiasNx Jul 14, 2025
@blackwinter
Copy link
Member Author

First of all, you should review the updated steps in MAINTAINING.md. Do they make sense to you? Are they sufficiently simple, fool-proof, without providing too many opportunities for mistakes?

Then you could run various scenarios (without actually pushing/publishing anything!). Different branches/detached head, different publishVersions, with and without providing the required tags (which should be cleaned up afterwards!). The most basic task would be clean which then just prints the version; you could also generate the distribution with assemble.

If you need more guidance we should meet for a "review session".

@blackwinter blackwinter assigned TobiasNx and unassigned blackwinter Jul 14, 2025
In order to minimize risk of injection attacks.
@blackwinter blackwinter requested a review from TobiasNx July 18, 2025 08:55
@TobiasNx
Copy link
Contributor

TobiasNx commented Jul 29, 2025

I followed the MAINTINGING.md locally creating snapshots, rc and releases with tags. This seems to work for the main part.

Two things may need some adjustments:

  1. The documentation is not very clear with regard to the signing creadentials and that additionally to the gradle credentials git needs gpg credentials to be able to create a signed tag. Documentation should be more clear when gpg credentials are needed. In my current test it seems that only for creating a release and not for creating a rc signing credentials for gradle are needed. This propably should be done in another ticket
    We should add:
    • How to add gpg credentials to git, as it is a prerequisite for creating a signed tag.
    • We should make it more explicit for what we need gradle signing credentials
    • Update the signing credentials code block (keyName seems to be unnecessary also " are not needed for file paths):
signing.gnupg.homeDir=/home/user/.gnupg # <--- no "..."
signing.password=...
# depending on gradle plugin versions etc. you may need to use:
signing.keyId=[last 8 sign of the gpg keys]
signing.secretKeyRingFile=/home/user/.gnupg/secring.gpg # <--- no "..."

  1. When building a release candidate this is handled as Snapshot and the build gets a -SNAPSHOT suffix, is this correct? @dr0i I remember that you complained when I was uploading the last release candidate for the first time that the runner archives should not have SNAPSHOT in the name and the build should be named "metafacture-core-A.B.C-rcN" See test 4.

For further context what I tested:

Created a new branch on this basis testBranchGradle

  1. ./gradlew assemble without -PpublishVersion
$./gradlew assemble

> Configure project :
Making snapshot build: testBranchGradle-SNAPSHOT
...
BUILD SUCCESSFUL in 17s
109 actionable tasks: 44 executed, 65 up-to-date
  1. ./gradlew clean
$ ./gradlew clean
> Configure project :
Making snapshot build: testBranchGradle-SNAPSHOT
...

BUILD SUCCESSFUL in 1s
34 actionable tasks: 34 executed

./gradlew assemble with -PpublishVersion=

 $ ./gradlew assemble -PpublishVersion=TestCase

> Configure project :
Making snapshot build: TestCase-SNAPSHOT
...
BUILD SUCCESSFUL in 22s
108 actionable tasks: 106 executed, 2 up-to-date

Create a tag: git tag -s metafacture-core-7.0.1-rc8

  1. ./gradlew assemble -PpublishVersion=7.0.1-rc8
 ./gradlew assemble -PpublishVersion=7.0.1-rc8

> Configure project :
Making release candidate build: 7.0.1-rc8-SNAPSHOT
...
BUILD SUCCESSFUL in 11s
108 actionable tasks: 43 executed, 65 up-to-date
  1. ./gradlew assemble -PpublishVersion=7.0.1-rc9 fails because the tag has a different name.
 ./gradlew assemble -PpublishVersion=7.0.1-rc9

FAILURE: Build failed with an exception.

* Where:
Build file '/home/tobias/git/metafacture-core/build.gradle' line: 369

* What went wrong:
A problem occurred evaluating root project 'metafacture-core'.
> HEAD has no matching annotated tag: metafacture-core-7.0.1-rc9

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 492ms

When adding a commit and creating a new tag this works.

  1. When changes were added but not commited,
$ ./gradlew assemble -PpublishVersion=7.0.1-rc9

FAILURE: Build failed with an exception.

* Where:
Build file '/home/tobias/git/metafacture-core/build.gradle' line: 355

* What went wrong:
A problem occurred evaluating root project 'metafacture-core'.
> Working copy has modifications

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 1s
  1. Interestingly release candidates do not complain if singing credentials in gradle.properties are added or not. It always seems to work.

  2. Try to create a release, without tag, fails as intended.

$ ./gradlew assemble -PpublishVersion=7.0.1

FAILURE: Build failed with an exception.

* Where:
Build file '/home/tobias/git/metafacture-core/build.gradle' line: 369

* What went wrong:
A problem occurred evaluating root project 'metafacture-core'.
> HEAD has no matching annotated tag: metafacture-core-7.0.1

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 498ms
  1. Try to create a release, with matching tag, but without signing credentials fails as intended.
$ ./gradlew assemble -PpublishVersion=7.0.1

> Configure project :
Making release build: 7.0.1

> Task :metafacture-runner:signArchives FAILED

[Incubating] Problems report is available at: file:///home/tobias/git/metafacture-core/build/reports/problems/problems-report.html

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':metafacture-runner:signArchives'.
> Cannot perform signing task ':metafacture-runner:signArchives' because it has no configured signatory

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.14.2/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 3s
91 actionable tasks: 33 executed, 58 up-to-date

10 Building release with tag and credentials works:

$ ./gradlew assemble -PpublishVersion=7.0.1

> Configure project :
Making release build: 7.0.1

[Incubating] Problems report is available at: file:///home/tobias/git/metafacture-core/build/reports/problems/problems-report.html

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.14.2/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD SUCCESSFUL in 13s
109 actionable tasks: 12 executed, 97 up-to-date

@blackwinter
Copy link
Member Author

blackwinter commented Jul 29, 2025

Thanks a lot for the thorough review! Does this mean you approve the pull request?

The documentation is not very clear with regard to the signing creadentials and that additionally to the gradle credentials git needs gpg credentials to be able to create a signed tag.

Just to be clear: This isn't related to the current pull request; signed tags have already been part of the workflow.

In my current test it seems that only for creating a release and not for creating a rc signing credentials for gradle are needed.

That's correct and hasn't changed with this pull request. Why do think release candidates should be signed?

It seems to be new

Is there something missing here? What "seems to be new"?Section has been updated by @TobiasNx.

Interestingly release candidates do not complain if singing credentials in gradle.properties are added or not. It always seems to work.

See above.

@TobiasNx
Copy link
Contributor

TobiasNx commented Jul 29, 2025

Thanks a lot for the thorough review! Does this mean you approve the pull request?

yes

The documentation is not very clear with regard to the signing creadentials and that additionally to the gradle credentials git needs gpg credentials to be able to create a signed tag.

Just to be clear: This isn't related to the current pull request; signed tags have already been part of the workflow.

Yes, but testing the changes showed a couple of flaws in our documentation.

In my current test it seems that only for creating a release and not for creating a rc signing credentials for gradle are needed.

That's correct and hasn't changed with this pull request. Why do think release candidates should be signed?

MAINTINGING.md says the following:

To upload to Sonatype you need (as well for the release candidate as for the release) a `gradle.properties` in the root directory that looks like this:

@blackwinter
Copy link
Member Author

blackwinter commented Jul 29, 2025

When building a release candidate this is handled as Snapshot and the build gets a -SNAPSHOT suffix, is this correct?

Again, this behaviour hasn't changed:

if (grgit.branch.current().name.contains('-rc')) {
logger.lifecycle('Release candidate branch found')
return "${grgit.branch.current().name}-SNAPSHOT"
}

See also:

1. Make an annotated signed tag (it's important to do that _after_ uploading to Sonatype's snapshot repository because otherwise the `-SNAPSHOT` will not be appended to the release candidate thus will not land in `snapshot repository`):

@blackwinter
Copy link
Member Author

To upload to Sonatype you need (as well for the release candidate as for the release) a gradle.properties in the root directory that looks like this:

I see, thanks. I'll leave it for @dr0i to give his reasons for the comment (introduced in e95332d).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Review
Development

Successfully merging this pull request may close these issues.

Simplify Gradle build logic.
3 participants