En las aplicaciones que desarrollo siempre incluyo un número de versión de dos dígitos junto a un registro de cambios (changelog) que documenta qué ha cambiado en cada versión. La gestión de todo esto es puramente manual.

Sin embargo me he encontrado a veces en situaciones en las que las iteraciones son muy rápidas, realizando despliegues de versiones locales en pocos minutos. Normalmente en trabajos junto con el cliente para pequeños ajustes de diseño, funcionalidad, etcétera y que requiere despliegues muy frecuentes. Para ello un número de compilación (build number) que se pudiera mostrar en alguna parte de la aplicación, quizás a voluntad, se presenta como una opción más funcional.

El entorno de desarrollo que utilizo, IntelliJ IDEA, no provee dicha funcionalidad así que toca resolver el problema con algo más de trabajo.

El IDEA utiliza, como muchos otros entornos de desarrollo, el concepto del artefacto para nombrar la preparación de un paquete o pieza de la aplicación. Las aplicaciones que despliego son habitualmente o aplicaciones sólo web (un fichero WAR) o aplicaciones Java EE (un fichero EAR). En ambos casos la construcción final del mismo se configura en IDEA mediante un artefacto. Y el entorno de desarrollo nos permite ejecutar un script Ant justo antes de generar el artefacto.

Ahora sólo falta que el script Ant genere un número de compilación secuencialmente. Por suerte esa funcionalidad ya está implementada en Ant sin necesitar ni siquiera una librería adicional. El script Ant es tremendamente sencillo:

<project>
 <target name="buildnumber">
  <buildnumber file="web/web/WEB-INF/build.number"/>
 </target>
</project>

Como se puede deducir de la ruta indicada en el fichero el objetivo es dejar el fichero con el número de compilación dentro del directorio WEB-INF del módulo web. Ahora tan solo tenemos que cargar ese fichero y mostrarlo donde queramos de nuestra aplicación web. En mi caso he utilizado un bean JSF para cargar el fichero y luego poder hacer referencia a las propiedades. En el mismo bean indico también la versión de la aplicación, aunque este campo es de actualización estrictamente manual.

/**
 * Bean de aplicación para controlar el número de versión de la aplicación y el número de compilación.
 */
@ManagedBean
@ApplicationScoped
public class Version {
  private static final Logger log = LoggerFactory.getLogger(Version.class);

  private String version = "alfa";
  private int build;

  @PostConstruct
  private void init() {
    try {
      Properties p = new Properties();
      InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/WEB-INF/build.number");
      p.load(stream);
      stream.close();
      build = Integer.parseInt(p.getProperty("build.number"));
    } catch (Exception e) {
      log.error("No puedo cargar el build.number", e);
      build = -1;
    }
  }

  public String getVersion() {
    return version;
  }

  public int getBuild() {
    return build;
  }
}

Tan sólo resta mostrar el número de compilación mediante #{version.build} en cualquier página JSF.