400 likes | 812 Views
Maven Release Plugin. Anthony Whyte, Sakai Foundation David Horwitz , UCT . Maven basics. POM: Project Object Model. Not just a build tool -- Maven aspires to be a comprehensive project management tool. DECLARATIVE: uses XML to describe and model:
E N D
Maven Release Plugin Anthony Whyte, Sakai Foundation David Horwitz, UCT
Maven basics POM: Project Object Model. Not just a build tool -- Maven aspires to be a comprehensive project management tool. DECLARATIVE: uses XML to describe and model: • Project information, structure, relationships • Dependencies and their management • Build environment and settings • Artifacts and their locations PLUGINS: provides an extensible plugin architecture promoting universal reuse: • maven-compiler-plugin • maven-release-plugin • maven-surefire-plugin • maven-war-plugin • sakai-maven-plugin -> handles Sakai artifact deployment to Tomcat
Maven basics CONVENTION OVER CONFIGURATION: Maven assumes reasonable default behaviors, layouts, patterns, etc. Use the defaults or override as necessary but beware of diverting too far from the Maven way. OPINIONATED: Maven defines a lifecycle and a set of common conventions for compiling code, packaging distributions, locating artifacts, etc. Examples: Compilation target: ${basedir}/target/classes Distribution target: ${basedir}/target (assumes JARs) Source code home: ${basedir}/src/main/java Sakai: <sourceDirectory>src/java</sourceDirectory> Resources home: ${basedir}/src/main/resource Sakai: <directory>${basedir}/src/bundle</directory> Tests home: ${basedir}/src/test
Maven lifecycle LIFECYCLE: a collection of build phases. • validate - validate the project is correct and all necessary information is available • compile - compile the source code of the project • test - test the compiled source code using a suitable unit testing framework. • package - take the compiled code and package it in its distributable format, such as a JAR. • integration-test - process and deploy the package if necessary into an environment where integration tests can be run • verify - run any checks to verify the package is valid and meets quality criteria • install - install the package into the local repository, for use as a dependency in other projects locally • deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects. Source:http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
Maven glossary COORDINATES: set of identifiers that provide a project address. <groupId>org.sakaiproject.kernel</groupId> <artifactId>sakai-kernel-api</artifactId> <version>1.1.8</version> SCOPE: determines which dependencies are available on the classpath: compile (default), provided, runtime, test, system. <scope>provided</scope> (provided by the container, exclude from *.war) INSTALL: compile and install artifacts into local Maven repository mvn clean install -> /{HOME}/.m2/repository
Maven glossary ARTIFACTS: stable distributable archives and files. basiclti-impl-1.1.3.jar polls-1.3.6.pom SNAPSHOT: convenience artifacts generated during development; unstable, replaceable without warning. messageforums-api-2.8-SNAPSHOT.pom sitestats-tool-2.2-SNAPSHOT.war REPOS: publicly accessible file stores of artifacts. http://source.sakaiproject.org/maven2/org/sakaiproject/ http://source.sakaiproject.org/maven2-snapshots/org/sakaiproject/
Maven glossary GOALS: a plugin set of tasks, a unit of work. Maven-release-plugin 2.0-beta-9 clean prepare perform stage rollback help mvn release:clean release:prepare release:perform
maven-release-plugin sakai-standard-tool-2.7.7.pom <build> <plugins> . . . <plugin> <inherited>true</inherited> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-9</version> <configuration> <preparationGoals>clean verify install</preparationGoals> <autoVersionSubmodules>true</autoVersionSubmodules> <useReleaseProfile>true</useReleaseProfile> </configuration> </plugin> . . . </plugins> </build>
mvn release plugin description mvn help:describe –Dplugin=release [INFO] -------------------------------------------------- [INFO] Building BasicLTI base pom (basiclti) [INFO] task-segment: [help:describe] (aggregator-style) [INFO] -------------------------------------------------- [INFO] [help:describe {execution: default-cli}] [INFO] org.apache.maven.plugins:maven-release-plugin:2.0-beta-9 Name: Maven Release Plugin Description: This plugin is used to release a project with Maven, saving a lot of repetitive, manual work. Group Id: org.apache.maven.plugins Artifact Id: maven-release-plugin Version: 2.0-beta-9 Goal Prefix: release This plugin has 7 goals: release:branch Description: Branch a project in SCM. Deprecated. No reason given release:clean Description: Clean up after a release preparation. Deprecated. No reason given release:help Description: Display help information on maven-release-plugin. Call mvn release:help -Ddetail=true -Dgoal=<goal-name> to display parameter details. Deprecated. No reason given release:perform Description: Perform a release from SCM. Deprecated. No reason given release:prepare Description: Prepare for a release in SCM. Deprecated. No reason given release:rollback Description: Rollback changes made by a previous release. Deprecated. No reason given release:stage Description: Perform a release from SCM to a staging repository. Deprecated. No reason given
mvn release plugin goal detail mvn release:help -Ddetail=true -Dgoal=prepare release:prepare Prepare for a release in SCM. Available parameters: addSchema (Default: true) Whether to add a schema to the POM if it was previously missing on release. allowTimestampedSnapshots (Default: false) Whether to allow timestamped SNAPSHOT dependencies. Default is to fail when finding any SNAPSHOT. Arguments Additional arguments to pass to the Maven executions, separated by spaces. autoVersionSubmodules (Default: false) Whether to automatically assign submodules the parent version. If set to false, the user will be prompted for the version of each submodules. commitByProject (Default: false) Commits to do are atomic or by project. developmentVersion Default version to use for new local working copy. dryRun (Default: false) Dry run: don't checkin or tag anything in the scm repository, or modify the checkout. Running mvn -DdryRun=true release:prepare is useful in order to check that modifications to poms and scm operations (only listed on the console) are working as expected. Modified POMs are written alongside the originals without modifying them. generateReleasePoms (Default: false) Whether to generate release-pom.xml files that contain resolved information about the project. javaHome (Default: ${java.home}) The JAVA_HOME parameter to use for forked Maven invocations. localRepoDirectory (Default: ${maven.repo.local}) The command-line local repository directory in use for this build (if specified). mavenExecutorId (Default: invoker) Role hint of the MavenExecutor implementation to use. mavenHome (Default: ${maven.home}) The M2_HOME parameter to use for forked Maven invocations.
mvn release plugin goal detail mvn release:help -Ddetail=true -Dgoal=prepare Password The SCM password to use. pomFileName The file name of the POM to execute any goals against. preparationGoals (Default: clean verify) Goals to run as part of the preparation step, after transformation but before committing. Space delimited. providerImplementations List of provider implementations. releaseVersion Default version to use when preparing a release or a branch. remoteTagging (Default: true) currently only implemented with svnscm. Enable a workaround to prevent issue due to svn client > 1.5.0 (http://jira.codehaus.org/browse/SCM-406) resume (Default: true) Resume a previous release attempt from the point where it was stopped. scmCommentPrefix (Default: [maven-release-plugin] ) The message prefix to use for all SCM changes. Tag The SCM tag to use. tagBase The tag base directory in SVN, you must define it if you don't use the standard svn layout (trunk/tags/branches). For example, http://svn.apache.org/repos/asf/maven/plugins/tags. The URL is an SVN URL and does not include the SCM provider and protocol. updateDependencies (Default: true) Whether to update dependencies version to the next development version. useEditMode (Default: false) Whether to use 'edit' mode on the SCM, to lock the file for editing during SCM operations. Username The SCM username to use.
Deploy/release prerequisites JAVA: SE 6 (e.g., 1.6) installed and on your shell’s path SVN: 1.6.5+ installed and on your shell’s path MVN: 2.2.1+ installed and on your shell’s path 2.0.x cannot deploy over scp; 2.1.0, 2.2.0 produce incorrect GPG signatures & checksums MVN_OPTS: Maven env variables: SSH: private/public ssh key created with passphrase. LICENSES: signed Sakai CLA on file; project licenses vetted (e.g., No GPL libraries) ACCOUNT: account on source.sakai.project created and accessible via ssh. LOCAL SETTINGS: settings.xml file created; <servers> element includes all Sakai servers defined along with <privateKey> and <passphrase>. POMS: project poms properly defined to both deploy and release project. MAVEN_OPTS=-Xms512m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=128m
Pom plumbing goals INSTALL: build from any location against an empty .m2 repo DEPLOY: deploy snapshots to snapshot repo RELEASE: generate stable release tags and binary artifacts; increment source branch pom version numbers automatically; deploy artifacts to release repo automatically. UPGRADE: update Sakai master pom <sakai.myproject.version>.
Adjust pom coordinates Maven dependencies are discovered by their “coordinates”, at a minimum <groupId>, <artifactId>, <packaging> and <version>. <groupId>: the standard Maven convention is for it to begin with the reverse domain name of the project owners and end with the project name, i.e., org.sakaiproject.sitestats. ✖ <groupId>org.sakaiproject</groupId> (old practice) to ✔ <groupId>org.sakaiproject.myproject</groupId> <artifactId>: most Sakai projects utilize the following pattern for the project’s unique identifier: sakai-myproject-module. Most Indie projects dispense with the “sakai” prefix as redundant, i.e., sitestats-api, sitestats-impl, sitestats-pack, sitestats-tool, sitestats-assembly sitestats-help, and sitestats (base pom).
<parent> switch to purepoms Unlike the “catch-all” Sakai master pom, purepom projectpoms (sakai-basic-tool, sakai-standard-tool, sakai-commons-tool, sakai-edu-tool) feature streamlined sets of dependencies limited to the kernel (all kernel dependencies are imported) entitybroker common edu-services Junit + any transitive dependencies In other words, the core set of dependencies required to build Sakai webapps. Additional Sakai dependencies required by a project must include explicit version declarations (e.g., <version> 2.7.3</version>, <version>[1.1.0, 1.2.0)</version>).
purepoms: sakai-standard-tool <parent>: none <dependencyManagement> includes the following dependencies: kernel base pom (<scope>=import) kernel util (<scope>=compile) kernel test-harness (<scope>=compile) entitybroker-api (<scope>=provided) junit (<scope>=test) <version> kernel: soft requirement (e.g., <version>1.1.8</version>) MNG-4463: artifacts with <scope>=import do not respect version ranges entitybroker: version range [1.0.0, 1.1.0) e.g., 1.0.0 <= x < 1.1.0 junit: soft requirement (e.g., <version>3.8.1</version>) Example tool: basiclti-1.1.3, sitestats-2.1.4
purepoms: sakai-commons-tool <parent>: sakai-standard-tool inherits kernel, entitybroker, junit dependencies. <dependencyManagement> includes the following common project dependencies: sakai-common-composite-component-data sakai-common-edu-person-api sakai-common-manager-api sakai-common-type-api sakai-privacy-api <version>: [1.0.0, 1.1.0) (all of the above) version range: 1.0.0 <= x < 1.1.0 <scope>: provided (all of the above) Example tool: profile2
purepoms: sakai-edu-tool <parent>: sakai-commons-tool inherits kernel, entitybroker, junit and common dependencies. <dependencyManagement> includes the following edu-services dependencies: sections-api coursemanagement-api gradebook-service-api <version>: [1.0.0, 1.1.0) (all of the above) version range: 1.0.0 <= x < 1.1.0 <scope>: provided (all of the above) Example tool: samigo-2.7.0
Add <scm> scm = source control management <scm> <connection> scm:svn:https://source.sakaiproject.org/svn/basiclti/ branches/basiclti-1.1.x </connection> <developerConnection> scm:svn:https://source.sakaiproject.org/svn/basiclti/ branches/basiclti-1.1.x </developerConnection> <url> https://source.sakaiproject.org/svn/basiclti/branches/ basiclti-1.1.x </url> </scm>
Add <distributionManagement> <downloadUrl>http://source.sakaiproject.org/maven2/</downloadUrl> <snapshotRepository> <uniqueVersion>false</uniqueVersion> <id>sakai-maven-snapshots-scp</id> <name>Sakai snapshot Repo</name> <url> scp://source.sakaiproject.org/var/www/html/maven2-snapshots </url> <layout>default</layout> </snapshotRepository> <repository> <uniqueVersion>false</uniqueVersion> <id>sakai-maven2-scp</id> <name>Sakai maven2 repository</name> <url>scp://source.sakaiproject.org/var/www/html/maven2</url> <layout>default</layout> </repository> <site> <id>sakai-site</id> <name>Sakai release Site</name> <url>${url.localsite}</url> </site>
Add <pluginRepositories> <pluginRepository> <id>Sakai Plugin Repo</id> <url>http://source.sakaiproject.org/maven2</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>maven2-central-repo</id> <name>Maven2 Central Repo</name> <url>http://repo1.maven.org/maven2/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository>
Add <repositories> <repository> <id>sakai-maven</id> <name>Sakai Maven Repo</name> <layout>default</layout> <url>http://source.sakaiproject.org/maven2</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>sakai-maven2-snapshots</id> <name>Sakai Maven Repo</name> <layout>default</layout> <url>http://source.sakaiproject.org/maven2-snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository>
Add <reporting> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.6.1</version> <configuration> <debug>true</debug> <links> <link>http://java.sun.com/j2se/1.5.0/docs/api/</link> </links> <breakiterator>true</breakiterator> <verbose>false</verbose> <aggregate>true</aggregate> <maxmemory>512m</maxmemory> <additionalJOption>-J-Xms168m -J-Xmx512m -J-XX:PermSize=128m -J-XX:NewSize=64m</additionalJOption> </configuration> </plugin> </plugins> </reporting>
Add an assembly module PURPOSE: leverage the maven-assembly-plugin to create binary and source distributions that include runtime dependencies, resource files, etc. Descriptors can be written to create custom assemblies in lieu of using pre-defined assemblies FORMATS: zip, tar.gz, tar.bz2, jar, dir, war. EXAMPLES BasicLTI:https://source.sakaiproject.org/svn/basiclti/branches/basiclti-1.2.x/basiclti-assembly/ Profile2:https://source.sakaiproject.org/svn/profile2/trunk/assembly/ Samigo:https://source.sakaiproject.org/svn/sam/trunk/samigo-assembly/ Sitestats:https://source.sakaiproject.org/svn/sitestats/branches/sitestats-2.1.x/sitestats-assembly/
Server settings (settings.xml) <servers> <server> <id>sakai-maven2-scp</id> <username>arwhyte</username> <privateKey>/Users/arwhyte/.ssh/id_dsa</privateKey> <passphrase>mypassphrase</passphrase> <directoryPermissions>775</directoryPermissions> <filePermissions>664</filePermissions> </server> <server> <id>sakai-maven-snapshots-scp</id> <username>arwhyte</username> <privateKey>/Users/arwhyte/.ssh/id_dsa</privateKey> <passphrase>mypassphrase</passphrase> <directoryPermissions>775</directoryPermissions> <filePermissions>664</filePermissions> </server> <server> <id>sakai-site</id> <privateKey>/Users/arwhyte/.ssh/id_dsa</privateKey> <passphrase>mypassphrase</passphrase> </server> <servers>
Create a branch Why perform an svn copy operation and then hack pom files in the new branch when instead you can use the release plugin’s branch goal: Result: one new branch with updated pom <version> (1.2.0-SNAPSHOT) and <scm> elements. <scm> <connection> scm:svn:https://source.sakaiproject.org/svn/basiclti/branches/ basiclti-1.2.x </connection> <developerConnection> scm:svn:https://source.sakaiproject.org/svn/basiclti/branches/ basiclti-1.2.x </developerConnection> <url> https://source.sakaiproject.org/svn/basiclti/branches/ basiclti-1.2.x </url> </scm> mvn release:branch -DautoVersionSubmodules=true \ –DbranchName=basiclti-1.2.x
Clean Removes release.properties and other release-related files from the source checkout. mvn release:clean
Prepare (dry-run) TEST RUN: always perform a test run of the release prepare goal before attempting a release. During the dry run and again during the release proper you will be prompted for version information. The release plugin will attempt to guess the release, tag and snapshot versions. You can accept the values as is or supply your own. mvn release:prepare -DdryRun=true . . . . [INFO] Checking dependencies and plugins for snapshots ... What is the release version for "BasicLTI base pom (basiclti)"? (org.sakaiproject.basiclti:basiclti) 1.1.4: : What is SCM release tag or label for "BasicLTI base pom (basiclti)"? (org.sakaiproject.basiclti:basiclti) basiclti-1.1.4: : What is the new development version for "BasicLTI base pom (basiclti)"? (org.sakaiproject.basiclti:basiclti) 1.1.5-SNAPSHOT: : . . . .
Release STEPS • Prompt user for release version info (name, number, next SNAPSHOT) • Check uncommitted changes in the source (fail) • Check for SNAPSHOT dependencies (fail) • Change pom version from x-SNAPSHOT to a new version • Change <scm> info to point to the final tag destination • Run project tests against modified poms; fail if tests fail • Commit modified poms • Tag code in the SCM with provided version name • Increment pom version to y-SNAPSHOT • Commit modified poms mvn release:clean release:prepare release:perform
Using profiles (-P) ACTIVATE: You can activate profiles when running the release plugin. SAMIGO: Test & Quizzes requires a signed audio jar (defined in samigo audio base pom). Signing the jar is accomplished by adding a profile in one's local settings.xml file that provides the Keystore location, password and alias. <profile> <id>jarsign</id> <activation> <activeByDefault>false</activeByDefault> </activation> <properties> <sakai.samigo-audio.jarsign.keystore.location> /Users/arwhyte/Sakai.keystore </sakai.samigo-audio.jarsign.keystore.location> <sakai.samigo-audio.jarsign.alias>myalias</sakai.samigo-audio.jarsign.alias> <sakai.samigo-audio.jarsign.password> mypassword </sakai.samigo-audio.jarsign.password> </properties> </profile> mvn –Pjarsign release:prepare release:perform
Rollback OOPS: if something goes wrong prior to the successful generation of release tags, you can rollback the release. RESULT: all poms are reverted back to their pre-release state locally, and also in the <scm> if the previous release command was able to successfully make changes in the poms. This is done by using the backup files created during release:prepare. WARN: If a tag was generated successfully before a plugin failure it will have to be removed manually. Release rollbacks will fail if mvn release:clean is executed prior to the rollback attempt. mvn release:rollback
Perform release using a tag You are part way through a release, the source branch is updated, the release tag has been created and then . . . Curse but don’t panic. If a tag has been generated DO NOT ROLLBACK; instead use it to perform the release (after addressing the permissions issue). [ERROR] BUILD ERROR . . . [INFO] Error deploying artifact: Exit code: 1 - mkdir: cannot create directory ‘/var/www/html/maven2/org/sakaiproject/scheduler/scheduler/2.7.3’: Permission denied svn co https://source.sakaiproject.org/…/tags/scheduler-2.7.3 cd scheduler-2.7.3 mvn release:perform -DconnectionUrl=scm:svn:https://source.sakaiproject.org/svn/jobscheduler/tags/scheduler-2.7.3
Snapshot deployments Refresh development artifacts Profile activation: cd msgcntr-trunk mvn clean install javadoc:jarsource:jar deploy cd samigo-trunk mvn -Pjarsign clean install javadoc:jarsource:jar deploy
Staging repository strategy Deploy pre-release artifacts to a staging server for final testing and review. If the test version passes muster, then it is copied to the public repository without change. Sakai currently does not use this approach. Instead, a release branch is created and any changes made to the branch are tested before the public release is generated from the branch. mvn release:clean release:prepare release:stage \ -DstagingRepository=maven2-staging::standard::scp://source.sakaiproject.org/var/www/html/maven2-staging
maven-release-plugin-2.0 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0</version> </plugin>
More info http://maven.apache.org/plugins/maven-release-plugin/ http://confluence.sakaiproject.org/display/REL/Maven+release+plugin+cheat+sheet