On 1/4/07, Andreas Sahlbach <[EMAIL PROTECTED]> wrote:

Hm, I have a different opinion here, but I think, this is a matter of
taste. I prefer to build a webapp once, then test it and then deploy
the very same artifact that I have successfully tested to the
production environment. Out webapps are independent from their
location, getting most configurations from the jndi environment, so
why taking a risk and do a new build just for promoting? Yeah sure, my
build should guarantee that the builds will produce the same
artifacts, but why taking a risk? This way the deployment is done just
by promoting and a little bit of file copy and server restart.


Thanks for sharing these useful tips and opinion. I agree  that as often
it's a matter of taste, but I think you point something interesting: you say
that you have a build which is reproducible, but you don't want to take the
risk. So there is a risk. So you are not confident your build is
reproducible. IMHO being totally confident a build is reproducible is very
important, because when you will actually need to reproduce it, it will be
very difficult to fix if something is wrong, because it's often a lot later
that you have to reproduce your build. So what I usually do is make a build
system where builds are reproducible. Then I test it, by doing automatic
comparisons. When I'm really confident that I have a reproducible build, I
setup build promotion. And during build promotion I can even test
automatically that the build after promotion is exactly the same as the
build before promotion. Then I can be confident I deliver what I want. And
note that I deliver externally only promoted build, so what really matters
is the promoted build. And it's very important to actually re publish a new
build because what I do is recursive delivery, in this case this could be
called recursive build promotion. So that you only deliver builds which are
not only reproducible but also distinguished from simple snapshots,
including all dependencies. Then the backup policy can be very different
from snapshots, which are never delivered externally and thus do not require
to be backed up for a long period, and for other builds which are delivered
externally and backed up for a very long period.

But once again it's mainly a matter of taste, and it's because there are a
lot of tastes out there that I like flexible tools :-)

Xavier

So I like build promoting and here is, what I am doing:

1) Our staging goes like this: development - integration - qs - productive

2) in my ivyconf, I have this
<?xml version="1.0" encoding="utf-8"?>
<ivyconf>
...
    <statuses default="development">
        <status name="productive" integration="false"/>
        <status name="release" integration="false"/>
        <status name="qs" integration="false"/>
        <status name="milestone" integration="false"/>
        <status name="integration" integration="false"/>
        <status name="development" integration="true"/>
    </statuses>
...
   <resolvers>
        <filesystem name="install">
            <artifact pattern="${user.home
}/.ivy/install/[artifact].[ext]"/>
            <ivy pattern="${user.home}/.ivy/install/[artifact].[ext]"/>
        </filesystem>
   </resolvers>
</ivyconf>

3) in my common ant script, I have this:
    <macrodef name="change-status-macro">
        <attribute name="fromstatus"/>
        <attribute name="tostatus" />
        <sequential>
            <delete dir="${install-rep}"/>
            <mkdir dir="${install-rep}"/>
            <ivy:install from="umsrep"
                         to="install"
                         organisation="${ivy.organisation}"
                         module="${ivy.module}"
                         revision="[EMAIL PROTECTED]"
                         overwrite="true"/>
            <delete>
                <fileset dir="${install-rep}" includes="ivy.xml.*"/>
            </delete>
            <groovy>
                import org.dom4j.*
                import org.dom4j.io.*
                File ivyFile = new File(properties['install-rep'],"ivy.xml
")
                Document ivyDoc = new SAXReader().read(ivyFile)
                def xpathSelector =
DocumentHelper.createXPath("/ivy-module/[EMAIL PROTECTED]'@{fromstatus}']")
                xpathSelector.selectNodes(ivyDoc).each() {
                    ((Element)it).addAttribute("status","@{tostatus}")
                    OutputFormat outformat =
OutputFormat.createPrettyPrint();
                    XMLWriter writer = new XMLWriter(
ivyFile.newOutputStream());
                    writer.write((Document)ivyDoc);
                    writer.flush();
                }
            </groovy>
            <ivy:install from="install"
                         to="umsrep"
                         organisation="${ivy.organisation}"
                         module="${ivy.module}"
                         revision="[EMAIL PROTECTED]"
                         overwrite="true"/>
        </sequential>
    </macrodef>

    <target name="promote-development" depends="configure,resolve"
            description="Pushes the latest.development version to
integration status">
        <change-status-macro fromstatus="development"
tostatus="integration"/>
    </target>

    <target name="promote-integration" depends="configure,resolve"
            description="Pushes the latest.integration version to qs
status">
        <change-status-macro fromstatus="integration" tostatus="qs"/>
    </target>

    <target name="promote-qs" depends="configure,resolve"
            description="Pushes the latest.qs version to productive
status">
        <change-status-macro fromstatus="qs" tostatus="productive"/>
    </target>
4) install-rep is a simple directory
<property name="install-rep" value="${user.home}/.ivy/install"/>
which is also defined as a repository (see above)

I had to simplify the script a bit, but it should give you an idea how
to do it. The targets configure and resolve do the ivy tasks that you
expect.

Some support in ivy itself for it would be nice too, but it actually
works pretty well this way. Once again groovy saved my day... :)

Hope that helped a bit,

ciao,

Andreas

On 1/3/07, Xavier Hanin <[EMAIL PROTECTED]> wrote:
> On 1/3/07, John Williams <[EMAIL PROTECTED]> wrote:
> >
> > I read about to idea of build promotion at
> > <http://www.jaya.free.fr/ivy/doc/bestpractices.html>, but I can't find
> > any documentation on how to actually do it.
>
>
> As I say on this best practices page, Ivy does not support build
promotion
> on its own, because build promotion is a complex thing that is not only
> related to module and dependency management. For instance you will
certainly
> need to tag the sources that were used for your build if you promote it.
>
> Is the best way just to
> > manually edit an Ivy file in the repository to change the status
> > declaration?  That sounds easy enough, but the presence of the
> > checksum files in the repository makes me think that editing the ivy
> > files after the fact is frowned upon.
>
>
> I don't think that editing the ivy file is a good thing. I think that a
> revision should never change. So in my opinion a build promotion needs
to be
> a new version. And in this case  you don't have to modify a file, you
just
> publish a new version, and state somewhere (maybe in your ivy file in
the
> description section) that it is simply another build which has been
> promoted.
>
> Ivy has no particular support for build promotion, the only thing is
that
> Ivy helps in build reproducibility, and it's a good basis for build
> promotion. But setting up a build system supporting build promotion is
not a
> trivial task IMO.
>
> Xavier
>
> Alternatively, does anyone have experiences to share with "snapshot"
> > revisions?  My understanding is that every snapshot revision should
> > eventually be replaced by a non-snapshot revision that is identical to
> > the last snapshot, but then what happens to the snapshot revision?
> > Does it just get deleted?  Or do you keep two identical revisions with
> > different numbers?
> >
> > --jw
> >
>
>



--
Andreas Sahlbach

Reply via email to