Files
KDE-x86_64-v4-Fedora/ci/copr-distgit-make-srpm.py
T
funkemunky 35f23d8969
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (008) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (005) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (006) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (010) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (011) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (013) (push) Successful in 18s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (003) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (007) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (004) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (009) (push) Successful in 21s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (001) (push) Successful in 41s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (015) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (002) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (017) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (016) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (012) (push) Successful in 26s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (019) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (020) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (018) (push) Successful in 19s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (021) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (022) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (024) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (014) (push) Successful in 43s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (025) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (026) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (028) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (023) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (029) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (027) (push) Successful in 19s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (033) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (030) (push) Successful in 23s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (035) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (032) (push) Successful in 21s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (031) (push) Successful in 25s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (036) (push) Successful in 23s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (034) (push) Successful in 26s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (037) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (039) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (042) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (044) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (041) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (043) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (045) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (040) (push) Successful in 24s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (046) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (047) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (049) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (050) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (038) (push) Successful in 48s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (052) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (053) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (054) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (051) (push) Successful in 24s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (055) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (056) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (048) (push) Successful in 38s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (057) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (058) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (060) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (061) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (062) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (063) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (065) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (064) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (059) (push) Successful in 26s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (067) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (068) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (069) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (066) (push) Successful in 23s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (071) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (072) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (073) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (070) (push) Successful in 26s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (075) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (076) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (077) (push) Successful in 18s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (074) (push) Successful in 22s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (078) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (080) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (083) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (085) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (084) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (079) (push) Successful in 29s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (082) (push) Failing after 23s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (081) (push) Successful in 25s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (087) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (090) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (088) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (089) (push) Failing after 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (091) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (086) (push) Successful in 27s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (092) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (093) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (095) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (097) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (094) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (099) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (096) (push) Successful in 25s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (103) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (100) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (098) (push) Successful in 30s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (101) (push) Successful in 31s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (106) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (108) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (107) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (102) (push) Successful in 31s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (104) (push) Successful in 27s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (105) (push) Successful in 22s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (111) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (112) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (113) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (114) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (109) (push) Successful in 18s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (115) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (110) (push) Successful in 18s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (116) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (117) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (118) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (122) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (119) (push) Successful in 15s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (121) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (120) (push) Successful in 17s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (123) (push) Successful in 14s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (124) (push) Successful in 12s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (126) (push) Successful in 11s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (128) (push) Successful in 13s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (127) (push) Successful in 16s
Validate Fedora x86_64-v3 Copr SRPMs (Gitea) / validate-srpms (125) (push) Successful in 18s
Fixing failure on a couple of srpms
2026-04-27 15:08:12 -04:00

283 lines
9.1 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import hashlib
import re
import shutil
import subprocess
import tempfile
import time
import urllib.parse
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
SOURCE_LINE_PATTERN = re.compile(
r"^(?P<algo>[A-Za-z0-9_+-]+)\s+\((?P<filename>.+)\)\s+=\s+(?P<checksum>[0-9A-Fa-f]+)$"
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=(
"Create an SRPM from a repo-local spec path or from a package snapshot "
"under SPECS/<package>/, downloading Fedora lookaside sources as needed."
)
)
parser.add_argument("--spec-ref", required=True, help="Local .spec path or package name under SPECS/")
parser.add_argument("--outdir", required=True, help="Directory where the generated SRPM should be written")
parser.add_argument(
"--specs-dir",
default="SPECS",
help="Directory containing repo-local Fedora packaging snapshots",
)
parser.add_argument("--dist", default=".fc43", help="RPM dist suffix to define while generating the SRPM")
parser.add_argument("--namespace", default="rpms", help="Fedora dist-git namespace")
parser.add_argument(
"--lookaside-baseurl",
default="https://src.fedoraproject.org/repo/pkgs",
help="Base URL for the Fedora lookaside cache",
)
parser.add_argument("--retry-count", type=int, default=3, help="Number of retries for network operations")
return parser.parse_args()
def run(command: list[str], *, cwd: Path | None = None) -> None:
subprocess.run(command, cwd=cwd, check=True)
def ensure_within_repo(path: Path) -> Path | None:
candidate = (REPO_ROOT / path).resolve()
try:
candidate.relative_to(REPO_ROOT)
except ValueError:
return None
if candidate.is_file() and candidate.suffix == ".spec":
return candidate
return None
def resolve_package_spec(package_name: str, specs_dir: Path) -> Path | None:
package_dir = (REPO_ROOT / specs_dir / package_name).resolve()
try:
package_dir.relative_to(REPO_ROOT)
except ValueError:
return None
if not package_dir.is_dir():
return None
package_named_spec = package_dir / f"{package_name}.spec"
if package_named_spec.is_file():
return package_named_spec
spec_files = sorted(package_dir.glob("*.spec"))
if len(spec_files) == 1:
return spec_files[0]
if len(spec_files) > 1:
raise RuntimeError(
f"multiple spec files found for {package_name} under {package_dir}; "
"use an explicit spec path"
)
return None
def package_name_for_specs_path(spec_path: Path, specs_dir: Path) -> str | None:
specs_root = (REPO_ROOT / specs_dir).resolve()
try:
relative = spec_path.resolve().relative_to(specs_root)
except ValueError:
return None
if len(relative.parts) < 2:
return None
return relative.parts[0]
def hash_file(path: Path, algorithm: str) -> str:
digest = hashlib.new(algorithm.lower())
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def download_file(url: str, destination: Path, *, algorithm: str, checksum: str, attempts: int) -> None:
destination.parent.mkdir(parents=True, exist_ok=True)
for attempt in range(1, attempts + 1):
if destination.exists() and hash_file(destination, algorithm) == checksum.lower():
return
try:
subprocess.run(
[
"curl",
"--fail",
"--location",
"--silent",
"--show-error",
"--output",
str(destination),
url,
],
check=True,
)
except subprocess.CalledProcessError:
if destination.exists():
destination.unlink()
if attempt == attempts:
raise
time.sleep(attempt * 3)
continue
if hash_file(destination, algorithm) == checksum.lower():
return
destination.unlink(missing_ok=True)
if attempt == attempts:
raise RuntimeError(f"checksum mismatch for {destination.name} from {url}")
time.sleep(attempt * 3)
def build_srpm(spec_path: Path, *, source_dir: Path, outdir: Path, dist: str) -> Path:
outdir.mkdir(parents=True, exist_ok=True)
existing = {path.resolve() for path in outdir.glob("*.src.rpm")}
with tempfile.TemporaryDirectory(prefix="copr-srpm-topdir-") as topdir_name:
topdir = Path(topdir_name)
command = [
"rpmbuild",
"-bs",
str(spec_path),
"--define",
f"_topdir {topdir}",
"--define",
f"_builddir {topdir / 'BUILD'}",
"--define",
f"_buildrootdir {topdir / 'BUILDROOT'}",
"--define",
f"_rpmdir {topdir / 'RPMS'}",
"--define",
f"_srcrpmdir {outdir}",
"--define",
f"_sourcedir {source_dir}",
"--define",
f"_specdir {spec_path.parent}",
]
if dist:
command.extend(["--define", f"dist {dist}"])
run(command, cwd=source_dir)
srpms = sorted(
(path for path in outdir.glob("*.src.rpm") if path.resolve() not in existing),
key=lambda path: path.stat().st_mtime,
reverse=True,
)
if not srpms:
raise RuntimeError(f"rpmbuild did not produce an SRPM in {outdir}")
return srpms[0]
def parse_sources_file(path: Path) -> list[tuple[str, str, str]]:
entries: list[tuple[str, str, str]] = []
if not path.exists():
return entries
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line:
continue
match = SOURCE_LINE_PATTERN.match(line)
if not match:
raise RuntimeError(f"unsupported lookaside source format: {line}")
entries.append(
(
match.group("algo").lower(),
match.group("filename"),
match.group("checksum").lower(),
)
)
return entries
def download_lookaside_sources(
package_name: str,
source_dir: Path,
*,
namespace: str,
lookaside_baseurl: str,
attempts: int,
) -> None:
for algorithm, filename, checksum in parse_sources_file(source_dir / "sources"):
encoded_filename = urllib.parse.quote(filename)
url = (
f"{lookaside_baseurl}/{namespace}/{package_name}/"
f"{encoded_filename}/{algorithm}/{checksum}/{encoded_filename}"
)
download_file(
url,
source_dir / filename,
algorithm=algorithm,
checksum=checksum,
attempts=attempts,
)
def ensure_lookaside_sources_present(package_name: str, source_dir: Path) -> None:
missing = [
filename
for _, filename, _ in parse_sources_file(source_dir / "sources")
if not (source_dir / filename).is_file()
]
if missing:
missing_list = ", ".join(missing)
raise RuntimeError(
f"lookaside sources missing for {package_name}: {missing_list}. "
"The Fedora lookaside download step did not leave the expected files in place."
)
def main() -> int:
args = parse_args()
outdir = Path(args.outdir).resolve()
specs_dir = Path(args.specs_dir)
local_spec = ensure_within_repo(Path(args.spec_ref))
if local_spec is not None:
package_name = package_name_for_specs_path(local_spec, specs_dir)
if package_name is not None:
download_lookaside_sources(
package_name,
local_spec.parent,
namespace=args.namespace,
lookaside_baseurl=args.lookaside_baseurl.rstrip("/"),
attempts=args.retry_count,
)
ensure_lookaside_sources_present(package_name, local_spec.parent)
srpm = build_srpm(local_spec, source_dir=local_spec.parent, outdir=outdir, dist=args.dist)
print(f"built local SRPM {srpm.name}")
return 0
package_spec = resolve_package_spec(args.spec_ref, specs_dir)
if package_spec is None:
raise RuntimeError(
f"spec reference {args.spec_ref!r} is not a repo-local spec path and no "
f"snapshot was found under {(REPO_ROOT / specs_dir / args.spec_ref)!s}"
)
package_dir = package_spec.parent
download_lookaside_sources(
args.spec_ref,
package_dir,
namespace=args.namespace,
lookaside_baseurl=args.lookaside_baseurl.rstrip("/"),
attempts=args.retry_count,
)
ensure_lookaside_sources_present(args.spec_ref, package_dir)
srpm = build_srpm(package_spec, source_dir=package_dir, outdir=outdir, dist=args.dist)
print(f"built package SRPM {srpm.name}")
return 0
if __name__ == "__main__":
raise SystemExit(main())