Use Gitea Releases for installation and ship VS Code highlighting

This commit is contained in:
Antigravity committed 2026-10-06 14:12:58 +00:00
1 parent a46bd6e132
commit 201bdee372
243 files changed
+3289 -12521

No files matched your search

+76 -16
View File
@@ -36,24 +36,30 @@ import urllib.error
import urllib.parse
import urllib.request
RELEASES = "https://git.dever.cc/shemic/dever/dist"
RELEASES = "https://git.dever.cc/api/v1/repos/shemic/dever/releases"
MAX_METADATA = 2 * 1024 * 1024
MAX_RELEASE = 2 * 1024 * 1024 * 1024
ASSET_HOSTS = {"git.dever.cc"}
DEFAULT_PUBLIC_KEY = "7889e0edaf5fbf1060bef4ad6e27106128485c8412a6f6cd4457dc67e112986e"
def official_address(address):
target = urllib.parse.urlsplit(address)
if (target.scheme != "https" or target.hostname not in ASSET_HOSTS
or target.username or target.password or target.port not in (None, 443)
or target.fragment):
raise ValueError("发行下载地址必须位于官方 HTTPS 站点")
return address
class OfficialRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, request, stream, code, message, headers, address):
target = urllib.parse.urlsplit(address)
if (target.scheme != "https" or target.hostname not in ASSET_HOSTS
or target.username or target.password or target.port not in (None, 443)
or target.fragment):
raise ValueError("发行下载重定向离开官方 HTTPS 站点")
official_address(address)
return super().redirect_request(request, stream, code, message, headers, address)
def download(address):
official_address(address)
# Installation does not inherit HTTP proxy/environment configuration.
client = urllib.request.build_opener(
urllib.request.ProxyHandler({}), OfficialRedirect(),
@@ -99,15 +105,61 @@ def read_bounded(path, limit):
return contents
def metadata(release, source, selection, platform):
def resolve_release(selection):
endpoint = "latest" if selection == "latest" else f"tags/v{selection}"
with download(f"{RELEASES}/{endpoint}") as stream:
contents = stream.read(MAX_METADATA + 1)
if len(contents) > MAX_METADATA:
raise ValueError("发行元数据超过大小限制")
record = json.loads(contents)
if (not isinstance(record, dict) or record.get("draft") is not False
or record.get("prerelease") is not False):
raise ValueError("需要已发布的稳定发行版本")
tag = record.get("tag_name")
if not isinstance(tag, str) or not re.fullmatch(
r"v(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)", tag):
raise ValueError("发行标签不是准确的 v<major.minor.patch>")
version = tag[1:]
if selection != "latest" and version != selection:
raise ValueError("发行版本与请求不匹配")
entries = record.get("assets")
if not isinstance(entries, list) or not 1 <= len(entries) <= 512:
raise ValueError("发行附件列表缺失或超限")
attachments = {}
for entry in entries:
if not isinstance(entry, dict):
raise ValueError("发行附件元数据错误")
name, size, address = (entry.get(key) for key in ("name", "size", "browser_download_url"))
if (not isinstance(name, str) or not name or name in attachments
or type(size) is not int or size <= 0 or size > MAX_RELEASE
or not isinstance(address, str)):
raise ValueError("发行附件名称重复、长度或地址错误")
attachments[name] = {"address": official_address(address), "bytes": size}
return version, attachments
def asset(attachments, platform, suffix, limit=MAX_RELEASE):
name = f"dever-{platform}.{suffix}"
entry = attachments.get(name)
if entry is None:
raise ValueError(f"该发行版本缺少附件:{name}")
if entry["bytes"] > limit:
raise ValueError("发行附件超过大小限制")
return entry
def metadata(release, source, attachments, platform):
for filename in ("manifest.json", "manifest.sig"):
if source:
contents = read_bounded(source / filename, MAX_METADATA)
else:
with download(f"{RELEASES}/{selection}/dever-{platform}.{filename}") as stream:
entry = asset(attachments, platform, filename, MAX_METADATA)
with download(entry["address"]) as stream:
contents = stream.read(MAX_METADATA + 1)
if len(contents) > MAX_METADATA:
raise ValueError("发行元数据超过大小限制")
if len(contents) != entry["bytes"]:
raise ValueError("发行元数据长度不匹配")
(release / filename).write_bytes(contents)
@@ -181,7 +233,7 @@ def copy_artifact(stream, destination, artifact):
destination.chmod(0o755 if executable else 0o644)
def payload(release, source, version, platform, catalog, trusted_key=None):
def payload(release, source, platform, catalog, trusted_key=None, attachments=None):
if source:
for name, artifact in catalog.items():
path = source / name
@@ -202,15 +254,20 @@ def payload(release, source, version, platform, catalog, trusted_key=None):
with tempfile.TemporaryDirectory(prefix=".extract-", dir=release.parent) as directory:
scratch = Path(directory)
helper = scratch / "helper"
base = f"{RELEASES}/{version}/dever-{platform}"
for name, artifact in catalog.items():
if name == "bootstrap/dever" or name.startswith("bootstrap/lib/"):
with download(f"{base}.blob-{artifact['sha256']}") as stream:
entry = asset(attachments, platform, f"blob-{artifact['sha256']}")
if entry["bytes"] != artifact["bytes"]:
raise ValueError("bootstrap 附件长度与签名不匹配")
with download(entry["address"]) as stream:
copy_artifact(stream, helper / name, artifact)
if stream.read(1):
raise ValueError("bootstrap 下载超过签名长度")
compressed = scratch / "base.tar.zst"
download_archive(f"{base}.tar.zst", compressed)
entry = asset(attachments, platform, "tar.zst")
download_archive(entry["address"], compressed)
if compressed.stat().st_size != entry["bytes"]:
raise ValueError("发行附件长度不匹配")
configuration = scratch / "extract.json"
configuration.write_text(json.dumps({
"release": str(release), "archive": str(compressed),
@@ -235,7 +292,8 @@ def install(arguments):
raise ValueError("机器安装需要管理员权限;请通过根 install 入口执行")
platform = platform_name()
prerequisites(platform)
if arguments.version != "latest" and not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+", arguments.version):
if arguments.version != "latest" and not re.fullmatch(
r"(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)", arguments.version):
raise ValueError("--version 需要 latest 或准确版本")
system_root = arguments.system_root.absolute()
if not system_root.is_dir() or system_root.is_symlink():
@@ -248,15 +306,17 @@ def install(arguments):
scratch = Path(directory)
release = scratch / "release"
release.mkdir()
metadata(release, source, arguments.version, platform)
selection, attachments = ((arguments.version, None) if source
else resolve_release(arguments.version))
metadata(release, source, attachments, platform)
key_path = arguments.trusted_key
if key_path is None:
key_path = scratch / "independent-release.pub"
key_path.write_text(DEFAULT_PUBLIC_KEY)
version, catalog, key = authenticate(release, key_path, scratch, platform, arguments.version)
version, catalog, key = authenticate(release, key_path, scratch, platform, selection)
trusted = scratch / "release.pub"
trusted.write_text(key.hex() + "\n")
payload(release, source, version, platform, catalog, trusted)
payload(release, source, platform, catalog, trusted, attachments)
configuration = scratch / "config"
configuration.mkdir()
(configuration / "setting.json").write_text(json.dumps({