Hi everyone, I’m new to Pants and need some guidan...
# general
e
Hi everyone, I’m new to Pants and need some guidance on setting up independent semantic versioning for services inside a monorepo. My current project structure looks like this:
Copy code
application/
  src/
    service_a/
      BUILD
    service_b/
      BUILD
  pants.toml
  pyproject.toml
Each
BUILD
file currently looks like this:
Copy code
# Include all Python source files in this directory
python_sources()

# Define a Docker image target
docker_image(
    image_tags=["latest"],
    name="docker_image",
    repository="service_a",
)

# Define a PEX (Python Executable) binary target
pex_binary(
    name="app",
    entry_point="app.py",
)
Right now I’m pushing Docker images with the
latest
tag using this command:
Copy code
pants --changed-since=origin/main --changed-dependents=transitive list publish
I’d like to generate independent semantic versions for each service. To do that, I added a
vcs_version
target in each service’s
BUILD
file:
Copy code
# Generate service-specific version
vcs_version(
    generate_to="src/service_a/version.py",
    name="version",
    template="__version__ = '{version}'",
)
This creates a
version.py
file per service. My questions are: • How do I tag the Docker image with this generated version? • Will this setup automatically produce an independent version for each service based on changes in that service only? Thanks in advance for any help!
Just following up on my earlier question — I’m still stuck on it and would really appreciate any insights or pointers. I really appreciate any help you can provide.
m
I’m 100% guessing here (I’m very much a learner, just like you!), but I do know the
BUILD
files are python. Your
vcs_version
line above generates a file with the version in it (which will be in the form
"0.1.dev244+g22ac66c.d20250929"
which, I assume, you can extract the version number details from the front of?). So you might be able to: • Create a python “labeller.py” file which imports the
version.py
you’ve created (dynamically, as an argument), then outputs a list of the versions you’d want to tag with (eg.
["latest", "v0", "v0.1"]
or whatever) • Then import “labeller” in your
BUILD
, and then call your new function:
docker_image(image_tags=labeller.process("./version"), dependencies=[":version"]…)
This may be entirely wrongheaded, but I figure something is useful to experiment with, even if it isn’t right! I hope this helps?
e
Thank you so much for your response. I tried that approach, but it seems that calling a Python method like
labeller.process("./version")
It isn’t possible directly within a
BUILD
file.
m
Ahh damn. My apologies! Hopefully one of the maintainers will be able to help!
🫠 1
e
For now, we’ve created a custom shell script to generate independent versions. When we chose to use Pants, we assumed it would support this out of the box—or at least provide some documentation on how to achieve it, since it seems like a fairly common requirement. I was a bit disappointed that I couldn’t find any resources explaining this.
d
Have you tried this approach? https://www.pantsbuild.org/blog/2024/04/27/simple-versioning-with-git-tags it still requires a shell script to set env vars but is pants native.
e
We can’t rely on
git describe
to detect changes, because we need independent versioning for each service—even when the changes come from shared modules or other dependencies. Instead, we want to use Pants to identify the impacted services with:
Copy code
pants --changed-since=origin/main --changed-dependents=transitive list
This way, we only bump the version of a service if it has actually changed or is affected by a change.
w
I'll be honest, I don't fully grok what you're trying to do... But have you looked into macros?
@mammoth-dawn-85816 Your approach looks good, but one qualifier (my qualifier, I don't think it's in the pants doc) is that BUILD files are like... mostly python. In the sense of being a limited subset (e.g. no imports) and I think a few other items
👍 1