At Boxfuse we have a separate build & publish flow, as not all our builds are meant to be publicly available. Only after we promote a build does it become available in our public Maven repository (http://files.boxfuse.com).
How can I publish a specific version our Gradle plugin to the plugin portal when we are ready to promote it after it has already been built?
Promotion in our case currently involves previously built artifacts being copied over to S3. We would now like to take one of those artifacts (the Boxfuse Gradle plugin jar) and push it to the Gradle Plugin portal instead.
Can the publishing plugin take an existing jar (containing all necessary metadata) and start from there?
It is possible, just a bit fiddly. The publishing plugin will upload jars from the places it expects them to be under build/, so if you put the published ones there then those ones will be uploaded. I go into more detail in this thread.
I put the jar and pom.xml under build/libs and build/publish-generated-resources
However this broke in numerous ways. First it insisted on always replacing the jar with an empty one, hence the “-x jar” to fix this. It however does the same for the pom.xml and I have not yet found a way to fix this.
Additionally, the plugin jar is dependent on other jars present in our own Maven repo, which must somehow be found. It would be great if Gradle could pick up a list of additional repos required for resolving a plugin’s dependencies.
Finally the publishing plugin always expects a source and javadoc jar, which we had to replace by empty ones as this is not van OSS plugin.
How would you recommend tackling these issues? Is the publishing plugin available publicly somewhere (ex. GitHub)?
Also please remove the current version published on the Portal as it causes Gradle to break with “Could not generate a proxy class for class com.boxfuse.client.gradle.task.CreateTask” as it misses dependencies referenced in the pom.xml that got overwritten.
The key parts are clearing out the default archives artifacts and adding the downloaded file.
This will work if your S3 bucket is set up as a maven compatible repo. If not, you’ll need to download the file in some other way and replace:
artifacts {
// add downloaded jar to the archives configuration set of artifacts
archives configurations.downloaded.resolve()[0]
}
with
artifacts {
// add downloaded jar to the archives configuration set of artifacts
archives new File("path/to/downloaded/file/here.jar")
}
and rip out the downloaded configuration stuff. How you download the jar will depend on how your S3 bucket and credentials are set up, but I’ll presume you can get the jar onto the local file system somehow.
I’d keep this build in a separate project, or a separate sub-project to the one that builds the jar, since we’re messing with the archives configuration here.
yes as it ignored the pom.xml I supplied and therefore will not find a dependent jar not present in Maven Central. How can I have a plugin depend on such a jar and still work when used from the plugin portal?
Our current solution is to ask our users to add this to their build:
It’s not documented right now as it may be subject to change in the future, but there is a way to modify the dependencies that your plugin uses. The pluginBundle block has a withDependencies closure that you can use to modify the dependencies:
It will be passed a List of org.apache.maven.model.Dependency. Exactly what gets passed in here is what may change in the future. But for the time being, you can add a new dependency to the list or remove dependencies that you don’t want in there in this closure.
You can’t add the repo automatically though, as we can’t modify end users’ repos to third party ones - this is a security risk.
Not really. We’re not intending to be a general purpose repo, so the expectation is that external dependencies for plugins would be published in the normal way wherever those dependencies live.
If you can’t publish the dependency somewhere like Bintray or Maven Central, or if the dependency itself is tied to the plugin quite closely, you could bundle the dependency into the plugin jar. This would look something like:
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
Please ensure that you only bundle your own dependency and not any common ones published to public repositories.
Your solution for withDependencies seems to have a problem and results in “You cannot create an instance from the abstract interface ‘org.gradle.api.artifacts.Dependency’”. Which class should I use instead?
Also is there a way to perform a dry run to ensure the results are good before uploading?
Could you also please delete all existing versions of the Boxfuse plugin as all are broken so far until a correct one is uploaded?
I got Artifact [group: gradle.plugin.com.boxfuse.client, artifactId: client,version: 1.11.0.713, classifier: None, extension: pom] has already been published -> Can you please also delete the previously uploaded poms?
I got “Could not find method archives() for arguments ...” and had to add apply plugin: 'maven' -> Is that the correct way to fix this? (BTW, the example you linked has this issue too)
This is a bit involved as we usually don’t allow overwriting of existing artifacts for security reasons. Can you just bump the version number?
archives is brought in by the java plugin, so you’ll need to apply that. It’s normally assumed that the java plugin will be applied in a Gradle plugin project.
Thank you very much Tom. The latest version is now working.
Two issues remain:
How can I also publish a JavaDoc jar?
The description and the tags are not updated with new versions. This is unfortunate as we would like to evolve these over time as features get added. Is there a way to force this? If not, could you do it manually for the current version (apply tags & description of 1.11.2 to plugin in general)?