dub-publish 0.3.2
CLI to register Git repositories with the DUB package registry (code.dlang.org)
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
= dub-publish
CLI to manage packages on the https://code.dlang.org[DUB package registry] — register, update, webhooks, logo, docs URL, categories, permissions, and remove.
Official dub has no publish / submit command. This tool automates the browser "My packages" flows.
== Install
[source,console]
git clone https://github.com/dlang-supplemental/dub-publish.git cd dub-publish dub build
Put the resulting dub-publish binary on your PATH, or run via dub run from a clone.
=== From CI (reusable workflow)
[source,yaml]
jobs: publish:
uses: dlang-supplemental/dub-publish/.github/workflows/register-package.yml@main
with:
package: mypkg
url: https://github.com/org/repo
root: .
secrets:
DUB_REGISTRY_USER: ${{ secrets.DUB_REGISTRY_USER }}
DUB_REGISTRY_PASSWORD: ${{ secrets.DUB_REGISTRY_PASSWORD }}
== Quick start
Agent / script friendly — default drop file (same path on Windows, macOS, and Linux under the config dir):
[source,console]
PowerShell
$dir = Join-Path $env:LOCALAPPDATA "dlang-supplemental\dub-publish" New-Item -ItemType Directory -Force -Path $dir | Out-Null Set-Content -Path (Join-Path $dir "password.incoming") -Value "your-registry-password" dub-publish login --user yourname --save-credentials
stores DPAPI credentials and deletes password.incoming
[source,console]
macOS / Linux
mkdir -p ~/.dlang-supplemental/dub-publish printf '%s\n' 'your-registry-password' > ~/.dlang-supplemental/dub-publish/password.incoming chmod 600 ~/.dlang-supplemental/dub-publish/password.incoming dub-publish login --user yourname --save-credentials
After that, later commands reuse the local store (no password flags):
[source,console]
dub-publish register --ignore-fork dub-publish hooks -n mypkg dub-publish update -n mypkg
Overrides: --password-file, --password-stdin, or -p. Interactive humans can use --prompt-password. -p appears in shell history and process lists — dub-publish itself does not log it.
CI still uses env vars / GitHub secrets (DUB_REGISTRY_USER, DUB_REGISTRY_PASSWORD) — do not rely on the local store in Actions.
== Commands
login:: Verify credentials. Pair with --save-credentials to persist them. Password via default password.incoming drop file, --password-file, --password-stdin, -p / env, saved store, or --prompt-password.
logout:: Delete the local credential store and any leftover password.incoming.
register / publish:: Log in and POST /register_package. Idempotent if already registered (then refreshes).
update:: Queue a metadata refresh (login, or --secret webhook).
status:: Check whether a package exists.
remove:: Owner delete (remove + remove_confirm). Requires --yes.
logo:: Upload logo (--logo-file). png/jpeg/gif/bmp, max 1 MiB.
logo-delete:: Reset to default logo.
docs-url:: Set documentation URL (--docs-url).
categories:: Set up to four categories (--category repeatable).
hooks:: Enable/regenerate webhook secret; print + save secret and clean generic/GitHub/GitLab URLs (avoids https://github.com/dlang/dub-registry/issues/614[#614] malformation).
hooks-disable:: Revoke webhook secret.
repo:: Transfer repository coordinates (--kind / --owner / --project).
perms-add:: Add a shared user (--username, --perm update|metadata|source|admin).
leave:: Leave a shared package.
== Options
--registry— defaulthttps://code.dlang.org--user/--password— orDUB_REGISTRY_USER/DUB_REGISTRY_PASSWORD--password-file— read password from file (first line)--password-stdin— read password from stdin (first line)--prompt-password— interactive TTY prompt (opt-in)--url— repository URL (default:git remote get-url origin)--package/-n— package name (default: fromdub.json/dub.sdl)--ignore-fork— register even when the repo is a fork--dry-run— print what would happen--save-credentials— store user/password locally; consumes + deletespassword.incoming--secret-out/--hooks-out— override paths forhooksoutput files
=== Local credentials
Passwords are not one-way hashed: the CLI must replay them to the registry. Industry practice for this is OS-backed reversible protection:
- Windows: DPAPI bound to the current user (
credentials.v1) - Elsewhere: Base64 payload in
credentials.v1with file mode0600
Default password drop file (plaintext, deleted after --save-credentials):
- Windows:
%LOCALAPPDATA%\dlang-supplemental\dub-publish\password.incoming - macOS / Linux:
~/.dlang-supplemental/dub-publish/password.incoming
Stored credentials:
- Windows:
%LOCALAPPDATA%\dlang-supplemental\dub-publish\credentials.v1 - Unix:
~/.dlang-supplemental/dub-publish/credentials.v1
Legacy plaintext credentials files are upgraded automatically on load.
About -p: the app does not write the password to its own logs, but the shell may keep it in history and other local users can see it in the process list. Prefer the drop file / --password-file / --password-stdin / saved store.
Webhook outputs (from hooks):
%LOCALAPPDATA%\dlang-supplemental\dub-publish\hooks\<pkg>.secret%LOCALAPPDATA%\dlang-supplemental\dub-publish\hooks\<pkg>.hooks.txt
== How versions get published
Registration only links the repository. New versions appear when you push SemVer tags (v1.2.3); the registry polls about twice an hour. You can also trigger an immediate refresh:
[source,console]
dub-publish update -n mypkg --secret YOURPACKAGESECRET
== Changelog
See link:CHANGELOG.adoc[CHANGELOG].
== License
Boost Software License 1.0.
- 0.3.2 released a day ago
- dlang-supplemental/dub-publish
- BSL-1.0
- Copyright © 2026, amdphreak
- Authors:
- Dependencies:
- none
- Versions:
-
Show all 5 versions0.3.3 2026-Jul-31 0.3.2 2026-Jul-31 0.3.1 2026-Jul-31 0.3.0 2026-Jul-31 ~main 2026-Jul-31 - Download Stats:
-
-
0 downloads today
-
1 downloads this week
-
1 downloads this month
-
1 downloads total
-
- Score:
- 0.0
- Short URL:
- dub-publish.dub.pm