Versionando los assets en Symfony 2

Actualmente en el proyecto donde estoy trabajando, me surgió la necesidad de añadir a los assets un parametro de versionado, para que tanto la cache de Symfony como la del navegador(cliente) dejaran de cachear dichos archivos y obtuvieran los nuevos. No se si sera la mejor forma o si existen alternativas mejores(seguro que sí, pero yo no las he encontrado).

Así que os pongo mi solución, después de buscar y juntar algunas ideas de varios sitios, entre ellos este:

http://developer.happyr.com/rename-dump-from-asseticbundle

Symfony no dispone de ninguna configuración que permita hacerlo de forma automatizada en cada deploy, sino que te dicen que lo modifiques tu manualmente en el config.yml. El mayor problema es que al hacer un assetic: dump si los assets ya estan generados, no se les cambia el nombre, y por tanto aunque el contenido cambie, el nombre es el mismo y de eso no se entera la cache. Desde la documentación oficial te dicen que puedes configurarlo así (http://symfony.com/doc/current/reference/configuration/framework.html#ref-framework-assets-version):

– config.yml:

framework:
    # ...
    templating: 
        engines: ['twig']
        assets_version: 2.1.5.3
        assets_version_format: %%s?v=%%s

Esto lo que hace es que los assets se enlacen en las plantillas twig de la siguiente forma:  /images/logo.png?v=2.1.5.3

El inconveniente de esto es que en cada deploy tenemos que acordarnos de venir aquí y modificar esa version a mano. Se me ocurrió que esto se podia automatizar de alguna forma, y que ese código de versión nuevo que iba a usar en cada deploy iba a ser el hash del ultimo commit de Git.

Así que vamos al lio:

1- Creamos un nuevo fichero de configuración de un nuevo parámetro llamado version.yml y metemos  un nuevo parámetro llamado “git_commit”

-version.yml

parameters:
    git_commit: 123

2- Añadimos en los imports el nuevo archivo y añadimos la configuración de los assets.

-config.yml:

imports:
    - { resource: version.yml }
framework:
    # ...
    templating: 
        ...
        assets_version: %git_commit%
        assets_version_format: %%s?v=%%s

3- Creamos un fichero shell-script para ejecutarlo en cada deploy y que se encargue de coger el ultimo commit de git y meterlo en el fichero donde hemos declarado el nuevo parámetro con la versión. En mi proyecto

-generate_version_assets.sh

#!/bin/bash

# This script gets the last commit of git to be used in assets version
# Source: http://developer.happyr.com/rename-dump-from-asseticbundle

FILE="./app/config/version.yml"

echo "#This is an auto generated file that will be updated at every deploy" > $FILE
echo "parameters:" >> $FILE
echo "    git_commit: '$(git rev-parse --short HEAD)'" >> $FILE

De esta forma, en cada deploy y después de generar los assets mediante los comandos (assets: install y assetic: dump), deberemos ejecutar este script para que se guarde correctamente el numero de version correspondiente y de esa forma no se cachee ni por Symfony ni por el navegador del usuario. En mi proyecto dispongo de otro script que genera estos assets y ademas, crea el numero de version nuevo de forma automática.

Si examinamos el código de la web veremos que ahora se añade en cada asset un nuevo parámetro tal que así :

/js/2e4fdaa.js?v=a33d45

Espero que os haya sido util y si tenéis cualquier duda o comentario al respecto no tenéis mas que comentarlo.

Un fuerte abrazo y hasta el proximo truco ¡