A pacman repository is now generated with built packages, and exported by AppVeyor to Bintray. Similar export can now be implemented for Drone, and services other than Bintray can also be used.
160 lines
5.1 KiB
Bash
160 lines
5.1 KiB
Bash
#!/bin/bash
|
|
|
|
# Continuous Integration Library for MSYS2
|
|
# Author: Renato Silva <br.renatosilva@gmail.com>
|
|
# Author: Qian Hong <fracting@gmail.com>
|
|
|
|
# Enable colors
|
|
if [[ -t 1 ]]; then
|
|
normal='\e[0m'
|
|
red='\e[1;31m'
|
|
green='\e[1;32m'
|
|
cyan='\e[1;36m'
|
|
fi
|
|
|
|
# Basic status function
|
|
_status() {
|
|
local type="${1}"
|
|
local status="${package:+${package}: }${2}"
|
|
local items=("${@:3}")
|
|
case "${type}" in
|
|
failure) local -n nameref_color='red'; title='[MSYS2 CI] FAILURE:' ;;
|
|
success) local -n nameref_color='green'; title='[MSYS2 CI] SUCCESS:' ;;
|
|
message) local -n nameref_color='cyan'; title='[MSYS2 CI]'
|
|
esac
|
|
printf "\n${nameref_color}${title}${normal} ${status}\n\n"
|
|
printf "${items:+\t%s\n}" "${items:+${items[@]}}"
|
|
}
|
|
|
|
# Convert lines to array
|
|
_as_list() {
|
|
local -n nameref_list="${1}"
|
|
local filter="${2}"
|
|
local strip="${3}"
|
|
local lines="${4}"
|
|
local result=1
|
|
while IFS= read -r line; do
|
|
test -z "${line}" && continue
|
|
result=0
|
|
[[ "${line}" = ${filter} ]] && nameref_list+=("${line/${strip}/}")
|
|
done <<< "${lines}"
|
|
return "${result}"
|
|
}
|
|
|
|
# Changes since master or from head
|
|
_list_changes() {
|
|
local list_name="${1}"
|
|
local filter="${2}"
|
|
local strip="${3}"
|
|
local git_options=("${@:4}")
|
|
_as_list "${list_name}" "${filter}" "${strip}" "$(git log "${git_options[@]}" upstream/master.. | sort -u)" ||
|
|
_as_list "${list_name}" "${filter}" "${strip}" "$(git log "${git_options[@]}" HEAD^.. | sort -u)"
|
|
}
|
|
|
|
# Get package information
|
|
_package_info() {
|
|
local package="${1}"
|
|
local properties=("${@:2}")
|
|
for property in "${properties[@]}"; do
|
|
local -n nameref_property="${property}"
|
|
nameref_property=($(
|
|
source "${package}/PKGBUILD"
|
|
declare -n nameref_property="${property}"
|
|
echo "${nameref_property[@]}"))
|
|
done
|
|
}
|
|
|
|
# Package provides another
|
|
_package_provides() {
|
|
local package="${1}"
|
|
local another="${2}"
|
|
local pkgname provides
|
|
_package_info "${package}" pkgname provides
|
|
for pkg_name in "${pkgname[@]}"; do [[ "${pkg_name}" = "${another}" ]] && return 0; done
|
|
for provided in "${provides[@]}"; do [[ "${provided}" = "${another}" ]] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
# Add package to build after required dependencies
|
|
_build_add() {
|
|
local package="${1}"
|
|
local depends makedepends
|
|
for sorted_package in "${sorted_packages[@]}"; do
|
|
[[ "${sorted_package}" = "${package}" ]] && return 0
|
|
done
|
|
_package_info "${package}" depends makedepends
|
|
for dependency in "${depends[@]}" "${makedepends[@]}"; do
|
|
for unsorted_package in "${packages[@]}"; do
|
|
_package_provides "${unsorted_package}" "${dependency}" && _build_add "${unsorted_package}"
|
|
done
|
|
done
|
|
sorted_packages+=("${package}")
|
|
}
|
|
|
|
# Git configuration
|
|
git_config() {
|
|
local name="${1}"
|
|
local value="${2}"
|
|
test -n "$(git config ${name})" && return 0
|
|
git config --global "${name}" "${value}" && return 0
|
|
failure 'Could not configure Git for makepkg'
|
|
}
|
|
|
|
# Run command with status
|
|
execute(){
|
|
local status="${1}"
|
|
local command=("${@:2}")
|
|
cd "${package:-.}"
|
|
message "${status}"
|
|
${command[@]} || failure "${status} failed"
|
|
cd - > /dev/null
|
|
}
|
|
|
|
# Sort packages by dependency
|
|
define_build_order() {
|
|
local sorted_packages=()
|
|
for unsorted_package in "${packages[@]}"; do
|
|
_build_add "${unsorted_package}"
|
|
done
|
|
packages=("${sorted_packages[@]}")
|
|
}
|
|
|
|
# Associate artifacts with this build
|
|
create_build_references() {
|
|
local repository_name="${1}"
|
|
local repository_url="${2}"
|
|
local references="${repository_name}.builds"
|
|
test -n "${repository_url}" && wget --no-verbose "${repository_url}/${references}" || touch "${references}"
|
|
for file in *; do
|
|
sed -i "/^${file}.*/d" "${references}"
|
|
printf '%-80s%s\n' "${file}" "${BUILD_URL}" >> "${references}"
|
|
done
|
|
sort "${references}" | tee "${references}.sorted" | sed -r 's/(\S+)\s.*\/([^/]+)/\2\t\1/'
|
|
mv "${references}.sorted" "${references}"
|
|
}
|
|
|
|
# Add packages to repository
|
|
create_pacman_repository() {
|
|
local name="${1}"
|
|
local url="${2}"
|
|
test -n "${url}" && wget --no-verbose "${url}/${name}".{db,files}{,.tar.xz} || rm -f "${name}".{db,files}{,.tar.xz}
|
|
repo-add "${name}.db.tar.xz" *.pkg.tar.xz
|
|
}
|
|
|
|
# Deployment is enabled
|
|
deploy_enabled() {
|
|
test -n "${BUILD_URL}" || return 1
|
|
test -n "${DEPLOY_ACCOUNT}" || return 1
|
|
local repository_account="$(git remote get-url origin | cut -d/ -f4)"
|
|
[[ "${repository_account}" = "${DEPLOY_ACCOUNT}" ]]
|
|
}
|
|
|
|
# Added commits or changed recipes
|
|
list_commits() { _list_changes commits '*' '#*::' --pretty=format:'%ai::[%h] %s'; }
|
|
list_packages() { _list_changes packages '*/PKGBUILD' '%/PKGBUILD' --pretty=format: --name-only; }
|
|
|
|
# Status functions
|
|
failure() { local status="${1}"; local items=("${@:2}"); _status failure "${status}." "${items[@]}"; exit 1; }
|
|
success() { local status="${1}"; local items=("${@:2}"); _status success "${status}." "${items[@]}"; exit 0; }
|
|
message() { local status="${1}"; local items=("${@:2}"); _status message "${status}" "${items[@]}"; }
|