Files
MoShiro/ci/release-node-images.sh
T
justme 29d998bc94
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline failed
ci/woodpecker/push/dev-image unknown status
build(quic): bundle Linux runtime libraries [CI]
2026-10-10 04:01:24 +08:00

122 lines
4.9 KiB
Bash

#!/usr/bin/env bash
# Publish musl OCI images for the Linux Agent and Probe on amd64 and arm64.
set -euo pipefail
tag="${CI_COMMIT_TAG:-}"
[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]] || {
echo "release must run from a vMAJOR.MINOR.PATCH tag" >&2
exit 2
}
[[ -n "${GITEA_TOKEN:-}" ]] || { echo "GITEA_TOKEN is required" >&2; exit 2; }
[[ -n "${ZOT_USERNAME:-}" && -n "${ZOT_SECRET:-}" ]] || {
echo "Zot credentials are required" >&2
exit 2
}
version="${tag#v}"
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# 版本取自 tag:写进工作区的 Directory.Build.props(仓库里的 <Version> 只是占位,发版不用再提交 bump)
source "$root/ci/version.sh"
moshiro_apply_version
gitea_base="${GITEA_BASE:-http://127.0.0.1:3100}"
gitea_base="${gitea_base%/}"
gitea_host="${gitea_base#https://}"
gitea_host="${gitea_host#http://}"
gitea_host="${gitea_host%%/*}"
gitea_host="${gitea_host%%:*}"
registry="${ZOT_REGISTRY:-registry.oeo.one}"
image_root="$registry/moshiro"
work="$root/.release/node-images"
netrc="$work/netrc"
buildah_home="/home/justme/woodpecker/buildah-home/node-images"
mkdir -p "$buildah_home"
export HOME="$buildah_home"
mkdir -p "$work"
chmod 700 "$work"
printf 'machine %s login justme password %s\n' "$gitea_host" "$GITEA_TOKEN" > "$netrc"
chmod 600 "$netrc"
export REGISTRY_AUTH_FILE="$work/zot-auth.json"
trap 'rm -rf "$work"' EXIT
logged_in=false
for attempt in 1 2 3 4; do
if buildah login --tls-verify=true --username "$ZOT_USERNAME" --password-stdin "$registry" <<< "$ZOT_SECRET" >/dev/null; then
logged_in=true
break
fi
if [[ "$attempt" -lt 4 ]]; then
echo "Zot login attempt $attempt failed; retrying in 3 seconds" >&2
sleep 3
fi
done
[[ "$logged_in" == true ]] || { echo "could not authenticate to Zot after 4 attempts" >&2; exit 1; }
build_arch_image() {
local component="$1" arch="$2" suffix="$3"
local filename="moshiro-$component-v$version-linux-$suffix.tar.gz"
local context="$work/$component-$arch"
local archive="$work/$filename"
local containerfile="$root/packaging/container/${component^}.Containerfile"
local image="$image_root/moshiro-$component"
local local_image="localhost/moshiro-$component:$version-$arch"
curl --fail-with-body --silent --show-error --retry 3 --netrc-file "$netrc" \
"$gitea_base/api/packages/justme/generic/moshiro-node/$version/$filename" -o "$archive"
mkdir -p "$context/app" "$context/config"
tar -xzf "$archive" -C "$work"
install -m 0755 "$work/fleet-enroll" "$context/app/fleet-enroll"
install -m 0755 "$work/moshiro-$component" "$context/app/moshiro-$component"
install -m 0644 "$work"/lib*.so.* "$context/app/"
: > "$context/config/.keep"
install -m 0755 "$root/packaging/container/entrypoint.sh" "$context/entrypoint.sh"
buildah bud --tls-verify=true --arch "$arch" \
--build-arg "APP_VERSION=$version" \
-f "$containerfile" -t "$local_image" "$context" >/dev/null
local pushed=false
for attempt in 1 2 3; do
if buildah push --tls-verify=true "$local_image" "docker://$image:$version-$arch" >/dev/null; then
pushed=true
break
fi
if [[ "$attempt" -lt 3 ]]; then
echo "Zot push for $component/$arch attempt $attempt failed; retrying in 5 seconds" >&2
sleep 5
fi
done
[[ "$pushed" == true ]] || { echo "could not push $component/$arch image after 3 attempts" >&2; return 1; }
echo "pushed Zot image $image:$version-$arch"
}
publish_index() {
local component="$1" image="$image_root/moshiro-$component"
local manifest="localhost/moshiro-$component:$version-multiarch"
buildah manifest rm "$manifest" >/dev/null 2>&1 || true
buildah manifest create "$manifest" >/dev/null
buildah manifest add "$manifest" "docker://$image:$version-amd64" >/dev/null
buildah manifest add "$manifest" "docker://$image:$version-arm64" >/dev/null
buildah manifest push --all --format oci --digestfile "$work/$component.digest" "$manifest" "docker://$image:$version" >/dev/null
if [[ "$version" != *-* ]]; then
buildah manifest push --all --format oci "$manifest" "docker://$image:latest" >/dev/null
fi
buildah manifest rm "$manifest" >/dev/null
echo "published multi-architecture index $image:$version"
if [[ "$version" != *-* ]]; then
echo "published multi-architecture index $image:latest"
fi
}
for component in agent probe; do
build_arch_image "$component" amd64 musl-amd64
build_arch_image "$component" arm64 musl-arm64
publish_index "$component"
# 发布清单:给多架构镜像的 digest 签名(私钥只在 CI 密钥里),放进镜像仓库(<仓库>-manifest:release),面板在线时再登记一份加速。
# 没有配置签名密钥(例如 fork)就只发镜像、不发清单。
if [[ -n "${RELEASE_SIGNING_KEY:-}" ]]; then
digest="$(cat "$work/$component.digest")"
bash "$root/ci/publish-release-offer.sh" "$component" "$image_root/moshiro-$component" "$digest" "$tag" release "$work/$component-release"
fi
done