Skip to content

Latest commit

 

History

History
398 lines (283 loc) · 11 KB

File metadata and controls

398 lines (283 loc) · 11 KB

Getting Started with dbpm

This guide walks through installing the dbpm CLI, configuring a Linux environment, bootstrapping Core, installing a package, and publishing a package artifact.

dbpm is an Oracle database package manager. It resolves package artifacts, plans dependency order, executes package manifests through SQL*Plus or SQLcl, and records deployment state in Core. Core is the in-database substrate for dbpm-managed deployments; ordinary packages depend on Core being present, but they should not list Core as a normal package dependency.

Prerequisites

You need:

  • Linux or another Unix-like shell environment.
  • Python 3.11 or newer.
  • Oracle SQLcl or SQL*Plus on the machine where dbpm runs.
  • A target Oracle schema and connect string.
  • A GitHub token if you consume private GitHub Packages artifacts.
  • GPG if you publish packages with dbpm publish.

Confirm the basic tools:

python3 --version
sql -version

If you use SQL*Plus instead of SQLcl, confirm sqlplus is on your PATH or set DBPM_SQL_RUNNER to its full path.

Install dbpm

Install dbpm as a user-level CLI tool:

# Stable released CLI version.
python3 -m pip install --user git+https://github.com/512itconsulting/dbpm.git@v1.1.1

# Latest development version from the default branch.
python3 -m pip install --user git+https://github.com/512itconsulting/dbpm.git

dbpm --help

If you use pipx, the equivalent install is:

pipx install git+https://github.com/512itconsulting/dbpm.git@v1.1.1

For development from a local checkout, use a virtual environment:

git clone https://github.com/512itconsulting/dbpm.git
cd dbpm
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[dev]'
dbpm --help

The examples below use dbpm directly. Contributors who prefer uv may use uv sync and uv run dbpm ..., but uv is not required to run dbpm.

Configure Environment

Create a local environment file. Do not commit this file; it can contain credentials.

cp dbpm-env.sh.example dbpm-env.sh

Edit dbpm-env.sh:

export TNS_ADMIN="$HOME/.oracle/tns_admin"
export DBPM_SQL_RUNNER="$HOME/opt/sqlcl/bin/sql"

# Option A: raw Oracle connect string.
export DBPM_CONNECT="user/password@service_name"

# Option B: SQLcl saved connection name local to this OS user.
# Do not put a saved connection name in DBPM_CONNECT.
# unset DBPM_CONNECT
# export DBPM_CONNECT_NAME="Development Database (APP_USER)"

# Required for private GitHub Packages.
export DBPM_GITHUB_TOKEN="github_token_with_package_read_access"
export DBPM_GITHUB_USER="github_username"

# Runtime directories.
export DBPM_CACHE_DIR="$HOME/.local/cache/dbpm"
export DBPM_LOG_DIR="$HOME/.local/state/dbpm_logs"

Load it before running dbpm:

source ./dbpm-env.sh

Check that dbpm can find the SQL runner and database connection setting:

printf '%s\n' "$DBPM_SQL_RUNNER"
printf '%s\n' "${DBPM_CONNECT:-$DBPM_CONNECT_NAME}"

DBPM_CONNECT is for raw Oracle connect strings, such as user/password@service_name. DBPM_CONNECT_NAME is for SQLcl saved connections from SQLcl's local connection store. It requires SQLcl (DBPM_SQL_RUNNER=sql or a SQLcl executable path) and cannot be set at the same time as DBPM_CONNECT. If your database is saved in SQLcl as dev_database, use DBPM_CONNECT_NAME=dev_database and unset DBPM_CONNECT.

Start a New Package

To scaffold a new package repository from scratch:

mkdir my_package
dbpm init package my_package --name my_package --description "My Oracle package"

To scaffold a new workspace with multiple packages:

mkdir my_workspace
dbpm init workspace my_workspace --package billing --package orders

dbpm init creates the standard directory layout, a self-documented dbpm.yaml manifest, a README, a LICENSE placeholder, and git-friendly placeholder files. Edit dbpm.yaml to fill in description, dependencies, and publishing config as needed.

See dbpm init for the full option reference.

Understand Package Sources

dbpm accepts several source formats:

  • A local package directory containing dbpm.yaml, dbpm.yml, dbpm.json, or package.dbpm.yaml.
  • A local ZIP package.
  • A GitHub Packages Maven coordinate.
  • A generic Maven coordinate.
  • A dbpm registry source such as registry:package@constraint.
  • A direct HTTPS ZIP URL for lockfile-driven installs.

Common GitHub Packages source form:

gh-maven:owner/repo:group:artifact:version[:extension]

Example:

gh-maven:512itconsulting/core:com.512itconsulting.database:core:3.5.0

See source types for the full syntax.

Bootstrap Core

Core must be installed before dbpm can run ordinary package deployments.

Preview the bootstrap plan:

dbpm bootstrap-core \
  gh-maven:512itconsulting/core:com.512itconsulting.database:core:3.5.0 \
  --dry-run

Bootstrap Core into an empty or prepared schema:

dbpm bootstrap-core \
  gh-maven:512itconsulting/core:com.512itconsulting.database:core:3.5.0 \
  --policy unlocked \
  --deploy-environment DEV

Verify Core:

dbpm check-core --minimum-version 3.5.0

Use bootstrap-core only for the initial Core installation. If Core already exists, dbpm will block bootstrap and tell you to use upgrade, resume, or an explicit destructive reinstall path.

Install a Package

Preview a package install:

dbpm plan \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0 \
  --mode install

Install the package:

dbpm install \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0

Validate it if the package declares a validation script:

dbpm validate \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0

Install With Dependencies

When dependencies are declared and all sources are known, provide dependency sources so dbpm can resolve the full graph before any script runs.

dbpm plan \
  gh-maven:rsantmyer/simple_scheduler:com.512itconsulting.database:simple_scheduler:1.1.0 \
  --mode install \
  --dependency-source gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0
dbpm install \
  gh-maven:rsantmyer/simple_scheduler:com.512itconsulting.database:simple_scheduler:1.1.0 \
  --dependency-source gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0

Dependencies are installed before consumers. Core remains an implicit substrate prerequisite, not a normal dependency to resolve and install as part of every package graph.

Use Lockfiles

For repeatable deployments, create a lockfile:

dbpm lock \
  gh-maven:rsantmyer/simple_scheduler:com.512itconsulting.database:simple_scheduler:1.1.0 \
  --dependency-source gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0

Install from the lockfile:

dbpm install --lockfile dbpm-lock.json

Check that a lockfile still matches package resolution:

dbpm lock \
  gh-maven:rsantmyer/simple_scheduler:com.512itconsulting.database:simple_scheduler:1.1.0 \
  --dependency-source gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0 \
  --check

Commit release-oriented lockfiles so production deployments use exact artifact identities and checksums.

Upgrade, Resume, and Reinstall

Upgrade an installed package:

dbpm upgrade \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.1.0

If a deployment failed or was interrupted, prefer resume:

dbpm resume \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0

Use reinstall only when a clean slate is acceptable:

dbpm reinstall \
  gh-maven:512itconsulting/utl_interval:com.512itconsulting.database:utl_interval:1.0.0 \
  --allow-destructive

Core reinstall is a schema-level dbpm system teardown. Treat it as equivalent to wiping dbpm-managed state from the schema. It requires both destructive flags:

dbpm reinstall \
  gh-maven:512itconsulting/core:com.512itconsulting.database:core:3.5.0 \
  --allow-destructive \
  --confirm-delete-system CORE

Avoid destructive reinstall in established environments unless Core deployment-lock policy and operator intent are absolutely clear.

Publish a Package

dbpm can build and publish a ZIP artifact to GitHub Packages or a generic Maven repository. It generates:

  • {artifact_id}-{version}.zip
  • checksums
  • a detached GPG signature
  • {artifact_id}-{version}.pom
  • maven-metadata.xml

The uploaded POM is generated from the dbpm manifest. A checked-in pom.xml is optional legacy compatibility for repositories that still have other Maven-based workflows.

Add publish metadata to dbpm.yaml:

publish:
  group: com.512itconsulting.database
  artifact_id: core

Configure GPG:

gpg --list-secret-keys --keyid-format=long
export DBPM_SIGNING_KEY="your-key-id-or-fingerprint"

Dry run:

dbpm publish ~/repos/core \
  --target gh-maven:512itconsulting/core \
  --group com.512itconsulting.database \
  --artifact-id core \
  --signing-key "$DBPM_SIGNING_KEY" \
  --dry-run

Publish:

dbpm publish ~/repos/core \
  --target gh-maven:512itconsulting/core \
  --group com.512itconsulting.database \
  --artifact-id core \
  --signing-key "$DBPM_SIGNING_KEY"

After verification, dbpm writes dbpm-publish-receipt.json in the package root. The receipt contains immutable artifact metadata but no credentials. To index it in a dbpm registry:

export DBPM_REGISTRY_URL="https://registry.dbpm.io"
export DBPM_REGISTRY_TOKEN="your-publisher-token"

dbpm registry index ~/repos/core --dry-run
dbpm registry index ~/repos/core

Use --index-registry on dbpm publish to perform both steps in one command. If indexing fails, the verified publish receipt remains available for retry.

See dbpm publish for details. See dbpm registry index for indexing details.

Troubleshooting

If dbpm cannot connect to the database, confirm:

source ./dbpm-env.sh
"$DBPM_SQL_RUNNER" -L "$DBPM_CONNECT"

For SQLcl saved connections, confirm with -name instead:

source ./dbpm-env.sh
"$DBPM_SQL_RUNNER" -S -L -name "$DBPM_CONNECT_NAME"

If artifact downloads fail from GitHub Packages, confirm DBPM_GITHUB_TOKEN has package read access and DBPM_GITHUB_USER is set.

If paths show a literal ~, use $HOME in environment files:

export DBPM_CACHE_DIR="$HOME/.local/cache/dbpm"
export DBPM_LOG_DIR="$HOME/.local/state/dbpm_logs"

If GPG signing fails, test signing outside dbpm:

echo "test" > /tmp/dbpm-gpg-test.txt
gpg --armor --detach-sign --local-user "$DBPM_SIGNING_KEY" /tmp/dbpm-gpg-test.txt
gpg --verify /tmp/dbpm-gpg-test.txt.asc /tmp/dbpm-gpg-test.txt

Next Steps