Skip to content

Commit

Permalink
github: Use API to properly tag prereleases
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanbruegge committed Jul 6, 2024
1 parent bbc3d71 commit fb85fc2
Show file tree
Hide file tree
Showing 6 changed files with 1,255 additions and 210 deletions.
28 changes: 20 additions & 8 deletions nix_update/version/github.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json
import os
import re
import urllib.request
import xml.etree.ElementTree as ET
Expand All @@ -8,7 +10,6 @@
from ..utils import info
from .version import Version


def version_from_entry(entry: Element) -> Version:
if entry is None:
raise VersionError("No release found")
Expand All @@ -19,21 +20,32 @@ def version_from_entry(entry: Element) -> Version:
# TODO: set pre-release flag
return Version(unquote(url.path.split("/")[-1]))


def fetch_github_versions(url: ParseResult) -> list[Version]:
if url.netloc != "github.com":
return []
parts = url.path.split("/")
owner, repo = parts[1], parts[2]
repo = re.sub(r"\.git$", "", repo)
# TODO fallback to tags?
feed_url = f"https://github.com/{owner}/{repo}/releases.atom"
info(f"fetch {feed_url}")
resp = urllib.request.urlopen(feed_url)
tree = ET.fromstring(resp.read())
releases = tree.findall(".//{http://www.w3.org/2005/Atom}entry")
return [version_from_entry(x) for x in releases]
try:
github_url = f"https://api.github.com/repos/{owner}/{repo}/releases"
token = os.environ.get('GITHUB_TOKEN')
req = github_url if token == None else urllib.request.Request(
github_url, headers={ 'Authorization': f'Bearer {token}' }
)
info(f"trying to fetch {github_url}")
resp = urllib.request.urlopen(req)
releases = json.loads(resp.read())
return [Version(x["tag_name"], x["prerelease"]) for x in releases]

except urllib.error.URLError as e:
print("Error while querying GitHub API, falling back to public atom feed")
feed_url = f"https://github.com/{owner}/{repo}/releases.atom"
info(f"fetch {feed_url}")
resp = urllib.request.urlopen(feed_url)
tree = ET.fromstring(resp.read())
releases = tree.findall(".//{http://www.w3.org/2005/Atom}entry")
return [version_from_entry(x) for x in releases]

def fetch_github_snapshots(url: ParseResult, branch: str) -> list[Version]:
if url.netloc != "github.com":
Expand Down
4 changes: 4 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def testpkgs(init_git: bool = False) -> Iterator[Path]:

subprocess.run(["git", "-C", tmpdirname, "init"], check=True)
subprocess.run(["git", "-C", tmpdirname, "add", "--all"], check=True)
subprocess.run(
["git", "-C", tmpdirname, "config", "commit.gpgsign", "false"],
check=True,
)
subprocess.run(
["git", "-C", tmpdirname, "commit", "-m", "first commit"],
check=True,
Expand Down
7 changes: 5 additions & 2 deletions tests/test_branch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env python3

import os
import unittest.mock
from pathlib import Path
from typing import BinaryIO
Expand All @@ -13,8 +15,9 @@


def fake_urlopen(url: str) -> BinaryIO:
if url.endswith("releases.atom"):
return open(TEST_ROOT.joinpath("test_branch_releases.atom"), "rb")
url = url if isinstance(url, str) else url.full_url
if url.endswith("releases"):
return open(TEST_ROOT.joinpath("test_branch_releases.json"), "rb")
else:
return open(TEST_ROOT.joinpath("test_branch_commits_master.atom"), "rb")

Expand Down
Loading

0 comments on commit fb85fc2

Please sign in to comment.