Skip to content

Commit 0b72e75

Browse files
Define yanked versions (#9)
1 parent 6c5f2a1 commit 0b72e75

File tree

2 files changed

+70
-19
lines changed

2 files changed

+70
-19
lines changed

.github/scripts/generate_index.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@
88
from urllib.parse import quote
99
from pathlib import Path
1010
from github import Github
11-
from typing import List, Dict
11+
from typing import List, Dict, Set
12+
13+
# Define yanked versions - modify this dictionary as needed
14+
yanked_versions = {
15+
"confluent-kafka": {
16+
"2.11.0+gr",
17+
"2.11.0+gr.1",
18+
},
19+
}
1220

1321
HTML_TEMPLATE = """<!DOCTYPE html>
1422
<html>
@@ -21,7 +29,7 @@
2129
</body>
2230
</html>
2331
"""
24-
32+
2533
def normalize(name):
2634
"""Normalize package name according to PEP 503."""
2735
return re.sub(r"[-_.]+", "-", name).lower()
@@ -32,12 +40,25 @@ def calculate_sha256(file_path):
3240

3341
return digest.hexdigest()
3442

43+
def extract_version_from_filename(filename: str) -> str:
44+
"""Extract version from wheel or sdist filename."""
45+
# Remove extension
46+
name = filename.replace('.tar.gz', '').replace('.whl', '')
47+
48+
# For wheels: package-version-python-abi-platform
49+
# For sdist: package-version
50+
parts = name.split('-')
51+
if len(parts) >= 2:
52+
return parts[1]
53+
return ""
54+
3555
class PackageIndexBuilder:
36-
def __init__(self, token: str, repo_name: str, output_dir: str):
56+
def __init__(self, token: str, repo_name: str, output_dir: str, yanked_versions: Dict[str, Set[str]] = None):
3757
self.github = Github(token)
3858
self.repo = self.github.get_repo(repo_name)
3959
self.output_dir = Path(output_dir)
4060
self.packages: Dict[str, List[Dict]] = {}
61+
self.yanked_versions = yanked_versions or {}
4162

4263
# Set up authenticated session
4364
self.session = requests.Session()
@@ -46,9 +67,13 @@ def __init__(self, token: str, repo_name: str, output_dir: str):
4667
"Accept": "application/octet-stream",
4768
})
4869

49-
def collect_packages(self):
70+
def is_version_yanked(self, package_name: str, version: str) -> bool:
71+
"""Check if a specific version of a package is yanked."""
72+
normalized_package = normalize(package_name)
73+
return normalized_package in self.yanked_versions and version in self.yanked_versions[normalized_package]
5074

51-
print ("Query release assets")
75+
def collect_packages(self):
76+
print("Query release assets")
5277

5378
for release in self.repo.get_releases():
5479
for asset in release.get_assets():
@@ -57,11 +82,13 @@ def collect_packages(self):
5782
if package_name not in self.packages:
5883
self.packages[package_name] = []
5984

85+
version = extract_version_from_filename(asset.name)
6086
self.packages[package_name].append({
6187
'filename': asset.name,
6288
'url': asset.url,
6389
'size': asset.size,
6490
'upload_time': asset.created_at.strftime('%Y-%m-%d %H:%M:%S'),
91+
'version': version,
6592
})
6693

6794
def generate_index_html(self):
@@ -84,7 +111,9 @@ def generate_index_html(self):
84111
file_links = []
85112
assets = sorted(assets, key=lambda x: x["filename"])
86113
for filename, items in itertools.groupby(assets, key=lambda x: x["filename"]):
87-
url = next(items)['url']
114+
asset_info = next(items)
115+
url = asset_info['url']
116+
version = asset_info['version']
88117

89118
# Download the file
90119
with open(package_dir / filename, 'wb') as f:
@@ -96,7 +125,15 @@ def generate_index_html(self):
96125
f.write(chunk)
97126

98127
sha256_hash = calculate_sha256(package_dir / filename)
99-
file_links.append(f'<a href="{quote(filename)}#sha256={sha256_hash}">{filename}</a><br/>')
128+
129+
# Check if this version is yanked
130+
yanked_attr = ""
131+
if self.is_version_yanked(package, version):
132+
yanked_attr = ' data-yanked="true"'
133+
134+
file_links.append(
135+
f'<a href="{quote(filename)}#sha256={sha256_hash}"{yanked_attr}>{filename}</a><br/>'
136+
)
100137

101138
package_index = HTML_TEMPLATE.format(
102139
package_name=f"Links for {package}",
@@ -126,7 +163,7 @@ def main():
126163
print ("Missing required environment variables")
127164
sys.exit(1)
128165

129-
builder = PackageIndexBuilder(token, repo, output_dir)
166+
builder = PackageIndexBuilder(token, repo, output_dir, yanked_versions)
130167
builder.build()
131168

132169
if __name__ == "__main__":

.github/workflows/package.yml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,18 @@ jobs:
5252
name: wheels-${{ env.OS_NAME }}-${{ env.ARCH }}
5353
path: wheelhouse/confluent_kafka*.whl
5454

55-
publish_pypi_index:
55+
create_release_artifacts:
5656
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
57-
name: Build a PyPI-compatible index
57+
name: Create release artifacts
5858
needs: [build-linux-x64, build-windows]
5959
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
60+
steps:
6861
- uses: actions/download-artifact@v4
6962
with:
7063
path: artifacts
7164
pattern: wheels-*
7265
merge-multiple: true
73-
66+
7467
- name: Create release
7568
uses: softprops/action-gh-release@v2
7669
with:
@@ -79,6 +72,22 @@ jobs:
7972
env:
8073
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8174

75+
publish_simple_package_index:
76+
name: Build&publish a PyPI-compatible package index
77+
runs-on: ubuntu-latest
78+
needs: [create_release_artifacts]
79+
if: always() && !failure() && !cancelled() && (github.event_name == 'push')
80+
concurrency:
81+
group: simple_package_index
82+
cancel-in-progress: true
83+
permissions:
84+
contents: write
85+
actions: read
86+
packages: read
87+
pages: write
88+
id-token: write
89+
steps:
90+
- uses: actions/checkout@v2
8291
- name: Generate Package Index
8392
run: |
8493
python -m pip install --upgrade pip
@@ -94,4 +103,9 @@ jobs:
94103
path: 'dist'
95104

96105
- name: Deploy to GitHub Pages
106+
id: deployment
97107
uses: actions/deploy-pages@v4
108+
109+
- name: Display GitHub Pages URL
110+
run: |
111+
echo "Package Index URL: ${{ steps.deployment.outputs.page_url }}"

0 commit comments

Comments
 (0)