Python packaging repo
About
A Python Packaging Repository (PPR) is a Git repository with a CI/CD pipeline designed to create and publish Python packages from code pushed to the repository. Using the package-auto-assembler tool, PPR can dynamically generate a packaging structure for .py files in a highly automated manner. This allows you to publish and maintain multiple packages from a single repository.
In its simplest form, adding a new .py file (or modifying an existing one) triggers the CI/CD pipeline to automatically prepare and publish release of new or existing package. Packages can be published to PyPI or private storage solutions such as Azure Artifacts Storage.

Diagram: Automated flow for packaging and publishing Python packages using PPR.
Inputs and Outputs of PPR
PPR produces Python packages with the structure shown below when all optional files are present. You can find more details about these files here.
Each package can include optional features:
- Store files - Include files or links to files within the package.
- CLI interface - Add command-line utilities to the package.
- FastAPI routes - Embed API routes to run FastAPI applications from packages.
- Streamlit apps - Include interactive UIs.
- MkDocs pages - Generate simple static documentation websites for each package.

Diagram: The structure includes core package files and additional optional components such as CLI interfaces, FastAPI routes, or documentation.
Basic usage
1. Prepare Local Environment
Before developing code within a packaging repository, ensure that the package-auto-assembler python package is installed in your environment:
pip install package-auto-assembler
Note: Some config files, like .pipirc and .pip.conf, might be required to configure access to private packages from Azure Artifacts storage.
2. Add or Edit a Package
To prepare your code for packaging:
-
Create/find a
.pyfile inmodule_dirwith a name of the package (use underscores (_) instead of hyphens (-) and spaces) -
Make sure the module you're trying to create/edit follows basic requirements, described here
-
Add/edit optional files and additional documentation.
Note: Relevant names of the directories, like module_dir, could be checked in .paa.config file from your instance of a packaging repository. This and the following steps assume that an instance of a packaging repository was already created or pulled. If not, to setup a new ppr take a look here.
3. Test-Install a Package
After adding or editing files related to your package, install it locally and ensure it works as expected.
paa test-install your-package
Note: Use the --skip-deps-install flag if reinstalling dependencies is unnecessary. More flags could be seen here.
4. Push Changes to PPR
When code is ready for release, commit changes, including the package name and a list of changes in your commit messages. Push the changes to a new branch your packaging repository, then create a pull request to the main branch.
git commit -m "[your_package] change one; comment about change two"
Note: Merge files for only one package at a time. The pipeline relies on commit history to determine which package to test and publish.
5. Publish a Package
If the test results are satisfactory, merge the pull request with main. The pipeline will then:
- Initialize the packaging process.
- Prepare the package.
- Publish it to package storage.
- Update tracking files in
.paaand README.
Note Due to possibility of multiple packaging feeds, trigger for azure devops + azure artifacts feed template would not be automatic on merge, but would need to be triggered manually after merging with main. To do so, in your Azure DevOps project, navigate to Pipelines -> your-packaging-repo-pipeline -> Run pipeline and select one of the configured upload feeds in Upload Feed as well as indicate package to be published (ensure to use underscores (_) instead of hyphens (-)) in Package Name field.
Additional Information
To see more CLI tools and options, run:
paa --help
Or visit package-auto-assembler documentation.
Setting up new PPR
A Python Packaging Repository can be created for:
- GitHub with PyPI
- Azure DevOps with Azure Artifacts
Prerequisites
- New Git Repository: A repository where the PPR will be set up.
- Pipeline Permissions: CI/CD pipelines must have read and write access to commit to the repository.
- Package Storage:
- GitHub: A PyPI account.
- Azure DevOps: An Azure Artifacts Feed.
Only two templates are provided:
- github + pypi
- azure devops + azure artifacts feed
Github
-
Set Up GitHub Pages:
- Navigate to
Settings->Pages. - Select
Deploy from a branchchoose thegh-pagesbranch (if it does not exist, create a new branch namedgh-pages), and set the directory to/root. More details.
- Navigate to
-
Configure GitHub Actions:
- Navigate to
Settings->Actions->General. - Under
Actions permissionsselectAllow all actions and reusable workflows - Under
Workflow permissionsselectRead and write permissionsMore details.
- Navigate to
-
Add PyPI Credentials:
- Go to
Settings->Secrets and variables->Actions. - Add
TWINE_USERNAMEandTWINE_PASSWORDas secrets. More details.
- Go to
-
Initialize the Template:
- Use
paato set up the PPR:
paa init-ppr --githubOr include all optional directories:
paa init-ppr --github --full- Edit
.paa.configif needed - Run
paa init-ppr --githuborpaa init-paaa second time to initialize directories for storing packaging files based on.paa.config.
- Use
-
Customize:
- Edit
.github/docs/README_base.mdand.github/tools/update_README.shto modify the repository-level README.
- Edit
Once setup is complete, pushing changes to the main will automatically trigger the pipeline to package and publish your Python packages.
Azure DevOps
-
Repository Permissions:
- Navigate to
Project settings->Repositories->Your Repository. - Set
ContributeandCreate tagpermissions forYour project build serviceto "Allow"
- Navigate to
-
Set Up Azure Artifacts Feed:
- Create an artifacts feed or use an existing one. More details.
-
Add Credentials:
- Generate a Personal Access Token (
TWINE_USERNAMEandTWINE_PASSWORD) withRead & writee permissions forPackagingMore details.
- Generate a Personal Access Token (
-
Initialize the Template:
- Use
paato set up the PPR:
paa init-ppr --azureOr include all optional directories:
paa init-ppr --azure --full- Edit
.paa.configif needed - Run
paa init-ppr --azureorpaa init-paaa second time to initialize directories for storing packaging files based on.paa.config. - Create
.azure/feeds/YOUR_FEED_NAME.ymlfiles based on.azure/feeds/example_feed.ymland remove the example.
- Use
-
Configure the Pipeline:
- Navigate to
Pipelines->New pipeline. - Choose
Azure Repos Git->Your Repository. - Select the
mainbranch and.azure/azure-pipelines.ymlto define the pipeline configuration for packaging and publishing. - Add
TWINE_USERNAMEandTWINE_PASSWORDunder "Variables"
- Navigate to
-
Customize:
- Edit
.azure/docs/README_base.mdand.azure/tools/update_README.shto modify the repository-level README.
- Edit
Note: Pushing changes to the main branch does not necessarily mean that a package will be published. Since multiple feeds can be published from this repository, a manual trigger is preferred.
To trigger the workflow:
- Navigate to
Pipelines->your-packaging-repo-pipeline->Run pipeline. - Select one of the configured upload feeds in the
Upload Feeddropdown. - Specify the package name in the
Package Namefield (use underscores (_) instead of hyphens (-)).