Skip to content

Commit 1260715

Browse files
librdkafka/confluent-kafka-python v2.8.0-gr (#4)
1 parent 92c83e7 commit 1260715

File tree

4 files changed

+244
-2
lines changed

4 files changed

+244
-2
lines changed

.github/scripts/generate_index.py

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import os
2+
import sys
3+
import re
4+
import itertools
5+
import requests
6+
import hashlib
7+
8+
from urllib.parse import quote
9+
from pathlib import Path
10+
from github import Github
11+
from typing import List, Dict
12+
13+
HTML_TEMPLATE = """<!DOCTYPE html>
14+
<html>
15+
<head>
16+
<title>{package_name}</title>
17+
</head>
18+
<body>
19+
<h1>{package_name}</h1>
20+
{package_links}
21+
</body>
22+
</html>
23+
"""
24+
25+
def normalize(name):
26+
"""Normalize package name according to PEP 503."""
27+
return re.sub(r"[-_.]+", "-", name).lower()
28+
29+
def calculate_sha256(file_path):
30+
with open(file_path, "rb") as f:
31+
digest = hashlib.file_digest(f, "sha256")
32+
33+
return digest.hexdigest()
34+
35+
class PackageIndexBuilder:
36+
def __init__(self, token: str, repo_name: str, output_dir: str):
37+
self.github = Github(token)
38+
self.repo = self.github.get_repo(repo_name)
39+
self.output_dir = Path(output_dir)
40+
self.packages: Dict[str, List[Dict]] = {}
41+
42+
# Set up authenticated session
43+
self.session = requests.Session()
44+
self.session.headers.update({
45+
"Authorization": f"token {token}",
46+
"Accept": "application/octet-stream",
47+
})
48+
49+
def collect_packages(self):
50+
51+
print ("Query release assets")
52+
53+
for release in self.repo.get_releases():
54+
for asset in release.get_assets():
55+
if asset.name.endswith(('.whl', '.tar.gz')):
56+
package_name = normalize(asset.name.split('-')[0])
57+
if package_name not in self.packages:
58+
self.packages[package_name] = []
59+
60+
self.packages[package_name].append({
61+
'filename': asset.name,
62+
'url': asset.url,
63+
'size': asset.size,
64+
'upload_time': asset.created_at.strftime('%Y-%m-%d %H:%M:%S'),
65+
})
66+
67+
def generate_index_html(self):
68+
# Generate main index
69+
package_list = self.packages.keys()
70+
main_index = HTML_TEMPLATE.format(
71+
package_name="Simple Package Index",
72+
package_links="\n".join([f'<a href="{x}/">{x}</a><br/>' for x in package_list])
73+
)
74+
75+
with open(self.output_dir / "index.html", "w") as f:
76+
f.write(main_index)
77+
78+
for package, assets in self.packages.items():
79+
80+
package_dir = self.output_dir / package
81+
package_dir.mkdir(exist_ok=True)
82+
83+
# Generate package-specific index.html
84+
file_links = []
85+
assets = sorted(assets, key=lambda x: x["filename"])
86+
for filename, items in itertools.groupby(assets, key=lambda x: x["filename"]):
87+
url = next(items)['url']
88+
89+
# Download the file
90+
with open(package_dir / filename, 'wb') as f:
91+
print (f"Downloading '{filename}' from '{url}'")
92+
response = self.session.get(url, stream=True)
93+
response.raise_for_status()
94+
for chunk in response.iter_content(chunk_size=8192):
95+
if chunk:
96+
f.write(chunk)
97+
98+
sha256_hash = calculate_sha256(package_dir / filename)
99+
file_links.append(f'<a href="{quote(filename)}#sha256={sha256_hash}">{filename}</a><br/>')
100+
101+
package_index = HTML_TEMPLATE.format(
102+
package_name=f"Links for {package}",
103+
package_links="\n".join(file_links)
104+
)
105+
106+
with open(package_dir / "index.html", "w") as f:
107+
f.write(package_index)
108+
109+
def build(self):
110+
# Create output directory
111+
self.output_dir.mkdir(parents=True, exist_ok=True)
112+
113+
# Collect and generate
114+
self.collect_packages()
115+
self.generate_index_html()
116+
117+
118+
def main():
119+
# Get environment variables
120+
token = os.environ.get("GITHUB_TOKEN")
121+
repo = os.environ.get("GITHUB_REPOSITORY")
122+
print (repo)
123+
output_dir = os.environ.get("OUTPUT_DIR", "dist")
124+
125+
if not all([token, repo]):
126+
print ("Missing required environment variables")
127+
sys.exit(1)
128+
129+
builder = PackageIndexBuilder(token, repo, output_dir)
130+
builder.build()
131+
132+
if __name__ == "__main__":
133+
main()

.github/workflows/package.yml

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# .github/workflows/build-wheels.yml
2+
name: Build and Package Wheels
3+
4+
on:
5+
pull_request:
6+
push:
7+
8+
env:
9+
LIBRDKAFKA_VERSION: v2.8.0-gr
10+
11+
jobs:
12+
13+
build-linux-x64:
14+
name: Build wheels for Linux x64
15+
runs-on: ubuntu-latest
16+
env:
17+
OS_NAME: linux
18+
ARCH: x64
19+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Build wheels
23+
run: |
24+
./tools/wheels/build-wheels.sh "${LIBRDKAFKA_VERSION#v}" wheelhouse
25+
- uses: actions/upload-artifact@v4
26+
with:
27+
name: wheels-${{ env.OS_NAME }}-${{ env.ARCH }}
28+
path: wheelhouse/confluent_kafka*.whl
29+
30+
build-windows:
31+
name: Build wheels for Windows
32+
runs-on: windows-latest
33+
env:
34+
OS_NAME: windows
35+
ARCH: x64
36+
CHERE_INVOKING: yes
37+
MSYSTEM: UCRT64
38+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39+
steps:
40+
- uses: actions/checkout@v4
41+
- name: Setup MSYS2
42+
uses: msys2/setup-msys2@v2
43+
- name: Build wheels
44+
shell: bash
45+
run: |
46+
./tools/mingw-w64/msys2-dependencies.sh
47+
bash tools/mingw-w64/semaphore_commands.sh
48+
bash tools/wheels/install-librdkafka.sh ${LIBRDKAFKA_VERSION#v} dest
49+
tools/wheels/build-wheels.bat x64 win_amd64 dest wheelhouse
50+
- uses: actions/upload-artifact@v4
51+
with:
52+
name: wheels-${{ env.OS_NAME }}-${{ env.ARCH }}
53+
path: wheelhouse/confluent_kafka*.whl
54+
55+
publish_pypi_index:
56+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
57+
name: Build a PyPI-compatible index
58+
needs: [build-linux-x64, build-windows]
59+
runs-on: ubuntu-latest
60+
permissions:
61+
contents: write
62+
actions: read
63+
packages: read
64+
pages: write
65+
id-token: write
66+
steps:
67+
- uses: actions/checkout@v2
68+
- uses: actions/download-artifact@v4
69+
with:
70+
path: artifacts
71+
pattern: wheels-*
72+
merge-multiple: true
73+
74+
- name: Create release
75+
uses: softprops/action-gh-release@v2
76+
with:
77+
files: |
78+
artifacts/confluent_kafka*
79+
env:
80+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
81+
82+
- name: Generate Package Index
83+
run: |
84+
python -m pip install --upgrade pip
85+
pip install PyGithub
86+
python .github/scripts/generate_index.py
87+
env:
88+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89+
OUTPUT_DIR: dist
90+
91+
- name: Upload Site Artifact
92+
uses: actions/upload-pages-artifact@v3
93+
with:
94+
path: 'dist'
95+
96+
- name: Deploy to GitHub Pages
97+
uses: actions/deploy-pages@v4

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "confluent-kafka"
7-
version = "2.8.0"
7+
version = "2.8.0+gr"
88
description = "Confluent's Python client for Apache Kafka"
99
classifiers = [
1010
"Development Status :: 5 - Production/Stable",

tools/wheels/install-librdkafka.sh

+13-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,19 @@ echo "$0: Installing librdkafka $VER to $DEST"
1919
[[ -d "$DEST" ]] || mkdir -p "$DEST"
2020
pushd "$DEST"
2121

22-
curl -L -o lrk$VER.zip https://www.nuget.org/api/v2/package/librdkafka.redist/$VER
22+
# Check if variable exists
23+
if [ -z "${GITHUB_TOKEN}" ]; then
24+
echo "Error: GITHUB_TOKEN is not set"
25+
exit 1
26+
fi
27+
28+
curl -H "Authorization: Bearer ${GITHUB_TOKEN}" \
29+
-H "Accept: application/vnd.github.v3+json" \
30+
-L \
31+
-o lrk$VER.zip \
32+
https://nuget.pkg.github.com/G-Research/download/librdkafka.redist/$VER/librdkafka.redist.$VER.nupkg
33+
34+
#curl -L -o lrk$VER.zip https://www.nuget.org/api/v2/package/librdkafka.redist/$VER
2335

2436
unzip lrk$VER.zip
2537

0 commit comments

Comments
 (0)