Download: via SVN only
Website: makerelease
SF Project: makerelease
One of the issues with releasing software is that you need to do mind-numbing tasks over and over and it is a barrier to "release early, release often". Not only that, releasing a particular package becomes an art-form to do all the right steps in the right order without forgetting anything.
The result of this problem is usually one of:
For projects I've worked on in the past, there is often been all three. The scripts get you "so far" but there is still a lot of operator knowledge. Sometimes that knowledge is encoded into a documentation file, but I've found that typically the documentation lags behind the script, the expert operator or both.
It is, of course, impossible to take all the fun out of the process and make everything totally automated. The goal of makerelease is a few fold:
makerelease divides up your release steps into pieces. Each step contains documentation and instructions (automatically done or not) that need to be done. There are a number of different types of steps.
All the steps are documented and defined using a simple xml syntax. This provides easy editing using any common text editor, but still allows for documentation to be easily embedded and displayable by the makerlease tool. The most basic step structure looks like:
<makerelease> <steps> <step type="informational"> <text> Advertise: NEWS upload to sf, publish on -announce, freshmeat, and the GNU FSF directory (http://directory.fsf.org/)... (send mail to bug-directory@gnu.org) </text> </step> </steps> </makerelease>
This example step (an informational step) simply prints the text to the screen for the user to read.
You can test running makerelease on a defined xml file using the -n switch. This produces documentation about the steps to be done. For example, running makerelease -n on the previous example would produce:
By default, makerelease looks for a makerelease.xml file in the current directory. Use the -c FILE flag to specify a particular file to load. It will then proceed to iterate through each step and act accordingly. See the Writing Steps section below for details.
# makerelease -c example.xml -n STEP: 1: Advertise: NEWS upload to sf, publish on -announce, freshmeat, and the GNU FSF directory (http://directory.fsf.org/)... (send mail to bug-directory@gnu.org)
Note: by default it wraps all text nicely to fit into the screen for you.
There are a large number of step types, each with their own purpose. Some flags for them work globally (on any step type) and some are Step specific.
The <text> section is used to describe a particular step for documentational purposes. It is output both to the operator doing an actual release as well as when using the -n flag to simply produce documentation.
A step with the /title="something"/ attribute to the step will "name" the step when displaying it to the user.
<step type="informational" title="Call Bob"> <text> Call Bob and have him commit all his outstanding changes. </text> </step>
Produces:
# makerelease -c example.xml [...] STEP: 2: Call Bob Call Bob and have him commit all his outstanding changes.
The stepname will eventually be used to control auto-skipping of things. It is most useful when used with a structured naming scheme like "build:configure".
Creating a step with <step pause="true" …> will tell makerelease to stop after the text is displayed and wait for the user to acknowledge the screen.
<step type="informational" pause="true" title="Call Bob"> <text> Call Bob and have him commit all his outstanding changes. </text> </step>
Produces:
# makerelease -c example.xml [...] STEP: 2: Call Bob Call Bob and have him commit all his outstanding changes. ---- PRESS ENTER TO CONTINUE (q=quit) ----
Informational steps simply present information to the administrator and do not perform any specific action. They're there just to document a step. They can be used to tell an administrator to do something that can't be automated by including the prompt flag to ensure the user sees it.
<step type="informational" pause="true"> <text> Call Bob and have him commit all his outstanding changes. </text> </step>
Produces:
# makerelease -c example.xml [...] STEP: 2: Call Bob and have him commit all his outstanding changes. ---- PRESS ENTER TO CONTINUE (q=quit) ----
The section type lets you group various sub-steps together. It allows for entire sections to be skipped when using the -i p flag and documentation to be divided up into sections.
<step type="section" title="Setup Steps" mandatory="1"> <text>These steps do preliminary work for making a release.</text> <steps> <step type="system"> <commands> <command>echo "hello world"</command> </commands> </step> <step type="informational"> <text>Also, Hello Universe</text> </step> </steps> </step>
Produces:
# makerelease -c example.xml -n STEP: 1: Setup Steps These steps do preliminary work for making a release. ===== Entering Step: 1 ===== STEP: 1.1: Commands to execute: echo "hello world" STEP: 1.2: Also, Hello Universe (Leaving Step: 1)
An include directive is functionally the same as a section directive, but the sections are specified in another makerelease xml file (which must be a fully qualified xml file with the top level <makerelease> tag in place.
<step type="include" title="Super extra steps"> <file>/path/to/foo.xml</file> </step>
Command steps are designed to run a particular set of commands via system() calls. All the commands must succeed or the user will be prompted for what to do next (continue, retry or quit).
<step type="command"> <commands> <command>echo "hello world"</command> <command>rm /</command> </commands> </step>
Produces:
STEP: 3: running 'echo "hello world"' hello world running 'rm /' rm: cannot remove `/': Is a directory failed: status=256 what now (c,r,q)?
<step type="prompt" prompt="Enter the version number:" title="Pick a Version Number for this release" parameter="VERSION"> </step>
Asks the user for a version number and assigns the result to the VERSION parameter. The VERSION parameter can be used in future system commands, text, etc by wrapping the parameter name in {} brackets.
<step type="system"> <text>We're going to produce {VERSION} <commands> <command>echo Hello World version {VERSION}</command> </commands> </step>
You can also add a values= attribute to specify the legal values that can be chosen based on a regular expression. For example, the following enforces a strict NUM.NUM format:
<step type="prompt" prompt="Enter the version number:" title="Pick a Version Number for this release" parameter="VERSION" values="^\d+\.\d+$"> </step>
The modify step lets you make regexp based modifications to files within the distribution. Files are passed through glob() so can include wildcards (*) characters.
<step type="modify" title="Update the version number"> <text> We will now modify files through the code to replace the version number with the newer one. </text> <modifications> <modify find="VERSION = '(.*)'" replace="VERSION = \'{VERSION}\'"> <files> <file>lib/MyModule.pm</file> <file>lib/SubDir/*.pm</file> </files> </modify> </modifications> </step>
Note: You may specify multiple <modify> sections within the <modifications> tag too.
A wise man once said "when all else fails, resort to perl". Ok, I don't know that anyone said that actually. But I bet someone did because it seems wise to me. Sometimes it's necessary to do extra processing of user-entered data or files or the moon. Embedding perl code directly lets you accomplish these sorts of things.
The $self variable will be to the current Makerelease::Step::Perl module, and within that is a reference to the parameters hash in $self->{'parameters'}.
Here's an example that takes the VERSION parameter and creates a new one called VERSIONDASHES with the dots replaced by dashes.
<step type="perl" title="Defining a second internal version string" mandatory="1"> <perl> <code> # version number with dashes instead of dots $self->{'parameters'}{'VERSIONDASHES'} = $self->{'parameters'}{'VERSION'}; $self->{'parameters'}{'VERSIONDASHES'} =~ s/\./-/g; </code> </perl> </step>
(scripts are located in the "dist" subdirectory if not otherwise specified):
Date: 2008-11-03 08:57:26 PST
HTML generated by org-mode 6.10c in emacs 21