-
Notifications
You must be signed in to change notification settings - Fork 0
PUBLISHING
The package includes built-in support for publishing to PyPI, TestPyPI, and Azure Artifacts.
Publish after building:
# Publish to PyPI (version resolved automatically via conventional commits)
python-package-folder --publish pypi
# See [Version Resolution](Version-Resolution) for details on automatic versioning
# Publish to PyPI with a specific version
python-package-folder --version "1.2.3" --publish pypi
# Publish to TestPyPI (for testing)
python-package-folder --publish testpypi
# Publish to Azure Artifacts
python-package-folder --publish azure --repository-url "https://pkgs.dev.azure.com/ORG/PROJECT/_packaging/FEED/pypi/upload"The command will prompt for credentials if not provided:
# Provide credentials via command line (less secure)
python-package-folder --publish pypi --username __token__ --password pypi-xxxxx
# Skip existing files on repository
python-package-folder --publish pypi --skip-existingFor PyPI/TestPyPI:
-
Username: Your PyPI username, or
__token__for API tokens - Password: Your PyPI password or API token (recommended)
-
Auto-detection: If you provide an API token (starts with
pypi-), the tool will automatically use__token__as the username, even if you entered a different username
Common Authentication Issues:
-
403 Forbidden: Usually means you used your username instead of
__token__with an API token. The tool now auto-detects this. - TestPyPI vs PyPI: TestPyPI requires a separate account and token from https://test.pypi.org/manage/account/token/
When publishing without --version, the tool automatically resolves the next version using conventional commits. This queries the target registry for the latest published version and calculates the next version based on commit messages since that version.
# Version resolved automatically from conventional commits
python-package-folder --publish pypi
# Or specify version explicitly
python-package-folder --version "1.2.3" --publish pypiSee Version Resolution for complete details on how automatic versioning works.
When publishing, the tool automatically filters distribution files to only upload those matching the current build:
- Package name matching: Only uploads files for the package being built
- Version matching: Only uploads files for the specified version
-
Automatic cleanup: Old build artifacts in
dist/are ignored, preventing accidental uploads
This ensures that when building a subfolder package, only that package's distribution files are uploaded, not files from previous builds of other packages.
If there's a version mismatch between the built package and the expected version (e.g., when a subfolder's pyproject.toml has a different version than the derived version), the error message will show:
- What version was actually built
- What version is expected for publishing
- An explanation of the mismatch
- A solution suggestion
The tool automatically updates the version in the subfolder's pyproject.toml to match the derived version, so this error should only occur if the build process fails before the version update takes effect.
To get a PyPI API token:
- Go to https://pypi.org/manage/account/token/
- Create a new API token
- Use
__token__as username and the token as password
For Azure Artifacts:
- Username: Your Azure username or feed name
- Password: Personal Access Token (PAT) with packaging permissions
- Repository URL: Your Azure Artifacts feed URL
You can also publish programmatically:
from pathlib import Path
from python_package_folder import BuildManager, Publisher, Repository
import subprocess
# Build and publish in one step
manager = BuildManager(project_root=Path("."), src_dir=Path("src"))
def build():
subprocess.run(["uv", "build"], check=True)
manager.build_and_publish(
build,
repository="pypi",
username="__token__",
password="pypi-xxxxx",
version="1.2.3" # Optional: set specific version
)Or publish separately:
from python_package_folder import Publisher, Repository
# Publish existing distribution
publisher = Publisher(
repository=Repository.PYPI,
dist_dir=Path("dist"),
username="__token__",
password="pypi-xxxxx"
)
publisher.publish()Note: The package does not store credentials by default. Credentials must be provided via command-line arguments (--username and --password) or will be prompted each time you run the publish command. This ensures credentials are not persisted and must be entered fresh each time.
If you previously used an older version that stored credentials in keyring, you can clear them using:
from python_package_folder import Publisher, Repository
publisher = Publisher(repository=Repository.AZURE)
publisher.clear_stored_credentials()Or manually using Python:
import keyring
keyring.delete_password("python-package-folder-azure", "username")
# Also delete the password if you know the username