Appyling Gradle signing plugin, without requiring a GPG keyring - gradle

I am following the instructions at http://central.sonatype.org/pages/gradle.html to use Gradle to upload artifacts to the Maven Central Repository. The instructions work. Examples appear at https://github.com/plume-lib/options/blob/master/build.gradle and https://github.com/plume-lib/bcel-util/blob/master/build.gradle .
My problem is that it results in a buildfile that other developers cannot use.
The Gradle signing plugin (https://docs.gradle.org/current/userguide/signing_plugin.html) requires a gradle.properties file with signing.keyId, signing.password, and signing.secretKeyRingFile, where the latter points to a valid GPG keyring. The plugin terminates the build with an error if the file doesn't exist or is not valid.
But signing is only needed when uploading artifacts to Maven Central.
I want any user to be able to run the gradle buildfile (except for actually uploading to Maven Central), even if they do not have a GPG keyring.
How can I achieve this?
Here are some things I have tried:
Split the gradle file into parts. (This is what is shown in the linked examples.) This requires two changes.
Change the main buildfile into a build script. (It can still be invoked from the command line). One gross thing about this is that only a gradle buildfile can contain a plugins { ... } block, and referring to a plugin outside the plugins { ... } block is verbose and ugly, as at the bottom of (say) https://plugins.gradle.org/plugin/com.github.sherter.google-java-format or
Create another buildfile, used only for signing, that uses apply from: to include the main one.
Question: Is there a way to do this without the ugly buildscript block?
Commit a dummy keyring to the repository, refer to it in the local gradle.properties, and the user's ~/gradle.properties can override it for any user who wants to upload to Maven Central. A problem is that using a local pathname yields a gradle warning.
Question: Is there a way to do this without a gradle warning?
Use conditional signing (https://docs.gradle.org/current/userguide/signing_plugin.html). In my experiments, this does not help. Even on a gradle execution where the artifacts are not signed, the signing plugin still requires the GPG keyring to exist.
Question: Can conditional signing be used to avoid the need for a GPG keyring?
Question: Is there a better way to achieve my goals than the above possibilities?

The documentation has a section on "Conditional Signing" which is exactly what you need here.
And you can even make that condition check that the required properties are indeed available to the build.

Related

Setting target directory for gRPC classes generated by Quarkus Gradle plugin

Running ./gradlew quarkusGenerateCode works well, however the generated sources fall under the build directory:
I wouldn't like to set this path as a Gradle SourcesSet, "Mark Directory As" Generated Sources Root in Intellij, and so on as it's under the build directory.
Is there a way to set the output dir to something such as src/quarkus-generated-sources? The Quarkus user guides and the gradle plugin documentation are not too informative regarding that subject.
There's the build.gradle, nothing much special about it
plugins {
id 'io.quarkus'
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-grpc'
...
}
There is no way to specify an alternative path for the built-in code generation mechanism.
The classes generated by Quarkus from your *.proto files may change quite often. If you run Quarkus in the development mode, they will be regenerated on each change (in the *.proto files). In such a set up this is an outcome of the build rather than a source, that's why I put it in build.
I think you could use Gradle protobuf plugin to generate the java files. It has an option to specify the output directory. Don't forget to register quarkus-grpc-protoc-plugin similarly to Maven protobuf plugin configuration.
The drawback of switching to it is that you won't be able to use the full power of the development mode when modifying the *.proto files.

How can I configure Gradle google-java-format plugin to run goJF in the build step?

We wired https://github.com/sherter/google-java-format-gradle-plugin into our project per the readme.
We also wired in a pre-commit hook to run the plugin before committing, which ensures that all of the code in a changelist is formatted before pushing it, which avoids errors in Jenkins when we run the verGJF task.
But we have to keep remembering to run goJF locally before running ./gradlew build, or the build fails with formatting errors.
We worked around this by adding the https://plugins.jetbrains.com/plugin/8527-google-java-format and https://plugins.jetbrains.com/plugin/7642-save-actions plugins for IntelliJ, enabling the google-java-format plugin, and configuring the save-actions plugin to format on save.
But that's a lot of extra configuration a developer has to remember to go through, plus it means they can't format code the way they want while working on it, and only have it be reformatted at the point of build or commit.
We'd prefer an all-Gradle solution, so that the goJF task is run before the build task (and before the verGJF task, which is already bound to the build task by the google-java-format Gradle plugin).
We couldn't figure out how to do that. Does someone else know?
It sounds like you want to essentially always ensure that the code is properly formatted before the verifyGoogleJavaFormat task is run (and could complain). In that case, I’d simply make the googleJavaFormat task a dependency of the verifyGoogleJavaFormat task. In your build.gradle file, after you have applied the google-java-format plugin, simply add the following:
verifyGoogleJavaFormat.dependsOn(tasks.googleJavaFormat)
Alternatively, if you really only want to run the code formatter when the build task is run (as opposed to when the verifyGoogleJavaFormat task is run only), you could add this instead:
build.dependsOn(tasks.googleJavaFormat)
verifyGoogleJavaFormat.mustRunAfter(tasks.googleJavaFormat)

Gradle equivalent of maven-versions-plugin

This is my build.gradle:
group 'whatever'
version '1.0.0-SNAPSHOT'
...
dependencies {
compile 'whatever:2.2.1-SNAPSHOT'
}
I want to automate releasing process, which includes the need to set both versions to particular values, e.g. 1.1.0 or 2.2.0 using command line only. Any kind of autoincrement is not an option.
With Maven, I'd do this using maven-versions-plugin:
mvn versions:set -DnewVersion=${WHATEVER_NEW_VERSION}
How can I do the same with Gradle? I only found this unanswered question. There must be some simple way to do that?
I ended up extracting version numbers to gradle.properties and updating them as part of the automated build script using sed:
sed -i -e \"/someVersionNumber=/ s/=.*/=${SOME_NEW_VERSION_NUMBER}/\" gradle.properties
It's what I want. Although for me, coming from the Maven background, this doesn't seem natural. I may research another alternative later.
Though not related to publishing, one way to pass command-line properties is as follows:
gradle -PWHATEVER_NEW_VERSION=2.0.0
Consider the following build.gradle snippet:
def newVersion = project."WHATEVER_NEW_VERSION"
println newVersion
See ~/utils/gradle/version.gradle in this project for another approach. It uses separate environment variables for major, minor, and incremental versions and then builds the string automatically. Because it resides in the gradle directory, it can simply be imported into build.gradle, which hides some boilerplate.
I successfully used Axion Release Plugin a couple of times and was very satisfied. Functionality-wise it comes the closest to what Maven's

how to prevent gradle from downloading dependencies

We would like to have a script that does "svn update" and if the depedency.gradle file is in that list of updates, we would like to run a task that ONLY updates dependencies so the developers machine is up to date. What would that task be? I don't see it when running "gradle tasks". Looking for an updatejars or something.
When we build our project, we don't want it to check for jar updates at all!!!! most because that only needs to be done in 2 situations which are #1 above and when someone is updating the dependency.gradle file themselves. For the second thing, they can just run "gradle updatejars" once I know the answer to question #1 that is.
Any ideas? I am just getting into gradle and we really want to keep a consistent environment where when we run our update script, it gets the source code AND the jars in one atomic sweep and we are no longer bothered by checking the repositories every build.
It would be nice to know how to do it by changing the build.gradle file if possible. If not, is there a command line option? (The build.gradle obviously would give me a command line option which is why I prefer that method as I could say compile does not depend on downloading jars).
Regarding the second question. As far as I understand, Gradle will not attempt to do remote lookups or try to download the jar if it is already in the local cache. This should be true for jars declared with a static version, e.g. testCompile 'junit:junit:4.10'.
If you have dynamic versions, e.g. 1.+ or 1.0-SNAPSHOT, etc. then Gradle has to do a check every now and then. You can fine tune the cache expiry for such dependencies.
To make sure Gradle does not do remote lookups you can also use --offline option. See this doc for details.
With regard to svn update, you have at least 3 options:
Try to use an SvnKit plugin for Gradle
Use the ant svn task (here's how to do svn checkout)
Run external command from Gradle. Use the ExecPlugin or just implement it yourself using Groovy API.
Looks like the 1st question I can do with the answer in this post
how to tell gradle to download all the source jars
so I can just gradle eclipse and it will download new jars and update my classpath...nice.

sbt 0.11: Using a corporate maven repository

How can a corporate Maven repository be used (to the exclusion of other repositories) with sbt 0.11.x, as described in how do I get sbt to use a local maven proxy repository (Nexus)? ? There is no mention of ivyRepositories in the new sbt wiki at github, so I'm assuming the accepted solution there is out of date.
Step 1: Follow the instructions at Detailed Topics: Proxy Repositories, which I have summarised and added to below:
(If you are using Artifactory, you can skip this step.) Create an entirely separate Maven proxy repository (or group) on your corporate Maven repository, to proxy ivy-style repositories such as these two important ones:
http://repo.typesafe.com/typesafe/ivy-releases/
http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/
This is needed because some repository managers cannot handle Ivy-style and Maven-style repositories being mixed together.
Create a file repositories, listing both your main corporate repository and any extra one that you created in step 1, in the format shown below:
[repositories]
my-maven-proxy-releases: http://repo.example.com/maven-releases/
my-ivy-proxy-releases: http://repo.example.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
Either save that file in the .sbt directory inside your home directory, or specify it on the sbt command line (you will need to specify if you have disabled sharing):
sbt -Dsbt.repository.config=<path-to-your-repo-file>
Good news for those using older versions of sbt: Even though, in the sbt 0.12.0 launcher jar at least, the boot properties files for older sbt versions don't contain the required line (the one that mentions repository.config), it will still work for those versions of sbt if you edit those files to add the required line, and repackage them into the sbt 0.12.0 launcher jar! This is because the feature is implemented in the launcher, not in sbt itself. And the sbt 0.12.0 launcher is claimed to be able to launch all versions of sbt, right back to 0.7!
Step 2: To make sure external repositories are not being used, remove the default repositories from your resolvers. This can be done in one of three ways:
Add the command line option -Dsbt.override.build.repos=true mentioned on the Detailed Topics page above. This will cause the repositories you specified in the file to override any repositories specified in any of your sbt files. This might only work in sbt 0.12 and above, though - I haven't tried it yet.
Having the same effect as 1, you can use overrideBuildResolvers := true, with the advantage that you can control the projects where it is applicable, depending on which scope (a project / ThisBuild / Global) you define it in. This works in sbt 0.13.
Use fullResolvers := Seq( resolver(s) for your corporate maven repositories ) in your build files, instead of resolvers ++= or resolvers := or whatever you used to use.
Finally, note that the sbt launcher script has a bug in reading the sbtopts file, so if you decide to put your common sbt command-line options in there, make sure the last line of the file ends in a newline (Emacs in particular can fail to ensure this, unless configured to do so).
An alternative for Step 2 of the accepted answer (am using sbt 0.13.1):
Add file .sbtopts to the project root directory with contents:
-Dsbt.override.build.repos=true
Another alternative is to add this line in $SBT_HOME/conf/.sbtopts, but this would force the setting for all projects.
Unpack the sbt-launcher.jar and copy the sbt.boot.properties file to a location of your choice. Change the launch script to use this file. In the file, change the repositories section to only contain your local repo and the corporate one. The distinction between Maven and Ivy comes from the given pattern (no pattern means Maven pattern by default).
Here is an example:
[repositories]
local
corporate: http://inhouse.acme.com/releases/

Resources