The story so far: Tapestry is a multi-module build. With help from Luke Daley, I've managed to get all the creating of sources JARs, signing of artifacts, and uploads to the Apache Nexus all set up.
I'm working currently on the Maven archetype; I have a quickstart module that isn't a Java project; instead we build a quickstart/build.gradle: import org.apache.tools.ant.filters.FixCrLfFilter import org.apache.tools.ant.filters.ReplaceTokens generatedDir = new File(buildDir, 'quickstart-generated') task generateArchetype(type: Copy) { srcDir = file('prototypes') // This let gradle know where is UP-TO-DATE inputs.file srcDir outputs.dir generatedDir generatedDir.mkdirs() from srcDir into generatedDir // Use some of the filters provided by Ant filter(FixCrLfFilter) filter(ReplaceTokens, tokens: [ quickstartVersion: version, tapestryReleaseVersion: version, servletApiReleaseVersion: servletAPIVersion, testngReleaseVersion: testngVersion, easymockReleaseVersion: easymockVersion ]) } task build(type: Jar, dependsOn: 'generateArchetype') { description = "Creates a the JAR archive for the quickstart archetype" group = "Release artifact" destinationDir = buildDir baseName = "quickstart" version = project.version from generatedDir } artifacts { archives build } View it here: https://gist.github.com/1282641 That seems to be working; a gradle build will create the JAR file, with the correct contents, as build/quickstart--xxx.jar However, I had a lot of issues, from my top-level build.gradle; basically things appeared to be off becuse quickstart wasn't a normal module (it didn't even apply the 'java' plugin), so I hacked it: description = "Apache Tapestry 5 Project" // Remember that when generating a release, this should be incremented. Also don't forget to // tag the release in Subversion. tapestryVersion = "5.3-beta-20" jettyVersion = '7.0.0.v20091005' tomcatVersion = '6.0.30' testngVersion = '5.14.9' easymockVersion = '3.0' servletAPIVersion = '2.4' // Provided so that Jenkins can override the normal version number for nightly builds. version = System.getProperty('project-version', tapestryVersion) stagingUrl = "https://repository.apache.org/service/local/staging/deploy/maven2/" snapshotUrl = "https://repository.apache.org/content/repositories/snapshots" doSign = !project.hasProperty('noSign') && project.hasProperty("signing.keyId") buildscript { repositories { mavenLocal() mavenRepo name: "Gradle", urls: "http://repo.gradle.org/gradle/plugins-snapshots/" } dependencies { classpath "org.gradle.plugins:gradle-signing-plugin:0.0.1-SNAPSHOT" } } allprojects { apply plugin: 'eclipse' apply plugin: 'idea' ideaProject { javaVersion = 1.5 beforeConfigured { project -> project.modulePaths.clear() } } repositories { mavenCentral() // All things JBoss/Javassist/Hibernate mavenRepo urls: "https://repository.jboss.org/nexus/content/repositories/releases/" } } subprojects { version = parent.version group = 'org.apache.tapestry' configurations { provided deployerJars // meta -- non-code artifacts, such as sources and javadoc JARs meta } if (name != "quickstart") { apply plugin: 'java' apply plugin: 'groovy' // mostly for testing apply plugin: 'maven' apply plugin: 'project-report' sourceCompatibility = '1.5' targetCompatibility = '1.5' // See http://jira.codehaus.org/browse/GRADLE-784 sourceSets { main { compileClasspath += configurations.provided } test { compileClasspath += configurations.provided runtimeClasspath += configurations.provided } } ideaModule { scopes.PROVIDED.plus += configurations.provided } dependencies { groovy "org.codehaus.groovy:groovy-all:1.7.4" deployerJars "org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-6" } test { useTestNG() options.suites("src/test/conf/testng.xml") maxHeapSize = "400M" // Turn off live service reloading systemProperties["tapestry.service-reloading-enabled"] = "false" jvmArgs("-XX:MaxPermSize=512m") } task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' from sourceSets.main.allSource } artifacts { meta sourcesJar } } configurations { // published -- what gets uploaded to the Nexus repository published.extendsFrom archives, meta if (doSign) { published.extendsFrom signatures } } if (doSign) { apply plugin: 'signing' // sign (create PGP signature for) archives (standard JARs) // and meta (sources JARs) signing { sign configurations.archives, configurations.meta } } // apacheDeployUserName and apacheDeployPassword should be specified in ~/.gradle/gradle.properties deployUsernameProperty = isSnapshot() ? "snapshotDeployUserName" : "apacheDeployUserName" deployPasswordProperty = isSnapshot() ? "snapshotDeployPassword" : "apacheDeployPassword" canDeploy = [deployUsernameProperty, deployPasswordProperty].every { project.hasProperty(it) } uploadPublished { doFirst { if (!canDeploy) { throw new InvalidUserDataException("Missing upload credentials. Set '$deployUsernameProperty' and '$deployPasswordProperty' project properties.") } } if (canDeploy) { repositories { project.deployer = repositories.mavenDeployer { if (doSign) { beforeDeployment { MavenDeployment deployment -> def signedPomArtifact = sign(deployment.pomArtifact).singleArtifact // See http://issues.gradle.org/browse/GRADLE-1589 signedPomArtifact.type = "pom." + signing.type.extension deployment.addArtifact(signedPomArtifact) } } repository(url: stagingUrl) { authentication(userName: project.getProperty(deployUsernameProperty), password: project.getProperty(deployPasswordProperty)) } snapshotRepository(url: snapshotUrl) { authentication(userName: project.getProperty(deployUsernameProperty), password: project.getProperty(deployPasswordProperty)) } } } } } } // Specific to top-level build, not set for subprojects: configurations { javadoc published.extendsFrom archives, meta if (doSign) { published.extendsFrom signatures } } dependencies { javadoc project(':tapestry-javadoc') } subprojects.each { project.evaluationDependsOn(it.name) } // Cribbed from https://github.com/hibernate/hibernate-core/blob/master/release/release.gradle#L19 javadocBuildDir = dir(buildDirName + "/documentation/javadocs") task aggregateJavadoc(type: Javadoc, group: "Documentation") { dependsOn configurations.javadoc description = "Build the aggregated JavaDocs for all modules" maxMemory = '512m' destinationDir = javadocBuildDir.dir configure(options) { // overview = new File( projectDir, 'src/javadoc/package.html' ) stylesheetFile = new File(projectDir, 'src/javadoc/stylesheet.css') windowTitle = 'Tapestry API Documentation' docTitle = "Tapestry JavaDoc ($project.version)" bottom = "Copyright © 2003-2011 <a href=\"http://tapestry.apache.org\">The Apache Software Foundation</a>." use = true links = ['http://download.oracle.com/javase/6/docs/api/', 'http://download.oracle.com/javaee/6/api/'] addStringOption "tagletpath", configurations.javadoc.asPath addStringOption "taglet", "org.apache.tapestry5.javadoc.TapestryDocTaglet" exclude "org/apache/tapestry5/internal/plastic/asm/**" } subprojects.findAll({ sp -> sp.name != "quickstart" }).each { sp -> sp.sourceSets.all.findAll { set -> set.name != "test" }.each { set -> source set.java classpath += set.classes + set.compileClasspath // Some of the component .xdoc files refer to PNG images // (we could also exclude .java and .xdoc) copy { from set.java.srcDirs.toList() into javadocBuildDir.dir include '**/*.png' } } } } aggregateJavadoc.doLast { copy { from new File(projectDir, 'src/javadoc/images') into new File(javadocBuildDir.dir, "/images") } } task clean(type: Delete) { delete buildDirName } task continuousIntegration(dependsOn: [subprojects.build, 'aggregateJavadoc', subprojects.uploadPublished], description: "Task executed on Jenkins CI server after SVN commits") task generateRelease(dependsOn: ['continuousIntegration', subprojects.uploadPublished, 'zippedSources', 'zippedJavadoc'], group: "Release artifact", description: "Generates and uploads a final release to Apache Nexus") task wrapper(type: Wrapper) { gradleVersion = '1.0-milestone-3' description = "Regenerates the Gradle Wrapper files" } task zippedSources(type: Zip) { description = "Creates a combined Zip file of all sub-project's sources" group = "Release artifact" destinationDir = buildDir baseName = "apache-tapestry" version = project.version classifier = "sources" from project.projectDir exclude "**/.*/**" exclude "**/bin/**" exclude "**/target/**" exclude "**/build/**" exclude "**/test-output/**" // Left around by TestNG sometimes } task zippedJavadoc(type: Zip, dependsOn: aggregateJavadoc) { description = "Zip archive of the project's aggregate JavaDoc" group = "Release artifact" destinationDir = buildDir baseName = "apache-tapestry" version = project.version classifier = "javadocs" from javadocBuildDir.dir into "apidocs" } boolean isSnapshot() { project.version.contains('SNAPSHOT') } https://gist.github.com/1282666 It's a bit ugly (suggestions welcome), but basically skips a bunch of setup that occurs in most modules for the "quickstart" module. Mostly it works fine, except for the uploadPublished task, as defined starting on line 143. When I try to build, I get an exception: $ gr genR -x test Note: the Gradle build daemon is an experimental feature. As such, you may experience unexpected build failures. You may need to occasionally stop the daemon. FAILURE: Build failed with an exception. * Where: Build file '/Users/hlship/workspaces/tapestry/tapestry5/build.gradle' line: 143 * What went wrong: A problem occurred evaluating root project 'tapestry5'. Cause: Could not find method uploadPublished() for arguments [build_13a7g2thd0j4oqok73diap6lkl$_run_closure2_closure25@5c304dd3] on root project 'tapestry5'. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 0.89 secs ~/workspaces/t5 $ More details here: https://gist.github.com/1282681 If I add "task " to the start of the line (to clearly indicate the uploadPublished is supposed to be a new task added to the subproject), it works, but uploadPublished doesn't seem to do anything. Perhaps this way it overwrites the uploadPublished task normally added by the :tapestry-yuicompressor:jar UP-TO-DATE :tapestry-yuicompressor:sourcesJar UP-TO-DATE :tapestry-yuicompressor:assemble UP-TO-DATE :tapestry-yuicompressor:check :tapestry-yuicompressor:build :tapestry-yuicompressor:uploadPublished :tapestry5-annotations:sourcesJar UP-TO-DATE :tapestry5-annotations:assemble UP-TO-DATE :tapestry5-annotations:check :tapestry5-annotations:build :tapestry5-annotations:uploadPublished :continuousIntegration :zippedJavadoc UP-TO-DATE :zippedSources :generateRelease ... see, it appears to have executed, but it certainly didn't upload anything to Nexus. I've tried a few things, such as reoganizing things to push the uploadPublished task definition further up but no dice. I'm going to dig a little deeper and see if there's an alternate way of dealing with quickstart specially. Any help would be appreciated! -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email