feat: bootstrap static musl build pipeline for iperf3
iperf3 static musl build / build-and-release (push) Failing after 16s

This commit is contained in:
Hermes Agent
2026-05-07 22:12:23 +00:00
commit 257889f1e2
7 changed files with 324 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
#!/bin/sh
set -eu
VERSION="${1:?usage: build_iperf3.sh <version> [output_dir]}"
OUTPUT_DIR="${2:-$PWD/dist}"
WORKDIR="${TMPDIR:-/tmp}/iperf3-build-${VERSION}"
PREFIX_NAME="iperf3-${VERSION}-linux-amd64-musl-static"
rm -rf "$WORKDIR"
mkdir -p "$WORKDIR" "$OUTPUT_DIR"
cd "$WORKDIR"
apk add --no-cache \
bash \
build-base \
curl \
file \
linux-headers \
openssl-dev \
tar \
xz \
zlib-dev
curl -fsSLO "https://downloads.es.net/pub/iperf/iperf-${VERSION}.tar.gz"
tar -xzf "iperf-${VERSION}.tar.gz"
cd "iperf-${VERSION}"
export CFLAGS="-O2 -static"
export CPPFLAGS=""
export LDFLAGS="-static"
./configure \
--disable-shared \
--enable-static \
--without-sctp
make -j"$(getconf _NPROCESSORS_ONLN || echo 2)"
strip src/iperf3
install -m 0755 src/iperf3 "$OUTPUT_DIR/$PREFIX_NAME"
(
cd "$OUTPUT_DIR"
tar -czf "${PREFIX_NAME}.tar.gz" "$PREFIX_NAME"
sha256sum "$PREFIX_NAME" "${PREFIX_NAME}.tar.gz" > "${PREFIX_NAME}.sha256"
)
file "$OUTPUT_DIR/$PREFIX_NAME"
ldd "$OUTPUT_DIR/$PREFIX_NAME" || true
+112
View File
@@ -0,0 +1,112 @@
#!/usr/bin/env python3
import json
import mimetypes
import os
import sys
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path
def api_request(method: str, url: str, token: str, data: bytes | None = None, headers: dict | None = None):
req_headers = {
"Authorization": f"token {token}",
"Accept": "application/json",
**(headers or {}),
}
req = urllib.request.Request(url, data=data, headers=req_headers, method=method)
try:
with urllib.request.urlopen(req, timeout=60) as resp:
body = resp.read()
if not body:
return None
return json.loads(body)
except urllib.error.HTTPError as exc:
body = exc.read().decode("utf-8", "ignore")
raise RuntimeError(f"HTTP {exc.code} for {method} {url}: {body}") from exc
def get_or_create_release(api_base: str, owner: str, repo: str, tag: str, title: str, body: str, token: str, target: str):
tag_url = f"{api_base}/repos/{owner}/{repo}/releases/tags/{urllib.parse.quote(tag, safe='')}"
try:
release = api_request("GET", tag_url, token)
if release is not None:
return release
except RuntimeError as exc:
if "HTTP 404" not in str(exc):
raise
create_url = f"{api_base}/repos/{owner}/{repo}/releases"
payload = {
"tag_name": tag,
"name": title,
"body": body,
"draft": False,
"prerelease": False,
"target_commitish": target,
}
return api_request(
"POST",
create_url,
token,
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"},
)
def replace_release_assets(api_base: str, owner: str, repo: str, release: dict, files: list[Path], token: str):
release_id = release["id"]
existing_assets = {asset["name"]: asset for asset in release.get("assets", [])}
for path in files:
name = path.name
if name in existing_assets:
asset_id = existing_assets[name]["id"]
delete_url = f"{api_base}/repos/{owner}/{repo}/releases/{release_id}/assets/{asset_id}"
api_request("DELETE", delete_url, token)
upload_url = f"{api_base}/repos/{owner}/{repo}/releases/{release_id}/assets?name={urllib.parse.quote(name, safe='')}"
content_type = mimetypes.guess_type(str(path))[0] or "application/octet-stream"
data = path.read_bytes()
api_request(
"POST",
upload_url,
token,
data=data,
headers={"Content-Type": content_type},
)
def main() -> int:
token = os.environ["GITEA_TOKEN"]
api_base = os.environ["GITEA_API_URL"].rstrip("/")
owner = os.environ["REPO_OWNER"]
repo = os.environ["REPO_NAME"]
version = os.environ["VERSION"]
target = os.environ.get("TARGET_SHA", "main")
files = [Path(p) for p in sys.argv[1:]]
if not files:
raise SystemExit("usage: publish_release.py <file> [file ...]")
missing = [str(p) for p in files if not p.exists()]
if missing:
raise SystemExit(f"missing files: {', '.join(missing)}")
tag = f"iperf3-v{version}"
title = f"iperf3 {version}"
body = (
f"Static musl build for iperf3 {version}.\\n\\n"
f"Repository: {owner}/{repo}\\n"
f"Commit: {target}"
)
release = get_or_create_release(api_base, owner, repo, tag, title, body, token, target)
replace_release_assets(api_base, owner, repo, release, files, token)
print(f"published_tag={tag}")
for path in files:
print(f"asset={path.name}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import argparse
import json
import re
import sys
import urllib.request
from pathlib import Path
VERSION_FILE = Path("versions/iperf3.version")
LATEST_RELEASE_URL = "https://api.github.com/repos/esnet/iperf/releases/latest"
def fetch_latest_version() -> str:
req = urllib.request.Request(
LATEST_RELEASE_URL,
headers={
"Accept": "application/vnd.github+json",
"User-Agent": "static-musl-builds-updater",
},
)
with urllib.request.urlopen(req, timeout=30) as resp:
data = json.load(resp)
tag = data["tag_name"].strip()
version = re.sub(r"^v", "", tag)
if not re.fullmatch(r"[0-9]+(?:\.[0-9]+)*", version):
raise ValueError(f"Unexpected iperf3 version format: {version!r}")
return version
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--update-file", action="store_true", help="Write latest version into versions/iperf3.version if changed")
args = parser.parse_args()
latest = fetch_latest_version()
current = VERSION_FILE.read_text(encoding="utf-8").strip() if VERSION_FILE.exists() else ""
print(f"current={current or '<missing>'}")
print(f"latest={latest}")
if current == latest:
print("status=up-to-date")
return 0
print("status=update-available")
if args.update_file:
VERSION_FILE.parent.mkdir(parents=True, exist_ok=True)
VERSION_FILE.write_text(latest + "\n", encoding="utf-8")
print(f"updated_file={VERSION_FILE}")
return 0
if __name__ == "__main__":
sys.exit(main())