Arch Builder INIT
This commit is contained in:
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
version="${1:?version required}"
|
||||
tag="${2:?release tag required}"
|
||||
|
||||
echo "==> Resolving exact tdlib commit from ${tag}"
|
||||
td_commit="$(./scripts/get-tdlib-commit.sh "$tag")"
|
||||
echo "tdlib commit: ${td_commit}"
|
||||
|
||||
./scripts/update-pkgbuild.sh "$version" "$td_commit"
|
||||
|
||||
rm -rf src pkg build
|
||||
|
||||
echo "==> Building ${version} with makepkg"
|
||||
|
||||
# AyuGram is a very large C++ project. Limit parallelism to avoid OOM on
|
||||
# smaller runners. Override with AYUGRAM_JOBS if your runner has more RAM.
|
||||
jobs="${AYUGRAM_JOBS:-$(nproc)}"
|
||||
export CMAKE_BUILD_PARALLEL_LEVEL="$jobs"
|
||||
|
||||
# makepkg must not be run as root.
|
||||
if [[ "$(id -u)" -eq 0 ]]; then
|
||||
echo "ERROR: makepkg must run as an unprivileged user." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
makepkg \
|
||||
--syncdeps \
|
||||
--cleanbuild \
|
||||
--clean \
|
||||
--noconfirm \
|
||||
--skippgpcheck
|
||||
|
||||
pkg="$(find . -maxdepth 1 -type f -name '*.pkg.tar.zst' -print -quit)"
|
||||
|
||||
[[ -n "$pkg" ]] || {
|
||||
echo "ERROR: no package produced" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "PACKAGE=$pkg" >> "$GITHUB_OUTPUT"
|
||||
echo "VERSION=$version" >> "$GITHUB_OUTPUT"
|
||||
echo "TD_COMMIT=$td_commit" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "==> Package: $pkg"
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo="${AYUGRAM_REPO:-AyuGram/AyuGramDesktop}"
|
||||
api="https://api.github.com/repos/${repo}/releases/latest"
|
||||
|
||||
json="$(curl -fsSL --retry 5 --retry-all-errors \
|
||||
-H 'Accept: application/vnd.github+json' \
|
||||
-H 'X-GitHub-Api-Version: 2022-11-28' \
|
||||
"$api")"
|
||||
|
||||
tag="$(jq -r '.tag_name // empty' <<<"$json")"
|
||||
prerelease="$(jq -r '.prerelease // false' <<<"$json")"
|
||||
draft="$(jq -r '.draft // false' <<<"$json")"
|
||||
|
||||
[[ -n "$tag" ]] || { echo "GitHub did not return a release tag" >&2; exit 1; }
|
||||
[[ "$draft" == "false" ]] || { echo "Latest release is a draft" >&2; exit 1; }
|
||||
[[ "$prerelease" == "false" ]] || { echo "Latest release is a prerelease: $tag" >&2; exit 1; }
|
||||
|
||||
version="${tag#v}"
|
||||
[[ "$version" =~ ^[0-9]+(\.[0-9]+)+([._-][0-9A-Za-z.-]+)?$ ]] || {
|
||||
echo "Unexpected release tag: $tag" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
archive="AyuGramDesktop-${version}-full.tar.gz"
|
||||
asset_url="https://github.com/${repo}/releases/download/${tag}/${archive}"
|
||||
|
||||
echo "Latest stable release: ${tag}"
|
||||
echo "Archive: ${asset_url}"
|
||||
|
||||
curl -fsSIL --retry 5 --retry-all-errors "$asset_url" >/dev/null
|
||||
|
||||
current=""
|
||||
[[ -f .current-version ]] && current="$(tr -d '[:space:]' < .current-version)"
|
||||
|
||||
echo "Current published version: ${current:-none}"
|
||||
|
||||
if [[ "$version" == "$current" ]]; then
|
||||
echo "update=false" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "update=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "archive=${archive}" >> "$GITHUB_OUTPUT"
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo="${AYUGRAM_REPO:-AyuGram/AyuGramDesktop}"
|
||||
tag="${1:?release tag required}"
|
||||
version="${tag#v}"
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
archive="${tmp}/AyuGramDesktop-${version}-full.tar.gz"
|
||||
url="https://github.com/${repo}/releases/download/${tag}/AyuGramDesktop-${version}-full.tar.gz"
|
||||
|
||||
echo "Downloading upstream full source archive to resolve its pinned tde2e..." >&2
|
||||
curl -fsSL --retry 5 --retry-all-errors -o "$archive" "$url"
|
||||
|
||||
dockerfile="$(tar -tzf "$archive" | grep -E '(^|/)Telegram/build/docker/centos_env/Dockerfile$' | head -n1 || true)"
|
||||
|
||||
if [[ -z "$dockerfile" ]]; then
|
||||
echo "Could not find upstream centos_env Dockerfile in the full release archive." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
content="$(tar -xOf "$archive" "$dockerfile")"
|
||||
|
||||
# Upstream's build environment pins tdlib/tde2e to an exact commit.
|
||||
td_commit="$(awk '
|
||||
/git remote add origin https:\/\/github.com\/tdlib\/td\.git/ { in_td=1; next }
|
||||
in_td && /git fetch --depth=1 origin [0-9a-f]{40}/ {
|
||||
match($0, /[0-9a-f]{40}/, m)
|
||||
print m[0]
|
||||
exit
|
||||
}
|
||||
' <<<"$content")"
|
||||
|
||||
if [[ -z "$td_commit" ]]; then
|
||||
echo "Could not resolve tdlib/tde2e commit from upstream build Dockerfile." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$td_commit"
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${NEXSPENCE_URL:?NEXSPENCE_URL is required}"
|
||||
: "${NEXSPENCE_TOKEN:?NEXSPENCE_TOKEN is required}"
|
||||
: "${NEXSPENCE_REPOSITORY:?NEXSPENCE_REPOSITORY is required}"
|
||||
|
||||
pkg="${1:?package path required}"
|
||||
repo_name="${NEXSPENCE_REPOSITORY}"
|
||||
base="${NEXSPENCE_URL%/}/repository/${repo_name}/x86_64"
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
cp "$pkg" "$tmp/"
|
||||
pkg_file="$(basename "$pkg")"
|
||||
|
||||
echo "==> Creating Arch repository database"
|
||||
repo-add --remove "$tmp/${repo_name}.db.tar.zst" "$tmp/$pkg_file"
|
||||
repo-add --remove "$tmp/${repo_name}.files.tar.zst" "$tmp/$pkg_file"
|
||||
|
||||
# Nexspence Raw is HTTP object storage, so symlinks created by repo-add cannot
|
||||
# be relied upon. Create real .db/.files files as well.
|
||||
zstd -q -d -c "$tmp/${repo_name}.db.tar.zst" > "$tmp/${repo_name}.db"
|
||||
zstd -q -d -c "$tmp/${repo_name}.files.tar.zst" > "$tmp/${repo_name}.files"
|
||||
|
||||
upload() {
|
||||
local file="$1"
|
||||
local remote="$base/$(basename "$file")"
|
||||
|
||||
echo "==> PUT $(basename "$file")"
|
||||
curl --fail-with-body \
|
||||
--retry 5 \
|
||||
--retry-all-errors \
|
||||
--connect-timeout 20 \
|
||||
--max-time 900 \
|
||||
-X PUT \
|
||||
-H "Authorization: Bearer ${NEXSPENCE_TOKEN}" \
|
||||
--upload-file "$file" \
|
||||
"$remote"
|
||||
}
|
||||
|
||||
upload "$tmp/$pkg_file"
|
||||
upload "$tmp/${repo_name}.db"
|
||||
upload "$tmp/${repo_name}.db.tar.zst"
|
||||
upload "$tmp/${repo_name}.files"
|
||||
upload "$tmp/${repo_name}.files.tar.zst"
|
||||
|
||||
echo "==> Nexspence publication complete"
|
||||
echo " ${base}/"
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
pkg="${1:?package path required}"
|
||||
|
||||
echo "==> pacman package metadata"
|
||||
pacman -Qip "$pkg"
|
||||
|
||||
echo "==> namcap"
|
||||
namcap "$pkg" || true
|
||||
|
||||
rm -rf /tmp/ayugram-package-test
|
||||
mkdir -p /tmp/ayugram-package-test
|
||||
|
||||
bsdtar -xf "$pkg" -C /tmp/ayugram-package-test
|
||||
|
||||
binary="/tmp/ayugram-package-test/usr/bin/AyuGram"
|
||||
|
||||
if [[ ! -x "$binary" ]]; then
|
||||
echo "ERROR: expected executable ${binary} was not found" >&2
|
||||
find /tmp/ayugram-package-test/usr -maxdepth 4 -type f -print
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> ELF information"
|
||||
file "$binary"
|
||||
|
||||
echo "==> Shared library resolution"
|
||||
ldd "$binary" | tee /tmp/ayugram-ldd.txt
|
||||
|
||||
if grep -q 'not found' /tmp/ayugram-ldd.txt; then
|
||||
echo "ERROR: unresolved shared library detected" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> RPATH/RUNPATH"
|
||||
readelf -d "$binary" | grep -E 'RPATH|RUNPATH' || true
|
||||
|
||||
echo "==> Basic executable smoke test"
|
||||
set +e
|
||||
timeout 15s "$binary" --version >/tmp/ayugram-version.txt 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
|
||||
cat /tmp/ayugram-version.txt || true
|
||||
|
||||
# GUI applications commonly return non-zero or remain alive when --version is
|
||||
# unsupported. We only reject an immediate dynamic-loader failure.
|
||||
if grep -Eq 'error while loading shared libraries|cannot open shared object file|symbol lookup error' /tmp/ayugram-version.txt; then
|
||||
echo "ERROR: runtime loader failure" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$rc" -eq 126 || "$rc" -eq 127 ]]; then
|
||||
echo "ERROR: executable could not be started" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Package validation passed."
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
version="${1:?version required}"
|
||||
td_commit="${2:?tdlib commit required}"
|
||||
|
||||
sed -i -E "s/^pkgver=.*/pkgver=${version}/" PKGBUILD
|
||||
sed -i -E "s/^_tdlib_commit=.*/_tdlib_commit='${td_commit}'/" PKGBUILD
|
||||
|
||||
# Release archives and tdlib tarballs are fetched by makepkg with SKIP hashes.
|
||||
# The workflow records the upstream release tag and validates that the archive
|
||||
# is reachable before starting the expensive build.
|
||||
Reference in New Issue
Block a user