bdcli-deploy
v0.3.1
Published
Build and deploy projects over SSH from the current project directory.
Downloads
26
Readme
bdcli
bdcli is a Node.js CLI for project-local build and deploy workflows. It discovers deployment config from the current directory tree, runs a local build command, uploads artifacts over SSH/SFTP, and executes remote deployment commands.
This project is suitable for small teams and personal infrastructure where deployment is driven from the application repository. The current release should be treated as early-stage software.
Installation
npm install -g bdcli-deploy
bdcli --helpFor one-off usage without a global install:
npx bdcli-deploy --helpRequirements
- Node.js 20 or newer
- A local project that can be built from a shell command such as
npm run build - SSH access to the target host
- A remote Unix-like environment with
mkdir,find,rm,tar, and/tmp
Supported environments
- Local machine: intended for macOS, Linux, and Windows with Node.js
- Remote machine: intended for Linux or other Unix-like servers
bdcli normalizes remote paths as POSIX paths and uses Unix shell commands on the server, so Windows targets are not supported.
Quick start
bdcli init --with-local
bdcli doctor --env staging
bdcli build
bdcli deploy staging --dry-run
bdcli deploy stagingCommands
bdcli init
bdcli init --with-local
bdcli build
bdcli build --target weapp
bdcli build --no-pack
bdcli build --pack-name my-bundle
bdcli doctor
bdcli doctor --env production
bdcli deploy
bdcli deploy staging
bdcli deploy production --dry-run
bdcli deploy production --skip-build
bdcli deploy production --target weappConfig files
/.deploy.config.json: required primary config, safe to commit/.deploy.local.json: optional local override config, intended for machine-local secrets and paths
Merge rules:
- objects: deep merge
- arrays: override completely
- scalar values: local overrides primary
/.deploy.local.json should stay out of version control.
Config example
{
"version": 1,
"project": "my-app",
"build": {
"command": "npm run build",
"output": "dist",
"cleanOutput": false,
"pack": {
"enabled": true,
"name": "my-app"
}
},
"deploy": {
"strategy": "upload",
"uploadMode": "archive",
"cleanRemoteBeforeUpload": false,
"gitVersionInfo": {
"enabled": true,
"filename": "._gitVersionInfo"
}
},
"environments": {
"staging": {
"enable": true,
"remotePath": "/var/www/my-app-staging",
"beforeUpload": [
"mkdir -p /var/www/my-app-staging"
],
"afterUpload": [
"echo deployment complete"
]
},
"production": {
"enable": false,
"remotePath": "/var/www/my-app",
"beforeUpload": [
"mkdir -p /var/www/my-app"
],
"afterUpload": [
"pm2 reload my-app"
]
}
}
}Optional local override:
{
"environments": {
"staging": {
"host": "127.0.0.1",
"port": 22,
"username": "deploy",
"privateKey": "C:/Users/your-name/.ssh/id_rsa"
},
"production": {
"host": "127.0.0.1",
"port": 22,
"username": "deploy",
"privateKey": "C:/Users/your-name/.ssh/id_rsa"
}
}
}build may also be an array of build configurations. With multiple entries, each item must have a unique name; bdcli build / bdcli deploy then prompt interactively for the target, or take it from --target <name>:
{
"build": [
{ "name": "h5", "command": "npm run build:h5", "output": "dist-h5" },
{ "name": "weapp", "command": "npm run build:weapp", "output": "dist-weapp" }
]
}Config fields
version: config version for future compatibilityproject: project name used in logsbuild: a single build object, or an array of build objectsbuild.name: optional identifier; required and unique on each item whenbuildis an array with multiple entriesbuild.command: local shell command for building the projectbuild.output: local artifact directory whose contents are deployedbuild.cleanOutput: clear the contents ofbuild.outputbefore running the build command, defaultfalsebuild.pack.enabled: pack the build output into a zip archive afterbdcli build, defaulttruebuild.pack.name: pack archive file name, default<project>[-<build.name>].zip; the archive is written intobuild.outputdeploy.strategy: currently onlyuploaddeploy.uploadMode:archiveordirect, defaultarchivedeploy.cleanRemoteBeforeUpload: clear target directory contents before uploaddeploy.gitVersionInfo.enabled: inject git version metadata into build output before upload, defaulttruedeploy.gitVersionInfo.filename: metadata file name written intobuild.output, default._gitVersionInfoenvironments.<name>.enable: whenfalse, deployment is blockedenvironments.<name>.host: SSH hostenvironments.<name>.port: SSH port, default22environments.<name>.username: SSH usernameenvironments.<name>.password: optional password authenvironments.<name>.privateKey: optional path to private key fileenvironments.<name>.passphrase: optional key passphraseenvironments.<name>.remotePath: remote upload directoryenvironments.<name>.beforeUpload: remote commands before uploadenvironments.<name>.afterUpload: remote commands after upload
Behavior notes
bdcli deploydeploys all enabled environments sequentially in config order and skips environments withenable: falsebdcli deploy <env>fails whenenableisfalse- when
buildhas multiple entries,bdcli buildandbdcli deployask which one to use; pass--target <name>to skip the prompt (required in non-interactive environments such as CI, and honored together with--skip-buildto pick the artifact source) - deploy uploads and extracts the contents inside
build.output, not the outer directory itself - bdcli never clears
build.outputon its own unlessbuild.cleanOutputistrue; when enabled, the directory contents (not the directory itself) are removed before the build command runs, and only paths strictly inside the project root are accepted — the project root itself and paths outside it are refused bdcli buildwrites git version info intobuild.outputfirst, then packs the output contents (including that file) into a zip stored insidebuild.output; use--no-packorbuild.pack.enabled: falseto skip- when
uploadModeisarchive, deploy excludes the pack zip produced bybdcli buildfrom the uploaded archive so artifacts are not transferred twice - with
uploadMode: directthe pack zip is uploaded along with everything else inbuild.output; directory upload has no per-file filtering, so keep pack disabled if that extra transfer matters - clean mode refuses
/and remote paths shallower than 3 levels, and clears contents instead of deleting the directory itself bdcli doctorvalidates config and attempts an SSH connection for enabled environmentsbdcli init --with-localcreates both config files- config discovery walks upward from the current working directory until it finds
/.deploy.config.json
Security notes
- Prefer
privateKeyauthentication overpasswordwhenever possible - Keep
/.deploy.local.jsonuntracked; it may contain secrets or workstation-specific key paths beforeUploadandafterUploadrun as remote shell commands; treat them as privileged operations- When git version info injection is enabled, bdcli writes a metadata file into
build.outputafter build and before upload - The default metadata file name is
._gitVersionInfo; if your web server exposes dot-underscore files, add a rule to block external access or change the filename
Development
npm test
npm run lint
npm pack --dry-run