"Before I could pull the trigger, I was hit by lightning and bitten by a cobra. I blacked out, and
saw images of ancient Shaolin temples and monks mastering the art of kung-fu. There was an ancient
prophecy about a new form of kung-fu so powerful, only one man can master it: The Chosen One. When I
woke up, I saw the kung-fu master running towards me. I could feel my body mutate, into some sort of
kung-fu freak of nature." --Kung Fury
Purpose
An alternative Gradle helper to publish multi-flavored Android artifacts to local and remote Maven
repositories with pretty POM files using simple property configuration. It also provides a wide
variety of things that Maven provides out of the box, in gradle, such as encrypted credentials and
the maven site plugin.
Why use Gradle-Fury
Great question, with a sea of many maven publisher helpers (this alone should raise a red flag that
something is wrong) what stands gradle-fury apart? Check out our Why would you want to use Gradle Fury? wiki page for the most update to date set of features which is always growing.
Build Status
Develop:
Master:
Requirements
Requirements for using Gradle-Fury
JDK 7 or JDK 8 (depending on what gradle version and android plugin you're using)
For Android support, gradle android plugin v1.3.0 or higher, we test using a variety of configurations. See the Travis build matrix
For digital signature support, GPG must be installed on your computer. We test with gnugpg.
Tested configurations for gradle and the android gradle build tools.
Gradle
Android Build Tools
JDK
Test Result
4.1
3.0.0
8
FAIL publish fails due to pom not being generated, Gradle changed APIs which prevents dependencies from being declared in the pom.
4.0.1
2.3.3
8
FAIL Gradle changed APIs which prevents dependencies from being declared in the pom.
4.0
2.3.3
8
FAIL Gradle changed APIs which prevents dependencies from being declared in the pom.
3.5.1
2.3.3
8
FAIL Gradle changed APIs which prevents dependencies from being declared in the pom.
3.5
2.3.3
8
FAIL Gradle changed APIs which prevents dependencies from being declared in the pom.
3.4
2.3.3
8
FAIL Gradle changed APIs which prevents dependencies from being declared in the pom.
3.3
2.3.3
8
OK
3.3
2.3.2
8
OK
3.3
2.3.1
8
OK
3.3
2.3.0
8
OK
3.2.1
2.3.0-alpha2
8
it worked at one point but not anymore
3.1
2.2.2
8
OK
3.1
2.2.1
8
OK
3.1
2.2.0
8
OK
3.0
2.2.0
8
OK
2.14.1
2.1.3
7,8
OK
2.10
2.1.2
7,8
OK
2.14
2.1.0
7,8
OK
2.14
2.0.0
7,8
FAIL - Fails to generate poms for android projects, maven install local and publish to nexus
2.2.1
1.5.0
7,8
FAIL - Fails to generate poms for android projects, maven install local and publish to nexus
2.2.1
1.3.1
7,8
OK*
2.2.1
1.3.0
7,8
FAIL - Fails to generate poms for android projects, maven install local and publish to nexus
So as long as you're not using one of those 3 versions of the android plugin, you're good to go.
When using gradle 2.2.1 with the application or distribution and it's a Java project, there are
some problems with hooking in the install task with distZip (the thing that makes the distribution).
The fix is to include distZip with your command.
Gradle
Build Command
version <= 2.2.1
gradlew clean distZip install
version > 2.2.1
gradlew clean install
Again, distZip this only applies if you're using gradle 2.2.1 AND you have a project module that uses
the (distribution OR application plugin) AND it's a Java project. I tried to tie it in, but I can't
make gold from lead - ao
Usage
Please refer to the dummy "Hello World" subprojects along with the provided root project
build.gradle and gradle.properties files included with this project as a general usage guide:
1. Create or modify the root gradle.properties file in your project
This is the secret sauce. I crave simplicity, and I just adore the idea of being able to house
simple project configuration in a singular, standard location in each of my projects, instead of
littering it in several locations throughout the codebase.
There are a handful of key properties which the gradle-fury helper scripts use to make the magic
happen, which are defined in the following sub-sections.
Define the properties which are used by the maven-publish plugin for artifact publication:
The NEXUS_USERNAME and NEXUS_PASSWORD properties define the username/password credentials used
to authenticate to the target repository. Though the properties are prefixed with NEXUS_, they
could really apply to any Maven repository.
The RELEASE_REPOSITORY_URL and SNAPSHOT_REPOSITORY_URL properties define the
repositories
in the PublishingExtension.getRepositories() container.
Define the Android versionCode property (per the
Android Documentation, "an
integer value that represents the version of the application code, relative to other versions"):
2. Modify the allprojects closure in your root project build.gradle
The required modifications consist of defining the default project.group and project.version
properties, and applying the
maven-support.gradle
script in the allprojects closure, which will subsequently apply the configuration to all subprojects.
Please note that project.group and project.versionmust be defined before including
maven-support.gradle
since it uses these values. Also note that these property values may be overridden by individual
subprojects.
allprojects {
// NOTE: project.group and project.version must be defined before including// maven-support.gradle since it uses these values...
project.group = ( project.hasProperty('pom.groupId')
? project.property('pom.groupId') :"" )
project.version =
( project.hasProperty('pom.version') ? project.property('pom.version') :"1.0" )
apply from: 'https://raw.githubusercontent.com/gradle-fury/gradle-fury/master/gradle/maven-support.gradle'
.
.
.
}
The included root build.gradle
file may be used as a reference for usage.
ProTip: apply the apply line BEFORE the android { ] block. This will allow you to override any default values or
values defined within your gradle.properties file.
Please note that no similar inclusions are required for standard Java subprojects, as illustrated in
the hello-world-lib example
Java project.
4. Publish multi-flavored Android artifacts with pretty POM files!
Install Artifacts to a Local .m2 Repository
$ gradle clean build publishToMavenLocal
OR
$ gradle clean build install
The Gradle pipeline has been hacked such that the install task invokes the publishToMavenLocal
task, along with a friendly "warning". Why? Because the install task does not work with Android
projects. See also the
Impetus and Rage section
below.
Eventually this new publishing support will replace publishing via the Upload task.
Don't hold your breath. Apparently "incubation" is perpetual with Gradle.
Publish Artifacts to a Remote Repository
$ gradle clean build publish
OR
$ gradle clean build uploadArchives
Similar to the install task, the Gradle pipeline has been "hacked" such that the uploadArchives
task simply invokes the publish task, along with a friendly "warning". So technically, you should
be able to use uploadArchives in place of the publish task.
Bonus: Javadoc and Source jars
Gradle Fury supports build profiles (similar to how Maven does things). Here's the profiles that exist today and how to use them.
To generate Javadocs (Android projects included)
$ gradle install -Pprofile=javadoc
To generate Sources (Android projects included)
$ gradle install -Pprofile=sources
To generate Javadocs and Sources (Android projects included)
$ gradle install -Pprofile=sources,javadoc
"Well then. It's hacking time." --Kung Fury
Publishing to maven central with GPG signatures
Not tested yet, but there's a specific procedure in place. It's tempting to slam then all
together into a single command, but unfortunately it won't work. Why? Because gradle.
Seriously why?
Well gradle simply won't let us do what needs to be done. It's lifecycle taskgraph thing
is strange and fires in all kinds of strange unintuitive ways. For instance, Android pom
generation is out of our hands. We can alter it but not control when it's written to disk.
That's a problem if you're trying to sign it. Unfortunately, we couldn't find a way to get
the hooks in place at the right time in the cycle to both sign and not get cleaned and still
be present in the right locations for the publish steps.
We're also not using the built in "publish" or "uploadArchive" task here because it does not
publish pom signatures correctly. It also uploads an additional variant of android libraries and APKs
for no apparent reason and we can't find a way to sign those before uploading.
Then you'll have to manually edit local.properties to insert your cipher text.
Gradle to Maven Scope Mappings
Gradle qualifier
Maven Scope
compile
compile
releaseCompile
compile
debugCompile
NOT MAPPED*
runtime
runtime
testCompile
test
androidTestCompile
test
provided
provided
Items marked as not mapped are not referenced in the pom. Pom's are
generally used for releases, such as, items specific to a scope, such as
'debugCompile' aren't useful since it won't be in the release version.
Quality Plugin
Runs findbugs, checkstyle, and pmd on all your projects (android and java).
Based off the work done here.
To apply to your project, apply this file under 'allprojects' then copy the files from gradle-fury/config and place it in your project
allprojects {
apply from 'https://raw.githubusercontent.com/gradle-fury/gradle-fury/master/gradle/quality.gradle'
}
then execute with gradelw build
Since the checks can add a lot of time to your build, you probably want to make it optional...
allprojects {
if (project.hasProperty('profile') && project.profile.split(',').contains("ci")) {
apply from 'https://raw.githubusercontent.com/gradle-fury/gradle-fury/master/gradle/quality.gradle' }
}
Well it's not exactly the Maven Site Plugin, but it's our version of it. It's pretty darn close.
It uses theming inspired by Apache Fluido and is loosely based
on the work Paul Speed-2 @ filament did over here.
Instead of the APT based sites, we opted for a simpler solution, a singular page template
which is then merged with generated content and your content using Markdown and the
Common Mark renderer. We also
looked at Pegdown but ran into performance issues.
Asciidoc/docbook
Make the site
Before making the site, you should run all your tests and any gradle tasks that generate reports.
If they were't created first, they won't be included with site generation.
Also before making, you need to make some directories and files.
mkdir src
mkdir src/site/
Next, you'll want to grab all the files from gradle-fury's src/site/.
Put those files in your src/site/ folder.
Next, create or edit index.md. This will be come your site's index.html, the first page people will look at it.
Note: if you're looking for gradle-fury's index.md page, you won't find it. Instead, we copy this readme.md to the right place
and rename it.
Most Github flavored markdown tags are supported. You can also any files put in src/site/ will
be included in the site. Any html or pdf files in the root src/site/ will be auto-linked on the left hand site
navigation menu.
Finally, put this in your root build.gradle file. Do not place it within allprojects.
apply from 'https://raw.githubusercontent.com/gradle-fury/gradle-fury/master/gradle/site.gradle'
We also took some liberties from the maven-site-plugin. Many of the pages it generates can be reduced to just a link.
For instance, the location of the source (do we really need an entire web page that only shows the link to the source code?).
Same goes for CI, distro management and issue tracking.
./gradlew install -Pprofile=javadoc,sources
# if needed, for distribution projects
./gradlew distZip -Pprofile=javadoc,sources
# if needed, for on device android test and reports
./gradlew cC
# if needed, for findbugs
./gradlew check
# if needed, for jacoco
./gradlew jacocoTestReport
# finally, generate the site
./gradlew site
The output goes to rootDir/build/site/ and can be overridden with ext.buildWebsiteDir = rootDir.absolutePath + "/docs/"
In the future, we may add some extra tasks for zipping up the site, deploying to an ftp or something else.
What is generated by the site plugin?
Here's a quick list
Project Summary, all of the artifacts of your project, derived from the project itself and gradle.properties
Project Team, from gradle.properties
Links to the source, issue tracker, CI and distribution pages
All javadocs are included and linked
Project repository list, from gradle.properties
Dependency report - for all the artifacts of your project, derived from the project itself
Project reports - for all artifacts of the project, any and all things from the build/reports folder is included and linked (see the quality plugin). Includes test reports, connectedCheck, Findbugs, PMD, etc
Converts and themes all your .md and .asciidoc files from the root/src/site and links them in
Acknowledgements
I absolutely want to extend a very sincere thanks to Chris Banes,
whose work served as the foundation and inspiration for this work. I would not be anywhere had it
not been for his outstanding efforts to overcome several of the glaring deficiencies within Gradle's
"support" of basic development lifecycle operations -- you know, like simple artifact publishing.
请发表评论