chore: rework script build
This commit is contained in:
parent
81d0dd60f5
commit
ff196e37b8
3 changed files with 199 additions and 67 deletions
20
.util.sh
20
.util.sh
|
@ -1,12 +1,23 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
update_repo_tags() {
|
||||||
|
local repo
|
||||||
|
repo=$(grep -oPm 1 'github\.com\/\K(\w|-)+\/(\w|-)+' .SRCINFO)
|
||||||
|
[[ -n "${repo}" ]] && update_github_tag "${repo}"
|
||||||
|
|
||||||
|
repo=$(grep -oPm 1 'gitea\.com\/\K(\w|-)+\/(\w|-)+' .SRCINFO)
|
||||||
|
[[ -n "${repo}" ]] && update_gitea_tag "${repo}"
|
||||||
|
}
|
||||||
|
|
||||||
update_github_tag() {
|
update_github_tag() {
|
||||||
local ver=$(curl -Ls https://api.github.com/repos/"$1"/tags | jq -r '[.[] | select(.name | index("rc") | not) | select (.name | index("dev") | not) | select (.name | index("beta") | not)] | first | .name' | sed 's/^v//')
|
local ver
|
||||||
|
ver=$(curl -Ls https://api.github.com/repos/"$1"/tags | jq -r '[.[] | select(.name | index("rc") | not) | select (.name | index("dev") | not) | select (.name | index("beta") | not)] | first | .name' | sed 's/^v//')
|
||||||
echo "${ver}" | grep -Eq "^(\w|\+|\.)+$" && sed -i "s/pkgver=.*/pkgver=${ver}/" PKGBUILD
|
echo "${ver}" | grep -Eq "^(\w|\+|\.)+$" && sed -i "s/pkgver=.*/pkgver=${ver}/" PKGBUILD
|
||||||
}
|
}
|
||||||
|
|
||||||
update_gitea_tag() {
|
update_gitea_tag() {
|
||||||
local ver=$(curl -Ls https://gitea.com/api/v1/repos/"$1"/releases/latest | jq -r '.name' | sed 's/^v//')
|
local ver
|
||||||
|
ver=$(curl -Ls https://gitea.com/api/v1/repos/"$1"/releases/latest | jq -r '.name' | sed 's/^v//')
|
||||||
echo "${ver}" | grep -Eq "^(\w|\+|\.)+$" && sed -i "s/pkgver=.*/pkgver=${ver}/" PKGBUILD
|
echo "${ver}" | grep -Eq "^(\w|\+|\.)+$" && sed -i "s/pkgver=.*/pkgver=${ver}/" PKGBUILD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +28,10 @@ update_pkg() {
|
||||||
|
|
||||||
if updpkgsums; then
|
if updpkgsums; then
|
||||||
makepkg --printsrcinfo >.SRCINFO
|
makepkg --printsrcinfo >.SRCINFO
|
||||||
local ver=$(grep 'pkgver' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
local ver
|
||||||
|
ver=$(grep 'pkgver' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
||||||
git add .SRCINFO PKGBUILD
|
git add .SRCINFO PKGBUILD
|
||||||
if git commit -m "$(basename $(pwd)): update to ${ver} [CI SKIP]"; then
|
if git commit -m "$(basename "$(pwd)"): update to ${ver} [CI SKIP]"; then
|
||||||
git push --set-upstream origin "${CI_COMMIT_BRANCH}"
|
git push --set-upstream origin "${CI_COMMIT_BRANCH}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -24,7 +24,7 @@ steps:
|
||||||
- mkdir /build
|
- mkdir /build
|
||||||
- chown -R build:build . /build
|
- chown -R build:build . /build
|
||||||
- sudo -u build --preserve-env=PGP_KEY,PGP_PWD,PGP_ID sh -c 'mkdir ~/.gnupg && echo -e "default-cache-ttl 3600\nallow-preset-passphrase" > ~/.gnupg/gpg-agent.conf && echo "$PGP_KEY" | gpg --import --no-tty --batch --yes && echo "$PGP_PWD" | /usr/lib/gnupg/gpg-preset-passphrase --preset $PGP_ID'
|
- sudo -u build --preserve-env=PGP_KEY,PGP_PWD,PGP_ID sh -c 'mkdir ~/.gnupg && echo -e "default-cache-ttl 3600\nallow-preset-passphrase" > ~/.gnupg/gpg-agent.conf && echo "$PGP_KEY" | gpg --import --no-tty --batch --yes && echo "$PGP_PWD" | /usr/lib/gnupg/gpg-preset-passphrase --preset $PGP_ID'
|
||||||
- sudo -u build --preserve-env=CI_REPO_CLONE_URL,CI_COMMIT_BRANCH,CI_PREV_COMMIT_SHA,GIT_USER,GIT_TOKEN sh -c './build.sh'
|
- sudo -u build --preserve-env=CI_REPO_CLONE_URL,CI_COMMIT_BRANCH,CI_PREV_COMMIT_SHA,GIT_USER,GIT_TOKEN,BUILD_DIR,REPO_DIR,GIT_USER_NAME,GIT_USER_EMAIL sh -c './build.sh'
|
||||||
environment:
|
environment:
|
||||||
PGP_ID:
|
PGP_ID:
|
||||||
from_secret: pgp_id
|
from_secret: pgp_id
|
||||||
|
@ -36,6 +36,10 @@ steps:
|
||||||
from_secret: git_user
|
from_secret: git_user
|
||||||
GIT_TOKEN:
|
GIT_TOKEN:
|
||||||
from_secret: git_token
|
from_secret: git_token
|
||||||
|
BUILD_DIR: /build
|
||||||
|
REPO_DIR: /repo
|
||||||
|
GIT_USER_NAME: drone
|
||||||
|
GIT_USER_EMAIL: drone@nyyu.dev
|
||||||
when:
|
when:
|
||||||
branch: master
|
branch: master
|
||||||
event: [ push, cron, tag, manual ]
|
event: [ push, cron, tag, manual ]
|
||||||
|
|
234
build.sh
234
build.sh
|
@ -1,93 +1,209 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# shellcheck disable=SC3044,SC3009,SC2312
|
|
||||||
|
set -euo pipefail
|
||||||
|
trap 'echo "Error on line $LINENO"' ERR
|
||||||
|
|
||||||
. .util.sh
|
. .util.sh
|
||||||
export BUILDDIR=/build
|
|
||||||
|
# Constants
|
||||||
|
readonly REQUIRED_ENV_VARS=(BUILD_DIR REPO_DIR GIT_USER_EMAIL GIT_USER_NAME CI_REPO_CLONE_URL GIT_USER GIT_TOKEN)
|
||||||
|
|
||||||
|
log() {
|
||||||
|
local level=$1
|
||||||
|
shift
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_env_vars() {
|
||||||
|
local missing_vars=()
|
||||||
|
for var in "${REQUIRED_ENV_VARS[@]}"; do
|
||||||
|
if [[ -z "${!var:-}" ]]; then
|
||||||
|
missing_vars+=("$var")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#missing_vars[@]} -gt 0 ]]; then
|
||||||
|
log "ERROR" "Missing required environment variables: ${missing_vars[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_build_dir() {
|
||||||
|
if [[ -d "${BUILD_DIR}" ]]; then
|
||||||
|
log "INFO" "Cleaning build directory"
|
||||||
|
rm -rf "${BUILD_DIR:?}"/*
|
||||||
|
else
|
||||||
|
log "INFO" "Creating build directory"
|
||||||
|
mkdir -p "${BUILD_DIR}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
local upd=$1
|
local upd=${1:-false}
|
||||||
|
local retries=3
|
||||||
|
cleanup_build_dir
|
||||||
|
|
||||||
rm -rf /build/*
|
if grep -q 'git+' PKGBUILD && ! grep -q '#tag=' PKGBUILD; then
|
||||||
|
if ! makepkg --noprepare --nodeps --nobuild --skippgpcheck --noconfirm; then
|
||||||
if grep -c 'git+' PKGBUILD >/dev/null && ! grep -c '#tag=' PKGBUILD >/dev/null; then
|
log "ERROR" "makepkg failed during preparation"
|
||||||
makepkg --noprepare --nodeps --nobuild --skippgpcheck --noconfirm
|
return 1
|
||||||
|
fi
|
||||||
makepkg --printsrcinfo >.SRCINFO
|
makepkg --printsrcinfo >.SRCINFO
|
||||||
if [[ "${upd}" = true ]]; then
|
[[ "${upd}" == true ]] && update_pkg
|
||||||
update_pkg
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local name ver rel epoch
|
||||||
name=$(grep -m1 'pkgname' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
name=$(grep -m1 'pkgname' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
||||||
ver=$(grep -m1 'pkgver' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
ver=$(grep -m1 'pkgver' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
||||||
rel=$(grep -m1 'pkgrel' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
rel=$(grep -m1 'pkgrel' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
||||||
epoch=$(grep -m1 'epoch' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
epoch=$(grep -m1 'epoch' .SRCINFO | cut -d'=' -f2 | tr -d ' ')
|
||||||
if [[ -n "${epoch}" ]]; then
|
[[ -n "${epoch}" ]] && epoch=${epoch}:
|
||||||
epoch=${epoch}:
|
|
||||||
|
# Check if package exists in official repos
|
||||||
|
if pacman -Si "${name}" 2>/dev/null | grep -v nyyu | grep -q -E '^Repository'; then
|
||||||
|
log "WARN" "Found ${name} in arch repo"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if pacman -Si "${name}" 2>/dev/null | grep -v nyyu | grep -c -E '^Repository' &>/dev/null; then
|
# Build package if it doesn't exist or needs updating
|
||||||
echo "WARN: Found ${name} in arch repo"
|
if ! compgen -G "${REPO_DIR}/${name}-${epoch}${ver}-${rel}-*.pkg.tar.zst" >/dev/null; then
|
||||||
fi
|
log "INFO" "Building package ${name}-${epoch}${ver}-${rel}"
|
||||||
|
|
||||||
if ! compgen -G "/repo/${name}-${epoch}${ver}-${rel}-*.pkg.tar.zst" >/dev/null; then
|
while ((retries > 0)); do
|
||||||
echo "Building package ${name}-${epoch}${ver}-${rel}"
|
if makepkg --nodeps --skippgpcheck --noconfirm --sign || \
|
||||||
if makepkg --nodeps --skippgpcheck --noconfirm --sign || makepkg -C -s --skippgpcheck --noconfirm --sign || makepkg -C -s --skippgpcheck --nocheck --noconfirm --sign; then
|
makepkg -C -s --skippgpcheck --noconfirm --sign || \
|
||||||
|
makepkg -C -s --skippgpcheck --nocheck --noconfirm --sign; then
|
||||||
|
|
||||||
|
# Copy and add to repo
|
||||||
for pkg in *.pkg.tar.zst; do
|
for pkg in *.pkg.tar.zst; do
|
||||||
cp "${pkg}"{,.sig} /repo/
|
if [[ -f "${pkg}" ]]; then
|
||||||
repo-add -R -s /repo/nyyu.db.tar.zst /repo/"${pkg}"
|
cp "${pkg}"{,.sig} "${REPO_DIR}/"
|
||||||
done
|
repo-add -R -s "${REPO_DIR}/nyyu.db.tar.zst" "${REPO_DIR}/${pkg}"
|
||||||
sudo pacman -Syu --noconfirm
|
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! sudo pacman -Syu --noconfirm; then
|
||||||
|
log "WARN" "Failed to update system packages"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
((retries--))
|
||||||
|
log "WARN" "Build failed, $retries retries remaining"
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
log "ERROR" "Failed to build package ${name}-${epoch}${ver}-${rel} after all retries"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
git config --global user.email "drone@nyyu.dev"
|
process_directory() {
|
||||||
git config --global user.name "drone"
|
local dir=$1
|
||||||
git config --global init.defaultBranch master
|
cd "${dir}" || { log "ERROR" "Failed to enter directory ${dir}"; return 1; }
|
||||||
git remote set-url origin "${CI_REPO_CLONE_URL}"
|
|
||||||
# shellcheck disable=SC2016
|
|
||||||
git config credential.helper '!f() { sleep 1; echo "username=${GIT_USER}"; echo "password=${GIT_TOKEN}"; }; f'
|
|
||||||
|
|
||||||
for d in */; do
|
|
||||||
cd "${d}" || continue
|
|
||||||
if [[ -f PKGBUILD ]]; then
|
if [[ -f PKGBUILD ]]; then
|
||||||
echo "--> ${d}"
|
log "INFO" "Processing ${dir}"
|
||||||
if [[ -f update.sh ]]; then
|
if [[ -f update.sh ]]; then
|
||||||
|
chmod +x update.sh
|
||||||
./update.sh
|
./update.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -c 'pkgver()' PKGBUILD >/dev/null; then
|
if ! grep -q 'pkgver()' PKGBUILD; then
|
||||||
repo=$(grep -oPm 1 'github\.com\/\K(\w|-)+\/(\w|-)+' .SRCINFO)
|
update_repo_tags
|
||||||
if [[ -n "${repo}" ]]; then
|
|
||||||
update_github_tag "${repo}"
|
|
||||||
fi
|
|
||||||
repo=$(grep -oPm 1 'gitea\.com\/\K(\w|-)+\/(\w|-)+' .SRCINFO)
|
|
||||||
if [[ -n "${repo}" ]]; then
|
|
||||||
update_gitea_tag "${repo}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
update_pkg
|
update_pkg
|
||||||
build true
|
build true
|
||||||
fi
|
fi
|
||||||
cd ..
|
cd ..
|
||||||
done
|
}
|
||||||
|
|
||||||
while read -r p; do
|
process_directories() {
|
||||||
git clone https://aur.archlinux.org/"${p}".git --depth 1 || echo "ERR: Package ${p} not found in AUR"
|
local exit_status=0
|
||||||
cd "${p}" || continue
|
local dirs=("$@")
|
||||||
build false
|
|
||||||
cd ..
|
|
||||||
done <aur.txt
|
|
||||||
|
|
||||||
LAST_COMMIT=$(git --no-pager log --oneline | grep -v 'CI SKIP' | cut -d' ' -f1 | sed -n '5p')
|
for dir in "${dirs[@]}"; do
|
||||||
LAST_COMMIT=${CI_PREV_COMMIT_SHA:-$LAST_COMMIT}
|
if ! process_directory "$dir"; then
|
||||||
echo "Finding removed packages from ${LAST_COMMIT}"
|
log "ERROR" "Failed to process directory ${dir}"
|
||||||
del=$(git --no-pager diff "${LAST_COMMIT}"..HEAD aur.txt | tail -n +4 | grep -E '^-' | cut -c2-)
|
exit_status=1
|
||||||
del+=" "
|
fi
|
||||||
del+=$(git --no-pager diff --name-status "${LAST_COMMIT}"..HEAD | grep -Po 'D\s+(\K.*)(?=/PKGBUILD)')
|
|
||||||
if [[ -n "${del}" ]]; then
|
|
||||||
for pkg in "${del[@]}"; do
|
|
||||||
echo "Removing packages ${pkg}"
|
|
||||||
repo-remove -s /repo/nyyu.db.tar.zst "${pkg}" || true
|
|
||||||
rm -vf /repo/"${pkg}"*
|
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
|
return $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
find_and_remove_deleted_packages() {
|
||||||
|
local last_commit del=()
|
||||||
|
|
||||||
|
if git cat-file -e "${CI_PREV_COMMIT_SHA:-}" 2>/dev/null; then
|
||||||
|
last_commit=${CI_PREV_COMMIT_SHA}
|
||||||
|
else
|
||||||
|
last_commit=$(git --no-pager log --oneline | grep -v 'CI SKIP' | cut -d' ' -f1 | sed -n '5p') || {
|
||||||
|
log "ERROR" "Failed to determine last commit"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Finding removed packages from ${last_commit}"
|
||||||
|
|
||||||
|
mapfile -t del < <(
|
||||||
|
{
|
||||||
|
git --no-pager diff "${last_commit}"..HEAD aur.txt | tail -n +4 | grep -E '^-' | cut -c2-
|
||||||
|
git --no-pager diff --name-status "${last_commit}"..HEAD | grep -Po 'D\s+(\K.*)(?=/PKGBUILD)'
|
||||||
|
} | sort -u
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ ${#del[@]} -gt 0 ]]; then
|
||||||
|
for pkg in "${del[@]}"; do
|
||||||
|
log "INFO" "Removing package ${pkg}"
|
||||||
|
if ! repo-remove -s "${REPO_DIR}/nyyu.db.tar.zst" "${pkg}"; then
|
||||||
|
log "WARN" "Failed to remove ${pkg} from repo"
|
||||||
|
fi
|
||||||
|
if ! rm -vf "${REPO_DIR}/${pkg}"*; then
|
||||||
|
log "WARN" "No files found for ${pkg} in ${REPO_DIR}/"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
log "INFO" "No packages to remove"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_git() {
|
||||||
|
git config --global user.email "${GIT_USER_EMAIL}"
|
||||||
|
git config --global user.name "${GIT_USER_NAME}"
|
||||||
|
git config --global init.defaultBranch master
|
||||||
|
git remote set-url origin "${CI_REPO_CLONE_URL}"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
git config credential.helper '!f() { sleep 1; echo "username=${GIT_USER}"; echo "password=${GIT_TOKEN}"; }; f'
|
||||||
|
}
|
||||||
|
|
||||||
|
process_aur_packages() {
|
||||||
|
if [[ ! -f aur.txt ]]; then
|
||||||
|
log "ERROR" "aur.txt not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r pkg; do
|
||||||
|
[[ -z "$pkg" ]] && continue
|
||||||
|
|
||||||
|
if ! git clone https://aur.archlinux.org/"${pkg}".git --depth 1; then
|
||||||
|
log "ERROR" "Failed to clone repository for package ${pkg}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
(cd "${pkg}" && build false) || log "ERROR" "Failed to build ${pkg}"
|
||||||
|
done < aur.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
validate_env_vars
|
||||||
|
setup_git
|
||||||
|
|
||||||
|
# Process local directories sequentially
|
||||||
|
mapfile -t dirs < <(find . -maxdepth 1 -type d ! -name ".*" -printf "%f\n")
|
||||||
|
process_directories "${dirs[@]}" || log "WARN" "Some directory processing failed"
|
||||||
|
|
||||||
|
process_aur_packages
|
||||||
|
find_and_remove_deleted_packages
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue