Much ado about scripting, Linux & Eclipse: card subject to change

Showing posts with label build. Show all posts
Showing posts with label build. Show all posts

2011-12-11

Build Nomenclature Conventions: What's in a name?

The following post is inspired by Mickael Istria's recent blog, Call a spade a spade, and a Nightly a Snapshot.

When I was doing builds for the Eclipse Modeling Project, I-builds were weekly published nightlies -- same level of stability as a SNAPSHOT (to use Maven parlance) or nightly, but published on a weekly schedule to bridge the gap between nightly/daily/SNAPSHOT/CI builds and the every-6-weeks milestone releases. The goal was to provide something stable enough for early adopters to grab once a week, but without the non-stop flux of nightlies. Regardless of the label on the build, the process was the same: tag CVS, then build using that tag.

The Final/GA/Release ("R") builds were done as simple renames of the last good milestone or release candidate build, so as to ensure binary-compatibility w/ the last-tested milestone/RC. The same was true for "M" and "S" builds -- they were just renamed "I" builds, and the letter was there simply to differentiate between a maintenance build (M), a stable milestone (S), or release (R).

Branching only happened when a release was done and it was time to produce the maintenance stream vs. the ongoing next-year-release. Sometimes branching would happen AFTER the x.y.1 maintenance because it saved duplication of commits in the x.y+1.0 and x.y.1 streams.

--

Now at JBoss, we publish "nightly" builds, which are keyed to SVN changes and therefore could be as often as hourly or as infrequent as weekly, depending on what's happening in the repo.

We also do milestone builds about once ever 6-8 weeks (similar to the Eclipse.org release train schedules), which is more carefully vetted, tested, and QE'd. It is produced using the same *process* as the nightlies, but are named differently and pulled from a freshly-created stable branch in the repo (so its degree of change/churn is less). (Branching happens right before every milestone or release candidate so that hardening/stabilization/documentation can happen in the branch while trunk stays open for new development.)

--

Bottom line -- I've only ever needed three types of builds, regardless of nomenclature or labelling differences. And of these 3, the last 2 are the same thing but renamed to underline the build quality/stability:

* nightly/CI/integration/weekly/SNAPSHOT build (unstable, for bleeding edge adopters)

* development milestone (probably a re-christened nightly; stable, early adopters)

* stable release / Final / GA (probably a re-christened milestone; release quality)

--

So... does it matter if it's called nightly, integration or SNAPSHOT? or Stable, Milestone, Maintenance, Final, GA or Release? As long as it's easily reproducible (yeah, Tycho!), what's in a name?

2011-10-29

HOWTO: See what happened in SVN between builds

I was recently asked how to determine what changed between two builds. Jenkins provides nice interlinks into JIRA (issues), Fisheye (source changes), SVN (sources), but let's say you want to kick things a little more old school and investigate the old way... or the builds you want to compare are no longer shown in Jenkins because they expired and their metadata was automatically purged.

If you can't just look at the changelog in Jenkins to see what revision of source was used for the build, you can check the SVN log to find revision numbers based on the timestamp of the build.

So, if your build was generated on 2011-10-18, you can see that the log shows the last commit before that build was this:

$ svn log http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

...

r35735 | bfitzpat | 2011-10-17 15:35:23 -0400 (Mon, 17 Oct 2011) | 2 lines
Changed paths:
   A esb/plugins/.project
   M esb/plugins/org.jboss.tools.esb.project.core/src/org/jboss/tools/esb/core/runtime/ESBRuntimeResolver_410.java

JBDS-1889 - Now checking for juddi-client-3.1.2.jar as well as 3.1.0 and 3.1.1 when seeing if the runtime includes ESB 4.10

...

Want to see actual diffs between that build and the latest one?

$ svn diff http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/@35735 http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

Or, if you want to collect just the section of log relevant to the change:

$ svn log -r35735:HEAD http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

Of course if you have all the sources locally, you don't need to log or diff via a URL - you can simply use local file paths. And if like me you use git-svn instead of pure svn, you can use that to diff or log too.

If you want to easily determine when a branch was created and get the SVN revision number for that branch point, use this:

# from r28571, returns -r28571:HEAD
rev=$(svn log --stop-on-copy \
  http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
  | egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#")

If you'd like to view a specific svn revision in your browser, use !svn/bc/REVISION_NUMBER/ before the branch and path to file or folder:

http://svn.jboss.org/repos/jbosstools/!svn/bc/35735/branches/jbosstools-3.2.x/

2010-10-08

HOWTO: Find the feature that contains a plugin

Tycho is awesome.

However, like all build systems, it has its limitations.

One such limitation is that when you're building against a target platform, and something's missing, you get errors such as these:

[INFO] Cannot complete the request.  Generating details.
{org.osgi.framework.executionenvironment=OSGi/Minimum-1.0,OSGi/Minimum-1.1, osgi.ws=cocoa, osgi.arch=x86, osgi.os=macosx, org.eclipse.update.install.features=true, org.osgi.framework.system.packages=}
[Software being installed: org.jboss.tools.tptp.feature.feature.group 1.2.0.qualifier, Missing requirement: org.eclipse.tptp.platform.instrumentation.ui 4.4.1.v201009092123 requires 'bundle org.eclipse.hyades.probekit [4.2.0,5.0.0)' but it could not be found, Cannot satisfy dependency: org.eclipse.tptp.platform.instrumentation.ui.feature.group 4.3.1.v201009092123-797908s73533D4H6D56 depends on: org.eclipse.tptp.platform.instrumentation.ui [4.4.1.v201009092123], Cannot satisfy dependency: org.jboss.tools.tptp.feature.feature.group 1.2.0.qualifier depends on: org.eclipse.tptp.platform.instrumentation.ui.feature.group 4.3.0]
[ERROR] Internal error: java.lang.RuntimeException: org.eclipse.equinox.p2.core.ProvisionException: No solution found because the problem is unsatisfiable. -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: org.eclipse.equinox.p2.core.ProvisionException: No solution found because the problem is unsatisfiable.

The important part of that error message is as follows:

org.jboss.tools.tptp.feature.feature.group 1.2.0.qualifier
   requirement: org.eclipse.tptp.platform.instrumentation.ui 4.4.1.v201009092123 
      requires 'bundle org.eclipse.hyades.probekit [4.2.0,5.0.0)' 
         but it could not be found

org.eclipse.tptp.platform.instrumentation.ui.feature.group 4.3.1.v201009092123-797908s73533D4H6D56 
   depends on: org.eclipse.tptp.platform.instrumentation.ui [4.4.1.v201009092123]
     dependency: org.jboss.tools.tptp.feature.feature.group 1.2.0.qualifier 
        depends on: org.eclipse.tptp.platform.instrumentation.ui.feature.group 4.3.0]

So, how do you find which feature contains that plugin, so that you can add it to your target platform?

First, you need access to the repository. If you have direct server access to the repository from which the plugin comes (eg., the TPTP Helios update site), you can run this script in the root of that repository.

If you don't have server access (eg., you can't ssh to dev.eclipse.org and look in ~/downloads/tptp/updates/helios), then you can pull down a zip of the site (or use a p2.mirror script to fetch a copy of the site to your local machine)... and then run this script in the root of that repository.

Essentially the script finds matching feature jar files, unpacks them to extract the feature.xml files therein, and then greps those files for lines which suggest an included plugin matching the pattern for which you're searching:

$ findInFeature platform.probekit
./features/org.eclipse.tptp.platform.probekit_4.5.1.v201009092123-7H7BF8PAkF7B77ZARCNEK.jar
   <plugin
         id="org.eclipse.tptp.platform.probekit"

./features/org.eclipse.tptp.platform.trace_4.5.1.v201009092123-7L7O8bBgJ9E99jAfGWEM.jar
   <plugin
         id="org.eclipse.tptp.platform.probekit.launch"
From there, it's a trivial exercise to add another line item into your target platform file. First, paste in the feature jar:
./features/org.eclipse.tptp.platform.probekit_4.5.1.v201009092123-7H7BF8PAkF7B77ZARCNEK.jar

Then use vim to pattern-replace that string:

:%s/.\+\/\(org.\+\)_\(\d\+.\+\)\.jar/\t\t\t/g

And you'll end up with a new .feature.group added to the target:

<unit version="4.5.1.v201009092123-7H7BF8PAkF7B77ZARCNEK" id="org.eclipse.tptp.platform.probekit.feature.group"/>

2010-07-20

Troubleshooting Eclipse.org Mirrors / Using Profiles & Target Platform Definition Files With Tycho

If you look in the mirror and you say his name 5 times, he'll appear behind you breathing down your neck. - Candyman

If only troubleshooting mirrors was so simple. Have you ever been running a build or an install which stalls at the provisioning step, with a message like:

[INFO] Fetching org.eclipse.birt.integration.wtp.ui_2.6.0.v20100617-1315.jar.pack.gz (4.3MB of 46.13MB at 171.56kB/s) from http://mirrors.xmission.com/eclipse/birt/update-site/2.6/plugins/org.eclipse.birt.integration.wtp.ui_2.6.0.v20100617-1315.jar.pack.gz

The solution here is often simply to force p2 to pick a specific mirror rather than letting it choose any mirror it wants.

How, you ask?

Well, assuming you were polling this site looking for artifacts to install or update...

http://download.eclipse.org/birt/update-site/2.6/

... you would then change that URL to this, and look at the list of available mirrors:

http://www.eclipse.org/downloads/download.php?file=/birt/update-site/2.6/

Now it's a trivial matter to select a mirror that's close to you and try that instead of the download.eclipse.org mirror, such as:

ftp://mirror.csclub.uwaterloo.ca/eclipse/birt/update-site/2.6/

If you're running a Tycho build, this URL should be changed in your parent-pom.xml ...

<url>http://download.eclipse.org/birt/update-site/2.6/</url>

... or your .target platform file, depending on which way you're building.

<repository location="http://download.eclipse.org/birt/update-site/2.6/"/>

If you rely on a parent-pom.xml, make sure you're activating the profile with the revised URL...

mvn3 clean install -U -B -fae -Phelios

... or, if you're building against a .target platform file, make sure you update the URL in that file, and that your build points to the profile which will load the .target file.

mvn3 clean install -U -B -fae -P!helios,helios-no-target

UPDATE, 2010/08/11: Forgot to mention that there are a number of p2 update site zips available here to help with your offsite mirroring: http://download.eclipse.org/athena/repos/.

2010-04-04

Cleaner Ant Build Logs: Get Rid of "Trying to override old definition of task"

If you use macros in Ant, you have probably seen clutter in your log such as

Trying to override old definition of task ...

Here's how to purge this garbage from your log and keep your build output cleaner.

  1. move your macros into a target such as <target name="init">
  2. have your main target(s) depend on the target that defines the macros
  3. call your macros

You can make your log even quieter with -q when running ant, eg., ant -f build.xml -q

Here's a complete example that will first self-bootstrap itself by downloading Ant-Contrib, define two ant macros, and produce very quiet output (unless debug=true):

<project default="run">
 <property name="COMMON_TOOLS" value="${java.io.tmpdir}" />
 <property name="debug" value="false"/>

 <target name="get.ant-contrib" unless="ant-contrib.jar.exists">
  <property name="ANTCONTRIB_MIRROR" value="http://downloads.sourceforge.net/ant-contrib/" />
  <get usetimestamp="true"
       dest="${COMMON_TOOLS}/ant-contrib-1.0b2-bin.zip"
       src="${ANTCONTRIB_MIRROR}/ant-contrib-1.0b2-bin.zip"
  />
  <touch file="${COMMON_TOOLS}/ant-contrib-1.0b2-bin.zip" />
  <mkdir dir="${java.io.tmpdir}/ant-contrib-1.0b2-bin.zip_" />
  <unzip src="${COMMON_TOOLS}/ant-contrib-1.0b2-bin.zip"
         dest="${java.io.tmpdir}/ant-contrib-1.0b2-bin.zip_"
         overwrite="true"
  />
  <copy file="${java.io.tmpdir}/ant-contrib-1.0b2-bin.zip_/ant-contrib/lib/ant-contrib.jar"
        tofile="${COMMON_TOOLS}/ant-contrib.jar"
        failonerror="true"
  />
  <delete dir="${java.io.tmpdir}/ant-contrib-1.0b2-bin.zip_" includeemptydirs="true" quiet="true" />
 </target>

 <target name="init">
  <available file="${COMMON_TOOLS}/ant-contrib.jar" type="file" property="ant-contrib.jar.exists" />
  <antcall target="get.ant-contrib" />

  <taskdef resource="net/sf/antcontrib/antlib.xml">
   <classpath>
    <pathelement location="${COMMON_TOOLS}/ant-contrib.jar" />
   </classpath>
  </taskdef>
  
  <macrodef name="debug">
   <text name="echo" />
   <sequential>
    <if>
     <and>
      <isset property="debug" />
      <istrue value="${debug}" />
     </and>
     <then>
      <echo message="@{echo}" />
     </then>
    </if>
   </sequential>
  </macrodef>

  <macrodef name="list.count">
   <attribute name="list" default="" />
   <sequential>
    <var name="count" value="" />
    <for param="listitem" list="@{list}" delimiter=", ">
     <sequential>
      <var name="count" value="${count}0" />
     </sequential>
    </for>
    <length property="list.count.return" string="${count}" />
   </sequential>
  </macrodef>
 </target>

 <target name="run" depends="init">
  <property name="list" value="foo bar baz"/>
  <list.count list="${list}" />
  <debug>For list [${list}], size = </debug>
  <echo>${list.count.return}</echo>
 </target>

</project>

2010-03-31

HOWTO: Build Plugin & Feature Projects, Then Run Their Unit Tests w/ Tycho :: GEF Example

Note that the instructions below are for Linux (or MacOSX). On Windows, your YMMV, but the process is the same.

1. Check out the entire source tree of your project from CVS, SVN, or Git into ~/build.

2. If needed, move plugins, features & test plugins into:

~/build/plugins/
~/build/features/
~/build/tests/

(Test features should go into features/ folder too.)

3. Install scala from http://www.scala-lang.org/downloads

4. Fetch genpom.scala and parent-pom.xml; save in ~/build or equivalent.

5. Tweak parent-pom.xml to suit your needs or use as-is.

6. Run this to generate pom.xml files for plugins, features, and tests:

cd ~/build/plugins/; scala ../genpom.scala
cd ~/build/features/; scala ../genpom.scala
cd ~/build/tests/; scala ../genpom.scala

7. Download Maven 3 from http://www.apache.org/dyn/closer.cgi?path=/maven/binaries/apache-maven-3.0-alpha-7-bin.tar.gz

8. Install Maven 3

sudo su; cd /opt; tar xvzf apache-maven-3.0-alpha-7-bin.tar.gz
ln -s apache-maven-3.0-alpha-7 maven3

9. For convenience, alias mvn3 to the new maven:

alias mvn3='/opt/maven3/bin/mvn 2>&1 clean install | tee buildlog.latest.txt'

10. Build the plugins, features, and finally tests:

cd ~/build/plugins/; mvn3
cd ~/build/features/; mvn3
cd ~/build/tests/; mvn3
Look in ~/build/plugins/org.eclipse.*/target/ for generated jars.
Look in ~/.m2/repository/org/eclipse/* for published jars.
To automate steps 6 and 10, you can run this script in the ~/build/ folder:
#!/bin/bash
for f in plugins/ features/ tests/; do \
  cd $f; scala ../genpom.scala; \
  /opt/maven3/bin/mvn 2>&1 clean install | tee buildlog.latest.txt; \
  cd ..; \
done

(The above blog is also posted here.)

2010-03-24

I'm in love with Tycho 0.8 and Maven 3

Monday:

Signed up for GitHub, downloaded apache-maven-3.0-alpha-7-bin.tar.gz, and built Tycho from source. Took a bit of path wrangling (namely figuring out that maven runs based on current directory), but it built and most of the tests passed. Not bad for my first day ever using Maven.

# First download Maven3 and unpack into /opt/
export MAVEN_OPTS="-Xmx512m"
export TYCHO_TARGET_PLATFORM=/home/nboldt/eclipse/35clean/eclipse
mvn=/opt/maven/bin/mvn
$mvn clean install -e -V -Pbootstrap-1
$mvn clean install -e -V -Pbootstrap-2 -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM
$mvn clean test -e -V -Pits -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM

The really confusing part was "what now? what did I just build? And how do I use it?" Answer: You can now run maven3 from .../sonatype-tycho/tycho-its/target/apache-maven-3.0-alpha-7/bin/mvn


Tuesday:

Attended the Sonatype-sponsored Tycho Build Workshop, and amazed Pascal by saying good things about Tycho and Maven3. Apparently I'm known to complain about all things p2, despite my numerous blogs and wiki contributions touting its success and usefulness. Also installed m2eclipse to see how effective the pom editor is.

During the workshop, I got the following JBoss Tools projects to build: jmx, archives, as, flow, jbpm3/4, drools, bpel, smooks, common. That's nearly half our projects! Thanks to Jason and Igor for their invaluable assistance.

The reason it was so easy was that Max had already created a scala script to generate all the pom.xml files we need to build JBoss Tools, and a parent-pom.xml on which those tiny pom.xml files depend. (For me as a Maven noob, not having to think at all about creating poms made this transition a no-brainer. Speaking of no-brainers, my slides from Monday's talk about Dash Athena and Zombies are here (PDF).

As an added bonus, Tycho, being more strict than PDE, exposes missing information in MANIFEST.MF files such as dependencies on plugins. PDE-based builds are apparently more forgiving because they generally include more crap than is actually needed in the target platform against which the build runs; Tycho builds against what you tell it you need. So, the mavenification of JBoss Tools will actually cause us to have better described plugins, and therefore make them easier to build anywhere. I'm very impressed so far.

Unlike Dash Athena which needs to be told all the IUs (features/plugins) against which your project needs to build, Tycho determines this information from your manifests, so the information need not be duplicated.

I still need to look at how to build update sites from the output of a Tycho build, and how to hook in SWTBot/JUnit4 tests. I have a suspicion this may be handled using Buckminster tools such as their Aggregator, or my own custom Ant hackery using the SWTBot wiki docs. Time will tell.


Wed

This morning on a whim I decided to see if I could port Max's scala script (aside: I've never seen scala before yesterday) to generate pom.xml files for EMF or GEF. Success! With some minor tweaks, I've managed to build GEF 3.6 into my local maven repo (~/.m2). Obviously there's more to be done here... but damn, this is easy.

2010-03-04

Athena: p2 repos w/ associate sites

Want to insert associate update sites into your user's Eclipse when they go to install your features from an update site/zip? With an Athena build this is now a trivial exercise. For example... say you're building a plugin which supports integration with Subclipse or Subversive. In a traditional install from an SDK or runtime zip, you'd unpack into eclipse/, and wonder why the new plugins didn't work. In the new p2 install world, you point Eclipse at the update site or zip, and are told that you cannot install the SVN integration because missing requirements cannot be found. So you hunt down the required sites, add them to Eclipse, and try again; this time you are allowed to install the new features. To improve the ease of use for the end user, Athena now allows you to define associate.sites in your build.properties. If this property is set, URLs will be added into your p2 repo's metadata and Eclipse will automatically add those sites when it scans your zip or site. No more manual copy+paste from documentation needed!

associate.sites=\
http://subclipse.tigris.org/update_1.6.x,\
http://download.eclipse.org/technology/subversive/0.7/update-site/,\
http://community.polarion.com/projects/subversive/download/eclipse/2.0/update-site/
And, of course, you can reuse these sites when resolving dependencies against which to build or test:
repositoryURLs=\
http://download.eclipse.org/releases/galileo/,\
http://download.eclipse.org/athena/repos/eclipse-Update-3.5.2-201002111343.zip,\
http://download.eclipse.org/eclipse/updates/3.5/,\
${associate.sites}

IUsToInstall=org.eclipse.sdk.feature.group+org.eclipse.sdk.ide+\
org.eclipse.team.svn+org.eclipse.team.svn.core+org.eclipse.team.svn.ui+\
org.tigris.subversion.subclipse.core+org.tigris.subversion.subclipse.ui

2010-01-05

PDE Best Practices : A Noob's Guide To Plugin & Build Health

I've drafted a collection of tips for keeping your plugins healthy and your builds green.

Feel free to add to, change, or comment on the list here:

http://wiki.eclipse.org/Common_Build_Infrastructure/Getting_Started/FAQ/Plugin_Health_And_Best_Practices

2009-12-04

Feeding The Right Sources To Your Builds

I was recently asked the best approach for how to control the input to one's builds, and while there is no single solution to this that fits all projects, here are two ways you might want to go.

Freeze Then Branch

The current approach for JBoss Tools development involves continuous nightly builds from trunk until such time as the project is deemed frozen in prep for an upcoming milestone or release candidate. At that time, the trunk is copied to branches/JBossTools-3.1.0.M4, and very little is done to that branch - only urgent tweaks and fixes. A new Hudson job is cloned from the current one, and adjusted to point at the branched sources instead of trunk. The maps are also updated to point at the new source location in SVN.

This allows more nightly builds towards an upcoming stable development milestone, while new development can continue in parallel in trunk. When the milestone is released, the unneeded job is disabled or removed.

The only issue with this approach is that all plugins, built from the head of a branch (or trunk) are re-versioned w/ the latest timestamp every time they're compiled. Thus upgrading from one 80M update to the next requires another 80M download. To mitigate this, milestones are released only once every month or two.

Tag And Release

The current approach for numerous Eclipse.org projects, such as GEF, is to develop continuously in HEAD and when a number of changes are ready to be released, a tool such as the org.eclipse.releng.tools plugin can be used to, in a single operation, both tag the sources and release those tags into the map file.

This permits a granular approach to plugin versioning wherein only the plugins which have actually changed are renumbered, and thus incremental updates between releases is possible, and if only a single plugin changes from week to week, only that plugin will be upgraded.

This approach also allows your adopters to get more stable, weekly updates rather than hourly or ad hoc nightlies which may include incomplete changes. Sure, you can only watch for good builds in Hudson, but a more predictable schedule makes inter-build communication easier.

The only issue with this approach is that it introduces extra overhead, unless the tag&release process can be automated and run on a (weekly?) schedule. For CVS sources, there is the org.eclipse.releng.tools.tagandrelease crontab script available; for SVN, no such script (yet) exists. Want to help? See bug 264713.

Hybrid Approach

With the Athena Common Build, you can set up a Hudson job to run from tagged maps, but also override those tags on demand to force a build from head (or trunk) instead of from the specific repo tags.

To do so, pass in the following flags to EXTRAFLAGS via your build's job configuration / parameters. To build from the workspace's sources instead of fetching anything new from the repo (bug 252774):

-localSourceCheckoutDir /opt/users/hudsonbuild/.hudson/jobs/${JOB_NAME}/workspace/

To fetch from the repo, but ignore tags (bug 251926):

-forceContextQualifier -fetchTag HEAD

Or, like many projects on build.eclipse.org have done, set up two jobs: one for nightly from trunk, and one for weekly integration from maps. Then instead of doing CI builds when you remember to, they will run automatically when the repo changes so you'll have immediate feedback when something has broken. Add email, IRC, or Twitter notification to the job, and everyone else will know too.

2009-10-13

Dash Athena News, Oct 2009

Have you heard the latest? Here's what's been going on in the Dash Athena project lately.

Infrastructure Changes

  • There are now 43 Athena jobs on build.eclipse.org! Of those, 30 are green, 1 is yellow, and 6 have not yet been enabled. These jobs represent 29 different projects' builds! 6 of them use SVN sources instead of CVS.

  • bug 257074 comment 12 build.eclipse.org now has SVN 1.6.5; if your map files no longer work (your build complains it can't resolve plugin or features sources) then read this.

New Features

  • bug 291446 Provide hook for extra actions after fetching code from repo and before compiling it (e.g. code generation, parser generators, etc.)

  • bug 275529 Athena is now a full Project rather than a Component! Now if we could just get someone to design a logo... Do I need to offer up prizes? I will, if you comment on bug 272723 with some design ideas (or prize ideas).

Better Documentation

See also Older New & Noteworthy.

2009-09-07

Re-Return to Athena

Thanks to Miles for taking the time to slap Athena into submission on his local system - frequent and regular stress testing is what's going to make this facade over PDE bridge the gap between today and the far-flung future (namely B3).

Because he took the time to itemize his concerns / problems / gotchas, I thought I'd take the time to explain why these happen... and which are bugs vs. features. Speaking of bugs and features, Athena has a handy New & Noteworthy wiki page which I update about once a month. If you've never seen the N&N, it's here.

# skipPack=true is useful if you want to test locally. I found that the update manager does not work with pak'd jars when running locally. Perhaps P2 is relying on something on the web server side..?
If p2 isn't properly unpacking pack'd jars, the problem is either: you're using a JDK with pack200 bugs (like Sun 1.6), or you have jars which should never be packed. How can you exclude jars from packing? See JarProcessor Options.
# The build scripts appear to be simply searching for the occurrence of strings to determine wether a given map entry type is being used. They do not appear to respect the comment lines. I guess I should file a bug report on this one -- it cost a bit of time because I have a dodgy SVN setup on my home laptop. I'm actually still not sure what is going on with that (and does the mysterious Java 134 error msg have anything to do with it) but I'm trying to learn not to fix things for which I have a work-around, i.e. if ti works on a different machine, just use that instead!
The purpose of the collectMapTypes task is to simply know what types of maps are being used so that warnings can be echoed to the user if appropriate. If you use SVN on linux, there's a good chance you'll get this message:
[echo] If you get a SIGSEGV or Java Result: 134 when fetching from SVN, remove 
[echo] subversion-javahl and svnkit to force PDE to use commandline svn client.
Why? Because it's a pain in the butt to debug, and at least having a message in the build log gives you some tea leaves to read. I favour documentation over performance in this case.
# There is a somewhat lengthy description at http://wiki.eclipse.org/Common_Build_Infrastructure/Getting_Started of how to setup your local build to use a local cache CVS site but I'm not sure what scenario that would really be helpful in. I just use COPY and it works fine. I suppose that using the CVS approach might excercie some issues that you wouldn't run into with a plain COPY. And I'm not sure wether the local build copies over the binary files or not. If it does, you could get different build results if say your local environment happens to place some artifacts in the copied directories that aren't cleaned out by the PDE build. Not going to worry about it!
A more useful scenario is to take a dump of a CVS, SVN, or Git tree, and point your build at that folder using localSourceCheckoutDir=/path/to/full/source/tree/root in your build.properties file. Then it'll build against that local source cache instead of having to fetch from the repo. Once you have the dump of the repo, from Eclipse do File > Import > Existing projects, and you can have those same projects compilable/editable in your workspace. You can also use Eclipse (eg., with Subversive, Subclipse, eGit) to update the cache before doing a build.
# A useful hack when building locally is to pack up your difficult dependency(s) into a zip file and refer to them in your dependencyURL. It doesn't matter what you use for the URL, because it will use the cached file instead. For example, GEF3D doesn't yet have a build or update site. (We've been collaborating a bit on this so hopefully the build I've got working will help them get one up soon.) So instead of solving the the SVN stuff right away, I put that off until everything else worked. So I created a zip and added an entry for http://download.eclipse.org/tools/gef/fake/gef3d.zip. You have to be careful to have your zip file packaged up correctly or it won't work. That's easy to get wrong..your file structure needs to conform to the standard structure, i.e. eclipse/plugins/some.plugin. On the other hand, you have to be careful to remove these fake dependencies when you begin testing the real fetched versions! The fetch part then fails silently; your build succeeds but using the previously downloaded files.
I generally add comments (TODO, FIXME) in my build.properties to mark temporary hacks, or use a new file, like build.properties.local.hack so I'm not breaking the server-friendly version. (Just make sure you tell build.xml which build.properties file to use, if not the default one -- and DON'T CHECK IN the changed file.)
# But in any case getting the SVN map file right has been a major headache. Again, the only reason I want this is to grab the GEF3D sources, but I can't seem to let this one go as it seems that it should be so easy. The Athena build seems to mangle things in the fetch script; or perhaps this is a PDE Build issue. So I tried the sourceforge style entry and after a couple of hours of fiddling (see below) I found a magic incantation that seems to work -- plugin@org.eclipse.draw3d=SVN,trunk,http://dev.eclipse.org/svnroot/technology/org.eclipse.gef3d,,org.eclipse.draw3d@HEAD
@HEAD is optional; you only need to specify a tag if it's not the HEAD of the branch or trunk. Here's a sample SVN map.
# It would be super nice if there were a built-in dependency analyzer so that one could find the root plugin issues easily. As it is, if you have a bad dependency you get the whole tree and you have to walk the tree by hand to find out the root cause. Overall I think this is another demonstration of the ultimate weakness of the standard build systems out there. They are by nature linear (batch) approaches and so usually you can't do post hoc or inline analysis of issues. There is no semantic information in logs! You end up having to parse them back if you want to do any useful analysis. In a parallel lifetime, I would love to work on a simple semantic logging system that would allow structured analysis of this sort.
I believe the Buckminster guys are doing work in this area, so this may make its way into B3.
# Here is something else that I would love to do given time. The map files are pretty well structured - it would be nice to whip up a quick XText editor that would at least check syntax and more ambitiously provide a mechanism for hooking in semantic checks -- wouldn't it be nice if you could check that that SVN url is correct while editing the map file itself?!
Add that to the wishlist for B3!
# I'm still not sure how Athena determines what goes in the sdk vs. runtime vs. example zips so for now I'm just building the examples manually. Anyone come across documentation for this?
This arbitrary allocation of files is done in common.releng/tools/scripts/buildAllHelper.xml, lines 1063-1097, and is only done if the build.steps entry 'buildZips' is enabled. This behaviour is as far as I'm concerned deprecated, but in place simply to ease transition for existing builds using the old Common Modeling Build to the Athena Common Build. IMHO, no one needs these zips - you only need an update site zip. If you don't like what's in the zips, you can omit the 'buildZips' step and package your own zips by hand, eg:
 <zip destfile="${buildDirectory}/${buildLabel}/${SDKZip}" update="true">
   <zipfileset src="${buildDirectory}/${buildLabel}/${allZip}" dirmode="775" filemode="664" excludes="**/*.pack.gz, **/pack.properties, **/features/*.jar, **/${domainNamespace}.*.all*, **/${domainNamespace}.*.all*/**" />
 </zip>

(For those unfamiliar with the story of the Re-Return, you need to watch HIMYM, S1E15.)

2009-07-24

Athena Common Builder: Thanks to the early adopters!

Here's a quick list of some of the projects @ Eclipse.org currently using Athena. If you haven't tried Athena, maybe it's time!

  1. Linux Tools
  2. Visual Editor (VE)
  3. Voice Tools (VTP)
  4. PDE Declarative Services Modeling Incubator (pde.ds.modeling.incubator)
  5. Nebula Widgets Gallery
  6. Faceted Project Framework (fproj)
  7. EMF Query (EMF MQ)
  8. EMF Validation (EMF VF)
  9. EMF Transaction (EMF MT)
  10. Ajax Tools Framework (ATF)
And @ JBoss.org, all available in JBoss Tools 3.1.0.M2 for Eclipse 3.5 (Galileo) ...
  1. JMX Console
  2. BPEL Editor*
  3. jBPM 3 and 4
  4. FreeMarker
  5. ...to name but a few.

* - will be available in M3 or you can get a nightly build here.

What are people saying about Athena?

"[I] really like the new build. It is much less confusing then the old [Common Modeling] one."

"[C]ongrats for this builder. It is quite good and I'm eager to rely fully on it."

"We are playing around with Athena and finding it really useful. It is already deployed to one of our customer developments. Thanks a lot for the hard work! We will definitely try to contribute back anything useful we will have in the process."

So, how do *you* get started? Here's a FAQ. Here's our New and Noteworthy. And here's all the rest of the knowledge base articles.

Oh, and I'd be remiss if I didn't mention that there's a big list of requested features still waiting for contributions. If you use Athena, you're already half-way to contributing back. Want to help? Drop me a line any time and we can discuss what holes need filling that match your skills and most directly improve your use of PDE, p2 and Athena.

2009-07-22

Using Hudson for parallel Athena builds

This week I set up a multi-configuration Hudson job to try doing EMF's Query, Validation, and Transaction projects as a single job (instead of the traditional three linked jobs), then Bernd took over to do most of the work required to migrate to the new, simpler build system... and unearthed a few sticky bugs along the way. For example, Athena now supports running from jarred test plugins, as well as test plugin folders. (Yes, I'm amazed no one ever tested that use case before now either. Anyway, it works now.)

Doing these builds in parallel (rather than serially) may be a bad idea, but for now, it lets the Q,V,T developers build all three linked components via a single build button, and if the sources for any of the three changes, all three will be rebuilt and tests will be run.

Since Transaction depends on Query and Validation, this is certainly useful; however, Query and Validation do not depend on each other, so there may be some extraneous build churn with this set up.

Still, it's nice to see a the status of all three builds in one place:

What's next? Well, hooking up FindBugs, eliminating all the old SDK/runtime zips (because we have the new, shiny, p2 update site zip instead, and you can convert from repo to "runnable" SDK easily using this script), and figuring out how to make the builds use each others' newer binary output instead of building from a known entity (Query 1.4.0.N.ten.minutes.ago vs. 1.3.0.R.last.month). Luckily, Athena supports building against p2 repos and Hudson has APIs for fetching the latest good output, so this should be as simple as configuring the Transaction build to fetch from the latest successful Query zip using properties like these:

dependencyURLs=https://build.eclipse.org/hudson/.../path/to/Update.zip

Of course if you want to build against the latest PUBLISHED update, you could do this:

repositoryURLs=http://download.eclipse.org/modeling/emf/query/updates/nightly/
featureIDsToInstall=org.eclipse.emf.query.sdk

2009-06-15

WTP Cruise Control #fail #eclipse35

Nine days without a green build this close to GA? Seriouslywtfbbq, people!

2009-05-26

Dash Athena: Eclipse Common Build System / Running Tests On Your System

Bjorn recently kvetched that Eclipse projects met two or three of those goals, but fell down on the "common build system" and "tests run on your system" [1].

While it's true I've seen a number of projects who don't have, don't run, or don't publish their tests, I'm a little disappointed to see Bjorn's no longer committed to the common build solution we've been working on since September 2006 (in earnest since June 2008). We do have a project to solve both those concerns, but like all things at Eclipse, it's powered by YOU. You want it to happen, you have to help. I'm looking for a few good contributors and committers for the Dash Athena project to supplement the great people we already have. Or, if you don't have time to contribute code, you can help by using the system, testing it, opening bugs, enhancing documentation, and blogging about it.

So, what is Dash Athena?

Well, it's a common build system using Hudson and PDE which can also be run commandline on Linux, Windows or Mac, or in Eclipse. It can produce zips of plugins, features, examples, tests, then run those tests. It can also produce update sites with p2 metadata, which can then be published to eclipse.org (or sourceforge.net, for that matter) so everyone can get your bits via Update.

Tests will currently only run on Linux - if you'd like to help us port to Mac OS X and Windows, please step up. The system works with CVS, SVN, and probably Git/Bzr/Hg too, since it supports building from locally checked-out sources and will copy your features/plugins so they're in the format that PDE requires. It supports source input via map files (soon Project Set Files (*.psf), too!) and binary inputs via zips and p2 repos / update sites.

If you aren't sure how to get started w/ an Athena build, please don't hesitate to ask. If you feel the docs are insufficient, incomplete, or inaccurate, let me know - or better - fix them! Want your own Hudson job to run your build? Just open a bug and we'll set you up.

Oh, and incidentally, the irony is not lost on me that I'm using American iconography above even though 5 of the 6 committers on the project are Canucks. :)

2009-04-18

All I really want is builds

With April 20 just around the corner, it's time to get ill... but first, something completely different.

Builds, all I really want is builds
And in the morning it's builds
'Cause in the evening it's builds

I like the way that they run
And when they're green they're so much fun
And I can always make 'em smile
Fetch all their sources and compile

Back in the day
There was this project 'round the way
It had no build system per se
But they kept codin', come what may

I asked them, "Please?" they said, "You may."
Their code was tight and that's ok
If they would code I'd be R.E.
And now it runs on build-dot-E

I hope you'll say, "Hey, me and you should try Athe-
na, more to come, but under way!"
We really need a website, eh?
For now slides, code, and the wi-kay

We'll move to Git when it's read-ay
But that won't be before this May
So get yourself a build today
Without the ol' P-D-E dismay

Builds - to do the fetchin'
Builds - do the compilin'
Builds - to do the testin'
Builds - and zipped-up filin'
Builds, that's all I really want is builds
Early adopters they want builds
In next-gen Hudson they want builds
Signed, packed, p2 repos...
Builds, builds, builds, builds, builds!

NOTE: Normally the artist name below links to the video on YouTube, but there's no official one, and everything else I found (school projects, Lego animation, stick figures, slideshows) were either incomplete, incorrect, or potentially NSFW. YMMV.

Beastie Boys - Girls

2009-04-02

Using EasyAnt with Ivy to fetch latest compile-time and run-time dependencies

Just started playing with Ivy and EasyAnt today.

Here's a quick guide to getting started with multi-module Ant builds (because the EasyAnt Examples documentation is incomplete). This also demonstrates Ivy's ability to pull the latest version of a dependency from a repository. (And I get to finally try out Alex Gorbatchev's SyntaxHighlighter.)

1. Download:

wget http://www.easyant.org/trac/downloads/5 -O /tmp/easyant-0.5-beta1-full.zip

2. Install as root, usable by all:

sudo su; 
unzip /tmp/easyant-0.5-beta1-full.zip -d /opt/easyant-0.5-beta1; \
cd /opt/easyant-0.5-beta1; \
mkdir modules repository cache; \
chmod -R g+rw *; chgrp -R users *; \
exit

3. Compile multi-module example's core jar:

export EASYANT_HOME=/opt/easyant-0.5-beta1; \
cd /opt/easyant-0.5-beta1/example/example-multimodule/example-core; \
$EASYANT_HOME/bin/easyant -p; \
$EASYANT_HOME/bin/easyant

4. Verify compiled jar:

unzip -l /opt/easyant-0.5-beta1/example/example-multimodule/example-core/target/artifacts/example-core.jar

5. Publish jar:

$EASYANT_HOME/bin/easyant repo-management:install-artifact -Dorg=org.apache.easyant \
  -Dmodule=example-core -Drev=0.1 -Dartifact=target/artifacts/example-core.jar \
  -Dinstall.override=true -Dto.resolver=local

6. Verify published:

unzip -l /opt/easyant-0.5-beta1/repository/org.apache.easyant/example-core/0.1/example-core.jar; \
cat /opt/easyant-0.5-beta1/repository/org.apache.easyant/example-core/0.1/example-core.ivy
<ivy-module version="1.0">
    <info organisation="org.apache.easyant" module="example-core" revision="0.1"/>
</ivy-module>

7. Compile multi-module example's Hello World jar:

cd /opt/easyant-0.5-beta1/example/example-multimodule/example-hello-world; $EASYANT_HOME/bin/easyant

8. Verify compiled jar:

unzip -l /opt/easyant-0.5-beta1/example/example-multimodule/example-hello-world/target/artifacts/example-hello-world.jar

8. Run Hello World app:

cd /opt/easyant-0.5-beta1/example/example-multimodule/example-hello-world; $EASYANT_HOME/bin/easyant run:run
...
run:run:
     [java] Hello World !

BUILD SUCCESSFUL
Total time: 2 seconds

9. Now, recompile the core jar, republish it as 0.2, then recompile the Hello World jar. Verify that the Hello World compilation used the newer 0.2 version instead.

cd /opt/easyant-0.5-beta1/example/example-multimodule/example-core; $EASYANT_HOME/bin/easyant; \
$EASYANT_HOME/bin/easyant repo-management:install-artifact -Dorg=org.apache.easyant \
  -Dmodule=example-core -Drev=0.2 -Dartifact=target/artifacts/example-core.jar \
  -Dinstall.override=true -Dto.resolver=local; unzip -l \
/opt/easyant-0.5-beta1/repository/org.apache.easyant/example-core/0.2/example-core.jar; \
cat /opt/easyant-0.5-beta1/repository/org.apache.easyant/example-core/0.2/example-core.ivy; \
cd /opt/easyant-0.5-beta1/example/example-multimodule/example-hello-world; \
$EASYANT_HOME/bin/easyant; $EASYANT_HOME/bin/easyant run:run
lib-resolve:
:: loading settings :: file = /opt/easyant-0.5-beta1/ivysettings.xml
[ivy:resolve] :: resolving dependencies :: org.apache.easyant#example-hello-world;working@x2lappy
[ivy:resolve]  confs: [default, test]
[ivy:resolve]  found org.apache.easyant#example-core;0.2 in local
[ivy:resolve]  [0.2] org.apache.easyant#example-core;latest.revision
[ivy:resolve] :: resolution report :: resolve 30ms :: artifacts dl 1ms

2008-12-08

Obfuscation 101: Ant-contrib

I have recently fallen in love with ant-contrib. I'd still rather write Bash scripts, but if one must interact w/ Ant, ant-contrib is the only way to survive it. Without it, you don't have variables, for-loops, or if-elseif-then trees.

Of course, with every love there are moments of extreme angst. For example, I've been fighting with this error for the last 12 hrs, on and off, as I've been trying to resolve bug 256440:

Invalid type class org.apache.tools.ant.TaskAdapter used in For task, it does not have a public iterator method

What does that mean? It means I'm a dumbass.

Though I should know better, I rely on tools such as Eclipse's Ant editor to tell me when I've messed up task syntax. And though it can do CTRL-SPACE completion for the <for> task, the editor doesn't mark this invalid (if I've already typed it in).

<for ...>
 <if>
   ...
 </if>
</for>

The fix?

<for ...>
 <sequential>
   <if>
     ...
   </if>
 </sequential>
</for>

Ultimately, though, I wish error messages would be written with the end-user in mind. The above problem would have been solved in seconds had it been simply "For task cannot contain nested If task... dumbass." :)

2008-01-25

Building Change

Seems everyone's talking about change these days. Hell, people are even ranting about the way media is changing.

But real issues aside, in part two of this series, I'd like to briefly mention two changes happening closer to home, here in releng-land:

  • EMF, SDO, and XSD are now being packaged a little differently. Consider this a little social experiment to see who, if anyone, still uses zips to get their downloads, rather than using Update Manager. Do you like the new "sourcedoc" zips? Feel free to let us know what you think (here, on IRC in #eclipse-modeling, or in the newsgroups).
  • GEF is now being built by the Common Modeling Build, the first (of many, I'm sure) projects to come over to the dark side. Will DSDP or VE be next? Time will tell.