Skip to main content

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...]
TargetDescription
local-ivyPublish to local ~/.ivy2 cache
sonatypePublish to Maven Central (GPG signing + staging)
setupInteractive setup wizard
resolver-namePublish to a named resolver from bleep.yaml

Named resolvers appear as subcommands automatically, with tab completion and help text.

Flags

FlagDescription
--version XOverride version (default: from git tags via DynVer)
--assert-releaseFail if git state would produce a snapshot version

Supported providers

ProviderResolver schemeCLI toolAuth config needed
Artifactory / Nexus / generic Mavenplain https://noneUser + token in ~/.config/bleep/config.yaml
Google Artifact Registryartifactregistry://gcloudAccount (if multiple)
GitHub Packagesgithub://ghNone
GitLab Package Registrygitlab://glabNone
Sonatype / Maven Centralbuilt-innoneEnv 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:

  1. The URI scheme identifies the provider (artifactregistry://, github://, gitlab://)
  2. The scheme is rewritten to https:// for the actual Maven HTTP requests
  3. A token is acquired by shelling out to the provider's CLI tool (gcloud auth print-access-token, gh auth token, glab auth token)
  4. The token is attached as HTTP authentication to the Coursier repository
  5. 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 slowgcloud 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.

FieldDescription
groupIdMaven groupId (required for publishing)
descriptionProject description (POM)
urlProject homepage (POM)
organizationOrganization name (POM)
developersList of {id, name, url} (POM)
licensesList of {name, url, distribution} (POM)
sonatypeProfileNameSonatype profile (defaults to groupId)
sonatypeCredentialHostSonatype 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):

  1. --version X flag, explicit override
  2. Git tags via DynVer, automatic from git describe

DynVer examples:

  • On tag v1.0.0 (clean) → 1.0.0
  • 3 commits after v1.0.01.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.