Skip to main content

CLI tool to publish Python packages and documentation with external configuration

Project description

cal-publish-python

CLI tool to publish Python packages and documentation with external configuration.

Overview

cal-publish-python is designed to keep sensitive configuration (tokens, registry URLs, SSH keys) outside of build jobs. The project being published defines the "what" (name, version), while a named profile in the publishing configuration defines the "where" (registry, documentation platform).

Installation

pip install cal-publish-python

Or with uv:

uv pip install cal-publish-python

Usage

# Publish everything in output/ (wheel + docs zip)
cal-publish-python --set-latest output/

# Publish only the PyPI package
cal-publish-python --pypi-only output/

# Publish only the documentation
cal-publish-python --docs-only --set-latest output/

# Specify a profile explicitly
cal-publish-python --profile internal --set-latest output/

# Specify individual files
cal-publish-python output/my-package-1.0.0-py3-none-any.whl output/my-package-1.0.0-docs.zip

CLI Arguments

Argument Short Description
ARTIFACT Directory or file(s) to publish (.whl and/or docs .zip)
--config -c Path to JSON configuration file
--profile Profile to use from the configuration file
--pypi-only Only publish to PyPI (skip documentation)
--docs-only Only publish documentation (skip PyPI)
--set-latest -l Also set this version as 'latest' (GitLab Pages mode only)
--force -f Overwrite existing documentation version if it exists
--verbose -v Verbose output

Configuration

Profiles

Configuration uses named profiles. Each profile contains the full set of publishing settings (PyPI credentials, documentation targets, etc.). This allows the same config file to serve both public and internal publishing.

Create a JSON config file at ~/.config/cal-publish-python/config.json:

{
    "profiles": {
        "public": {
            "pypi": {
                "token": "pypi-xxxxxxxxxxxx",
                "username": "__token__",
                "repository_url": "https://upload.pypi.org/legacy/"
            },
            "docs": {
                "mode": "gitlab-pages",
                "gitlab_pages": {
                    "token": "glpat-xxxxxxxxxxxx",
                    "url": "https://gitlab.com",
                    "group": "mygroup/public/docs"
                }
            }
        },
        "internal": {
            "pypi": {
                "token": "nexus-xxxxxxxxxxxx",
                "username": "deploy-user",
                "repository_url": "https://nexus.internal/repository/pypi/"
            },
            "docs": {
                "mode": "ssh",
                "ssh": {
                    "host": "docs.internal",
                    "base_path": "/var/www/docs"
                }
            }
        }
    }
}

Profile Selection

A profile is required when a config file is present. The profile is resolved in this order:

  1. --profile NAME CLI argument
  2. CAL_PUBLISH_PROFILE environment variable
  3. [tool.cal-publish-python] in pyproject.toml:
[tool.cal-publish-python]
profile = "public"

This means each project can declare which profile it uses, and make publish just works without any extra arguments.

Config File Location

The config file is resolved in this order:

  1. --config FILE CLI argument
  2. CAL_PUBLISH_CONFIG environment variable
  3. ~/.config/cal-publish-python/config.json (default)

If no config file exists at the default path, the tool runs in environment-variable-only mode (useful for CI).

Environment Variables

All configuration values can be overridden by environment variables, regardless of what the config file/profile contains:

Variable Description
CAL_PUBLISH_CONFIG Path to JSON config file
CAL_PUBLISH_PROFILE Profile name to use from config file
CAL_PUBLISH_PYPI_TOKEN PyPI API token or password
CAL_PUBLISH_PYPI_USERNAME PyPI username (default: __token__)
CAL_PUBLISH_PYPI_REPOSITORY_URL PyPI repository URL
CAL_PUBLISH_DOCS_MODE Documentation mode (gitlab-pages, ssh, or cal-docs-server)
CAL_PUBLISH_GITLAB_TOKEN GitLab personal access token
CAL_PUBLISH_GITLAB_URL GitLab instance URL
CAL_PUBLISH_GITLAB_GROUP GitLab group for docs
CAL_PUBLISH_SSH_HOST SSH host
CAL_PUBLISH_SSH_BASE_PATH Base path on remote server
CAL_PUBLISH_SSH_KEY Path to SSH private key
CAL_PUBLISH_SSH_USER SSH user
CAL_PUBLISH_SSH_PORT SSH port
CAL_PUBLISH_DOCS_SERVER_URL cal-docs-server URL
CAL_PUBLISH_DOCS_SERVER_TOKEN API token for cal-docs-server

Integration with Makefile

Add a publish target to your project's Makefile:

.PHONY: publish
publish: check-dependencies
	uv run cal-publish-python --set-latest output/

And declare the profile in pyproject.toml:

[tool.cal-publish-python]
profile = "public"

Documentation Zip Filename

The docs zip filename is used to determine the project name and version:

project-name-VERSION-docs.zip

Examples: myproject-1.0.0-docs.zip, my-lib-2.3.4.post5+gabcdef-docs.zip

Development

# Clone the repository
git clone <repo-url>
cd cal-publish-python

# Set up development environment
make dev

# Run checks
make check

# Build
make build

Licence

MIT License - Copyright (c) 2026 Cyber Assessment Labs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cal_publish_python-1.1.0b1-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file cal_publish_python-1.1.0b1-py3-none-any.whl.

File metadata

File hashes

Hashes for cal_publish_python-1.1.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 97e066062be51b5be5ed3849ac7f30a22cbf2f5b89f24a86c0b72aa3c3a685b5
MD5 3b3b6c4b159d9828481ed842a24cb8c1
BLAKE2b-256 e25b588aa22bc0018859e0f9b41baecd5b3eec189196b9ed12cc35639e215a35

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page