Publishing & Private Repositories
Bleep has built-in support for publishing artifacts and resolving dependencies from private Maven repositories.
Getting started: making your build publishable
Starting from a basic bleep.yaml, you need two things: a publish config on your projects and a named resolver if publishing to a private registry.
Step 1: Add publish to your projects
The publish field marks a project as publishable. At minimum, set groupId:
projects:
mylib:
publish:
groupId: com.mycompany
Use a template to share config across projects. Test projects are automatically excluded, any project with isTestProject: true is never published, even if it inherits publish from a template.
templates:
template-common:
publish:
groupId: com.mycompany
description: Our shared libraries
url: https://github.com/mycompany/mylibs
developers:
- id: teamlead
name: Team Lead
url: https://github.com/teamlead
licenses:
- name: MIT
url: http://opensource.org/licenses/MIT
distribution: repo
projects:
mylib:
extends: template-common # published
mylib-utils:
extends: template-common # published
mylib-tests:
extends: template-common
isTestProject: true # not published (test projects are always skipped)
This means you can safely put publish in your common template without worrying about test projects leaking into your releases.
Step 2: Add a named resolver (for private repos)
If publishing to a private registry, declare it as a named resolver:
resolvers:
- name: company-releases
type: maven
uri: artifactregistry://europe-north1-maven.pkg.dev/my-project/my-repo
This resolver is used for both fetching dependencies and publishing. The name becomes a publish subcommand.
Step 3: Publish
bleep publish company-releases # all publishable projects
bleep publish company-releases mylib # specific project
Version is derived from git tags automatically. Tag with v prefix:
git tag v1.0.0
bleep publish company-releases
Command reference
bleep publish <target> [--version X] [--assert-release] [projects...]
| Target | Description |
|---|---|
local-ivy | Publish to local ~/.ivy2 cache |
sonatype | Publish to Maven Central (GPG signing + staging) |
setup | Interactive setup wizard |
| resolver-name | Publish to a named resolver from bleep.yaml |
Named resolvers appear as subcommands automatically, with tab completion and help text.
Flags
| Flag | Description |
|---|---|
--version X | Override version (default: from git tags via DynVer) |
--assert-release | Fail if git state would produce a snapshot version |
Supported providers
| Provider | Resolver scheme | CLI tool | Auth config needed |
|---|---|---|---|
| Artifactory / Nexus / generic Maven | plain https:// | none | User + token in ~/.config/bleep/config.yaml |
| Google Artifact Registry | artifactregistry:// | gcloud | Account (if multiple) |
| GitHub Packages | github:// | gh | None |
| GitLab Package Registry | gitlab:// | glab | None |
| Sonatype / Maven Central | built-in | none | Env vars + GPG |
Each provider page covers both resolving and publishing in detail.
How the provider schemes work
When bleep encounters a private repository scheme in resolvers:
- The URI scheme identifies the provider (
artifactregistry://,github://,gitlab://) - The scheme is rewritten to
https://for the actual Maven HTTP requests - A token is acquired by shelling out to the provider's CLI tool (
gcloud auth print-access-token,gh auth token,glab auth token) - The token is attached as HTTP authentication to the Coursier repository
- Tokens are cached in-memory, so only one CLI invocation per provider per build
Token acquisition is lazy — it only happens when Coursier actually needs to resolve against the private repository, not at bleep startup.
Plain https:// resolvers (Artifactory, Nexus) shell out to nothing; their credentials come from the authentications: block in your bleep config file.
Maven Central is always in the list
Whatever you declare in resolvers:, bleep appends ~/.ivy2/local and Maven Central
(CoursierResolver.coursierRepos does repos ++ constants.DefaultRepos). Your own resolvers are
consulted first, but there is no way to remove Maven Central from the resolver list. If your
network cannot reach repo1.maven.org at all, a Coursier mirror is the supported redirect — see
Proxies, TLS & air-gapped networks.
Managing authentication
bleep config auth setup # interactive setup wizard
bleep config auth list # list configured authentications
bleep config auth remove <uri-prefix> # remove one
Troubleshooting the provider CLIs
"gcloud not found" / "gh not found" / "glab not found" — the provider CLI tool is not installed
or not on your PATH. Install it and re-run.
"credentials expired" — run gcloud auth login, gh auth login or glab auth login to
re-authenticate.
"Failed to get credentials for account X" — the configured GCP account has no valid
credentials. Either gcloud auth login <account>, or update the config with
bleep config auth setup.
Token acquisition is slow — gcloud takes ~2s (it is Python). This only happens on a cache
miss, and the token is cached in-memory for the lifetime of the bleep process. gh and glab are
~70ms.
The publish config
All fields merge through templates using the same rules as other bleep config.
| Field | Description |
|---|---|
groupId | Maven groupId (required for publishing) |
description | Project description (POM) |
url | Project homepage (POM) |
organization | Organization name (POM) |
developers | List of {id, name, url} (POM) |
licenses | List of {name, url, distribution} (POM) |
sonatypeProfileName | Sonatype profile (defaults to groupId) |
sonatypeCredentialHost | Sonatype host (defaults to central.sonatype.com) |
Projects without publish are never published. Projects with isTestProject: true are also never published, even if they inherit publish from a template.
Version management
Version is determined by (in priority order):
--version Xflag, explicit override- Git tags via DynVer, automatic from
git describe
DynVer examples:
- On tag
v1.0.0(clean) →1.0.0 - 3 commits after
v1.0.0→1.0.0+3-abcdef12 - No tags →
0.0.0+N-abcdef12
Release assertions
Use --assert-release to fail if the git state would produce a snapshot version:
bleep publish sonatype --assert-release
This checks DynVer structurally, fails if there are commits after the tag, the working tree is dirty, or no tags exist. Useful in CI to prevent accidental snapshot publishes.
Interactive setup
bleep publish setup
Walks you through configuring auth for private repos and (for Sonatype) generating GPG keys.
Troubleshooting
"No publishable projects found"
Add publish config with at least groupId to your projects or templates. Projects without publish are skipped.
Version issues
Ensure your repo has git tags (git tag v0.1.0). Without tags, DynVer falls back to 0.0.0+N-hash, which some registries may reject for releases. Use --version to override, or --assert-release to catch this in CI.
Resolver not found
The resolver name must match a named resolver in your bleep.yaml. Check resolvers: section. Unnamed resolvers (plain URIs) cannot be used as publish targets.