Files
MSYS2-packages/ci-library.sh
Renato Silva 35e1904fdf CI: Support for package deployment.
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.
2016-03-17 15:12:59 -03:00

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[@]}"; }