I want to create a plugin that will publish artifacts from a task to a maven repository by means of the maven-publish
plugin. I’m wanting to use the model rule approach. I want to remove as much boilerplate code as possible from build.gradle
, hence my desire to move the publishing code into a plugin.
I have a task created in a plugin (that itself applies the maven-publish plugin) that will zip up files that are produced by a native build process. I need access to the Project class, so there is an extension container that I have created that has a project property that enables me to do this.
@Mutate
public void createPackageNativeArtifactsTask(final ModelMap<Task> tasks, @Path("binaries") ModelMap<NativeBinarySpec> binaries,
final ExtensionContainer extensionContainer) {
// Get ProjectWrapper and enclosed Project object.
final ProjectWrapper projectWrapper = extensionContainer.getByType(ProjectWrapper)
final Project project = projectWrapper.project
// these are the files we will package up
def exportedBinaryList = binaries.findAll {
it instanceof StaticLibraryBinarySpec &&
it.buildable &&
it.flavor.name == 'export'
}
// this is the repo I want to publish to
def bktNexusPublishingRepository = (project.version.endsWith('-SNAPSHOT')) ? "snapshots" : "releases"
project.publishing.repositories.maven {
credentials {
username = project.findProperty('bktNexusUser')
password = project.findProperty('bktNexusPassword')
}
url "${project.property('bktNexusRepositoryUrlPrefix')}/${bktNexusPublishingRepository}"
}
// this is the task that will zip everything up when the binaries are built
tasks.create("packageNativeArtifacts", Zip) {
outputs.upToDateWhen { false }
group = "Publishing"
description = "Zips all files defined in 'from' into 'destinationDir' in preparation for publishing by the publish* task(s)."
baseName "${project.name}"
version "${project.version}"
extension 'nar'
exportedBinaryList.each { binary ->
def binaryDir = binary.targetPlatform.name + "/" + binary.buildType.name + "/" + binary.flavor.name
def exportedHeaderDirs = binary.component.sources.cpp.exportedHeaders.getSrcDirs() as List
from("${project.buildDir}/libs/${binary.component.baseName}/static/${binaryDir}") {
into("${binaryDir}/lib")
}
exportedHeaderDirs.each { dir ->
from("${dir}") {
into("${binaryDir}/include")
}
}
}
}
}
This works ok - it zips up binaries by their variant and puts them into a zip file. It also adds the exported header files and replicates them throughout the zip file. The rule that makes this task run after building and testing is not shown.
I have another rule that I want to have create the MavenPublication and set its artifact to be the output of the packageNativeArtifacts
task that I just created. I can’t seem to add this step to the previous rule as the task doesn’t seem to be created when I call tasks.create()
, it’s null. I’m guessing this is because the creation of the task is deferred. I annotate this new rule with @Finalize
rule in order to have visibility of all tasks.
@Finalize
public void finalizePackageNativeArtifactsTask(final ModelMap<Task> tasks, @Path("binaries") ModelMap<NativeBinarySpec> binaries,
final ExtensionContainer extensionContainer) {
// Get ProjectWrapper and enclosed Project object.
final ProjectWrapper projectWrapper = extensionContainer.getByType(ProjectWrapper)
final Project project = projectWrapper.project
def packageNativeArtifacts = tasks.get('packageNativeArtifacts')
project.publishing.publications.create("mavPub", MavenPublication) { publication ->
publication.artifact(packageNativeArtifacts)
}
}
When I call the publish
task, it runs through its dependencies ok, building all files as required. The packageNativeArtifacts
task is set as a dependency too, so once the files are built, it then zips them up. However, nothing is uploaded to Nexus. When I run the task with --debug
, I see the following:
17:37:50.134 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :publish (Thread[Daemon worker Thread 79,5,main]) started.
17:37:50.134 [LIFECYCLE] [class org.gradle.internal.buildevents.TaskExecutionLogger] :publish
17:37:50.134 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':publish'
17:37:50.134 [INFO] [org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter] Skipping task ':publish' as it has no actions.
17:37:50.134 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':publish'
17:37:50.134 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :publish (Thread[Daemon worker Thread 79,5,main]) completed. Took 0.0 secs.
The publish
task seems to have no actions (whatever that means), and is therefore not executed. I have no idea why this is.