dub-publish 0.3.3

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 or -p / --password. 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, -p / --password / 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 — default https://code.dlang.org
  • --user / --password — or DUB_REGISTRY_USER / DUB_REGISTRY_PASSWORD
  • --password-file — read password from file (first line)
  • --prompt-password — interactive TTY prompt (opt-in)
  • --url — repository URL (default: git remote get-url origin)
  • --package / -n — package name (default: from dub.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 + deletes password.incoming
  • --secret-out / --hooks-out — override paths for hooks output 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.v1 with file mode 0600

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 / 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.

Authors:
  • amdphreak
Dependencies:
none
Versions:
0.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
Show all 5 versions
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