1
0
forked from wrenn/wrenn

v0.1.4 (#38) — pipeline test 2
All checks were successful
ci/woodpecker/push/pipeline Pipeline was successful

This commit is contained in:
Tasnim Kabir Sadik
2026-05-03 00:11:43 +06:00
parent 52ad21c339
commit af79047503
28 changed files with 979 additions and 117 deletions

View File

@ -0,0 +1,126 @@
import os
import sys
from wrenn import Capsule, StreamExitEvent, StreamStderrEvent, StreamStdoutEvent
from wrenn._git import GitCommandError
from wrenn.models import FileEntry
GO_VERSION = os.getenv("GO_VERSION", "1.25.8")
REPO_URL = "https://git.omukk.dev/wrenn/wrenn.git"
REPO_DIR = "/opt/wrenn"
BUILDS_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "builds")
def run(capsule: Capsule, cmd: str, timeout: int = 30) -> int:
result = capsule.commands.run(cmd, timeout=timeout)
if result.exit_code != 0:
print(f"FAIL [{cmd.split()[0]}]: exit={result.exit_code}", file=sys.stderr)
if result.stderr:
print(result.stderr.strip(), file=sys.stderr)
return result.exit_code
print(f"OK [{cmd.split()[0]}]")
return 0
def install_go(capsule: Capsule) -> bool:
tarball = f"go{GO_VERSION}.linux-amd64.tar.gz"
url = f"https://go.dev/dl/{tarball}"
if run(capsule, "apt update") != 0:
return False
if run(capsule, "apt install -y make build-essential file") != 0:
return False
if run(capsule, f"curl -LO {url}", timeout=120) != 0:
return False
if run(capsule, f"tar -C /usr/local -xzf {tarball}", timeout=60) != 0:
return False
if run(capsule, 'echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.profile') != 0:
return False
if run(capsule, "rm -f " + tarball) != 0:
return False
result = capsule.commands.run("/usr/local/go/bin/go version")
print(result.stdout.strip())
return result.exit_code == 0
def clone_repo(capsule: Capsule) -> bool:
try:
capsule.git.clone(REPO_URL, REPO_DIR)
print("OK [git clone]")
return True
except GitCommandError as e:
print(f"FAIL [git clone]: {e}", file=sys.stderr)
return False
def build_app(capsule: Capsule) -> bool:
handle = capsule.commands.run(
"CGO_ENABLED=1 make build",
background=True,
cwd=REPO_DIR,
envs={
"PATH": "/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
},
)
print(f"make build started (pid={handle.pid}), streaming output...")
exit_code = 0
for event in capsule.commands.connect(handle.pid):
if isinstance(event, StreamStdoutEvent):
print(event.data, end="")
elif isinstance(event, StreamStderrEvent):
print(event.data, end="", file=sys.stderr)
elif isinstance(event, StreamExitEvent):
exit_code = event.exit_code
if exit_code != 0:
print(f"FAIL [make build]: exit={exit_code}", file=sys.stderr)
return False
print("OK [make build]")
return True
def download_artifacts(capsule: Capsule) -> bool:
remote_dir = f"{REPO_DIR}/builds"
entries = capsule.files.list(remote_dir, depth=1)
files = [e for e in entries if e.type != "directory"]
if not files:
print("FAIL [download]: no files found in builds/", file=sys.stderr)
return False
local_dir = os.path.normpath(BUILDS_DIR)
os.makedirs(local_dir, exist_ok=True)
for entry in files:
name = entry.name or "unknown"
remote_path = f"{remote_dir}/{name}"
local_path = os.path.join(local_dir, name)
print(f"Downloading {name} ({entry.size or '?'} bytes)...")
with open(local_path, "wb") as f:
for chunk in capsule.files.download_stream(remote_path):
f.write(chunk)
print(f"OK [download {name}]")
return True
def main() -> None:
with Capsule(wait=True, vcpus=4, memory_mb=4096) as capsule:
print(f"Capsule: {capsule.capsule_id}")
if not install_go(capsule):
sys.exit(1)
if not clone_repo(capsule):
sys.exit(1)
if not build_app(capsule):
sys.exit(1)
if not download_artifacts(capsule):
sys.exit(1)
print("Done.")
if __name__ == "__main__":
main()