enforcer:enforce and maven release plugin

November 12, 2011

enforcer:enforce and maven release plugin

[ru] [en]

"How To" check active maven profile at working of the maven release plugin

В любом серьезном maven-проекте вы рано или поздно столкнетесь с двумя вещами - звездным небом над собой и моральным законом в себе. Ой, это из Канта :) Так вот:
  • автоматизацией релизов при помощи maven release plugin
  • организации свойств проекта и параметров его сборки при помощи maven profile
А раз так, то рано или поздно вы столкнетесь с тем, что периодически выпускаете релиз на основе неверно выбранных профилей. На самом деле это достаточно грустно, так как понять что же имено произошло вы часто сможете ролько развернув все на продакшене, когда увидите что jms ломится на тестовые сервера и т.д.

Самое неприятное это то, что relese-plugin не содержит явных механизмов проверки пред-условий. Есть один - preparationGoals - немного корявый, так как срабатывает НЕ в самом начале процесса, но ...

Мой совет такой - вам нужно выбрать одну из двух стратегий:

  • или в секции "properties" в pom.xml файлах проекта содержатся все необходимые production-настройки, а локальные settings.xml программистов их, при необходимости, перегружают
  • или вы делаете один выделенный production-профиль, который всегда используете только для релизов
На самом деле жизнь сложнее, поскольку приличные админы никогда не согласятся "забить" пароль к production-базе в самый распркрасный и самый локальный-прелокальный maven-профиль, но, по крайней мере, можно попытаться автоматизировать релиз артефактов под тестовые сервера. Итак, я выбрал первую стретегию, поскольку она позволяет мне "собраться" и "релизнуться" практически на любой машине, где застала меня сия суровая необходимость.

Итак, release plugin я настраиваю таким образом

<pluginManagement>
  <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-release-plugin</artifactId>
      <version>2.2.1</version>
      <configuration>
          <autoVersionSubmodules>true</autoVersionSubmodules>
          <scmCommentPrefix>MF-69 [maven-release-plugin]</scmCommentPrefix>
          <localCheckout>true</localCheckout>
          <preparationGoals>
              enforcer:enforce clean verify
          </preparationGoals>
      </configuration>
  </plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <configuration>
        <rules>
            <AlwaysFail/>
        </rules>
        <fail>true</fail>
        <skip>${maven.enforcer.skip}</skip>
    </configuration>
</plugin>
</pluginManagement>
Внимательный взгляд разглядит тут enforcer:enforce в каком-то maven-enforcer-plugin. На самом деле этот плагин предназначен для проверки различных условий (например, обратите внимание на Ban Duplicate Classes), но в данном случае я его использую только как "падать всегда когда разрешено". Поскольку все что мне нужно - это прервать задачу релиза если активирован неверный профиль.

Собственно, это все что я хотел рассказать. Вам остается только верно задать свойство "<maven.enforcer.skip/>", в зависмости от того что вам нужно. Лично я в самом "pom.xml" указал его как <maven.enforcer.skip>true</maven.enforcer.skip>, а вот в локальном профиле в "settings.xml" у меня наоборот - <maven.enforcer.skip>false</maven.enforcer.skip> и результат получается такой - пока не отключу локальный профиль релиз не проходит - именно то что мне и было нужно.

Удачи, берегите себя. И будте добрее

In any serious maven-project you soon or later will meet two things - the starry sky above your and the moral law in yourself (Sorry, it's Kant, again) : So, after that you will soon or later faced with usage of wrong profile at release procedure. But it's really sadly because of you will get the real idea about what has really happened only after deploy on production server when JMS start to ping a test server, etc...

The worst that the relese-plugin has no clever pre-condition checker. Just one the preparationGoals but it a bit clumsy so it works NOT in the very beginning of the release process but ...

Let me give a small advise – you should select one of the followed:

  • either keep all production settings in "properties" of pom.xml files and hold all local programmer's settings in their local settings.xml files
  • or to create one production-profile, that should only be used for release procedure
The second way is more elegant but a “cruel truth” that there is NO serous sys-admin in the World that allows you to keep a password to production database in “your perfect local maven profile”. But in any case you can try to make it for you test servers. So, I've select the first way because it allows me to make a new release on any workstation in the office.

So, I manage it in such way:

<pluginManagement>
  <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-release-plugin</artifactId>
      <version>2.2.1</version>
      <configuration>
          <autoVersionSubmodules>true</autoVersionSubmodules>
          <scmCommentPrefix>MF-69 [maven-release-plugin]</scmCommentPrefix>
          <localCheckout>true</localCheckout>
          <preparationGoals>
              enforcer:enforce clean verify
          </preparationGoals>
      </configuration>
  </plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <configuration>
        <rules>
            <AlwaysFail/>
        </rules>
        <fail>true</fail>
        <skip>${maven.enforcer.skip}</skip>
    </configuration>
</plugin>
</pluginManagement>
A close look make out some enforcer:enforce in some maven-enforcer-plugin. That is a suitable “check-rules” plugin (take a look on Ban Duplicate Classes for example), but I've use it only as "to fall always when allowed". Because all I need is to brake a release if some incorrect profile is activated.

That is all in general. You only need is to specify the "<maven.enforcer.skip/>" property in accordance with your needs. I've use it in root "pom.xml" as <maven.enforcer.skip>true</maven.enforcer.skip> but in local development profile in "settings.xml" it is a <maven.enforcer.skip>false</maven.enforcer.skip>. And the result is – I can't perform a release if the local development profile is active. And it is I really need.

Regards, take care of yourself. And be more kind, please.

2 comments:

shurik said...

А не проще релизы делать из командной строки, а сборку SNAPSHOT версии делать из IDE, в которой подключены все нужные профили...?

s13o said...

Ну, вероятно, кому-то и проще. Я лишь нашел способ немного обезопастить себя от глупых ошибок. Я предпочитаю консоль всему прочему.

Post a Comment