{"id":22802584,"url":"https://github.com/code-specialist/pypi-poetry-publish","last_synced_at":"2025-07-18T19:07:30.041Z","repository":{"id":63408530,"uuid":"566963344","full_name":"code-specialist/pypi-poetry-publish","owner":"code-specialist","description":"Opinionated GitHub action to fully automate publishing packages to PyPI - using Poetry and GitHub releases","archived":false,"fork":false,"pushed_at":"2023-04-09T15:31:49.000Z","size":50,"stargazers_count":14,"open_issues_count":4,"forks_count":5,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-15T04:44:23.909Z","etag":null,"topics":["automation","github-action","github-actions","package","packaging","packaging-python","poetry","publishing","pypi","pypi-package","python","workflow"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/code-specialist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-16T19:33:45.000Z","updated_at":"2025-04-27T00:18:05.000Z","dependencies_parsed_at":"2024-11-17T15:36:54.509Z","dependency_job_id":"538c74bc-c787-496b-804c-76bed1fba223","html_url":"https://github.com/code-specialist/pypi-poetry-publish","commit_stats":{"total_commits":40,"total_committers":3,"mean_commits":"13.333333333333334","dds":"0.050000000000000044","last_synced_commit":"9009a9cb531bba9623ba89b7ef329d61619a0bb6"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/code-specialist/pypi-poetry-publish","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-specialist%2Fpypi-poetry-publish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-specialist%2Fpypi-poetry-publish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-specialist%2Fpypi-poetry-publish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-specialist%2Fpypi-poetry-publish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/code-specialist","download_url":"https://codeload.github.com/code-specialist/pypi-poetry-publish/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-specialist%2Fpypi-poetry-publish/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265465300,"owners_count":23770346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","github-action","github-actions","package","packaging","packaging-python","poetry","publishing","pypi","pypi-package","python","workflow"],"created_at":"2024-12-12T09:06:37.636Z","updated_at":"2025-07-18T19:07:30.013Z","avatar_url":"https://github.com/code-specialist.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# pypi-poetry-publish\n\nOpinionated GitHub action to fully automate publishing packages to PyPI - using Poetry and GitHub releases.\n\nWe published this action because we use it in our projects and thought it would be useful to others as well. This action is **open to any kind of\ncollaboration and contribution** - We're happy to receive feedback, issues, pull requests or just kudos.\n\n## Features\n\n- Automatically publish your package to PyPI when you create a new release on GitHub\n- Publish to the public PyPI, the TestPyPI, or a custom PyPI registry\n- Runs on private GitHub Actions runners\n- Support for private PyPI repository dependencies\n- Configurable **Python version**, **Poetry**, and **Poetry Core version** for specific needs\n- Configurable branch e.g. `main`, `master`, `beta`, etc.\n\nJump to example:\n\t- [Publish to public PyPI](#publish-to-public-pypi)\n\t- [With private dependencies](#with-private-dependencies)\n\t- [To a private PyPI](#publish-to-a-private-pypi)\n\t- [With private dependencies](#with-private-dependencies)\n\n## Prerequisites\n\nThis action assumes you use [poetry](https://python-poetry.org/) as your package manager and have the `pyproject.toml` and `poetry.lock` files in the root directory of your\nrepository.\n\n```\nmy_project/\n├─ example_package/\n│  ├─ __init__.py\n├─ pyproject.toml\n├─ poetry.lock\n```\n\n\u003e :information_source: If you do not use a custom runner, you may use the builtin functionality `GITHUB_TOKEN` with write permissions as the `ACCESS_TOKEN` as seen in the first\n\u003e example.\n\u003e See [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow](https://docs.github.\n\u003e com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow)\n\n\u003e :warning: We recommend you to use this workflow with the test PyPI registry e.g. `PUBLISH_REGISTRY: \"https://test.pypi.org/simple/\"` until you can confirm your workflow works as\n\u003e expected.\n\n## Minimal example\n\n```yaml\nname: Build and publish python package\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  publish-service-client-package:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    steps:\n      - name: Publish PyPi package\n        uses: code-specialist/pypi-poetry-publish@v1\n        with:\n          ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PUBLISH_REGISTRY_PASSWORD: ${{ secrets.PYPI_TOKEN }}\n```\n\n## Process\n\n1. You create a new Release and Tag e.g. `1.0.0` (Trigger)\n2. The action will:\n\t1. build your package\n\t2. adjust the version in the `pyproject.toml` and `__init__.py` in the package directory according to the tag\n\t3. publish the package to a PyPI registry\n\n## Example process\n\n### Before the release\n\n**./pyproject.toml**\n\n```toml \n[tool.poetry]\nname = \"code-specialist-example-package\"\nversion = \"0.1.0\"\ndescription = \"Example package\"\nauthors = [\"Code Specialist\"]\npackages = [{include = \"example_package\"}]\n\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\n```\n\n**./example_package/__init__.py**\n\n```python\n__version__ = \"0.1.0\"\n```\n\n### After GitHub Release 1.0.0\n\nThe action will alter the content of your repository to avoid conflicts and version mismatches:\n\n**pyproject.toml**\n\n```toml \n[tool.poetry]\nname = \"code-specialist-example-package\"\nversion = \"1.0.0\" # adjusted to 1.0.0\ndescription = \"Example package\"\nauthors = [\"Code Specialist\"]\npackages = [{include = \"example_package\"}]\n\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\n```\n\n**./example_package/__init__.py**\n\n```python\n__version__ = \"1.0.0\"  # adjusted to 1.0.0\n```\n\n## Inputs\n\u003e The inputs marked with (✓) are required if the `POETRY_DEPENDENCY_REGISTRY_URL` is set.\n\n| Name                                  | Description                                                                                                                         | Mandatory | Default                    |\n|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|-----------|----------------------------|\n| `ACCESS_TOKEN`                        | GitHub token with write access to the repository, to adjust the version                                                             | ✓         |                            |\n| `PUBLISH_REGISTRY_PASSWORD`           | Either a password for the registry user or a token in combination with `__token__` as the `PUBLISH_REGISTRY_USERNAME`               | ✓         |                            |\n| `PUBLISH_REGISTRY_USERNAME`           | The username for the pypi registry                                                                                                  |           | `__token__`                |\n| `PACKAGE_DIRECTORY`                   | The directory the package is located in e.g. `./src/`, `./example_package`                                                          |           | './'                       |\n| `POETRY_VERSION`                      | The Poetry version to perform the build with                                                                                        |           | `1.1.8`                    |   \n| `POETRY_CORE_VERSION`                 | The Poetry Code version to perform the build with                                                                                   |           | `1.0.4`                    |   \n| `PYTHON_VERSION`                      | The Python version to perform the build with                                                                                        |           | `3.10`                     |   \n| `BRANCH`                              | The branch to publish from                                                                                                          |           | `master`                   |\n| `PUBLISH_REGISTRY`                    | The registry to publish to e.g.`https://test.pypi.org/simple/`                                                                      |           | `https://pypi.org/simple/` |\n| `POETRY_DEPENDENCY_REGISTRY_URL`      | Allows to define a custom registry to be used by Poetry for dependency installation e.g. `https://pypi.code-specialist.com/simple/` |           |                            |\n| `POETRY_DEPENDENCY_REGISTRY_NAME`     | The name used for the custom registry in the dependencies. Must match the name in the `pyproject.toml`                              | (✓)       |                            |\n| `POETRY_DEPENDENCY_REGISTRY_USERNAME` | The username for the custom registry                                                                                                | (✓)       |                            |\n| `POETRY_DEPENDENCY_REGISTRY_PASSWORD` | The password for the custom registry                                                                                                | (✓)       |                            |\n| `POETRY_CUSTOM_REGISTRY_AUTH`         | The authentication type for the custom registry                                                                                     |           | `http-basic`               |\n\n\n\n## Examples\n\nEach example requires you to:\n\n1. Create a workflow file e.g. `.github/workflows/publish.yaml`\n2. Create a new release and tag e.g. `1.0.0` and the action will be triggered and publishes your package\n\n\u003e :information_source: If there is a use case you would like to see, please open an issue or a pull request.\n\n### Publish to Public PyPI\n\n- Requires GitHub secrets:\n\t- `PUBLISH_REGISTRY_PASSWORD` with a valid token\n\nIn order to use the `GITHUB_TOKEN` you also have to provide permissions for the token. In this case you require the `contents:write` permission.\n\n**publish.yaml**\n```yaml\nname: Build and publish python package\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  publish-service-client-package:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    steps:\n      - name: Publish PyPi package\n        uses: code-specialist/pypi-poetry-publish@v1\n        with:\n          PACKAGE_DIRECTORY: \"./example-package/\"\n          PYTHON_VERSION: \"3.10\"\n          ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PUBLISH_REGISTRY_PASSWORD: ${{ secrets.PUBLISH_REGISTRY_PASSWORD }}\n```\n\n### Publish Test PyPI\n\n- Requires GitHub secrets:\n    - `PUBLISH_REGISTRY_PASSWORD` with a valid token\n    - `ACCESS_TOKEN` access token with write access to the GitHub repository\n  \n**publish.yaml**\n```yaml\nname: Build and publish python package\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  publish-service-client-package:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Publish PyPi package\n        uses: code-specialist/pypi-poetry-publish@v1\n        with:\n          PACKAGE_DIRECTORY: \"./example-package/\"\n          PYTHON_VERSION: \"3.10\"\n          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}\n          PUBLISH_REGISTRY_PASSWORD: ${{ secrets.PUBLISH_REGISTRY_PASSWORD }}\n          PUBLISH_REGISTRY: \"https://test.pypi.org/legacy/\"\n```\n\n### Publish to a Private PyPI\n\n- Requires GitHub secrets:\n\t- `PUBLISH_REGISTRY_USER` username for the PyPI registry\n\t- `PUBLISH_REGISTRY_PASSWORD` with the password for the `PUBLISH_REGISTRY_USER` user\n\t- `ACCESS_TOKEN` access token with write access to the GitHub repository\n\n**publish.yaml**\n```yaml\nname: Build and publish python package\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  publish-service-client-package:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Publish PyPI package\n        uses: code-specialist/pypi-poetry-publish@v1\n        with:\n          PACKAGE_DIRECTORY: \"./example-package/\"\n          PYTHON_VERSION: \"3.10\"\n          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}\n          PUBLISH_REGISTRY_PASSWORD: ${{ secrets.PUBLISH_REGISTRY_PASSWORD }}\n          PUBLISH_REGISTRY_USER: ${{ secrets.PUBLISH_REGISTRY_USER }}\n          PUBLISH_REGISTRY: \"https://pypi.code-specialist.com/simple/\"\n```\n\n###  With Private Dependencies\n\n- Requires GitHub secrets:\n  - `ACCESS_TOKEN` access token with write access to the GitHub repository\n  - `PUBLISH_REGISTRY_USER` username for the PyPI registry\n  - `PUBLISH_REGISTRY_PASSWORD` with the password for the `PUBLISH_REGISTRY_USER` user\n  - `POETRY_DEPENDENCY_REGISTRY_USERNAME` username for the custom registry\n  - `POETRY_DEPENDENCY_REGISTRY_PASSWORD` password for the custom registry\n\n**publish.yaml**\n```yaml\nname: Build and publish python package\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  publish-service-client-package:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Publish PyPI package\n      uses: code-specialist/pypi-poetry-publish@v1\n      with:\n        ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}\n        PUBLISH_REGISTRY_USER: ${{ secrets.PUBLISH_REGISTRY_USER }}\n        PUBLISH_REGISTRY_PASSWORD: ${{ secrets.PUBLISH_REGISTRY_PASSWORD }}\n        PUBLISH_REGISTRY: \"https://pypi.code-specialist.com\"\n        POETRY_DEPENDENCY_REGISTRY_URL: \"https://pypi.code-specialist.com\"\n        POETRY_DEPENDENCY_REGISTRY_NAME: \"codespecialist\"\n        POETRY_DEPENDENCY_REGISTRY_USERNAME: ${{ secrets.CUSTOM_PUBLISH_REGISTRY_USERNAME }}\n        POETRY_DEPENDENCY_REGISTRY_PASSWORD: ${{ secrets.CUSTOM_PUBLISH_REGISTRY_PASSWORD }}\t\t\t\t\t\t\t\t\t\n```\n\nFor this to install the dependency `private-code-specialist-example-package` from `https://pypi.code-specialist.com/simple/`, the corresponding `pyproject.toml` would look like \nthis:\n\n```toml\n[tool.poetry]\nname = \"code-specialist-example-package\"\nversion = \"1.0.0\" # adjusted to 1.0.0\ndescription = \"Example package\"\nauthors = [\"Code Specialist\"]\npackages = [{include = \"example_package\"}]\n\n[[tool.poetry.source]]\nname = \"codespecialist\"\nurl = \"https://pypi.code-specialist.com\"\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\nprivate-code-specialist-example-package = {version = \"^1.0.0\", source = \"codespecialist\"}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-specialist%2Fpypi-poetry-publish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-specialist%2Fpypi-poetry-publish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-specialist%2Fpypi-poetry-publish/lists"}