Custom publication plugin in gradle - gradle

I'd like to implement custom publication plugin for gradle.
My goal is to support syntax like this:
publishing {
publications {
custom(CustomPublication) {
artifact fooDistZip
artifact foo2DistZip
}
}
repositories {
custom {
url 'http://192.168.1.100:80'
}
}
}
I've checked the MavenPublication, but the implementation seems to be rather complicated.
Any reference for simple custom publisher in gradle would be much appreciated.

Sounds like you'll want to create a CustomPublisher that extends the Publisher thats consumed by a PublicationContainer
Update:
I’ve added a code snippet from gradles documentation about configuration of the upload task
repositories {
flatDir {
name "fileRepo"
dirs "repo"
}
}
uploadArchives {
repositories {
add project.repositories.fileRepo
ivy {
credentials {
username "username"
password "pw"
}
url "http://repo.mycompany.com"
}
}
}

Related

In build.gradle how to extract and reuse Maven repository configuration?

I've got this build.gradle file:
repositories {
maven {
credentials {
username "$artifactory_user"
password "$artifactory_password"
}
url 'http://some.domain/artifactory/repo'
}
}
publishing {
repositories {
publications {
maven(MavenPublication) {
from components.java
}
}
maven {
credentials {
username "$artifactory_user"
password "$artifactory_password"
}
url 'http://some.domain/artifactory/repo'
}
}
}
I want to extract and reuse the Maven repository definition.
This is not working:
repositories {
mavenRepository()
}
publishing {
repositories {
publications {
maven(MavenPublication) {
from components.java
}
}
mavenRepository()
}
}
private void mavenRepository() {
maven {
credentials {
username "$artifactory_user"
password "$artifactory_password"
}
url 'http://some.domain/artifactory/repo'
}
}
It results in
Could not find method mavenRepository() for arguments [gradle-dev] on
repository container of type
org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler.
How can I achieve this goal?
lets say you have a separate repositories.gradle file and name your maven repo..
maven {
name 'myrepo'
url 'https://xxxx'
credentials {
username = System.getenv("xxx") ?: "${xxx}"
password = System.getenv("xxx") ?: "${xxx}"
}
}
maven { name 'anotherrepo' }
then at root project level you can run:
apply from: "$rootDir/gradle/repositories.gradle"
This will populate repositories with all repos. Then to use populate a specific one somehwere else, you can use:
repositories.add(rootProject.repositories.getByName('myrepo'))
I found the answer on this blog page: https://themightyprogrammer.dev/snippet/reusing-gradle-repo
thanks to mightprogrammer!

Move publishing configuration to one place in gradle

I have a project which has modules, my goal is to configure publishing after each module is built and after all modules are built, so I could create a zip file with all the jars inside and upload it as well. I do it in subprojects section and in outer section.
publishing {
publications {
mavenJava(MavenPublication) {
//my artifacts here
}
}
repositories {
maven {
url "${artifactoryURL}"
credentials {
username = "${artifactoryUsername}"
password = "${artifactoryPassword}"
}
}
}
}
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
I guess that you're creating your deployables in a top-level (root, parent) project, that does not have any sources.
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
Sure. Just use subprojects, allprojects or generic configure, depending on your needs:
allprojects {
id 'maven-publish'
publishing {
repositories {
maven {
url "http://maven.repo"
}
}
}
}
This will configure publishing for all the projects (be aware of that you may not want to publish everything).
For a projects with Java source you can configure publishing like usual:
subprojects {
publishing {
publications {
main(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
}
}
And for root project just configure deployments as in your previous question.

Can I add a custom repository to gradle.properties?

I'd like to be able to define a repository in settings (ideally user gradle.properties)
The end goal is something like this:
repositories {
mavenCentral() // Can't/don't want to use this
nexusCentral() // Can use these - on network Nexus server
nexusSnapshot()
}
How would I go about doing this? Again, this would go in the user-level gradle.properties file ideally, so we don't have to reference it in every single module.
This is just a plain maven style artifact repository provided by Maven, the manual way would be:
maven {
url "http://path/to/nexus"
}
One other requirement is the use of the "publish" task, which has credentials defined for a repository (that Jenkins uses to publish the module):
publishing {
...
maven {
url "http://path/to/nexus"
// Jenkins provides these as -P Gradle parameters.
credentials {
username = "${uploaderUser}"
password = "${uploaderPassword}"
}
}
These credentials would not be known to regular users, but would ideally be configured in Jenkin's gradle.properties. We wouldn't want users builds to fail because they can't resolve the credentials - they would never even use the "publish" task.
You can use somenthing like this:
maven {
credentials {
username getCredentialsMavenUsername()
password getCredentialsMavenPassword()
}
url 'xxxxx'
}
/**
* Returns the credential username used by Maven repository
* Set this value in your ~/.gradle/gradle.properties with CREDENTIALS_USERNAME key
* #return
*/
def getCredentialsMavenUsername() {
return hasProperty('CREDENTIALS_USERNAME') ? CREDENTIALS_USERNAME : ""
}
/**
* Returns the credential password used by Maven repository
* Set this value in your ~/.gradle/gradle.properties with CREDENTIALS_PASSWORD key
* #return
*/
def getCredentialsMavenPassword() {
return hasProperty('CREDENTIALS_PASSWORD') ? CREDENTIALS_PASSWORD : ""
}
If the user hasn't the credentials the script doesn't fail.
Not sure if that answers your question, but you can put this in the gradle.properties file:
nexusUrl=http://path/to/nexus
and do this in the build.gradle:
maven {
url project.property(nexusUrl)
}
EDIT:
regarding your credentials, all you should need is something like
if (project.hasProperty('uploaderUser') && project.hasProperty('uploaderPassword')) {
credentials {
username = project.property('uploaderUser')
password = project.property('uploaderPassword')
}
}
Solved this issue by replacing jcenter() in Project/andoird/build.gradle with maven { url 'http://nexusUrl' } under buildscript and allprojects:
buildscript {
repositories {
google()
maven { url 'http://nexusUrl' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
allprojects {
repositories {
google()
maven { url 'http://nexusUrl' }
}
}
and in fluttersdk/packages/flutter_tools/gradle/flutter.gradle replaced jcenter with maven { url 'http://nexusUrl' } under buildscript:
buildscript {
repositories {
google()
maven { url 'nexusUrl' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}

Trouble injecting the build block while exporting a Maven pom.xml file from gradle

task writeNewPom {
pom {
project {
/*
build {
plugins {
plugin {
groupId 'GROUP_ID'
artifactId 'maven-ipcentral-plugin'
version '4.7'
executions {}
configuration {
url "http://CENTRAL_REPORTING_SERVER"
logfileprefix "test"
ipcProject = true
businessUnit "FOUR_DIGIT_CODE"
componentEditorsGrouper "ccp-dev"
assetEditorsGrouper "ccp-dev"
username "USERNAME"
}
}
}
}
*/
pluginRepositories {
pluginRepository {
id 'ipcentral-snapshots'
name 'IPCentral Snapshot Repository'
url 'http://PLUGIN_SOURCE/'
snapshots {
enabled = false
}
releases {
enabled = true
}
}
}
profiles {
profile {
id 'inject-cec-credentials'
activation {
activeByDefault = true
}
properties {
username = "USERNAME"
}
}
}
}
}.writeTo("ipcentral/pom.xml")
}
I am attempting to create a pom.xml file using the gradle maven plugin. It must reference a maven plugin designed for central dependency reporting. As it is right now it successfully creates the pom.xml file containing all dependencies, plugin repository info, and profile info. However if the build section is un-commented the I get an error along the lines of:
> No such property: _SCRIPT_CLASS_NAME_ for class: org.apache.maven.model.
If I try something simple like
task writeNewPom {
pom {
project {
build {
}
}
}
}
then I get the same error. It seems that gradle does not recognize build as a valid identifier. I am just hoping for a more elegant solution than manually editing xml through groovy. The only documentation on this that I can find is Gradle docs Chap 53
This is due to the fact that the project {...} closure is delegating to an instance of ModelBuilder which extends Groovy's FactoryBuilderSupport class that already defines a method named build. So instead of configuring the build property of the Maven Model object, the preexisting build method is being called.
To get around this I'd use withXml {...} to configure that portion of your pom.
pom {
project {
// other non-<build> configuration
}
}.withXml {
asNode().appendNode('build').appendNode('plugins').appendNode('plugin').with {
appendNode('groupId', 'GROUP_ID')
}
}.writeTo('pom.xml')
Here is a more detailed example:
.withXml
{
asNode().appendNode('build').appendNode('plugins').with
{
with
{
appendNode('plugin')
.with
{
appendNode('groupId', 'groupId1')
appendNode('artifactId', 'artifactId1')
appendNode('version', 'version1')
}
}
with
{
appendNode('plugin')
.with{
appendNode('groupId', 'groupId2')
appendNode('artifactId', 'artifactId2')
appendNode('version', 'version2')
}
}
}
}
.writeTo("pom.xml")

Publishing custom artifact built from task in gradle

I am having some issues trying to create a task that build a special file which is then uploaded to artifactory.
Heres a simplified version:
apply plugin: 'maven-publish'
task myTask {
ext.destination = file('myfile')
doLast {
// Here it should build the file
}
}
publishing {
repositories {
maven {
name 'ArtifactoryDevDirectory'
url 'http://artifactory/artifactory/repo-dev'
credentials {
username 'username'
password 'password'
}
}
}
publications {
MyJar(MavenPublication) {
artifactId "test"
version "1.0"
groupId "org.example"
artifact myTask.destination
}
}
}
This works, except that gradle publish does not run myTask. I tried adding
publishMyJarPublicationToArtifactoryDevDirectoryRepository.dependsOn myTask
but i just get:
Could not find property 'publishMyJarPublicationToArtifactoryDevDirectoryRepository' on root project 'test'.
I tried messing about with the artifact, adding a custom artifact and configuration and publishing that instead but that did not work either.
Any help would be greatly appreciated.
afterEvaluate {
publishMyJarPublicationToArtifactoryDevDirectoryRepository.dependsOn myTask
}
Accomplishes what I want.

Resources