Find the Best Cosmetic Hospitals

Explore trusted cosmetic hospitals and make a confident choice for your transformation.

“Invest in yourself — your confidence is always worth it.”

Explore Cosmetic Hospitals

Start your journey today — compare options in one place.

Apache Ant Script to Reset and Increment Build Numbers (CI-Friendly Modes)

Originally published on 2009-06-20; fully revised and updated.

This guide shows how to manage a resettable, multi-part build number in Apache Ant. It is useful for teams maintaining Ant-based CI/release pipelines and needing predictable version increments for major, minor, hotfix, revision, and optional continuous builds.

Source context: original DevOpsSchool post.

Ant script to reset build number

How this build numbering pattern works

The script keeps version state in a build.number file and updates it based on -Dincrement=.... By default, the build number is four parts (major.minor.hotfix.revision). For continuous builds, it can include a fifth part (continuous).

increment valueWhat changesOutput formatExample command
(not set)Revision increments by 1major.minor.hotfix.revisionant
majormajor +1, minor=1, hotfix=0, revision=1major.minor.hotfix.revisionant -Dincrement=major
minorminor +1, hotfix=0, revision=1major.minor.hotfix.revisionant -Dincrement=minor
hotfixhotfix +1, revision=1major.minor.hotfix.revisionant -Dincrement=hotfix
continuouscontinuous +1major.minor.hotfix.revision.continuousant -Dincrement=continuous
contResetcontinuous=1major.minor.hotfix.revision.continuousant -Dincrement=contReset
rebuildNo counter change in the provided switch casemajor.minor.hotfix.revisionant -Dincrement=rebuild

Create the build.number state file

Initialize the property file once in your project root:

major.number=1
minor.number=0
hotfix.number=0
revision.number=0
continuous.number=0

Add task definitions and targets in build.xml

The original snippet relies on Ant-Contrib tasks (such as var, switch, math, if) plus an unset task from Antelope.

Task definitions

<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<taskdef name="unset" classname="ise.antelope.tasks.Unset"/>Code language: HTML, XML (xml)

Target 1: initialize counters from build.number

<target name="initBuildNum" description="Get current build number properties">
    <property file="build.number"/>
    <var name="next.major" value="${major.number}"/>
    <var name="next.minor" value="${minor.number}"/>
    <var name="next.hotfix" value="${hotfix.number}"/>
    <var name="next.revision" value="${revision.number}"/>
    <var name="next.continuous" value="${continuous.number}"/>
</target>Code language: HTML, XML (xml)

Target 2: apply increment logic

<target name="getBuildNum">
    <switch value="${increment}">
        <case value="rebuild"/>

        <case value="major">
            <math result="next.major" operand1="${next.major}" operation="+" operand2="1" datatype="int"/>
            <var name="next.minor" value="1"/>
            <var name="next.hotfix" value="0"/>
            <var name="next.revision" value="1"/>
        </case>

        <case value="minor">
            <math result="next.minor" operand1="${next.minor}" operation="+" operand2="1" datatype="int"/>
            <var name="next.hotfix" value="0"/>
            <var name="next.revision" value="1"/>
        </case>

        <case value="hotfix">
            <math result="next.hotfix" operand1="${next.hotfix}" operation="+" operand2="1" datatype="int"/>
            <var name="next.revision" value="1"/>
        </case>

        <case value="continuous">
            <math result="next.continuous" operand1="${next.continuous}" operation="+" operand2="1" datatype="int"/>
        </case>

        <case value="contReset">
            <var name="next.continuous" value="1"/>
        </case>

        <default>
            <math result="next.revision" operand1="${next.revision}" operation="+" operand2="1" datatype="int"/>
        </default>
    </switch>
</target>Code language: HTML, XML (xml)

Target 3: persist and expose full.buildnumber

<target name="setBuildNumber" depends="initBuildNum,getBuildNum">
    <propertyfile file="build.number">
        <entry key="major.number" value="${next.major}"/>
        <entry key="minor.number" value="${next.minor}"/>
        <entry key="hotfix.number" value="${next.hotfix}"/>
        <entry key="revision.number" value="${next.revision}"/>
        <entry key="continuous.number" value="${next.continuous}"/>
    </propertyfile>

    <unset name="major.number"/>
    <unset name="minor.number"/>
    <unset name="hotfix.number"/>
    <unset name="revision.number"/>
    <unset name="continuous.number"/>

    <property file="build.number"/>

    <if>
        <or>
            <equals arg1="${increment}" arg2="continuous"/>
            <equals arg1="${increment}" arg2="contReset"/>
        </or>
        <then>
            <property name="full.buildnumber" value="${major.number}.${minor.number}.${hotfix.number}.${revision.number}.${continuous.number}"/>
        </then>
        <else>
            <property name="full.buildnumber" value="${major.number}.${minor.number}.${hotfix.number}.${revision.number}"/>
        </else>
    </if>

    <echo>${full.buildnumber}</echo>
</target>Code language: HTML, XML (xml)

Make your main build target depend on setBuildNumber so the version is calculated before packaging.

<target name="build" depends="setBuildNumber,compile,test,package"/>Code language: HTML, XML (xml)

Command examples

ant
ant -Dincrement=major
ant -Dincrement=minor
ant -Dincrement=hotfix
ant -Dincrement=continuous
ant -Dincrement=contReset

Build number update workflow

flowchart TD
    A[Run ant with optional increment] --> B[Load build.number]
    B --> C[Evaluate increment mode]
    C --> D[Update counters in memory]
    D --> E[Write counters to build.number]
    E --> F[Reload properties]
    F --> G[Set full.buildnumber]
    G --> H[Echo version for downstream targets]

Common pitfalls and best practices

  • Keep build.number under controlled write access; concurrent CI jobs can overwrite each other.
  • Ensure required task libraries are on Ant’s classpath before running this script.
  • Document when to use major, minor, and hotfix to avoid accidental version jumps.
  • Be explicit in CI: pass -Dincrement=... rather than relying on defaults.
  • If you need immutable build metadata, publish ${full.buildnumber} as an artifact variable after each run.

Find Trusted Cardiac Hospitals

Compare heart hospitals by city and services — all in one place.

Explore Hospitals
I'm Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms. I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.

Related Posts

Apache Ant Interview Questions Answered: Concepts, build.xml Examples, and Practical Snippets

This guide converts a long Apache Ant interview question list into clear, practical answers with working build.xml examples. It covers core Ant concepts, common tasks, debugging, and Ant vs Maven vs Make.

Read More

Apache Ant Comments and echo Task: Write Clear build.xml Files and Control Log Output

Learn the correct way to add comments in Apache Ant and when to use the echo task instead. This guide covers echo attributes, log-level behavior, and practical build.xml examples.

Read More

How to Run Ant Builds in IntelliJ IDEA: Setup, Troubleshooting, and Copy Task Patterns

This guide shows how to integrate a build.xml file with IntelliJ IDEA, run Ant targets from the IDE, and troubleshoot common environment-variable issues. It also compares practical Ant copy/fileset patterns with reusable examples.

Read More

Apache Ant clean, prepare, and compile Targets: A Practical build.xml Walkthrough

Learn how to structure a simple Ant build pipeline using clean, prepare, and compile targets with explicit dependencies. This revision includes a complete build.xml example, execution commands, and a workflow diagram.

Read More

Apache Ant Copy Task Examples: File, FileSet, Include/Exclude, and Flatten Patterns

Learn practical Apache Ant copy task patterns for real build pipelines, from single-file copies to filtered FileSets and flattened library bundles. Includes reusable XML snippets and a workflow diagram.

Read More

Apache Ant Dependency Visualization: AntScript Visualizer, Grand, and Vizant

A practical, updated guide to three classic Apache Ant visualization tools and how they help you understand target dependencies. Includes a side-by-side comparison, workflow diagram, and example commands.

Read More
Subscribe
Notify of
guest
1 Comment
Newest
Oldest Most Voted
Jason Mitchell
Jason Mitchell
3 months ago

When managing build numbers in automation pipelines, one important aspect is maintaining traceability rather than only focusing on incrementing or resetting values. In real CI/CD environments, build numbers are often linked with artifacts, deployment records, release notes, and monitoring systems, so resetting them without a proper versioning strategy can make debugging and auditing difficult. Teams should consider keeping build history, using immutable artifact identifiers, and ensuring that parallel builds do not generate conflicting versions. As projects grow, build numbering becomes part of release governance, and a small script change can impact deployment tracking and production support processes. 

1
0
Would love your thoughts, please comment.x
()
x