mirror of
https://github.com/git/git.git
synced 2024-10-28 04:49:43 +01:00
Merge branch 'js/ci-discard-prove-state' into maint-2.43
The way CI testing used "prove" could lead to running the test suite twice needlessly, which has been corrected. * js/ci-discard-prove-state: ci: avoid running the test suite _twice_ ci: add support for GitLab CI ci: install test dependencies for linux-musl ci: squelch warnings when testing with unusable Git repo ci: unify setup of some environment variables ci: split out logic to set up failed test artifacts ci: group installation of Docker dependencies ci: make grouping setup more generic ci: reorder definitions for grouping functions
This commit is contained in:
commit
c8bcf66bf7
5 changed files with 237 additions and 58 deletions
53
.gitlab-ci.yml
Normal file
53
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,53 @@
|
|||
default:
|
||||
timeout: 2h
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_COMMIT_REF_PROTECTED == "true"
|
||||
|
||||
test:
|
||||
image: $image
|
||||
before_script:
|
||||
- ./ci/install-docker-dependencies.sh
|
||||
script:
|
||||
- useradd builder --create-home
|
||||
- chown -R builder "${CI_PROJECT_DIR}"
|
||||
- sudo --preserve-env --set-home --user=builder ./ci/run-build-and-tests.sh
|
||||
after_script:
|
||||
- |
|
||||
if test "$CI_JOB_STATUS" != 'success'
|
||||
then
|
||||
sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh
|
||||
fi
|
||||
parallel:
|
||||
matrix:
|
||||
- jobname: linux-sha256
|
||||
image: ubuntu:latest
|
||||
CC: clang
|
||||
- jobname: linux-gcc
|
||||
image: ubuntu:20.04
|
||||
CC: gcc
|
||||
CC_PACKAGE: gcc-8
|
||||
- jobname: linux-TEST-vars
|
||||
image: ubuntu:20.04
|
||||
CC: gcc
|
||||
CC_PACKAGE: gcc-8
|
||||
- jobname: linux-gcc-default
|
||||
image: ubuntu:latest
|
||||
CC: gcc
|
||||
- jobname: linux-leaks
|
||||
image: ubuntu:latest
|
||||
CC: gcc
|
||||
- jobname: linux-asan-ubsan
|
||||
image: ubuntu:latest
|
||||
CC: clang
|
||||
- jobname: pedantic
|
||||
image: fedora:latest
|
||||
- jobname: linux-musl
|
||||
image: alpine:latest
|
||||
artifacts:
|
||||
paths:
|
||||
- t/failed-test-artifacts
|
||||
when: on_failure
|
|
@ -3,6 +3,10 @@
|
|||
# Install dependencies required to build and test Git inside container
|
||||
#
|
||||
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
begin_group "Install dependencies"
|
||||
|
||||
case "$jobname" in
|
||||
linux32)
|
||||
linux32 --32bit i386 sh -c '
|
||||
|
@ -12,11 +16,26 @@ linux32)
|
|||
'
|
||||
;;
|
||||
linux-musl)
|
||||
apk add --update build-base curl-dev openssl-dev expat-dev gettext \
|
||||
pcre2-dev python3 musl-libintl perl-utils ncurses >/dev/null
|
||||
apk add --update shadow sudo build-base curl-dev openssl-dev expat-dev gettext \
|
||||
pcre2-dev python3 musl-libintl perl-utils ncurses \
|
||||
apache2 apache2-http2 apache2-proxy apache2-ssl apache2-webdav apr-util-dbd_sqlite3 \
|
||||
bash cvs gnupg perl-cgi perl-dbd-sqlite >/dev/null
|
||||
;;
|
||||
linux-*)
|
||||
# Required so that apt doesn't wait for user input on certain packages.
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
apt update -q &&
|
||||
apt install -q -y sudo git make language-pack-is libsvn-perl apache2 libssl-dev \
|
||||
libcurl4-openssl-dev libexpat-dev tcl tk gettext zlib1g-dev \
|
||||
perl-modules liberror-perl libauthen-sasl-perl libemail-valid-perl \
|
||||
libdbd-sqlite3-perl libio-socket-ssl-perl libnet-smtp-ssl-perl ${CC_PACKAGE:-${CC:-gcc}} \
|
||||
apache2 cvs cvsps gnupg libcgi-pm-perl subversion
|
||||
;;
|
||||
pedantic)
|
||||
dnf -yq update >/dev/null &&
|
||||
dnf -yq install make gcc findutils diffutils perl python3 gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
end_group "Install dependencies"
|
||||
|
|
196
ci/lib.sh
196
ci/lib.sh
|
@ -1,16 +1,7 @@
|
|||
# Library of functions shared by all CI scripts
|
||||
|
||||
if test true != "$GITHUB_ACTIONS"
|
||||
if test true = "$GITHUB_ACTIONS"
|
||||
then
|
||||
begin_group () { :; }
|
||||
end_group () { :; }
|
||||
|
||||
group () {
|
||||
shift
|
||||
"$@"
|
||||
}
|
||||
set -x
|
||||
else
|
||||
begin_group () {
|
||||
need_to_end_group=t
|
||||
echo "::group::$1" >&2
|
||||
|
@ -23,27 +14,50 @@ else
|
|||
need_to_end_group=
|
||||
echo '::endgroup::' >&2
|
||||
}
|
||||
trap end_group EXIT
|
||||
|
||||
group () {
|
||||
set +x
|
||||
begin_group "$1"
|
||||
shift
|
||||
# work around `dash` not supporting `set -o pipefail`
|
||||
(
|
||||
"$@" 2>&1
|
||||
echo $? >exit.status
|
||||
) |
|
||||
sed 's/^\(\([^ ]*\):\([0-9]*\):\([0-9]*:\) \)\(error\|warning\): /::\5 file=\2,line=\3::\1/'
|
||||
res=$(cat exit.status)
|
||||
rm exit.status
|
||||
end_group
|
||||
return $res
|
||||
elif test true = "$GITLAB_CI"
|
||||
then
|
||||
begin_group () {
|
||||
need_to_end_group=t
|
||||
printf "\e[0Ksection_start:$(date +%s):$(echo "$1" | tr ' ' _)\r\e[0K$1\n"
|
||||
trap "end_group '$1'" EXIT
|
||||
set -x
|
||||
}
|
||||
|
||||
begin_group "CI setup"
|
||||
end_group () {
|
||||
test -n "$need_to_end_group" || return 0
|
||||
set +x
|
||||
need_to_end_group=
|
||||
printf "\e[0Ksection_end:$(date +%s):$(echo "$1" | tr ' ' _)\r\e[0K\n"
|
||||
trap - EXIT
|
||||
}
|
||||
else
|
||||
begin_group () { :; }
|
||||
end_group () { :; }
|
||||
|
||||
set -x
|
||||
fi
|
||||
|
||||
group () {
|
||||
group="$1"
|
||||
shift
|
||||
begin_group "$group"
|
||||
|
||||
# work around `dash` not supporting `set -o pipefail`
|
||||
(
|
||||
"$@" 2>&1
|
||||
echo $? >exit.status
|
||||
) |
|
||||
sed 's/^\(\([^ ]*\):\([0-9]*\):\([0-9]*:\) \)\(error\|warning\): /::\5 file=\2,line=\3::\1/'
|
||||
res=$(cat exit.status)
|
||||
rm exit.status
|
||||
|
||||
end_group "$group"
|
||||
return $res
|
||||
}
|
||||
|
||||
begin_group "CI setup"
|
||||
trap "end_group 'CI setup'" EXIT
|
||||
|
||||
# Set 'exit on error' for all CI scripts to let the caller know that
|
||||
# something went wrong.
|
||||
#
|
||||
|
@ -71,10 +85,32 @@ skip_branch_tip_with_tag () {
|
|||
fi
|
||||
}
|
||||
|
||||
# Check whether we can use the path passed via the first argument as Git
|
||||
# repository.
|
||||
is_usable_git_repository () {
|
||||
# We require Git in our PATH, otherwise we cannot access repositories
|
||||
# at all.
|
||||
if ! command -v git >/dev/null
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# And the target directory needs to be a proper Git repository.
|
||||
if ! git -C "$1" rev-parse 2>/dev/null
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Save some info about the current commit's tree, so we can skip the build
|
||||
# job if we encounter the same tree again and can provide a useful info
|
||||
# message.
|
||||
save_good_tree () {
|
||||
if ! is_usable_git_repository .
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$(git rev-parse $CI_COMMIT^{tree}) $CI_COMMIT $CI_JOB_NUMBER $CI_JOB_ID" >>"$good_trees_file"
|
||||
# limit the file size
|
||||
tail -1000 "$good_trees_file" >"$good_trees_file".tmp
|
||||
|
@ -90,6 +126,11 @@ skip_good_tree () {
|
|||
return
|
||||
fi
|
||||
|
||||
if ! is_usable_git_repository .
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
if ! good_tree_info="$(grep "^$(git rev-parse $CI_COMMIT^{tree}) " "$good_trees_file")"
|
||||
then
|
||||
# Haven't seen this tree yet, or no cached good trees file yet.
|
||||
|
@ -121,6 +162,11 @@ skip_good_tree () {
|
|||
}
|
||||
|
||||
check_unignored_build_artifacts () {
|
||||
if ! is_usable_git_repository .
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
! git ls-files --other --exclude-standard --error-unmatch \
|
||||
-- ':/*' 2>/dev/null ||
|
||||
{
|
||||
|
@ -133,6 +179,26 @@ handle_failed_tests () {
|
|||
return 1
|
||||
}
|
||||
|
||||
create_failed_test_artifacts () {
|
||||
mkdir -p t/failed-test-artifacts
|
||||
|
||||
for test_exit in t/test-results/*.exit
|
||||
do
|
||||
test 0 != "$(cat "$test_exit")" || continue
|
||||
|
||||
test_name="${test_exit%.exit}"
|
||||
test_name="${test_name##*/}"
|
||||
printf "\\e[33m\\e[1m=== Failed test: ${test_name} ===\\e[m\\n"
|
||||
echo "The full logs are in the 'print test failures' step below."
|
||||
echo "See also the 'failed-tests-*' artifacts attached to this run."
|
||||
cat "t/test-results/$test_name.markup"
|
||||
|
||||
trash_dir="t/trash directory.$test_name"
|
||||
cp "t/test-results/$test_name.out" t/failed-test-artifacts/
|
||||
tar czf t/failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
|
||||
done
|
||||
}
|
||||
|
||||
# GitHub Action doesn't set TERM, which is required by tput
|
||||
export TERM=${TERM:-dumb}
|
||||
|
||||
|
@ -156,11 +222,8 @@ then
|
|||
# among *all* phases)
|
||||
cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME"
|
||||
|
||||
export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save"
|
||||
export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml"
|
||||
MAKEFLAGS="$MAKEFLAGS --jobs=10"
|
||||
test windows_nt != "$CI_OS_NAME" ||
|
||||
GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS"
|
||||
GIT_TEST_OPTS="--write-junit-xml"
|
||||
JOBS=10
|
||||
elif test true = "$GITHUB_ACTIONS"
|
||||
then
|
||||
CI_TYPE=github-actions
|
||||
|
@ -173,40 +236,63 @@ then
|
|||
CC="${CC_PACKAGE:-${CC:-gcc}}"
|
||||
DONT_SKIP_TAGS=t
|
||||
handle_failed_tests () {
|
||||
mkdir -p t/failed-test-artifacts
|
||||
echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV
|
||||
|
||||
for test_exit in t/test-results/*.exit
|
||||
do
|
||||
test 0 != "$(cat "$test_exit")" || continue
|
||||
|
||||
test_name="${test_exit%.exit}"
|
||||
test_name="${test_name##*/}"
|
||||
printf "\\e[33m\\e[1m=== Failed test: ${test_name} ===\\e[m\\n"
|
||||
echo "The full logs are in the 'print test failures' step below."
|
||||
echo "See also the 'failed-tests-*' artifacts attached to this run."
|
||||
cat "t/test-results/$test_name.markup"
|
||||
|
||||
trash_dir="t/trash directory.$test_name"
|
||||
cp "t/test-results/$test_name.out" t/failed-test-artifacts/
|
||||
tar czf t/failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
|
||||
done
|
||||
create_failed_test_artifacts
|
||||
return 1
|
||||
}
|
||||
|
||||
cache_dir="$HOME/none"
|
||||
|
||||
export GIT_PROVE_OPTS="--timer --jobs 10"
|
||||
export GIT_TEST_OPTS="--verbose-log -x --github-workflow-markup"
|
||||
MAKEFLAGS="$MAKEFLAGS --jobs=10"
|
||||
test windows != "$CI_OS_NAME" ||
|
||||
GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS"
|
||||
GIT_TEST_OPTS="--github-workflow-markup"
|
||||
JOBS=10
|
||||
elif test true = "$GITLAB_CI"
|
||||
then
|
||||
CI_TYPE=gitlab-ci
|
||||
CI_BRANCH="$CI_COMMIT_REF_NAME"
|
||||
CI_COMMIT="$CI_COMMIT_SHA"
|
||||
case "$CI_JOB_IMAGE" in
|
||||
macos-*)
|
||||
CI_OS_NAME=osx;;
|
||||
alpine:*|fedora:*|ubuntu:*)
|
||||
CI_OS_NAME=linux;;
|
||||
*)
|
||||
echo "Could not identify OS image" >&2
|
||||
env >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
CI_REPO_SLUG="$CI_PROJECT_PATH"
|
||||
CI_JOB_ID="$CI_JOB_ID"
|
||||
CC="${CC_PACKAGE:-${CC:-gcc}}"
|
||||
DONT_SKIP_TAGS=t
|
||||
handle_failed_tests () {
|
||||
create_failed_test_artifacts
|
||||
return 1
|
||||
}
|
||||
|
||||
cache_dir="$HOME/none"
|
||||
|
||||
runs_on_pool=$(echo "$CI_JOB_IMAGE" | tr : -)
|
||||
JOBS=$(nproc)
|
||||
else
|
||||
echo "Could not identify CI type" >&2
|
||||
env >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MAKEFLAGS="$MAKEFLAGS --jobs=$JOBS"
|
||||
GIT_PROVE_OPTS="--timer --jobs $JOBS"
|
||||
|
||||
GIT_TEST_OPTS="$GIT_TEST_OPTS --verbose-log -x"
|
||||
case "$CI_OS_NAME" in
|
||||
windows|windows_nt)
|
||||
GIT_TEST_OPTS="$GIT_TEST_OPTS --no-chain-lint --no-bin-wrappers"
|
||||
;;
|
||||
esac
|
||||
|
||||
export GIT_TEST_OPTS
|
||||
export GIT_PROVE_OPTS
|
||||
|
||||
good_trees_file="$cache_dir/good-trees"
|
||||
|
||||
mkdir -p "$cache_dir"
|
||||
|
@ -285,5 +371,5 @@ esac
|
|||
|
||||
MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}"
|
||||
|
||||
end_group
|
||||
end_group "CI setup"
|
||||
set -x
|
||||
|
|
|
@ -51,6 +51,12 @@ do
|
|||
tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
|
||||
continue
|
||||
;;
|
||||
gitlab-ci)
|
||||
mkdir -p failed-test-artifacts
|
||||
cp "${TEST_EXIT%.exit}.out" failed-test-artifacts/
|
||||
tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir"
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
echo "Unhandled CI type: $CI_TYPE" >&2
|
||||
exit 1
|
||||
|
|
|
@ -67,7 +67,8 @@ for DEFAULT_HTTPD_MODULE_PATH in '/usr/libexec/apache2' \
|
|||
'/usr/lib/apache2/modules' \
|
||||
'/usr/lib64/httpd/modules' \
|
||||
'/usr/lib/httpd/modules' \
|
||||
'/usr/libexec/httpd'
|
||||
'/usr/libexec/httpd' \
|
||||
'/usr/lib/apache2'
|
||||
do
|
||||
if test -d "$DEFAULT_HTTPD_MODULE_PATH"
|
||||
then
|
||||
|
@ -127,6 +128,20 @@ else
|
|||
"Could not identify web server at '$LIB_HTTPD_PATH'"
|
||||
fi
|
||||
|
||||
if test -n "$LIB_HTTPD_DAV" && test -f /etc/os-release
|
||||
then
|
||||
case "$(grep "^ID=" /etc/os-release | cut -d= -f2-)" in
|
||||
alpine)
|
||||
# The WebDAV module in Alpine Linux is broken at least up to
|
||||
# Alpine v3.16 as the default DBM driver is missing.
|
||||
#
|
||||
# https://gitlab.alpinelinux.org/alpine/aports/-/issues/13112
|
||||
test_skip_or_die GIT_TEST_HTTPD \
|
||||
"Apache WebDAV module does not have default DBM backend driver"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
install_script () {
|
||||
write_script "$HTTPD_ROOT_PATH/$1" <"$TEST_PATH/$1"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue