[clang] [llvm] [libclang/python][ci] Add release Clang Python Bindings CI workflow (PR #168234)
Ryan Mast via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 15 12:18:19 PST 2025
https://github.com/nightlark created https://github.com/llvm/llvm-project/pull/168234
This migrates the CI workflow from https://github.com/trolldbois/python-clang/blob/master/.github/workflows/release.yml and adapts it to work within the structure of the LLVM monorepo.
It builds upon the Python packaging files added in https://github.com/llvm/llvm-project/pull/125806, and should be merged after that one.
The CI workflow is set up to use two jobs:
- the first just builds the package and saves it as an artifact and will work for testing in forks, PRs, and untagged commits
- the second checks for release manager permissions and uses trusted publishing to upload the package to PyPI
>From 6bb389392615b27c167a718b275bd497c1201f9c Mon Sep 17 00:00:00 2001
From: Ryan Mast <mast.ryan at gmail.com>
Date: Tue, 4 Feb 2025 21:59:28 -0800
Subject: [PATCH 1/2] [libclang/python] Enable packaging clang python bindings
This adds a pyproject.toml file for creating sdist and wheel packages for the clang python bindings. It is required to move updates of the clang and libclang PyPI packages to the LLVM monorepo. Versioning information is derived from LLVM git tags, so no manual updates are needed to bump version numbers. The minimum python version required is set to 3.10 due to cindex.py using PEP 604 union type syntax (str | bytes | None).
Signed-off-by: Ryan Mast <mast.ryan at gmail.com>
---
.gitattributes | 2 ++
clang/bindings/python/.git_archival.txt | 3 ++
clang/bindings/python/.gitignore | 21 ++++++++++++
clang/bindings/python/pyproject.toml | 43 +++++++++++++++++++++++++
4 files changed, 69 insertions(+)
create mode 100644 clang/bindings/python/.git_archival.txt
create mode 100644 clang/bindings/python/.gitignore
create mode 100644 clang/bindings/python/pyproject.toml
diff --git a/.gitattributes b/.gitattributes
index 6b281f33f737d..142d6689f1088 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,5 @@
+clang/bindings/python/.git_archival.txt export-subst
+
libcxx/src/**/*.cpp merge=libcxx-reformat
libcxx/include/**/*.h merge=libcxx-reformat
diff --git a/clang/bindings/python/.git_archival.txt b/clang/bindings/python/.git_archival.txt
new file mode 100644
index 0000000000000..7876d4af4c620
--- /dev/null
+++ b/clang/bindings/python/.git_archival.txt
@@ -0,0 +1,3 @@
+node: $Format:%H$
+node-date: $Format:%cI$
+describe-name: $Format:%(describe:tags=true,match=llvmorg-*[0-9]*)$
diff --git a/clang/bindings/python/.gitignore b/clang/bindings/python/.gitignore
new file mode 100644
index 0000000000000..1641a745fb682
--- /dev/null
+++ b/clang/bindings/python/.gitignore
@@ -0,0 +1,21 @@
+# setuptools_scm auto-generated version file
+_version.py
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# Distribution / packaging
+build/
+dist/
+*.egg-info/
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
diff --git a/clang/bindings/python/pyproject.toml b/clang/bindings/python/pyproject.toml
new file mode 100644
index 0000000000000..69fd628e8222a
--- /dev/null
+++ b/clang/bindings/python/pyproject.toml
@@ -0,0 +1,43 @@
+[build-system]
+requires = ["hatchling>=1.27", "hatch-vcs>=0.4"]
+build-backend = "hatchling.build"
+
+[project]
+name = "clang"
+description = "clang python bindings"
+readme = {file = "README.txt", content-type = "text/plain"}
+
+license = "Apache-2.0 WITH LLVM-exception"
+authors = [
+ { name = "LLVM" }
+]
+keywords = ["llvm", "clang", "libclang"]
+classifiers = [
+ "Intended Audience :: Developers",
+ "Development Status :: 5 - Production/Stable",
+ "Topic :: Software Development :: Compilers",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python :: 3",
+]
+requires-python = ">=3.10"
+dynamic = ["version"]
+
+[project.urls]
+Homepage = "https://clang.llvm.org/"
+Download = "https://llvm.org/releases/download.html"
+Discussions = "https://discourse.llvm.org/"
+"Issue Tracker" = "https://github.com/llvm/llvm-project/issues"
+"Source Code" = "https://github.com/llvm/llvm-project/tree/main/clang/bindings/python"
+
+[tool.hatch.version]
+source = "vcs"
+version-scheme = "no-guess-dev"
+# regex version capture group gets x.y.z with optional -rcN, -aN, -bN suffixes; -init is just consumed
+tag-pattern = "^llvmorg-(?P<version>\\d+(?:\\.\\d+)*(?:-rc\\d+)?)"
+
+[tool.hatch.build.hooks.vcs]
+version-file = "clang/_version.py"
+
+[tool.hatch.version.raw-options]
+search_parent_directories = true
+version_scheme = "no-guess-dev"
>From bfbdf3c6107095c92c219ea05ab36fa872742d4b Mon Sep 17 00:00:00 2001
From: Ryan Mast <mast.ryan at gmail.com>
Date: Sat, 15 Nov 2025 10:50:14 -0800
Subject: [PATCH 2/2] [libclang/python][ci] Add release Clang Python Bindings
CI workflow
This migrates the CI workflow from https://github.com/trolldbois/python-clang/blob/master/.github/workflows/release.yml and adapts it to work within the structure of the LLVM monorepo.
It builds upon the Python packaging files added in #125806, and should be merged after that one.
The CI workflow is set up to use two jobs:
- the first just builds the package and saves it as an artifact and will work for testing in forks, PRs, and untagged commits
- the second checks for release manager permissions and uses trusted publishing to upload the package to PyPI
Signed-off-by: Ryan Mast <mast.ryan at gmail.com>
---
.github/workflows/release-clang-pypi.yml | 111 +++++++++++++++++++++++
1 file changed, 111 insertions(+)
create mode 100644 .github/workflows/release-clang-pypi.yml
diff --git a/.github/workflows/release-clang-pypi.yml b/.github/workflows/release-clang-pypi.yml
new file mode 100644
index 0000000000000..8c0b00a574cf5
--- /dev/null
+++ b/.github/workflows/release-clang-pypi.yml
@@ -0,0 +1,111 @@
+name: Release Clang Python Bindings
+
+permissions:
+ contents: read
+
+on:
+ push:
+ branches:
+ - main
+ - release/*
+ paths:
+ - .github/workflows/release-clang-pypi.yml
+ - 'clang/bindings/python/**'
+
+ pull_request:
+ paths:
+ - .github/workflows/release-clang-pypi.yml
+ - 'clang/bindings/python/**'
+
+ workflow_dispatch:
+ inputs:
+ release-version:
+ description: 'Release Version'
+ required: false
+ type: string
+
+ workflow_call:
+ inputs:
+ release-version:
+ description: 'Release Version'
+ required: true
+ type: string
+ secrets:
+ RELEASE_TASKS_USER_TOKEN:
+ description: "Secret used to check user permissions."
+ required: false
+
+jobs:
+ build-release:
+ if: github.repository_owner == 'llvm' || github.event_name == 'workflow_dispatch'
+ runs-on: ubuntu-24.04
+ steps:
+ - name: Checkout LLVM (tagged release)
+ if: inputs.release-version != ''
+ uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ with:
+ ref: "llvmorg-${{ inputs.release-version }}"
+ fetch-depth: 0
+ sparse-checkout: clang/bindings/python/
+
+ - name: Checkout LLVM (latest commit)
+ if: inputs.release-version == ''
+ uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ with:
+ fetch-depth: 0
+ sparse-checkout: clang/bindings/python/
+
+ - uses: actions/setup-python at e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
+ with:
+ python-version: '3.13'
+
+ - name: Package Clang Python Bindings
+ working-directory: clang/bindings/python
+ run: |
+ pip install build twine
+ python -m build
+ python -m twine check dist/*
+
+ - name: Upload Clang Python Bindings package dist artifacts
+ uses: actions/upload-artifact at 330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
+ with:
+ name: python-package-dist
+ path: clang/bindings/python/dist
+
+ pypi-publish:
+ name: Upload release to PyPI
+ runs-on: ubuntu-24.04
+ needs: build-release
+ # Only run this job in the main llvm repository when a release version is provided.
+ if: github.repository_owner == 'llvm' && inputs.release-version != ''
+ environment:
+ name: pypi
+ url: https://pypi.org/p/clang
+ permissions:
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
+ steps:
+ - name: Checkout github-upload-release.py for permissions check
+ uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ with:
+ sparse-checkout: llvm/utils/release/github-upload-release.py
+
+ - name: Install dependencies for github-upload-release.py
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y python3-github
+
+ - name: Check Permissions
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}
+ run: |
+ ./llvm/utils/release/github-upload-release.py --token "$GITHUB_TOKEN" --user ${{ github.actor }} --user-token "$USER_TOKEN" check-permissions
+
+ - name: Download Python package dist artifacts
+ uses: actions/download-artifact at 018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
+ with:
+ name: python-package-dist
+ path: dist
+
+ - name: Publish package distributions to PyPI
+ uses: pypa/gh-action-pypi-publish at ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
\ No newline at end of file
More information about the llvm-commits
mailing list