ci: speed up backend build and parallelize image publishing [CI]
This commit is contained in:
1 parent
04f116e092
commit
d7b48c068c
5 files changed
+109
-32
No files matched your search
+55
-10
@@ -50,11 +50,39 @@ if [[ ! -f "$root/web/display/dist/index.html" || ! -f "$root/web/admin/dist/ind
|
||||
fi
|
||||
[[ -f "$root/web/display/dist/index.html" && -f "$root/web/admin/dist/index.html" ]] || { echo "the web build did not produce both apps" >&2; exit 1; }
|
||||
|
||||
(cd "$root/backend" && dotnet publish src/MoShiro.Backend \
|
||||
-m:3 -c Release -r "$rid" --self-contained true \
|
||||
-p:DebugType=none -p:DebugSymbols=false \
|
||||
-p:PublishAot=true -p:UseAotAnywhere=true -p:SqliteStaticLink=true -p:OpenApiGenerateDocuments=false \
|
||||
--artifacts-path "$build_root" -o "$output")
|
||||
sqlite_cache_root="${MOSHIRO_SQLITE_CACHE:-${NUGET_PACKAGES:-${HOME:-/home/justme}/.nuget/packages}/moshiro-sqlite-static}"
|
||||
sqlite_cache_key="$(python3 - "$root" <<'PY'
|
||||
import hashlib, json, sys, xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
root = Path(sys.argv[1])
|
||||
global_json = json.loads((root / "global.json").read_text())
|
||||
zig = next(p.attrib["VersionOverride"] for p in ET.parse(root / "backend/Directory.Build.props").iter("PackageReference") if p.attrib.get("Include") == "Vezel.Zig.Toolsets.linux-x64")
|
||||
packages = ET.parse(root / "Directory.Packages.props").getroot()
|
||||
sqlite = {p.tag: p.text for p in packages.iter() if p.tag.startswith("MoShiroSqliteSource")}
|
||||
fingerprint = {
|
||||
"sdk": global_json["sdk"]["version"],
|
||||
"aotanywhere": global_json["msbuild-sdks"]["StuDev.AotAnywhere"],
|
||||
"zig": zig,
|
||||
"sqlite": sqlite,
|
||||
"compile-target": (root / "backend/src/MoShiro.Backend/StaticSqlite.targets").read_text(),
|
||||
}
|
||||
print(hashlib.sha256(json.dumps(fingerprint, sort_keys=True).encode()).hexdigest()[:24])
|
||||
PY
|
||||
)"
|
||||
mkdir -p "$sqlite_cache_root/locks"
|
||||
# Stable cache paths let MSBuild reuse the SQLite amalgamation object between
|
||||
# fresh Woodpecker workspaces. Lock per RID so overlapping retries cannot write
|
||||
# the same object concurrently; amd64 and arm64 builds remain parallel.
|
||||
(
|
||||
cd "$root/backend"
|
||||
flock -w 900 "$sqlite_cache_root/locks/$rid.lock" \
|
||||
dotnet publish src/MoShiro.Backend \
|
||||
-m:8 -c Release -r "$rid" --self-contained true \
|
||||
-p:DebugType=none -p:DebugSymbols=false \
|
||||
-p:PublishAot=true -p:UseAotAnywhere=true -p:SqliteStaticLink=true -p:OpenApiGenerateDocuments=false \
|
||||
-p:SqliteStaticCacheRoot="$sqlite_cache_root" -p:SqliteStaticCacheKey="$sqlite_cache_key" \
|
||||
--artifacts-path "$build_root" -o "$output"
|
||||
)
|
||||
[[ -x "$output/moshiro-backend" ]] || { echo "NativeAOT Backend executable is missing" >&2; exit 1; }
|
||||
[[ "$(wc -c < "$output/moshiro-backend")" -gt 2000000 ]] || { echo "Backend output is an apphost, not a NativeAOT executable" >&2; exit 1; }
|
||||
install -m 0755 "$output/moshiro-backend" "$container_context/app/moshiro-backend"
|
||||
@@ -93,9 +121,9 @@ for attempt in 1 2 3 4; do
|
||||
done
|
||||
[[ "$logged_in" == true ]] || { echo "could not authenticate to Zot after 4 attempts" >&2; exit 1; }
|
||||
push_tag() {
|
||||
local target_tag="$1" pushed=false
|
||||
local target_tag="$1" digest_file="$2" pushed=false
|
||||
for attempt in 1 2 3; do
|
||||
if buildah push --tls-verify=true --digestfile "$output/image.digest" "$local_image" "docker://$image:$target_tag"; then
|
||||
if buildah push --tls-verify=true --digestfile "$digest_file" "$local_image" "docker://$image:$target_tag"; then
|
||||
pushed=true
|
||||
break
|
||||
fi
|
||||
@@ -116,12 +144,29 @@ if [[ -n "${IMAGE_TAGS:-}" ]]; then
|
||||
echo "invalid image tag: $image_tag" >&2
|
||||
exit 2
|
||||
}
|
||||
push_tag "$image_tag"
|
||||
done
|
||||
push_pids=()
|
||||
digest_files=()
|
||||
for image_tag in "${image_tags[@]}"; do
|
||||
digest_file="$output/image-$image_tag.digest"
|
||||
push_tag "$image_tag" "$digest_file" &
|
||||
push_pids+=("$!")
|
||||
digest_files+=("$digest_file")
|
||||
done
|
||||
push_status=0
|
||||
for push_pid in "${push_pids[@]}"; do
|
||||
wait "$push_pid" || push_status=1
|
||||
done
|
||||
[[ "$push_status" == 0 ]] || { echo "one or more image tag pushes failed" >&2; exit 1; }
|
||||
image_digest="$(cat "${digest_files[0]}")"
|
||||
for digest_file in "${digest_files[@]}"; do
|
||||
[[ "$(cat "$digest_file")" == "$image_digest" ]] || { echo "published tags have different image digests" >&2; exit 1; }
|
||||
done
|
||||
printf '%s\n' "$image_digest" > "$output/image.digest"
|
||||
else
|
||||
push_tag "$version-$arch"
|
||||
push_tag "$version-$arch" "$output/image.digest"
|
||||
if [[ -z "$tag" ]]; then
|
||||
push_tag "$version"
|
||||
push_tag "$version" "$output/image.digest"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
Reference in new issue
Block a user