Files
Logging-System/.gitea/workflows/ci.yml
T
weichen 2e2620009f
ci / docker-checkout-hostgateway (pull_request) Successful in 0s
ci / vet-and-test (pull_request) Successful in 9s
Adopt credential safe CI and retire replaced source gitlinks
Why:
Make independent version consumption work from ordinary clones while retaining historical commits and existing branch workspaces.

Evidence:
SELF Dev task receipts record 24 CI boundary cases, all workflow syntax checks, readonly private-source prefetch in clean exports, provider tests and package installation without acquisition scripts. Platform CI remains pending.

Impact:
Remove only replaced index links, preserve old physical checkouts, and update dependency guidance. Library consumers retain their immutable versions until an explicit dependency update.

Refs:
Agent-System-Dev feature/dependency-workspace; approved versioned-dependency r1, U3-U7 and R15.
2026-10-13 17:11:41 +00:00

512 lines
31 KiB
YAML

name: ci
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
vet-and-test:
runs-on: nightly
env:
GOTOOLCHAIN: local
GOWORK: "off"
GOPROXY: https://goproxy.cn,direct
steps:
- name: Checkout
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
SUBMODULE_TOKEN: ${{ secrets.SUBMODULE_TOKEN }}
run: &trusted_acquisition_1 |
set -euo pipefail
python3 - <<'PY_TRUSTED'
# Trusted workflow code only: never import or execute checkout scripts here.
# Token scopes, workflow provenance and runner isolation are platform NOT_RUN.
import json
import os
from pathlib import Path
import re
import shlex
import subprocess
import sys
import tempfile
from urllib.parse import urlsplit
SERVER = os.environ.get("GITHUB_SERVER_URL", "").rstrip("/")
parsed = urlsplit(SERVER)
if (parsed.scheme not in {"http", "https"} or not parsed.netloc or
parsed.username or parsed.password or parsed.query or parsed.fragment):
sys.exit("Acquisition requires the platform-injected http(s) server")
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
GO_PREFIX = "git-ssh.u1680832.nyat.app/weichen/"
REPOS = {"Agent-System-Dev", "Logging-System", "Error-Code-System", "Agent-System-Core", "Agent-Native",
"Agent-Intent", "Agent-Command", "Agent-Squad", "Agent-System-Backend",
"Agent-System-Frontend", "Agent-System-UI", "Agent-System-RDM",
"Development-Guidelines", "Agent-System-Documents"}
LEGACY = {
"modules/core": "Agent-System-Core", "modules/backend": "Agent-System-Backend",
"modules/frontend": "Agent-System-Frontend", "modules/ui": "Agent-System-UI",
"modules/documents": "Agent-System-Documents", "deps/agent-system-core": "Agent-System-Core",
"deps/development-guidelines": "Development-Guidelines", "deps/agent-native": "Agent-Native",
"deps/agent-squad": "Agent-Squad", "deps/agent-intent": "Agent-Intent",
"deps/agent-command": "Agent-Command", "deps/error-code-system": "Error-Code-System",
"deps/logging-system": "Logging-System", "pins/agent-system-backend": "Agent-System-Backend",
"pins/agent-system-core": "Agent-System-Core", "pins/agent-system-frontend": "Agent-System-Frontend",
"pins/agent-system-ui": "Agent-System-UI",
}
GO_REPOS = REPOS - {"Agent-System-Dev", "Agent-System-UI", "Agent-System-Frontend", "Development-Guidelines", "Agent-System-Documents"}
GO_MODULES = {GO_PREFIX + repo + ".git" for repo in GO_REPOS}
GO_MODULES |= {GO_PREFIX + "Agent-Squad.git/" + suffix for suffix in
("adapters/native", "adapters/intent", "adapters/sqlite", "adapters/a2a", "cmd/agent-squad")}
root_token = os.environ.pop("TOKEN", "")
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
# Go environment files and inherited Git tracing/config must not change acquisition.
clean = {k: v for k, v in os.environ.items()
if not k.startswith(("GIT_", "NPM_CONFIG_", "npm_config_")) and
not any(word in k.upper() for word in ("TOKEN", "PASSWORD", "SECRET"))}
clean.update(GIT_CONFIG_NOSYSTEM="1", GIT_CONFIG_SYSTEM="/dev/null", GIT_CONFIG_GLOBAL="/dev/null",
GIT_TERMINAL_PROMPT="0", GOENV="off", GOTOOLCHAIN="local", GOWORK="off", GOFLAGS="-mod=readonly",
GOPRIVATE=GO_PREFIX.rstrip("/"), GONOPROXY=GO_PREFIX.rstrip("/"), GONOSUMDB=GO_PREFIX.rstrip("/"))
if os.environ.get("npm_config_cache"):
clean["npm_config_cache"] = os.environ["npm_config_cache"]
config = {"core.hooksPath": "/dev/null", "core.fsmonitor": "false", "init.templateDir": "",
"credential.helper": "", "fetch.recurseSubmodules": "false", "submodule.recurse": "false",
"http.followRedirects": "false", "protocol.allow": "never", "protocol." + parsed.scheme + ".allow": "always"}
root = Path.cwd()
mirrors = root / ".ci-mirrors"
def process_env(values):
env = clean | {"GIT_CONFIG_COUNT": str(len(values))}
for index, (key, value) in enumerate(values.items()):
env[f"GIT_CONFIG_KEY_{index}"] = key
env[f"GIT_CONFIG_VALUE_{index}"] = value
return env
def git(directory, *args, token="", repo=""):
values = config.copy()
if token:
if repo not in REPOS:
raise ValueError("Credential destination is outside the reviewed repository allowlist")
values[f"http.{SERVER}/weichen/{repo}.git.extraheader"] = "AUTHORIZATION: token " + token
result = subprocess.run(["git", "-C", str(directory), *args], env=process_env(values),
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.stdout
def fixed_sha(value):
if not isinstance(value, str) or not re.fullmatch(r"[0-9a-fA-F]{40}", value):
raise ValueError("Source acquisition requires a fixed commit SHA")
return value.lower()
def mirror(repo, sha, token):
sha = fixed_sha(sha)
destination = mirrors / (repo + ".git")
if destination.is_symlink() or mirrors.is_symlink():
raise ValueError("Mirror directory cannot be a symlink")
mirrors.mkdir(exist_ok=True)
if not destination.exists():
destination.mkdir()
git(destination, "init", "--bare", "-q")
url = f"{SERVER}/weichen/{repo}.git"
try:
git(destination, "cat-file", "-e", sha + "^{commit}")
except subprocess.CalledProcessError:
git(destination, "fetch", "--depth=200", url, sha, token=token, repo=repo)
git(destination, "update-ref", "refs/heads/main", sha)
git(destination, "symbolic-ref", "HEAD", "refs/heads/main")
git(destination, "update-ref", "refs/ci/" + sha, sha)
return destination
def mirror_env():
values = {"protocol.file.allow": "always", "core.hooksPath": "/dev/null", "credential.helper": ""}
# Distinct keys use repeated .insteadOf values, represented as a sequence below.
pairs = list(values.items())
for repo in sorted(REPOS):
destination = mirrors / (repo + ".git")
if not destination.exists():
continue
key = "url." + destination.as_uri() + ".insteadOf"
pairs.extend((key, url) for url in (SSH + repo + ".git", "https://" + GO_PREFIX + repo + ".git",
SERVER + "/weichen/" + repo + ".git", "https://" + GO_PREFIX + repo))
env = clean | {"CI_DEPENDENCY_MIRRORS": str(mirrors), "GIT_CONFIG_COUNT": str(len(pairs))}
for index, (key, value) in enumerate(pairs):
env[f"GIT_CONFIG_KEY_{index}"] = key
env[f"GIT_CONFIG_VALUE_{index}"] = value
exports = {k: v for k, v in env.items() if k.startswith("GIT_CONFIG_") or k == "CI_DEPENDENCY_MIRRORS"}
(root / ".ci-mirrors.env").write_text("".join("export " + k + "=" + shlex.quote(v) + "\n" for k, v in exports.items()))
return env
def materialize_legacy(directory, depth=0):
if depth > 16:
raise ValueError("Historical submodule depth exceeds the checkout limit")
links = {}
for entry in git(directory, "ls-tree", "-rz", "HEAD").split(b"\0"):
if entry:
metadata, path = entry.split(b"\t", 1)
mode, kind, commit = metadata.decode().split()
if mode == "160000":
links[path.decode()] = commit
if not links:
return
raw = git(directory, "config", "--no-includes", "--blob", "HEAD:.gitmodules", "--null", "--list")
entries = {}
for item in raw.split(b"\0"):
if not item:
continue
key, value = item.decode().split("\n", 1)
match = re.fullmatch(r"submodule\.(.+)\.(path|url)", key)
if not match:
raise ValueError("Unsupported candidate .gitmodules setting")
name, field = match.groups()
if field in entries.setdefault(name, {}):
raise ValueError("Duplicate candidate .gitmodules setting")
entries[name][field] = value
if set(entries) != set(links):
raise ValueError("Submodule names must match fixed gitlink paths")
for name, fields in entries.items():
repo = LEGACY.get(name)
if not repo or fields.get("path") != name or fields.get("url") not in {
SSH + repo + ".git", f"{SERVER}/weichen/{repo}.git"}:
raise ValueError("Historical submodule source is outside the reviewed allowlist")
for name in entries:
repo = LEGACY[name]
sha = links[name]
url = f"{SERVER}/weichen/{repo}.git"
git(directory, "config", f"submodule.{name}.url", url)
# Trusted explicit checkout prevents candidate update commands from running.
git(directory, "submodule", "update", "--init", "--checkout", "--", name, token=component_token, repo=repo)
child = directory / name
if git(child, "rev-parse", "HEAD").decode().strip() != sha:
raise ValueError("Historical submodule does not match its fixed SHA")
mirror(repo, sha, component_token)
materialize_legacy(child, depth + 1)
def materialize_manifest(directory):
manifest = directory / "components.json"
lock = directory / "components.lock.json"
if not manifest.exists() and not lock.exists():
materialize_legacy(directory)
return
data = json.loads(manifest.read_text())
locked = json.loads(lock.read_text())
if data.get("schema") != 1 or locked.get("schema") != 1:
raise ValueError("Unsupported source manifest schema")
entries = {}
for item in data["components"]:
repo = item["id"]
path = ".workspace/" + repo
if (repo not in REPOS or repo in entries or item["path"] != path or
item["repo"] not in {SSH + repo + ".git", f"{SERVER}/weichen/{repo}.git"} or
item.get("role") not in {"go-library", "npm-library", "application", "guidelines", "documentation"}):
raise ValueError("Candidate source manifest is outside the reviewed allowlist")
for module in item.get("modules", []):
if module.get("path") not in GO_MODULES or not module["path"].startswith(GO_PREFIX + repo + ".git"):
raise ValueError("Candidate module mapping is outside the reviewed allowlist")
entries[repo] = item
selected = locked["components"]
if set(selected) - set(entries):
raise ValueError("Source lock refers to an unregistered repository")
for repo, item in entries.items():
if item["role"] in {"application", "guidelines", "documentation"} and repo not in selected:
raise ValueError("Application and documentation source needs a fixed lock")
for repo, pin in selected.items():
fixed_sha(pin["commit"])
destination = directory / entries[repo]["path"]
if destination.exists() or destination.is_symlink() or destination.parent.is_symlink():
raise ValueError("Source materialization requires a fresh destination")
# Validate the complete lock before any authenticated component fetch.
for repo, pin in selected.items():
sha = fixed_sha(pin["commit"])
destination = directory / entries[repo]["path"]
destination.mkdir(parents=True)
url = f"{SERVER}/weichen/{repo}.git"
git(destination, "init", "-q")
git(destination, "remote", "add", "origin", url)
git(destination, "fetch", "--depth=1", "origin", sha, token=component_token, repo=repo)
git(destination, "checkout", "-q", "--detach", "FETCH_HEAD")
if git(destination, "rev-parse", "HEAD").decode().strip() != sha:
raise ValueError("Materialized source differs from the fixed lock")
# Persist the registered identity; process config chooses the transport.
git(destination, "remote", "set-url", "origin", entries[repo]["repo"])
mirror(repo, sha, component_token)
materialize_legacy(destination)
try:
if os.environ.get("GITHUB_REPOSITORY") != "weichen/Logging-System":
raise ValueError("Checkout repository is outside the reviewed allowlist")
sha = fixed_sha(os.environ.get("GITHUB_SHA", ""))
if not root_token:
raise ValueError("Checkout requires TOKEN")
if (root / ".git").exists():
raise ValueError("Checkout requires a fresh workspace")
git(root, "init", "-q")
git(root, "remote", "add", "origin", SERVER + "/weichen/Logging-System.git")
git(root, "fetch", "--depth=1", "origin", sha, token=root_token, repo="Logging-System")
git(root, "checkout", "-q", "--detach", "FETCH_HEAD")
if git(root, "rev-parse", "HEAD").decode().strip() != sha:
raise ValueError("Checked-out commit differs from the platform commit")
if (root / ".ci-mirrors").exists() or (root / ".ci-mirrors.env").exists():
raise ValueError("Candidate cannot provide trusted prefetch state")
materialize_manifest(root)
mirror_env()
except (ValueError, KeyError, OSError, subprocess.CalledProcessError) as error:
# Do not print child stderr or environment: a failed credential fetch stays redacted.
sys.exit("Checkout refused: " + str(error))
print("Fixed source checkout complete; credentials were not persisted")
PY_TRUSTED
unset TOKEN SUBMODULE_TOKEN
- name: Install Go 1.27.1
run: |
set -euo pipefail
curl -fsSL -o "$RUNNER_TEMP/go.tgz" https://mirrors.aliyun.com/golang/go1.27.1.linux-amd64.tar.gz
tar -C /usr/local -xzf "$RUNNER_TEMP/go.tgz"
ln -sfn /usr/local/go/bin/go /usr/local/bin/go
ln -sfn /usr/local/go/bin/gofmt /usr/local/bin/gofmt
- name: Prefetch Go modules without executing candidate code
env:
SUBMODULE_TOKEN: ${{ secrets.SUBMODULE_TOKEN }}
run: &trusted_acquisition_2 |
set -euo pipefail
python3 - <<'PY_TRUSTED'
# Trusted workflow code only: never import or execute checkout scripts here.
# Token scopes, workflow provenance and runner isolation are platform NOT_RUN.
import json
import os
from pathlib import Path
import re
import shlex
import subprocess
import sys
import tempfile
from urllib.parse import urlsplit
SERVER = os.environ.get("GITHUB_SERVER_URL", "").rstrip("/")
parsed = urlsplit(SERVER)
if (parsed.scheme not in {"http", "https"} or not parsed.netloc or
parsed.username or parsed.password or parsed.query or parsed.fragment):
sys.exit("Acquisition requires the platform-injected http(s) server")
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
GO_PREFIX = "git-ssh.u1680832.nyat.app/weichen/"
REPOS = {"Agent-System-Dev", "Logging-System", "Error-Code-System", "Agent-System-Core", "Agent-Native",
"Agent-Intent", "Agent-Command", "Agent-Squad", "Agent-System-Backend",
"Agent-System-Frontend", "Agent-System-UI", "Agent-System-RDM",
"Development-Guidelines", "Agent-System-Documents"}
LEGACY = {
"modules/core": "Agent-System-Core", "modules/backend": "Agent-System-Backend",
"modules/frontend": "Agent-System-Frontend", "modules/ui": "Agent-System-UI",
"modules/documents": "Agent-System-Documents", "deps/agent-system-core": "Agent-System-Core",
"deps/development-guidelines": "Development-Guidelines", "deps/agent-native": "Agent-Native",
"deps/agent-squad": "Agent-Squad", "deps/agent-intent": "Agent-Intent",
"deps/agent-command": "Agent-Command", "deps/error-code-system": "Error-Code-System",
"deps/logging-system": "Logging-System", "pins/agent-system-backend": "Agent-System-Backend",
"pins/agent-system-core": "Agent-System-Core", "pins/agent-system-frontend": "Agent-System-Frontend",
"pins/agent-system-ui": "Agent-System-UI",
}
GO_REPOS = REPOS - {"Agent-System-Dev", "Agent-System-UI", "Agent-System-Frontend", "Development-Guidelines", "Agent-System-Documents"}
GO_MODULES = {GO_PREFIX + repo + ".git" for repo in GO_REPOS}
GO_MODULES |= {GO_PREFIX + "Agent-Squad.git/" + suffix for suffix in
("adapters/native", "adapters/intent", "adapters/sqlite", "adapters/a2a", "cmd/agent-squad")}
root_token = os.environ.pop("TOKEN", "")
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
# Go environment files and inherited Git tracing/config must not change acquisition.
clean = {k: v for k, v in os.environ.items()
if not k.startswith(("GIT_", "NPM_CONFIG_", "npm_config_")) and
not any(word in k.upper() for word in ("TOKEN", "PASSWORD", "SECRET"))}
clean.update(GIT_CONFIG_NOSYSTEM="1", GIT_CONFIG_SYSTEM="/dev/null", GIT_CONFIG_GLOBAL="/dev/null",
GIT_TERMINAL_PROMPT="0", GOENV="off", GOTOOLCHAIN="local", GOWORK="off", GOFLAGS="-mod=readonly",
GOPRIVATE=GO_PREFIX.rstrip("/"), GONOPROXY=GO_PREFIX.rstrip("/"), GONOSUMDB=GO_PREFIX.rstrip("/"))
if os.environ.get("npm_config_cache"):
clean["npm_config_cache"] = os.environ["npm_config_cache"]
config = {"core.hooksPath": "/dev/null", "core.fsmonitor": "false", "init.templateDir": "",
"credential.helper": "", "fetch.recurseSubmodules": "false", "submodule.recurse": "false",
"http.followRedirects": "false", "protocol.allow": "never", "protocol." + parsed.scheme + ".allow": "always"}
root = Path.cwd()
mirrors = root / ".ci-mirrors"
def process_env(values):
env = clean | {"GIT_CONFIG_COUNT": str(len(values))}
for index, (key, value) in enumerate(values.items()):
env[f"GIT_CONFIG_KEY_{index}"] = key
env[f"GIT_CONFIG_VALUE_{index}"] = value
return env
def git(directory, *args, token="", repo=""):
values = config.copy()
if token:
if repo not in REPOS:
raise ValueError("Credential destination is outside the reviewed repository allowlist")
values[f"http.{SERVER}/weichen/{repo}.git.extraheader"] = "AUTHORIZATION: token " + token
result = subprocess.run(["git", "-C", str(directory), *args], env=process_env(values),
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.stdout
def fixed_sha(value):
if not isinstance(value, str) or not re.fullmatch(r"[0-9a-fA-F]{40}", value):
raise ValueError("Source acquisition requires a fixed commit SHA")
return value.lower()
def mirror(repo, sha, token):
sha = fixed_sha(sha)
destination = mirrors / (repo + ".git")
if destination.is_symlink() or mirrors.is_symlink():
raise ValueError("Mirror directory cannot be a symlink")
mirrors.mkdir(exist_ok=True)
if not destination.exists():
destination.mkdir()
git(destination, "init", "--bare", "-q")
url = f"{SERVER}/weichen/{repo}.git"
try:
git(destination, "cat-file", "-e", sha + "^{commit}")
except subprocess.CalledProcessError:
git(destination, "fetch", "--depth=200", url, sha, token=token, repo=repo)
git(destination, "update-ref", "refs/heads/main", sha)
git(destination, "symbolic-ref", "HEAD", "refs/heads/main")
git(destination, "update-ref", "refs/ci/" + sha, sha)
return destination
def mirror_env():
values = {"protocol.file.allow": "always", "core.hooksPath": "/dev/null", "credential.helper": ""}
# Distinct keys use repeated .insteadOf values, represented as a sequence below.
pairs = list(values.items())
for repo in sorted(REPOS):
destination = mirrors / (repo + ".git")
if not destination.exists():
continue
key = "url." + destination.as_uri() + ".insteadOf"
pairs.extend((key, url) for url in (SSH + repo + ".git", "https://" + GO_PREFIX + repo + ".git",
SERVER + "/weichen/" + repo + ".git", "https://" + GO_PREFIX + repo))
env = clean | {"CI_DEPENDENCY_MIRRORS": str(mirrors), "GIT_CONFIG_COUNT": str(len(pairs))}
for index, (key, value) in enumerate(pairs):
env[f"GIT_CONFIG_KEY_{index}"] = key
env[f"GIT_CONFIG_VALUE_{index}"] = value
exports = {k: v for k, v in env.items() if k.startswith("GIT_CONFIG_") or k == "CI_DEPENDENCY_MIRRORS"}
(root / ".ci-mirrors.env").write_text("".join("export " + k + "=" + shlex.quote(v) + "\n" for k, v in exports.items()))
return env
def source_roots():
bases = [root]
composition = root / ".ci-composition-dev"
if composition.is_dir() and not composition.is_symlink():
bases.append(composition)
paths = []
for base in bases:
paths += [base, base / "rdm"] + [base / path for path in LEGACY] + [base / ".workspace" / repo for repo in sorted(REPOS)]
return [path for path in paths if path.is_dir() and not path.is_symlink()]
try:
targets = []
for source in source_roots():
for suffix in (".", "examples/trace", "adapters/native", "adapters/intent", "adapters/sqlite", "adapters/a2a", "cmd/agent-squad"):
directory = source / suffix
if (directory / "go.mod").is_file() and directory.resolve() not in targets:
targets.append(directory.resolve())
# Parse using the installed local Go tool without credentials or candidate execution.
original_files = {}
for directory in targets:
parsed_mod = json.loads(subprocess.check_output(["go", "mod", "edit", "-json"], cwd=directory, env=clean))
canonical = parsed_mod["Module"]["Path"].startswith(GO_PREFIX)
for name in ("go.mod", "go.sum"):
dependency_file = directory / name
if dependency_file.is_file():
original_files[(directory, name)] = dependency_file.read_bytes()
elif canonical and name == "go.sum":
original_files[(directory, name)] = None
for dep in (parsed_mod.get("Require") or []):
path = dep["Path"]
if path.startswith(GO_PREFIX) and path not in GO_MODULES:
raise ValueError("Go dependency is outside the reviewed module mapping")
for replacement in (parsed_mod.get("Replace") or []):
path = replacement["New"]["Path"]
if canonical and not replacement["New"].get("Version"):
raise ValueError("Canonical module cannot acquire a local path replacement")
if path.startswith(GO_PREFIX) and path not in GO_MODULES:
raise ValueError("Go replacement is outside the reviewed module mapping")
auth = config.copy()
for repo in sorted(GO_REPOS):
url = f"{SERVER}/weichen/{repo}.git"
auth[f"url.{url}.insteadOf"] = "https://" + GO_PREFIX + repo
auth[f"http.{url}.extraheader"] = "AUTHORIZATION: token " + component_token
def objects(output):
decoder = json.JSONDecoder()
remaining = output.strip()
while remaining:
item, end = decoder.raw_decode(remaining)
remaining = remaining[end:].lstrip()
yield item
def unchanged():
for (owner, name), contents in original_files.items():
dependency_file = owner / name
current = dependency_file.read_bytes() if dependency_file.exists() else None
if current != contents:
raise ValueError("Go acquisition modified a committed Go dependency file: " + str(dependency_file))
for directory in targets:
# Resolve private go.mod metadata only through exact repository headers;
# validate the complete selected graph before acquiring module zip files.
graph = subprocess.run(["go", "list", "-mod=readonly", "-m", "-json", "all"], cwd=directory,
env=process_env(auth), capture_output=True, text=True)
if graph.returncode:
raise ValueError("Go selected graph resolution failed: " + graph.stderr.strip())
for item in objects(graph.stdout):
if item.get("Main"):
continue
selected = item.get("Replace") or item
for path in (item.get("Path", ""), selected.get("Path", "")):
if path.startswith(GO_PREFIX) and path not in GO_MODULES:
raise ValueError("Selected Go module is outside the reviewed mapping")
unchanged()
# Go 1.27 can prune go.sum even under -mod=readonly for this
# metadata-only command. Use a disposable copy, then validate actual
# package loading against the unchanged committed source locks.
local_replacements = json.loads(subprocess.check_output(
["go", "mod", "edit", "-json"], cwd=directory, env=clean)).get("Replace") or []
downloaded = ""
if not any(not item["New"].get("Version") for item in local_replacements):
with tempfile.TemporaryDirectory(prefix="ci-go-prefetch-") as temporary:
download_root = Path(temporary)
for name in ("go.mod", "go.sum"):
if (directory / name).is_file():
(download_root / name).write_bytes((directory / name).read_bytes())
result = subprocess.run(["go", "mod", "download", "-json"], cwd=download_root,
env=process_env(auth), capture_output=True, text=True)
if result.returncode:
raise ValueError("Go module acquisition failed: " + result.stderr.strip())
downloaded = result.stdout
unchanged()
for item in objects(downloaded):
path = item.get("Path", "")
if path.startswith(GO_PREFIX):
if path not in GO_MODULES:
raise ValueError("Resolved Go module is outside the reviewed mapping")
repo = path[len(GO_PREFIX):].split(".git", 1)[0]
origin = item.get("Origin") or json.loads(Path(item["Info"]).read_text()).get("Origin") or {}
mirror(repo, fixed_sha(origin.get("Hash")), component_token)
# Package metadata loads actual test/build dependencies without running
# vet, compilers, package init functions or candidate tests. No CGO tools.
packages = subprocess.run(["go", "list", "-mod=readonly", "-deps", "-test", "./..."], cwd=directory,
env=process_env(auth) | {"CGO_ENABLED": "0"}, capture_output=True, text=True)
if packages.returncode:
raise ValueError("Go test/build dependency acquisition failed: " + packages.stderr.strip())
unchanged()
mirror_env()
except (ValueError, OSError, subprocess.CalledProcessError) as error:
sys.exit("Go prefetch refused: " + str(error))
print("Go modules cached with GOTOOLCHAIN=local; no candidate code executed")
PY_TRUSTED
unset TOKEN SUBMODULE_TOKEN
- run: |
set -euo pipefail
source .ci-mirrors.env
for module in . examples/trace; do
test -f "$module/go.mod"
(cd "$module" && go vet -mod=readonly ./... && go test -mod=readonly -count=1 ./...)
done
docker-checkout-hostgateway:
runs-on: ubuntu-latest
options: --add-host gitea:host-gateway
env:
GITHUB_SERVER_URL: http://gitea:3000
steps:
- name: Checkout
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
SUBMODULE_TOKEN: ${{ secrets.SUBMODULE_TOKEN }}
run: *trusted_acquisition_1
- run: test -f go.mod && echo "docker-mode checkout via host-gateway OK"