Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions .github/workflows/golang_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,58 @@ on:
- 'scripts/build/setup/termux_setup_golang.sh'

jobs:
planning:
runs-on: ubuntu-slim
strategy:
matrix:
target_arch: [aarch64, arm, i686, x86_64]
steps:
- name: Clone repository
uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Generate test matrix list
run: ./scripts/bin/validation ${{ matrix.target_arch }} golang list | tee list.txt
- name: Get test matrix batch
id: list
run: |
echo "batch=$(grep -Po '^Batches \(actual\):\s*\K(\d+)' list.txt | python3 -c 'import json,sys;num = int(sys.stdin.readline().rstrip());print(json.dumps([i for i in range(1, num+1)]))')" | tee -a "$GITHUB_OUTPUT"
outputs:
batch: ${{ steps.list.outputs.batch }}
golang_validation:
needs: planning
runs-on: ubuntu-latest
strategy:
matrix:
target_arch: [aarch64, arm, i686, x86_64]
batch: ${{ fromJson(needs.planning.outputs.batch) }}
fail-fast: false
steps:
- name: Clone repository
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-depth: 1
- name: Set process id limit for 32-bit builds depending on aosp-libs
run: echo 65535 | sudo tee /proc/sys/kernel/pid_max
- name: Enable zram
if: ${{ steps.build-info.outputs.skip-building != 'true' }}
uses: ./.github/actions/zram
with:
algorithm: zstd
size: 16G
priority: 100
device_name: /dev/zram0
- name: Prepare environment
run: |
./scripts/setup-ubuntu.sh
./scripts/setup-android-sdk.sh
sudo apt install ninja-build
./scripts/free-space.sh
- name: Golang validation
run: ./scripts/bin/golang-validation "${{ matrix.target_arch }}" || exit 1
run: ./scripts/bin/validation ${{ matrix.target_arch }} golang ${{ matrix.batch }} || exit 1
- name: Upload report artifact
if: always()
uses: actions/upload-artifact@v6
with:
name: report-${{ matrix.target_arch }}
name: report-${{ matrix.target_arch }}-${{ matrix.batch }}
path: /tmp/golang-validation-report.txt
1 change: 1 addition & 0 deletions packages/golang/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ TERMUX_PKG_DESCRIPTION="Go programming language compiler"
TERMUX_PKG_LICENSE="BSD 3-Clause"
TERMUX_PKG_MAINTAINER="@termux"
TERMUX_PKG_VERSION="3:1.25.4"
TERMUX_PKG_REVISION=1
TERMUX_PKG_SRCURL=https://go.dev/dl/go${TERMUX_PKG_VERSION#*:}.src.tar.gz
TERMUX_PKG_SHA256=160043b7f17b6d60b50369436917fda8d5034640ba39ae2431c6b95a889cc98c
TERMUX_PKG_DEPENDS="clang"
Expand Down
3 changes: 2 additions & 1 deletion packages/step-cli/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ TERMUX_PKG_DESCRIPTION="An easy-to-use CLI tool for building, operating, and aut
TERMUX_PKG_LICENSE="Apache-2.0"
TERMUX_PKG_MAINTAINER="@termux"
TERMUX_PKG_VERSION="0.29.0"
TERMUX_PKG_REVISION=1
TERMUX_PKG_SRCURL=https://github.com/smallstep/cli/archive/refs/tags/v${TERMUX_PKG_VERSION}.tar.gz
TERMUX_PKG_SHA256=67b8575c95d8d1e64d3ab0160776479de43734052f92cfd150952f6e31fbe9bd
TERMUX_PKG_SHA256=6dbdec708ed4b52914113925e2fd1af53ca7484a2affa2dfb93749adec524c0e
TERMUX_PKG_AUTO_UPDATE=true
TERMUX_PKG_BUILD_IN_SRC=true
TERMUX_PKG_DEPENDS="termux-tools"
Expand Down
75 changes: 0 additions & 75 deletions scripts/bin/golang-validation

This file was deleted.

241 changes: 241 additions & 0 deletions scripts/bin/validation
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
#!/bin/bash
cd "$(realpath "$(dirname "$0")")/../.." || { echo "cd failed"; exit 1; }
readarray -t TERMUX_PACKAGE_DIRECTORIES < <(jq --raw-output 'del(.pkg_format) | keys | .[]' repo.json)

usage() {
echo "USAGE: $0 ARCH PACKAGES [list|batch_number]"
echo
echo "OPTIONS:"
echo " ARCH - aarch64, arm, i686, x86_64"
echo " PACKAGES - golang"
echo
echo "EXAMPLES:"
echo " $0 aarch64 golang Build all aarch64 golang based packages"
echo " $0 aarch64 golang list Split aarch64 golang based package list"
echo " $0 aarch64 golang 2 Build 2nd batch of said list"
}

case "${1}" in
aarch64|arm|i686|x86_64)
ARCH="${1}"
;;
*)
echo "ERROR: Invalid args: $*" 1>&2
usage
exit 1
;;
esac

STRATEGY=(50 50)
EXCLUDE_BIG_PACKAGES=false
BIG_PACKAGES_IN_SEPARATE_BATCH=false

case "${2}" in
golang)
readarray -t PACKAGES < <(grep -rl termux_setup_golang --include=build.sh --exclude-dir=golang "${TERMUX_PACKAGE_DIRECTORIES[@]}" | cut -d/ -f1,2 | sort -u | cut -d/ -f2 || :) || :
STRATEGY=(100)
EXCLUDE_BIG_PACKAGES=true
BIG_PACKAGES_IN_SEPARATE_BATCH=true
;;
*)
echo "ERROR: Invalid args: $*" 1>&2
usage
exit 1
;;
esac

SUM_PERCENT=0
for PERCENT in "${STRATEGY[@]}"; do
SUM_PERCENT=$((SUM_PERCENT+PERCENT))
done
if [[ "${SUM_PERCENT}" != 100 ]]; then
echo "ERROR: STRATEGY = $(echo "${STRATEGY[@]}" | tr " " "+") = ${SUM_PERCENT} != 100" 1>&2
exit 1
fi

split_build_job() {
local PACKAGE_RATIO=()
local CUM_PACKAGE_RATIO=()
local BATCHES=${#STRATEGY[@]}
local PREV_RATIO=0
local BATCH
for BATCH in $(seq 0 $((BATCHES-1))); do
PACKAGE_RATIO[BATCH]=$((STRATEGY[BATCH]*${#PACKAGES[@]}/100))
CUM_PACKAGE_RATIO[BATCH]=$((STRATEGY[BATCH]*${#PACKAGES[@]}/100+PREV_RATIO))
PREV_RATIO=${CUM_PACKAGE_RATIO[BATCH]}
done
local REMAINDER=$((${#PACKAGES[@]}-CUM_PACKAGE_RATIO[-1]))
if [[ "${REMAINDER}" != 0 ]]; then
PACKAGE_RATIO[-1]=$((PACKAGE_RATIO[-1]+REMAINDER))
CUM_PACKAGE_RATIO[-1]=${#PACKAGES[@]}
fi

unset BIG_PACKAGES
BIG_PACKAGES=()
local PACKAGE
for PACKAGE in "${PACKAGES[@]}"; do
while IFS= read -r PKG; do
if [[ "${PKG}" == "${PACKAGE}" ]]; then
BIG_PACKAGES+=("${PACKAGE}")
break
fi
done < scripts/big-pkgs.list
done

local PACKAGES1=()
local BATCH_NO=0
local OLD_MIDPOINT=0
for MIDPOINT in "${CUM_PACKAGE_RATIO[@]}"; do
local COUNT=0
for PACKAGE in "${PACKAGES[@]}"; do
COUNT=$((COUNT+1))
if [[ "${EXCLUDE_BIG_PACKAGES}" == "true" ]]; then
local PKG
local BIG_PACKAGE=false
while IFS= read -r PKG; do
if [[ "${PKG}" == "${PACKAGE}" ]]; then
BIG_PACKAGE=true
break
fi
done < <(echo "${BIG_PACKAGES[@]}" | tr " " "\n")
if [[ "${BIG_PACKAGE}" == true ]]; then
continue
fi
fi
if (( "${COUNT}" <= "${OLD_MIDPOINT}" )); then
continue
elif (( "${COUNT}" <= "${MIDPOINT}" )); then
PACKAGES1+=("${BATCH_NO}:${PACKAGE}")
else
break
fi
done
OLD_MIDPOINT=${MIDPOINT}
BATCH_NO=$((BATCH_NO+1))
done
local BATCH=0
local PACKAGE_NO=0
local NEW_PACKAGE_RATIO=()
for PACKAGE in "${PACKAGES1[@]}"; do
if [[ "${EXCLUDE_BIG_PACKAGES}" == "true" ]]; then
local PKG
local BIG_PACKAGE=false
while IFS= read -r PKG; do
if [[ "${PKG}" == "${PACKAGE%:*}" ]]; then
BIG_PACKAGE=true
break
fi
done < <(echo "${BIG_PACKAGES[@]}" | tr " " "\n")
if [[ "${BIG_PACKAGE}" == true ]]; then
continue
fi
fi
if [[ "${BATCH}" != "${PACKAGE%:*}" ]]; then
printf "\n"
BATCH=$((BATCH+1))
PACKAGE_NO=0
fi
if [[ "${PACKAGE_NO}" == 0 ]]; then
printf "%s" "${PACKAGE#*:}"
NEW_PACKAGE_RATIO[BATCH]=1
else
printf " %s" "${PACKAGE#*:}"
NEW_PACKAGE_RATIO[BATCH]=$((NEW_PACKAGE_RATIO[BATCH]+1))
fi
PACKAGE_NO=$((PACKAGE_NO+1))
done
if [[ "${BIG_PACKAGES_IN_SEPARATE_BATCH}" == "true" ]]; then
printf "\n%s" "$(echo "${BIG_PACKAGES[@]}" | tr "\n" " " | sed "s| $||")"
NEW_PACKAGE_RATIO+=("${#BIG_PACKAGES[@]}")
fi
printf "\n\n"
echo "Number of packages: ${#PACKAGES[@]}"
echo "Number of big packages: ${#BIG_PACKAGES[@]}"
echo "Batches (expected): ${#STRATEGY[@]}"
echo "Packages per batch (expected): ${PACKAGE_RATIO[*]}"
echo "Batches (actual): ${#NEW_PACKAGE_RATIO[*]}"
echo "Packages per batch (actual): ${NEW_PACKAGE_RATIO[*]}"
}

if [[ "${3}" == "list" ]]; then
split_build_job
exit
elif (( "${3}" )); then
readarray -t SPLIT_PACKAGES < <(split_build_job 2>/dev/null | head -n "${3}" | tail -n1 | tr " " "\n")
unset PACKAGES
PACKAGES=("${SPLIT_PACKAGES[@]}")
elif [[ -n "${3}" ]]; then
echo "ERROR: Invalid args: $*" 1>&2
usage
exit 1
fi

# Converts milliseconds to human-readable format.
# Example: `ms_to_human_readable 123456789` => 34h 17m 36s 789ms
ms_to_human_readable() {
echo "$(($1/3600000))h $(($1%3600000/60000))m $(($1%60000/1000))s $(($1%1000))ms" | sed 's/0h //;s/0m //;s/0s //'
}

maybe_cleanup() {
[[ -z "$CI" ]] && return
local PACKAGE="$1" CLEANUP_THRESHOLD=10 # GiB

if grep -Fxq "$PACKAGE" scripts/big-pkgs.list; then
echo "INFO: performing cleanup before building big package."
elif df "$HOME" | awk -v t="$CLEANUP_THRESHOLD" 'NR == 2 { exit ($4 / 1024^2 < t ? 0 : 1) }'; then
echo "INFO: Cleaning up, free disk space is below the threshold (${CLEANUP_THRESHOLD} GiB)."
else
return
fi

./clean.sh
rm -rf ./output/*
}

# This script aims to:
# 1. Obtain a list of all Golang packages.
# 2. Build them.
# 3. Create a CI summary containing only build logs of failed build attempts.

[[ -z "$CI" ]] && echo "INFO: Not running in CI environment, cleanup will not be performed."
echo "INFO: Rebuild list: ${PACKAGES[*]}" | tee "${GITHUB_STEP_SUMMARY}"

output=""
declare -A failed=()
start_building_arch="$(date +%10s%3N)"
for package in "${PACKAGES[@]}"; do
output="$(
start="$(date +%10s%3N)"
exec > >(tee /dev/fd/2) 2>&1 # output everything to both variable and stdout.

# Header
echo "INFO: Building ${package} for ${ARCH}"
maybe_cleanup "${package}"
./build-package.sh -I -f -a "${ARCH}" "${package}"
status="${PIPESTATUS[0]}"
echo # newline
echo "INFO: Building ${package} for ${ARCH} took $(ms_to_human_readable $(( $(date +%10s%3N) - start )))"
echo # newline
exit "$status"
)" || failed["${package} ${ARCH}"]="${output}"
done
echo "INFO: Building all packages for ${ARCH} took $(ms_to_human_readable $(( $(date +%10s%3N) - start_building_arch )))" | tee -a "${GITHUB_STEP_SUMMARY}"
echo # newline

if (( ${#failed[@]} > 0 )); then
echo "Writing output for failed packages to '$GITHUB_STEP_SUMMARY' to be logged in summary." >&2
echo "### The packages below failed to build for ${ARCH}." >> "$GITHUB_STEP_SUMMARY"
fi

for entry in "${!failed[@]}"; do
echo "${failed["${entry}"]}" >> "${GITHUB_STEP_SUMMARY}"
{
echo "<details><summary><code>${entry% *}</code></summary><p>"
echo ""
echo "${failed["${entry}"]}"
echo ""
echo "</p></details>"
} >> "$GITHUB_STEP_SUMMARY"
done

exit $(( ${#failed[@]} > 0 ))
Loading