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/.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@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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + sparse-checkout: clang/bindings/python/ + + - uses: actions/setup-python@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@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@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@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + with: + name: python-package-dist + path: dist + + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 \ No newline at end of file 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\\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"