Offer to run CI/PR builds in Visual Studio Team Services
cover Offer to run CI/PR builds in Visual Studio Team Services
For a long time already, we have Git's source code continuously tested via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Visual Studio Team Services (VSTS) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
One might ask why we did not use Visual Studio Team Services directly. There were a couple of reasons for that:
* most notably, VSTS's build logs could not be viewed anonymously,
* while VSTS had Linux and Windows agents, it lacked macOS agents,
* etc
The main two reasons no longer apply: macOS agents are available now
[https://docs.microsoft.com/en-us/vsts/release-notes/2018/jul-10-vsts], and there is a limited preview of "public projects"
[https://blogs.msdn.microsoft.com/devops/2018/04/27/vsts-public-projects-limited-preview/]
, i.e. it is possible to configure a VSTS project so that anybody can view the logs.
I had secured such a public project for Git for Windows already, and I recently also got one for Git. For now, the latter is hooked up with my personal git.git fork on GitHub, but it is my hope that I convince y'all that these VSTS builds are a good idea, and then hook it up with
https://github.com/git/git.
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the VSTS build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://git.visualstudio.com/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://git.visualstudio.com/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).
This patch series took way more time than I had originally planned, but I think that in particular the advanced display of the test results was worth it. Please let me know what you think about this.
Johannes Schindelin (9):
ci: rename the library of common functions
ci/lib.sh: encapsulate Travis-specific things
test-date: add a subcommand to measure times in shell scripts
tests: optionally write results as JUnit-style .xml ci/lib.sh: add support for VSTS CI
Add a build definition for VSTS
tests: include detailed trace logs with --write-junit-xml upon failure
tests: record more stderr with --write-junit-xml in case of failure
README: add a build badge (status of the VSTS build)
.vsts-ci.yml | 296 +++++++++++++++++++++++++++++++++
README.md | 2 +
ci/install-dependencies.sh | 5 +-
ci/{lib-travisci.sh => lib.sh} | 67 ++++++--
ci/mount-fileshare.sh | 26 +++
ci/print-test-failures.sh | 4 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 3 +-
t/.gitignore | 1 +
t/helper/test-date.c | 12 ++
t/test-lib.sh | 142 ++++++++++++++++
14 files changed, 544 insertions(+), 22 deletions(-)
create mode 100644 .vsts-ci.yml
rename ci/{lib-travisci.sh => lib.sh} (61%)
create mode 100755 ci/mount-fileshare.shbase-commit: 2f743933341f276111103550fbf383a34dfcfd38
Published-As: https://github.com/gitgitgadget/git/releases/tags/pr-31%2Fdscho%2Fvsts-ci-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-31/dscho/vsts-ci-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/31
Signature · 1 line
gitgitgadget
PATCH 1/9 ci: rename the library of common functions
From: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
In the next commits, we will extend this to be able use Visual Studio Team Services, too.
So let's adjust the name to make it more generic.
---
ci/install-dependencies.sh | 2 +-
ci/{lib-travisci.sh => lib.sh} | 0
ci/print-test-failures.sh | 2 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 2 +-
8 files changed, 7 insertions(+), 7 deletions(-)
rename ci/{lib-travisci.sh => lib.sh} (100%)ci/install-dependencies.sh +1 -1
@@ -3,7 +3,7 @@ # Install dependencies required to build and test Git on Linux and macOS # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
ci/lib.sh renamed from ci/lib-travisci.sh +0 -0
ci/print-test-failures.sh +1 -1
@@ -3,7 +3,7 @@ # Print output of failing tests # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh # Tracing executed commands would produce too much noise in the loop below. set +x
ci/run-build-and-tests.sh +1 -1
@@ -3,7 +3,7 @@ # Build and test Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh ln -s "$cache_dir/.prove" t/.prove
ci/run-linux32-docker.sh +1 -1
@@ -3,7 +3,7 @@ # Download and run Docker image to build and test 32-bit Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh docker pull daald/ubuntu32:xenial
ci/run-static-analysis.sh +1 -1
@@ -3,7 +3,7 @@ # Perform various static code analysis checks # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh make --jobs=2 coccicheck
ci/run-windows-build.sh +1 -1
@@ -6,7 +6,7 @@ # supported) and a commit hash. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh test $# -ne 2 && echo "Unexpected number of parameters" && exit 1 test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit
ci/test-documentation.sh +1 -1
@@ -3,7 +3,7 @@ # Perform sanity checks on documentation and build it. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh gem install asciidoctor
Signature · 1 line
gitgitgadget
PATCH 2/9 ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via VSTS CI, where variable names and URLs look a bit different than in Travis CI.
--- ci/install-dependencies.sh | 3 ++- ci/lib.sh | 44 +++++++++++++++++++++++++++----------- ci/print-test-failures.sh | 2 +- ci/test-documentation.sh | 1 + 4 files changed, 35 insertions(+), 15 deletions(-)
ci/install-dependencies.sh +2 -1
@@ -28,7 +28,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + eval brew install $BREW_INSTALL_PACKAGES brew link --force gettext brew install caskroom/cask/perforce ;;
ci/lib.sh +31 -13
98 lines not on this page · raw message
ci/print-test-failures.sh +1 -1
@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ] then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
ci/test-documentation.sh +1 -0
@@ -5,6 +5,7 @@ . ${0%/*}/lib.sh +test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtins
Signature · 1 line
gitgitgadget
Re: [PATCH 2/9] ci/lib.sh: encapsulate Travis-specific things
ci/install-dependencies.sh osx-clang|osx-gcc) · line 31
Quoted 12 lines · Johannes Schindelin via GitGitGadget
The upcoming patches will allow building git.git via VSTS CI, where variable names and URLs look a bit different than in Travis CI.
Signed-off-by Johannes Schindelin <[email protected]>---
ci/install-dependencies.sh +2
-1@@ -28,7 +28,8 @@ osx-clang|osx-gcc) # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + eval brew install $BREW_INSTALL_PACKAGES
This 'eval' is unnecessary, isn't it?
brew install $BREW_INSTALL_PACKAGES
should give the same result.
Quoted 5 lines
ci/install-dependencies.sh +0
-0brew link --force gettext brew install caskroom/cask/perforceci/lib.sh +1
-0@@ -1,5 +1,26 @@ + BREW_INSTALL_PACKAGES="git-lfs gettext"
Re: [PATCH 2/9] ci/lib.sh: encapsulate Travis-specific things
Hi Eric,
Quoted 17 lines · Eric Sunshine
ci/install-dependencies.sh osx-clang|osx-gcc) · line 31
Quoted 12 lines · Johannes Schindelin via GitGitGadget
The upcoming patches will allow building git.git via VSTS CI, where variable names and URLs look a bit different than in Travis CI.
Signed-off-by Johannes Schindelin <[email protected]>---
ci/install-dependencies.sh +2
-1@@ -28,7 +28,8 @@ osx-clang|osx-gcc) # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + eval brew install $BREW_INSTALL_PACKAGESThis 'eval' is unnecessary, isn't it?
Quoted 3 lines
brew install $BREW_INSTALL_PACKAGES
should give the same result.
Oh right! Fixed in https://github.com/gitgitgadget/git/pull/31 (and I also opened https://github.com/git/git/pull/531 to verify that Travis CI still works).
Thanks,
Dscho
Quoted 6 lines
Quoted 5 lines
ci/install-dependencies.sh +0
-0brew link --force gettext brew install caskroom/cask/perforceci/lib.sh +1
-0@@ -1,5 +1,26 @@ + BREW_INSTALL_PACKAGES="git-lfs gettext"
Re: [PATCH 2/9] ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetci/lib.sh line 5
Quoted 3 lines · Johannes Schindelin via GitGitGadget
ci/lib.sh +3
-0+if test -n "$TRAVIS_COMMIT" +then + # We are running within Travis CI
Personally, I'd find a check like
if test "$TRAVIS" = "true"
more speaking (also see [1]).
[1] https://docs.travis-ci.com/user/environment-variables/
Signature · 1 line
Sebastian Schuberth
Re: [PATCH 2/9] ci/lib.sh: encapsulate Travis-specific things
Hi Sebastian,
Quoted 11 lines · Sebastian Schuberth
ci/lib.sh line 5
Quoted 3 lines · Johannes Schindelin via GitGitGadget
ci/lib.sh +3
-0+if test -n "$TRAVIS_COMMIT" +then + # We are running within Travis CIPersonally, I'd find a check like
if test "$TRAVIS" = "true"
more speaking (also see [1]).
Good call.
Will fix,
Dscho
Quoted 7 lines
[1] https://docs.travis-ci.com/user/environment-variables/
Signature · 1 line
Sebastian Schuberth
PATCH 3/9 test-date: add a subcommand to measure times in shell scripts
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use date +%s for that, this will give us only seconds, i.e. very coarse-grained timings.
GNU date supports date +%s.%N (i.e. nanosecond-precision output), but there is no equivalent in BSD date (read: on macOS, we would not be able to obtain precise timings).
So let's introduce test-tool date getnanos, with an optional start time, that outputs preciser values.
Granted, it is a bit pointless to try measuring times accurately in shell scripts, certainly to nanosecond precision. But it is better than second-granularity.
--- t/helper/test-date.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
t/helper/test-date.c +12 -0
@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"" test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n" ;
@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos (const char **argv,struct timeval *now) +{ +double seconds =getnanotime () /1.0e9 ; + +if (*argv) + seconds -=strtod (*argv,NULL ); +printf ("%lf\n" , seconds); +} +int cmd__date (int argc,const char **argv) {struct timeval now;
@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)parse_approxidate (argv+1 , &now); else if (!strcmp(*argv, "timestamp"))parse_approx_timestamp (argv+1 , &now); + else if (!strcmp(*argv, "getnanos")) +getnanos (argv+1 , &now); else if (!strcmp(*argv, "is64bit"))return sizeof (timestamp_t) ==8 ?0 :1 ; else if (!strcmp(*argv, "time_t-is64bit"))
Signature · 1 line
gitgitgadget
PATCH 4/9 tests: optionally write results as JUnit-style .xml
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This will come in handy when publishing the results of Git's test suite during an automated VSTS CI run.
--- t/.gitignore | 1 + t/test-lib.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+)
t/.gitignore +1 -0
@@ -2,3 +2,4 @@ /test-results /.prove /chainlinttmp +/out/
t/test-lib.sh +98 -0
159 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH 4/9] tests: optionally write results as JUnit-style .xml
Quoted 7 lines · Johannes Schindelin via GitGitGadget
This will come in handy when publishing the results of Git's test suite during an automated VSTS CI run.
Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh trap 'exit $?' INT · line 441
Quoted 8 lines
t/test-lib.sh +7
-0@@ -431,11 +434,24 @@ trap 'exit $?' INT test_failure_ () { + if test -n "$write_junit_xml" + then + junit_insert="<failure message=\"not ok $test_count -" + junit_insert="$junit_insert $(xml_attr_encode "$1")\">" + junit_insert="$junit_insert $(xml_attr_encode \ + "$(printf '%s\n' "$@" | sed 1d)")" + junit_insert="$junit_insert</failure>"
This is a genuine failure, so you're creating a <failure> node. Okay.
t/test-lib.sh test_failure_ () { · line 467
Quoted 11 lines
t/test-lib.sh +6
-0+ write_junit_xml_testcase "$1" " $junit_insert" + fi@@ -444,11 +460,19 @@ test_failure_ () { test_known_broken_ok_ () { + if test -n "$write_junit_xml" + then + write_junit_xml_testcase "$* (breakage fixed)" + fi test_fixed=$(($test_fixed+1)) say_color error "ok $test_count - $@ # TODO known breakage vanished" }
This was expected to fail but didn't, which means it probably needs some sort of attention. test_known_broken_ok_() prints this result in the 'error' color, and test_done() re-inforces that by printing a message, also in 'error' color:
42 known breakage(s) vanished; please update test(s)
So, should this emit a <failure> node also, perhaps with 'type' attribute set to "warning" or something? (<failure type="WARNING" message="...">)
t/test-lib.sh test_at_end_hook_ () { · line 802
Quoted 11 lines
t/test-lib.sh +10
-0@@ -758,9 +793,58 @@ test_at_end_hook_ () { +xml_attr_encode () { + # We do not translate CR to 
 because BSD sed does not handle + # \r in the regex. In practice, the output should not even have any + # carriage returns. + printf '%s\n' "$@" | + sed -e 's/&/\&/g' -e "s/'/\'/g" -e 's/"/\"/g' \ + -e 's/</\</g' -e 's/>/\>/g' \ + -e 's/ /\	/g' -e 's/$/\
/' -e '$s/
$//' | + tr -d '\012\015' +}
It's possible to insert a literal CR in the 'sed' expression, which does match correctly on BSD (and MacOS). For instance:
CR=$(printf "\r")
sed -e "s/$CR/\
/g"Re: [PATCH 4/9] tests: optionally write results as JUnit-style .xml
Hi Eric,
Quoted 37 lines · Eric Sunshine
Quoted 7 lines · Johannes Schindelin via GitGitGadget
This will come in handy when publishing the results of Git's test suite during an automated VSTS CI run.
Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh trap 'exit $?' INT · line 441
Quoted 8 lines
t/test-lib.sh +7
-0@@ -431,11 +434,24 @@ trap 'exit $?' INT test_failure_ () { + if test -n "$write_junit_xml" + then + junit_insert="<failure message=\"not ok $test_count -" + junit_insert="$junit_insert $(xml_attr_encode "$1")\">" + junit_insert="$junit_insert $(xml_attr_encode \ + "$(printf '%s\n' "$@" | sed 1d)")" + junit_insert="$junit_insert</failure>"This is a genuine failure, so you're creating a <failure> node. Okay.
t/test-lib.sh test_failure_ () { · line 467
Quoted 11 lines
t/test-lib.sh +6
-0+ write_junit_xml_testcase "$1" " $junit_insert" + fi@@ -444,11 +460,19 @@ test_failure_ () { test_known_broken_ok_ () { + if test -n "$write_junit_xml" + then + write_junit_xml_testcase "$* (breakage fixed)" + fi test_fixed=$(($test_fixed+1)) say_color error "ok $test_count - $@ # TODO known breakage vanished" }This was expected to fail but didn't, which means it probably needs some sort of attention.
test_known_broken_ok_()prints this result in the 'error' color, andtest_done()re-inforces that by printing a message, also in 'error' color:
Quoted 5 lines
42 known breakage(s) vanished; please update test(s)
So, should this emit a <failure> node also, perhaps with 'type' attribute set to "warning" or something? (<failure type="WARNING" message="...">)
My primary aim is to display the test results in the web interface, see e.g.
https://git.visualstudio.com/git/_build/results?buildId=128&view=ms.vss-test-web.test-result-details
The parser for JUnit XML (and in fact, the JUnit XML schema itself) do not allow for such a warning. If you add a <failure>, then the build fails.
And we do not want the build to fail. Historically, I saw quite a couple of "vanished" breakages depending on the platform where I ran the tests.
Quoted 15 lines
t/test-lib.sh test_at_end_hook_ () { · line 802
Quoted 11 lines
t/test-lib.sh +10
-0@@ -758,9 +793,58 @@ test_at_end_hook_ () { +xml_attr_encode () { + # We do not translate CR to 
 because BSD sed does not handle + # \r in the regex. In practice, the output should not even have any + # carriage returns. + printf '%s\n' "$@" | + sed -e 's/&/\&/g' -e "s/'/\'/g" -e 's/"/\"/g' \ + -e 's/</\</g' -e 's/>/\>/g' \ + -e 's/ /\	/g' -e 's/$/\
/' -e '$s/
$//' | + tr -d '\012\015' +}It's possible to insert a literal CR in the 'sed' expression, which does match correctly on BSD (and MacOS). For instance:
Quoted 2 lines
CR=$(printf "\r")
sed -e "s/$CR/\
/g"Okay. But since we are talking about displaying some chunk of text, I would rather just delete the CR here anyway.
Ciao,
Dscho
PATCH 5/9 ci/lib.sh: add support for VSTS CI
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
ci/lib.sh +23 -0
@@ -19,6 +19,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in VSTS CI + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/vsts-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
Signature · 1 line
gitgitgadget
PATCH 6/9 Add a build definition for VSTS
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This commit adds a .vsts-ci.yml which is Visual Studio Team Services' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the matrix feature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
--- .vsts-ci.yml | 296 ++++++++++++++++++++++++++++++++++++++++++ ci/mount-fileshare.sh | 26 ++++ 2 files changed, 322 insertions(+) create mode 100644 .vsts-ci.yml create mode 100755 ci/mount-fileshare.sh
.vsts-ci.yml new file +296 -0
@@ -0,0 +1,296 @@ +resources: +- repo: self + fetchDepth: 1 + +phases: +- phase: linux_clang + displayName: linux-clang + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin + + export CC=clang + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux_gcc + displayName: linux-gcc + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_clang + displayName: osx-clang + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_gcc + displayName: osx-gcc + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: gettext_poison + displayName: GETTEXT_POISON + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev + + export jobname=GETTEXT_POISON + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'gettext-poison' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: windows + displayName: Windows + condition: succeeded() + queue: + name: Hosted VS2017 + timeoutInMinutes: 240 + steps: + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + net use s: \\gitfileshare.file.core.windows.net\vsts-cache "$(gitfileshare.pwd)" /user:AZURE\gitfileshare /persistent:no; c + cmd /c mklink /d "$(Build.SourcesDirectory)\vsts-cache" S:\; c + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + git init; c + } else { + git status + } + } else { + git init $path; c + cd $path; c + } + git config core.autocrlf false; c + git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + git remote add origin $url; c + } + git fetch --depth=1 $url master; c + git reset --hard FETCH_HEAD; c + git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://git-for-windows.visualstudio.com/_git/git-sdk-64" 0 + init usr\src\build-extra https://github.com/git-for-windows/build-extra 1 + + cd "$(Build.SourcesDirectory)"; c + + $env:HOME = "$(Build.SourcesDirectory)" + $env:MSYSTEM = "MINGW64" + git-sdk-64\git-cmd --command=usr\\bin\\bash.exe -lc @" + . ci/lib.sh + + make -j10 DEVELOPER=1 NO_PERL=1 || exit 1 + NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"--quiet --write-junit-xml\" time make -j15 -k DEVELOPER=1 test || { + NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"-i -v -x\" make -k failed; exit 1 + } + + save_good_tree + "@ + + cmd /c rmdir "$(Build.SourcesDirectory)\vsts-cache" + displayName: 'build & test' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux32 + displayName: Linux32 + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get -y install \ + apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + sudo add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + sudo apt-get update + sudo apt-get -y install docker-ce + + sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1 + + sudo chmod a+r t/out/TEST-*.xml + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-linux32-docker.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux32' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: static_analysis + displayName: StaticAnalysis + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get install -y coccinelle + + export jobname=StaticAnalysis + + ci/run-static-analysis.sh || exit 1 + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/run-static-analysis.sh' + +- phase: documentation + displayName: Documentation + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1 + + sudo apt-get update + sudo apt-get install -y asciidoc xmlto asciidoctor + + export ALREADY_HAVE_ASCIIDOCTOR=yes. + export jobname=Documentation + + ci/test-documentation.sh || exit 1 + + sudo umount "$HOME/vsts-cache" || exit 1 + displayName: 'ci/test-documentation.sh'
ci/mount-fileshare.sh new file +26 -0
@@ -0,0 +1,26 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint" + +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;; +Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4" +
Signature · 1 line
gitgitgadget
PATCH 7/9 tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the --verbose-log option to get those traces. However, that seems excessive, as we do not need/use the logs in almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different in VSTS: let's run all the tests with --quiet first, and only if a failure is encountered, try to trace the commands as they are executed.
Of course, we cannot turn on --verbose-log after the fact. So let's just re-run the test with all the same options, adding --verbose-log. And then munging the output file into the JUnit XML on the fly.
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with. Ideally, we would label this as "Passed upon rerun", and that outcome even exists on VSTS, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/vsts-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
This patch contains a slightly inelegant workaround for the p4 and git-daemon tests: when we try to re-run the p4/git-daemon tests after the daemon has been started already, we need to kill said daemon. We do this by detecting the presence of the kill_p4d and stop_git_daemon shell functions and calling them if available.
--- t/test-lib.sh | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
t/test-lib.sh +39 -1
@@ -85,6 +85,13 @@ done,*) test "$(cat "$BASE.exit")" = 0 exit ;; +*' --write-junit-xml '*) + # record how to call this script *with* --verbose-log, in case + # we encounter a breakage + junit_rerun_options_sq="$(printf '%s\n' "$0" --verbose-log -x "$@" | + sed -e "s/'/'\\\\''/g" -e "s/^/'/" -e "s/\$/'/" | + tr '\012' ' ')" + ;; esac # For repeatability, reset the environment to known value.
@@ -445,10 +452,37 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" then + if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + case "$(type kill_p4d 2>/dev/null | head -n 1)" in + *function*) kill_p4d;; + esac + + case "$(type stop_git_daemon 2>/dev/null | + head -n 1)" in + *function*) stop_git_daemon;; + esac + + # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi + junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")" + >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fi
@@ -733,6 +767,10 @@ test_start_ () { if test -n "$write_junit_xml" then junit_start=$(test-tool date getnanos) + + # truncate output + test -z "$GIT_TEST_TEE_OUTPUT_FILE" || + >"$GIT_TEST_TEE_OUTPUT_FILE" fi }
Signature · 1 line
gitgitgadget
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 11 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh +0
-0@@ -445,10 +452,37 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" then
t/test-lib.sh test_ok_ () { · line 464
Quoted 10 lines
t/test-lib.sh +10
-0+ if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + case "$(type kill_p4d 2>/dev/null | head -n 1)" in + *function*) kill_p4d;; + esac + + case "$(type stop_git_daemon 2>/dev/null | + head -n 1)" in + *function*) stop_git_daemon;; + esac
In the long run, it might make more sense, and be more scalable, to have those scripts define a "prepare_for_rerun" variable or function which this code then runs generically rather than having special knowledge of those facilities.
I could imagine, for instance, test-lib.sh defining a no-op:
test_failure_prepare_rerun () {}and then each of those scripts overriding the function:
# in lib-git-p4.sh
test_failure_prepare_rerun () {
kill_p4d
} # in lib-git-daemon.sh
test_failure_prepare_rerun () {
stop_git_daemon
}Quoted 14 lines
t/test-lib.sh +14
-0+ # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi
t/test-lib.sh test_ok_ () { · line 488
Quoted 10 lines
t/test-lib.sh +3
-1+ junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")" + >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fi
This junit-related stuff is getting pretty lengthy. I wonder if it would make sense to pull it out to its own function at some point (again, in the long run).
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Eric,
Quoted 40 lines · Eric Sunshine
Quoted 11 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh +0
-0@@ -445,10 +452,37 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" thent/test-lib.sh test_ok_ () { · line 464
Quoted 10 lines
t/test-lib.sh +10
-0+ if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + case "$(type kill_p4d 2>/dev/null | head -n 1)" in + *function*) kill_p4d;; + esac + + case "$(type stop_git_daemon 2>/dev/null | + head -n 1)" in + *function*) stop_git_daemon;; + esacIn the long run, it might make more sense, and be more scalable, to have those scripts define a "
prepare_for_rerun" variable or function which this code then runs generically rather than having special knowledge of those facilities.I could imagine, for instance,
test-lib.shdefining a no-op:test_failure_prepare_rerun () {}and then each of those scripts overriding the function:
# in lib-git-p4.sh test_failure_prepare_rerun () { kill_p4d }
Quoted 4 lines
# in lib-git-daemon.sh
test_failure_prepare_rerun () {
stop_git_daemon
}Or we could implement test_atexit (similar to test_when_finished, but to be executed at test_done time). I guess that's what the p4 and daemon tests really needed to begin with (and probably also the apache2-using tests).
Quoted 21 lines
Quoted 21 lines
t/test-lib.sh +16
-1+ # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi + junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")"
Quoted 8 lines
t/test-lib.sh test_ok_ () { · line 488
Quoted 4 lines
t/test-lib.sh +1
-0+ >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fiThis junit-related stuff is getting pretty lengthy. I wonder if it would make sense to pull it out to its own function at some point (again, in the long run).
Now that you mention it... I agree. This is getting long.
In the short run, I have two things to consider, though: I want to make this work first, then think about introducing a layer of abstraction, and I want to go on vacation tomorrow.
So I agree that this is something to be considered in the long run, i.e. not right now ;-)
Thanks,
Dscho
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 9 lines · Johannes Schindelin
Hi Eric,
Quoted 5 lines · Eric Sunshine
Quoted 3 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]
Is this re-running just an individual test on its own or all the tests within a single file?
The latter shouldn't need this at all. And the former, I'm not sure will actually work - most of the tests assume some particular p4 state. But perhaps I'm missing something?
I also think it does look kind of ugly. And if there's one thing I've learned, it's that the ugly hack you write today with the words "we'll tidy this up later" goes on to live with you forever!
Quoted 86 lines
Quoted 35 lines
Quoted 8 lines
Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh +0
-0@@ -445,10 +452,37 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" thent/test-lib.sh test_ok_ () { · line 464
Quoted 10 lines
t/test-lib.sh +10
-0+ if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + case "$(type kill_p4d 2>/dev/null | head -n 1)" in + *function*) kill_p4d;; + esac + + case "$(type stop_git_daemon 2>/dev/null | + head -n 1)" in + *function*) stop_git_daemon;; + esacIn the long run, it might make more sense, and be more scalable, to have those scripts define a "
prepare_for_rerun" variable or function which this code then runs generically rather than having special knowledge of those facilities.I could imagine, for instance,
test-lib.shdefining a no-op:test_failure_prepare_rerun () {}and then each of those scripts overriding the function:
# in lib-git-p4.sh test_failure_prepare_rerun () { kill_p4d }Quoted 4 lines
# in lib-git-daemon.sh test_failure_prepare_rerun () { stop_git_daemon }Or we could implement
test_atexit(similar totest_when_finished, but to be executed attest_donetime). I guess that's what the p4 and daemon tests really needed to begin with (and probably also the apache2-using tests).Quoted 21 lines
Quoted 21 lines
t/test-lib.sh +16
-1+ # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi + junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")"Quoted 8 lines
t/test-lib.sh test_ok_ () { · line 488
Quoted 4 lines
t/test-lib.sh +1
-0+ >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fiThis junit-related stuff is getting pretty lengthy. I wonder if it would make sense to pull it out to its own function at some point (again, in the long run).
Now that you mention it... I agree. This is getting long.
In the short run, I have two things to consider, though: I want to make this work first, then think about introducing a layer of abstraction, and I want to go on vacation tomorrow.
So I agree that this is something to be considered in the long run, i.e. not right now ;-)
Thanks,
Dscho
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Luke,
Quoted 5 lines · Luke Diamand
Quoted 3 lines · Johannes Schindelin
On Tue, 4 Sep 2018, Eric Sunshine wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]Is this re-running just an individual test on its own or all the tests within a single file?
Upon encountering a failed test, it is re-running the entire test script afresh.
Quoted 1 line
The latter shouldn't need this at all.
Please do not let me die dumb. In other words, I would love for you to explain what exactly you mean by that sentence.
Quoted 2 lines
And the former, I'm not sure will actually work - most of the tests assume some particular p4 state. But perhaps I'm missing something?
No, the former would not work at all. Not only for the p4 tests: Git's tests frequently commit the deadly sin of relying on output of one another (wreaking havoc e.g. when test cases are skipped due to missing prerequisites, and latter test cases relying on their output). It is not the only thing that is wrong with the test suite, of course.
Quoted 3 lines
I also think it does look kind of ugly. And if there's one thing I've learned, it's that the ugly hack you write today with the words "we'll tidy this up later" goes on to live with you forever!
Okay.
(And having read lib-git-p4.sh, I kind of see where you learned that.)
But maybe you also have some splendid idea what to do instead? Because doing something about it, that we need. We can't just say "oh, the only solution we found is ugly, so let's not do it at all".
I am even going so far as to say: unless you have a better idea, it is pretty detrimental to criticize the current approach. It is the opposite of constructive.
So let's hear some ideas how to improve the situation, m'kay?
Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
What do you suggest to solve this?
Ciao,
Johannes
Quoted 86 lines
Quoted 85 lines
Quoted 34 lines
Quoted 7 lines
Signed-off-by Johannes Schindelin <[email protected]>---
t/test-lib.sh +0
-0@@ -445,10 +452,37 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" thent/test-lib.sh test_ok_ () { · line 464
Quoted 10 lines
t/test-lib.sh +10
-0+ if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + case "$(type kill_p4d 2>/dev/null | head -n 1)" in + *function*) kill_p4d;; + esac + + case "$(type stop_git_daemon 2>/dev/null | + head -n 1)" in + *function*) stop_git_daemon;; + esacIn the long run, it might make more sense, and be more scalable, to have those scripts define a "
prepare_for_rerun" variable or function which this code then runs generically rather than having special knowledge of those facilities.I could imagine, for instance,
test-lib.shdefining a no-op:test_failure_prepare_rerun () {}and then each of those scripts overriding the function:
# in lib-git-p4.sh test_failure_prepare_rerun () { kill_p4d }Quoted 4 lines
# in lib-git-daemon.sh test_failure_prepare_rerun () { stop_git_daemon }Or we could implement
test_atexit(similar totest_when_finished, but to be executed attest_donetime). I guess that's what the p4 and daemon tests really needed to begin with (and probably also the apache2-using tests).Quoted 21 lines
Quoted 21 lines
t/test-lib.sh +16
-1+ # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi + junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")"Quoted 8 lines
t/test-lib.sh test_ok_ () { · line 488
Quoted 4 lines
t/test-lib.sh +1
-0+ >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fiThis junit-related stuff is getting pretty lengthy. I wonder if it would make sense to pull it out to its own function at some point (again, in the long run).
Now that you mention it... I agree. This is getting long.
In the short run, I have two things to consider, though: I want to make this work first, then think about introducing a layer of abstraction, and I want to go on vacation tomorrow.
So I agree that this is something to be considered in the long run, i.e. not right now ;-)
Thanks,
Dscho
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 18 lines · Johannes Schindelin
Hi Luke,
Quoted 5 lines · Luke Diamand
Quoted 3 lines · Johannes Schindelin
On Tue, 4 Sep 2018, Eric Sunshine wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]Is this re-running just an individual test on its own or all the tests within a single file?
Quoted 7 lines
Upon encountering a failed test, it is re-running the entire test script afresh.
Quoted 1 line
The latter shouldn't need this at all.
Please do not let me die dumb. In other words, I would love for you to explain what exactly you mean by that sentence.
Just re-run the script. You shouldn't need to kill p4d, as each script starts up its own instance of p4d, and shuts it down when it exits.
$ cd t $ ./t9800-git-p4-basic.sh Ctrl^C $ ./t9800-git-p4-basic.sh -v
There's a cleanup() function in lib-git-p4.sh which kills the p4d server, and that's invoked via:
trap cleanup EXIT
That's the only cleanup that each of the scripts require AFAIK.
Quoted 28 lines
Quoted 3 lines
And the former, I'm not sure will actually work - most of the tests assume some particular p4 state. But perhaps I'm missing something?
No, the former would not work at all. Not only for the p4 tests: Git's tests frequently commit the deadly sin of relying on output of one another (wreaking havoc e.g. when test cases are skipped due to missing prerequisites, and latter test cases relying on their output). It is not the only thing that is wrong with the test suite, of course.
Quoted 3 lines
I also think it does look kind of ugly. And if there's one thing I've learned, it's that the ugly hack you write today with the words "we'll tidy this up later" goes on to live with you forever!
Okay.
(And having read
lib-git-p4.sh, I kind of see where you learned that.)But maybe you also have some splendid idea what to do instead? Because doing something about it, that we need. We can't just say "oh, the only solution we found is ugly, so let's not do it at all".
I am even going so far as to say: unless you have a better idea, it is pretty detrimental to criticize the current approach. It is the opposite of constructive.
So let's hear some ideas how to improve the situation, m'kay?
Quoted 8 lines
Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
What do you suggest to solve this?
I don't know about any other tests, but the git-p4 tests don't take any longer in verbose mode. So one simple solution is to just run it in verbose mode - unless there are other tests which have more overhead.
The trap/exit/cleanup method that the git-p4 tests already use would seem to be ideally suited to cleaning up everything on exit.
There might be some specific tests where this doesn't quite work out, if you let me know what they are I can have a look at fixing them for you.
Thanks,
Luke
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Luke,
Quoted 27 lines · Luke Diamand
Quoted 17 lines · Johannes Schindelin
Quoted 5 lines · Luke Diamand
Quoted 3 lines · Johannes Schindelin
On Tue, 4 Sep 2018, Eric Sunshine wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines · Johannes Schindelin via GitGitGadget
So let's do something different in VSTS: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed. [...]Is this re-running just an individual test on its own or all the tests within a single file?
Quoted 7 lines
Upon encountering a failed test, it is re-running the entire test script afresh.
Quoted 1 line
The latter shouldn't need this at all.
Please do not let me die dumb. In other words, I would love for you to explain what exactly you mean by that sentence.
Quoted 6 lines
Just re-run the script. You shouldn't need to kill p4d, as each script starts up its own instance of p4d, and shuts it down when it exits.
$ cd t $ ./t9800-git-p4-basic.sh Ctrl^C
That Ctrl^C is not possible in the automated builds (which are the subject of this patch series).
What *is* possible is to detect in the test script that there was a breakage, and then re-run the test script.
Unfortunately, at this stage the first test script has not exited yet, so your p4d has not exited yet, and we have to clean up in some way before re-running (because the port in use is determined by the test script's number, so we really need to kill the old daemon).
And this is exactly what my patches try to achieve here.
Quoted 8 lines
$ ./t9800-git-p4-basic.sh -vThere's a
cleanup()function inlib-git-p4.shwhich kills the p4d server, and that's invoked via:trap cleanup EXIT
That's the only cleanup that each of the scripts require AFAIK.
Good.
However, we really will want to consider introducing something consistent here, something that works for *all* test scripts. IOW if any test script wants to start a process for the life-time of that script, and needs to kill that process at the end, we will want to have a consistent, documented way to register a function (or commands) to be called at the end.
And that function (or commands) need to be run also when stopping everything in preparation for a re-run.
Quoted 33 lines
Quoted 33 lines
Quoted 2 lines
And the former, I'm not sure will actually work - most of the tests assume some particular p4 state. But perhaps I'm missing something?
No, the former would not work at all. Not only for the p4 tests: Git's tests frequently commit the deadly sin of relying on output of one another (wreaking havoc e.g. when test cases are skipped due to missing prerequisites, and latter test cases relying on their output). It is not the only thing that is wrong with the test suite, of course.
Quoted 3 lines
I also think it does look kind of ugly. And if there's one thing I've learned, it's that the ugly hack you write today with the words "we'll tidy this up later" goes on to live with you forever!
Okay.
(And having read
lib-git-p4.sh, I kind of see where you learned that.)But maybe you also have some splendid idea what to do instead? Because doing something about it, that we need. We can't just say "oh, the only solution we found is ugly, so let's not do it at all".
I am even going so far as to say: unless you have a better idea, it is pretty detrimental to criticize the current approach. It is the opposite of constructive.
So let's hear some ideas how to improve the situation, m'kay?
Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
Quoted 5 lines
Quoted 2 lines
What do you suggest to solve this?
I don't know about any other tests, but the git-p4 tests don't take any longer in verbose mode.
That statement is too general to be correct. It may be the case in your setup, but I found that even a redirected, chatty stderr can slow down things on Windows substantially, probably due to the POSIX emulation going on in the background that needs to prepare for all kinds of eventualities (that we do not even need, but the MSYS2 runtime has no way of knowing that).
Quoted 2 lines
So one simple solution is to just run it in verbose mode - unless there are other tests which have more overhead.
It is a bit of an overhead. As the entire test run on Windows takes *quite* a while (due to said POSIX emulation issues), I was not able to quantify it exactly.
Quoted 2 lines
The trap/exit/cleanup method that the git-p4 tests already use would seem to be ideally suited to cleaning up everything on exit.
Yes. On exit. But I cannot exit here, not before re-running the script.
Quoted 3 lines
There might be some specific tests where this doesn't quite work out, if you let me know what they are I can have a look at fixing them for you.
Thanks. I will let you know when I encounter other tests than the p4 and git-daemon tests (which I fixed in this patch series).
Ciao,
Dscho
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Johannes SchindelinQuoted 6 lines · Johannes Schindelin
So let's hear some ideas how to improve the situation, m'kay? Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
What about the very different approach of capturing the full "verbose" output the executed tests in addition to whatever is actually output to the terminal? If a test fails, then (and only then) you can insert the captured verbose output into the JUnit XML file. This way (if we always have the full verbose output at hand), you don't need to re-run the test at all.
I've cc:'d Peff and Jonathan since I believe they are more familiar with how all the capturing / output-redirection works in the test suite.
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 16 lines · Eric Sunshine
Quoted 6 lines · Johannes Schindelin
So let's hear some ideas how to improve the situation, m'kay? Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
What about the very different approach of capturing the full "verbose" output the executed tests in addition to whatever is actually output to the terminal? If a test fails, then (and only then) you can insert the captured verbose output into the JUnit XML file. This way (if we always have the full verbose output at hand), you don't need to re-run the test at all.
Quoted 3 lines
I've cc:'d Peff and Jonathan since I believe they are more familiar with how all the capturing / output-redirection works in the test suite.
I don't think there's much to know beyond what you wrote. The "--verbose" case does not really cost any more than the non-verbose one, because the only difference is whether output goes to a file versus /dev/null. But the commands all call write() regardless.
For --verbose-log, it does of course cost a little extra to run one tee per script, and to write a few kb of logs. I doubt those are measurable versus the rest of a script run, but I'm happy to be disproven by numbers. There are some gymnastics done to re-exec the test script with the same shell, but AFAIK those are robust and don't cost a lot (again, one extra process per script run).
I'm not overly concerned about the cost of re-running a test, since the idea is that failed tests should be rare. I would be a little worried about flaky tests mysteriously righting themselves on the second run (so you know a failure happened, but you have no good output to describe it).
I do agree that a test_atexit() cleanup would make a lot more sense than what's in the original patch. And that's nicer than the exit trap we're using already, because you may note that each caller has to manually restore the original 'die' handler that test-lib.sh installs.
That would also help with bitrot. If this funky cleanup case only causes problems with junit output, then other people are likely to forget to do it, and the mess falls onto the junit folks (i.e., Dscho). But if the tests start _relying_ on test_atexit() being called (i.e., don't call stop_git_daemon manually, but assume that the atexit handler does so), then the responsible authors are a lot more likely to notice and fix it early.
-Peff
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Peff,
Quoted 19 lines · Jeff King
Quoted 17 lines · Eric Sunshine
Quoted 7 lines · Johannes Schindelin
So let's hear some ideas how to improve the situation, m'kay? Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
What about the very different approach of capturing the full "verbose" output the executed tests in addition to whatever is actually output to the terminal? If a test fails, then (and only then) you can insert the captured verbose output into the JUnit XML file. This way (if we always have the full verbose output at hand), you don't need to re-run the test at all.
Quoted 8 lines
Quoted 3 lines
I've cc:'d Peff and Jonathan since I believe they are more familiar with how all the capturing / output-redirection works in the test suite.
I don't think there's much to know beyond what you wrote. The "--verbose" case does not really cost any more than the non-verbose one, because the only difference is whether output goes to a file versus
/dev/null. But the commands all callwrite()regardless.
This really only holds true on systems where redirected output is essentially a no-op.
For the MSYS2-emulated case, this is incorrect. And as that case is already suffering, time-wise, I would be loathe to pile more onto it.
Quoted 4 lines
For --verbose-log, it does of course cost a little extra to run one
teeper script, and to write a few kb of logs. I doubt those are measurable versus the rest of a script run, but I'm happy to be disproven by numbers.
I tried, and failed, to quantify this properly. Essentially because a single test run takes over 1h15m, so I tried to do it in the cloud, but those timings are too variable for anything approaching an accurate measurement.
Quoted 3 lines
There are some gymnastics done to re-exec the test script with the same shell, but AFAIK those are robust and don't cost a lot (again, one extra process per script run).
It *is* actually a bit worse here (but only in the case of failures, which should be the minority of the cases): imagine an expensive test like t0027 that takes something like 14 minutes to run, and then a test failure near the end: re-running with verbose output will cost another 14 minutes.
However, the benefit of allowing to pass flakey tests outweighs the costs here, if you ask me.
Quoted 5 lines
I'm not overly concerned about the cost of re-running a test, since the idea is that failed tests should be rare. I would be a little worried about flaky tests mysteriously righting themselves on the second run (so you know a failure happened, but you have no good output to describe it).
This is actually a benefit.
Pretty much all the times I can remember a test being flakey (with the one notable exception of the O_APPEND issue with GIT_TRACE), the *tests* were buggy.
Plus, it is less concerning if a test fails occasionally vs a test that fails all the time.
My plan is to indicate the outcome of "Passed upon rerun" in the test output eventually, as soon as there is server-side support for it.
(Sidenote: there is technically already server-side support for it, but we would have to generate Visual Studio-style test output, and I had the hunch that some die-hard Linuxers among the core Git developers would take objection to that.)
Quoted 4 lines
I do agree that a
test_atexit()cleanup would make a lot more sense than what's in the original patch. And that's nicer than the exit trap we're using already, because you may note that each caller has to manually restore the original 'die' handler thattest-lib.shinstalls.
Okay, then. I will work on this.
Ciao,
Dscho
Quoted 10 lines
That would also help with bitrot. If this funky cleanup case only causes problems with junit output, then other people are likely to forget to do it, and the mess falls onto the junit folks (i.e., Dscho). But if the tests start _relying_ on
test_atexit()being called (i.e., don't callstop_git_daemonmanually, but assume that the atexit handler does so), then the responsible authors are a lot more likely to notice and fix it early.-Peff
Re: [PATCH 7/9] tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Eric SunshineHi Eric,
Quoted 9 lines · Eric Sunshine
Quoted 6 lines · Johannes Schindelin
So let's hear some ideas how to improve the situation, m'kay? Just as a reminder, this is the problem I want to solve: I want to run the tests in a light-weight manner, with minimal output, and only in case of an error do I want to crank up the verbosity. Instead of wasting most of the effort to log everything and then throwing it away in most of the common cases, I suggest to re-run the entire test.
Quoted 3 lines
What about the very different approach of capturing the full "verbose" output the executed tests in addition to whatever is actually output to the terminal?
I fear it is not really possible to do a "verbose but not really" mode. I want the console output to be quiet, there is no use in chatting up the build log with these messages, as we have to run the tests in parallel, so the output would be utterly hard to interpret anyway. At the same time, I want verbose output for use in the test results. It is not really possible to tee all output, then "quiet down" the part that makes it into the log.
Quoted 2 lines
If a test fails, then (and only then) you can insert the captured verbose output into the JUnit XML file.
Yep. That's what my patch series does.
If a test fails, then (and only then) I re-run the script with verbose output that is immediately moved into that JUnit XML file.
Quoted 2 lines
This way (if we always have the full verbose output at hand), you don't need to re-run the test at all.
But that way, if we always have the full verbose output, the build log will be unnecessarily verbose and confusing.
Quoted 3 lines
I've cc:'d Peff and Jonathan since I believe they are more familiar with how all the capturing / output-redirection works in the test suite.
Okay.
Ciao,
Dscho
P.S.: An unintended side effect of re-running the tests is to identify flakey tests. I do not yet have a way to represent this outcome in the test result, but I deem this an additional benefit in favor of keeping my current strategy.
PATCH 8/9 tests: record more stderr with --write-junit-xml in case of failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Sometimes, failures in a test case are actually caused by issues in earlier test cases.
To make it easier to see those issues, let's attach the output from before the failing test case (i.e. stdout/stderr since the previous failing test case, or the start of the test script). This will be visible in the "Attachments" of the details of the failed test.
--- t/test-lib.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
t/test-lib.sh +9 -3
@@ -484,6 +484,9 @@ test_failure_ () { "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")" >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE.err")")</system-err>" + >"$GIT_TEST_TEE_OUTPUT_FILE.err" write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1))
@@ -768,9 +771,12 @@ test_start_ () { then junit_start=$(test-tool date getnanos) - # truncate output - test -z "$GIT_TEST_TEE_OUTPUT_FILE" || - >"$GIT_TEST_TEE_OUTPUT_FILE" + # append to future <system-err>; truncate output + test -z "$GIT_TEST_TEE_OUTPUT_FILE" || { + cat "$GIT_TEST_TEE_OUTPUT_FILE" \ + >>"$GIT_TEST_TEE_OUTPUT_FILE.err" + >"$GIT_TEST_TEE_OUTPUT_FILE" + } fi }
Signature · 1 line
gitgitgadget
PATCH 9/9 README: add a build badge (status of the VSTS build)
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Just like so many other OSS projects, we now also have a build badge.
--- README.md | 2 ++ 1 file changed, 2 insertions(+)
README.md +2 -0
@@ -1,3 +1,5 @@ +[](https://git.visualstudio.com/git/_build/latest?definitionId=2) + Git - fast, scalable, distributed revision control system =========================================================
Signature · 1 line
gitgitgadget
Quoted 4 lines · Johannes Schindelin via GitGitGadget
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Visual Studio Team Services (VSTS) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
I'm sorry if this has been discussed before, but as this recap doesn't mention it: Has AppVeyor been considered as an option? It seems to be the defacto standard for Windows CI for projects on GitHub.
Signature · 1 line
Sebastian Schuberth
Quoted 11 lines · Sebastian Schuberth
Quoted 4 lines · Johannes Schindelin via GitGitGadget
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Visual Studio Team Services (VSTS) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
I'm sorry if this has been discussed before, but as this recap doesn't mention it: Has AppVeyor been considered as an option? It seems to be the defacto standard for Windows CI for projects on GitHub.
There was
https://public-inbox.org/git/[email protected]/
and
https://public-inbox.org/git/[email protected]/
v2 cover Offer to run CI/PR builds in Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFor a long time already, we have Git's source code continuously tested via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
One might ask why we did not use Azure Pipelines directly. There were a couple of reasons for that:
* most notably, Azure Pipelines' build logs could not be viewed anonymously,
* while Azure Pipelines had Linux and Windows agents, it lacked macOS agents,
* etc
The main two reasons no longer apply: macOS agents are available now
[https://docs.microsoft.com/en-us/azure/devops/release-notes/2018/jul-10-vsts]
, and there is a limited preview of "public projects"
[https://blogs.msdn.microsoft.com/devops/2018/04/27/vsts-public-projects-limited-preview/]
, i.e. it is possible to configure a Azure Pipelines project so that anybody can view the logs.
I had secured such a public project for Git for Windows already, and I recently also got one for Git. For now, the latter is hooked up with my personal git.git fork on GitHub, but it is my hope that I convince y'all that these Azure Pipelines builds are a good idea, and then hook it up with
https://github.com/git/git.
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).
This patch series took way more time than I had originally planned, but I think that in particular the advanced display of the test results was worth it. Please let me know what you think about this.
Changes since v1:
* Removed a superfluous eval.
* Added the commit that fixes the Travis PR builds targeting master that just happens to be tagged (see
https://travis-ci.org/git/git/jobs/424276413 for an incorrectly-skipped build).
* The commit messages and the cover letter now reflect the name change from Visual Studio Team Services to Azure DevOps (and in particular, Azure Pipelines for the automated builds).
* Now we're using test_atexit (which we introduced for that purpose) instead of hard-coding kill_p4d and stop_git_daemon.
* The build should now also succeed for Pull Requests (where secret variables are not available, for security reasons, and as a consequence the file share cannot be mounted).
* The shell scripted parts now use proper && chains.
Johannes Schindelin (13):
ci: rename the library of common functions
ci/lib.sh: encapsulate Travis-specific things
test-date: add a subcommand to measure times in shell scripts
tests: optionally write results as JUnit-style .xml ci/lib.sh: add support for Azure Pipelines
Add a build definition for Azure DevOps
tests: introduce test_atexit
git-daemon: use test_atexit in the tests
git-p4: use test_atexit to kill the daemon
tests: include detailed trace logs with --write-junit-xml upon failure
tests: record more stderr with --write-junit-xml in case of failure
README: add a build badge (status of the Azure Pipelines build)
travis: fix skipping tagged releases
README.md | 2 +
azure-pipelines.yml | 319 +++++++++++++++++++++
ci/install-dependencies.sh | 5 +-
ci/{lib-travisci.sh => lib.sh} | 67 ++++-
ci/mount-fileshare.sh | 26 ++
ci/print-test-failures.sh | 4 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 3 +-
t/.gitignore | 1 +
t/helper/test-date.c | 12 +
t/interop/i5500-git-daemon.sh | 1 -
t/lib-git-daemon.sh | 3 +-
t/lib-git-p4.sh | 10 +-
t/t0000-basic.sh | 20 ++
t/t5570-git-daemon.sh | 1 -
t/t9800-git-p4-basic.sh | 4 -
t/t9801-git-p4-branch.sh | 4 -
t/t9802-git-p4-filetype.sh | 4 -
t/t9803-git-p4-shell-metachars.sh | 4 -
t/t9804-git-p4-label.sh | 4 -
t/t9805-git-p4-skip-submit-edit.sh | 4 -
t/t9806-git-p4-options.sh | 5 -
t/t9807-git-p4-submit.sh | 4 -
t/t9808-git-p4-chdir.sh | 4 -
t/t9809-git-p4-client-view.sh | 4 -
t/t9810-git-p4-rcs.sh | 4 -
t/t9811-git-p4-label-import.sh | 5 -
t/t9812-git-p4-wildcards.sh | 4 -
t/t9813-git-p4-preserve-users.sh | 4 -
t/t9814-git-p4-rename.sh | 4 -
t/t9815-git-p4-submit-fail.sh | 4 -
t/t9816-git-p4-locked.sh | 4 -
t/t9817-git-p4-exclude.sh | 4 -
t/t9818-git-p4-block.sh | 4 -
t/t9819-git-p4-case-folding.sh | 4 -
t/t9820-git-p4-editor-handling.sh | 4 -
t/t9821-git-p4-path-variations.sh | 4 -
t/t9822-git-p4-path-encoding.sh | 4 -
t/t9823-git-p4-mock-lfs.sh | 4 -
t/t9824-git-p4-git-lfs.sh | 4 -
t/t9825-git-p4-handle-utf16-without-bom.sh | 4 -
t/t9826-git-p4-keep-empty-commits.sh | 4 -
t/t9827-git-p4-change-filetype.sh | 4 -
t/t9828-git-p4-map-user.sh | 4 -
t/t9829-git-p4-jobs.sh | 4 -
t/t9830-git-p4-symlink-dir.sh | 4 -
t/t9831-git-p4-triggers.sh | 4 -
t/t9832-unshelve.sh | 4 -
t/t9833-errors.sh | 5 -
t/test-lib-functions.sh | 29 ++
t/test-lib.sh | 140 +++++++++
54 files changed, 616 insertions(+), 174 deletions(-)
create mode 100644 azure-pipelines.yml
rename ci/{lib-travisci.sh => lib.sh} (61%)
create mode 100755 ci/mount-fileshare.shbase-commit: 5a0cc8aca797dbd7d2be3b67458ff880ed45cddf
Published-As: https://github.com/gitgitgadget/git/releases/tags/pr-31%2Fdscho%2Fvsts-ci-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-31/dscho/vsts-ci-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/31
Range-diff vs v1:
1: 858b80bfcf ! 1: c963184510 ci: rename the library of common functions
@@ -5,8 +5,8 @@
The name is hard-coded to reflect that we use Travis CI for continuous testing.
- In the next commits, we will extend this to be able use Visual Studio
- Team Services, too.
+ In the next commits, we will extend this to be able use Azure DevOps,
+ too.
So let's adjust the name to make it more generic.
2: 18e6beec5f ! 2: 815152e0f5 ci/lib.sh: encapsulate Travis-specific things
@@ -2,8 +2,9 @@
ci/lib.sh: encapsulate Travis-specific things
- The upcoming patches will allow building git.git via VSTS CI, where
- variable names and URLs look a bit different than in Travis CI.
+ The upcoming patches will allow building git.git via Azure Pipelines
+ (i.e. Azure DevOps' Continuous Integration), where variable names and
+ URLs look a bit different than in Travis CI.
@@ -16,7 +17,7 @@
# brew install gnu-time
- brew install git-lfs gettext
+ test -z "$BREW_INSTALL_PACKAGES" ||
-+ eval brew install $BREW_INSTALL_PACKAGES
++ brew install $BREW_INSTALL_PACKAGES
brew link --force gettext
brew install caskroom/cask/perforce ;;
@@ -27,7 +28,7 @@
@@
# Library of functions shared by all CI scripts
-+if test -n "$TRAVIS_COMMIT"
++if test true = "$TRAVIS"
+then
+ # We are running within Travis CI
+ CI_BRANCH="$TRAVIS_BRANCH"
3: 064db77669 = 3: 52337f1875 test-date: add a subcommand to measure times in shell scripts 4: 2b5d678594 ! 4: cf4c5ae470 tests: optionally write results as JUnit-style .xml
@@ -3,7 +3,7 @@
tests: optionally write results as JUnit-style .xml
This will come in handy when publishing the results of Git's test suite
- during an automated VSTS CI run.
+ during an automated Azure DevOps run.
5: 127dfcfb09 ! 5: 486d1d2518 ci/lib.sh: add support for VSTS CI
@@ -1,6 +1,6 @@
Author: Johannes Schindelin <[email protected]>
- ci/lib.sh: add support for VSTS CI
+ ci/lib.sh: add support for Azure Pipelines
This patch introduces a conditional arm that defines some environment
variables and a function that displays the URL given the job id (to
@@ -17,7 +17,7 @@
export GIT_TEST_OPTS="--verbose-log -x --immediate"
+elif test -n "$SYSTEM_TASKDEFINITIONSURI"
+then
-+ # We are running in VSTS CI
++ # We are running in Azure Pipelines
+ CI_BRANCH="$BUILD_SOURCEBRANCH"
+ CI_COMMIT="$BUILD_SOURCEVERSION"
+ CI_JOB_ID="$BUILD_BUILDID"
@@ -29,7 +29,7 @@
+
+ # use a subdirectory of the cache dir (because the file share is shared
+ # among *all* phases)
-+ cache_dir="$HOME/vsts-cache/$SYSTEM_PHASENAME"
++ cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME"
+
+ url_for_job_id () {
+ echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1"
6: ab66060c57 ! 6: 1a22efe849 Add a build definition for VSTS
@@ -1,8 +1,8 @@
Author: Johannes Schindelin <[email protected]>
- Add a build definition for VSTS
+ Add a build definition for Azure DevOps
- This commit adds a .vsts-ci.yml which is Visual Studio Team Services'
+ This commit adds an azure-pipelines.yml file which is Azure DevOps'
equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the
@@ -19,10 +19,10 @@
Signed-off-by: Johannes Schindelin <[email protected]>
-diff --git a/.vsts-ci.yml b/.vsts-ci.yml
+diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
--- /dev/null
-+++ b/.vsts-ci.yml
++++ b/azure-pipelines.yml
@@
+resources:
+- repo: self
@@ -36,12 +36,12 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
-+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin
++ sudo apt-get update &&
++ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin &&
+
-+ export CC=clang
++ export CC=clang || exit 1
+
+ ci/install-dependencies.sh
+ ci/run-build-and-tests.sh || {
@@ -49,8 +49,10 @@
+ exit 1
+ }
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -67,10 +69,10 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
-+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin
++ sudo apt-get update &&
++ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1
+
+ ci/install-dependencies.sh
+ ci/run-build-and-tests.sh || {
@@ -78,8 +80,10 @@
+ exit 1
+ }
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -96,7 +100,7 @@
+ name: Hosted macOS
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ export CC=clang
+
@@ -106,8 +110,10 @@
+ exit 1
+ }
+
-+ umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -124,7 +130,7 @@
+ name: Hosted macOS
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ ci/install-dependencies.sh
+ ci/run-build-and-tests.sh || {
@@ -132,8 +138,10 @@
+ exit 1
+ }
+
-+ umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -150,20 +158,22 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
-+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev
++ sudo apt-get update &&
++ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev &&
+
-+ export jobname=GETTEXT_POISON
++ export jobname=GETTEXT_POISON || exit 1
+
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -184,8 +194,10 @@
+ # Helper to check the error level of the latest command (exit with error when appropriate)
+ function c() { if (!$?) { exit(1) } }
+
-+ net use s: \\gitfileshare.file.core.windows.net\vsts-cache "$(gitfileshare.pwd)" /user:AZURE\gitfileshare /persistent:no; c
-+ cmd /c mklink /d "$(Build.SourcesDirectory)\vsts-cache" S:\; c
++ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
++ net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no; c
++ cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\; c
++ }
+
+ # Add build agent's MinGit to PATH
+ $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH
@@ -215,7 +227,7 @@
+
+ # Initialize Git for Windows' SDK
+ $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64"
-+ init "$sdk_path" "https://git-for-windows.visualstudio.com/_git/git-sdk-64" 0
++ init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0
+ init usr\src\build-extra https://github.com/git-for-windows/build-extra 1
+
+ cd "$(Build.SourcesDirectory)"; c
@@ -227,14 +239,19 @@
+
+ make -j10 DEVELOPER=1 NO_PERL=1 || exit 1
+ NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"--quiet --write-junit-xml\" time make -j15 -k DEVELOPER=1 test || {
-+ NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"-i -v -x\" make -k failed; exit 1
++ NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"-i -v -x\" make -k -C t failed; exit 1
+ }
+
+ save_good_tree
+ "@
++ c
+
-+ cmd /c rmdir "$(Build.SourcesDirectory)\vsts-cache"
++ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
++ cmd /c rmdir "$(Build.SourcesDirectory)\test-cache"
++ }
+ displayName: 'build & test'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -251,28 +268,30 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
++ sudo apt-get update &&
+ sudo apt-get -y install \
+ apt-transport-https \
+ ca-certificates \
+ curl \
-+ software-properties-common
-+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
++ software-properties-common &&
++ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &&
+ sudo add-apt-repository \
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) \
-+ stable"
-+ sudo apt-get update
-+ sudo apt-get -y install docker-ce
++ stable" &&
++ sudo apt-get update &&
++ sudo apt-get -y install docker-ce &&
+
+ sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1
+
+ sudo chmod a+r t/out/TEST-*.xml
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-linux32-docker.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
@@ -289,17 +308,19 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
-+ sudo apt-get install -y coccinelle
++ sudo apt-get update &&
++ sudo apt-get install -y coccinelle &&
+
-+ export jobname=StaticAnalysis
++ export jobname=StaticAnalysis &&
+
+ ci/run-static-analysis.sh || exit 1
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-static-analysis.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
+
+- phase: documentation
+ displayName: Documentation
@@ -308,18 +329,20 @@
+ name: Hosted Ubuntu 1604
+ steps:
+ - bash: |
-+ ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/vsts-cache gitfileshare "$(gitfileshare.pwd)" "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update
-+ sudo apt-get install -y asciidoc xmlto asciidoctor
++ sudo apt-get update &&
++ sudo apt-get install -y asciidoc xmlto asciidoctor &&
+
-+ export ALREADY_HAVE_ASCIIDOCTOR=yes.
-+ export jobname=Documentation
++ export ALREADY_HAVE_ASCIIDOCTOR=yes. &&
++ export jobname=Documentation &&
+
+ ci/test-documentation.sh || exit 1
+
-+ sudo umount "$HOME/vsts-cache" || exit 1
++ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/test-documentation.sh'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
diff --git a/ci/mount-fileshare.sh b/ci/mount-fileshare.sh
new file mode 100755
-: ---------- > 7: 12d6137f8d tests: introduce `test_atexit`
-: ---------- > 8: 3bb226b79b git-daemon: use `test_atexit` in the tests
-: ---------- > 9: 3e2193a73d git-p4: use `test_atexit` to kill the daemon
7: 942bf423a4 ! 10: ae3c42519a tests: include detailed trace logs with --write-junit-xml upon failure @@ -14,9 +14,9 @@
almost all of those cases: only when a test fails do we have a way to include the trace.
- So let's do something different in VSTS: let's run all the tests with
- --quiet first, and only if a failure is encountered, try to trace the
- commands as they are executed.
+ So let's do something different when using Azure DevOps: let's run all
+ the tests with --quiet first, and only if a failure is encountered,
+ try to trace the commands as they are executed.
Of course, we cannot turn on --verbose-log after the fact. So let's just re-run the test with all the same options, adding --verbose-log.
@@ -25,15 +25,10 @@
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with. Ideally, we would label
- this as "Passed upon rerun", and that outcome even exists on VSTS, but
- it is not available when using the JUnit XML format for now:
- https://github.com/Microsoft/vsts-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
-
- This patch contains a slightly inelegant workaround for the p4 and
- git-daemon tests: when we try to re-run the p4/git-daemon tests after
- the daemon has been started already, we need to kill said daemon. We do
- this by detecting the presence of the kill_p4d and stop_git_daemon
- shell functions and calling them if available.
+ this as "Passed upon rerun", and Azure Pipelines even know about that
+ outcome, but it is not available when using the JUnit XML format for
+ now:
+ https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
@@ -60,14 +55,8 @@
then
+ if test -z "$GIT_TEST_TEE_OUTPUT_FILE"
+ then
-+ case "$(type kill_p4d 2>/dev/null | head -n 1)" in
-+ *function*) kill_p4d;;
-+ esac
-+
-+ case "$(type stop_git_daemon 2>/dev/null |
-+ head -n 1)" in
-+ *function*) stop_git_daemon;;
-+ esac
++ # clean up
++ test_atexit_handler
+
+ # re-run with --verbose-log
+ echo "# Re-running: $junit_rerun_options_sq" >&2
8: 3e83c64090 = 11: 2466a48aa3 tests: record more stderr with --write-junit-xml in case of failure
9: dc1d890d71 ! 12: d112b3fe86 README: add a build badge (status of the VSTS build)
@@ -1,6 +1,6 @@
Author: Johannes Schindelin <[email protected]>
- README: add a build badge (status of the VSTS build)
+ README: add a build badge (status of the Azure Pipelines build)
Just like so many other OSS projects, we now also have a build badge.
@@ -10,7 +10,7 @@
--- a/README.md
+++ b/README.md
@@
-+[](https://git.visualstudio.com/git/_build/latest?definitionId=2)
++[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
+
Git - fast, scalable, distributed revision control system
========================================================= -: ---------- > 13: 0a53f37135 travis: fix skipping tagged releases
Signature · 1 line
gitgitgadget
PATCH v2 1/13 ci: rename the library of common functions
From: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
In the next commits, we will extend this to be able use Azure DevOps, too.
So let's adjust the name to make it more generic.
---
ci/install-dependencies.sh | 2 +-
ci/{lib-travisci.sh => lib.sh} | 0
ci/print-test-failures.sh | 2 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 2 +-
8 files changed, 7 insertions(+), 7 deletions(-)
rename ci/{lib-travisci.sh => lib.sh} (100%)ci/install-dependencies.sh +1 -1
@@ -3,7 +3,7 @@ # Install dependencies required to build and test Git on Linux and macOS # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
ci/lib.sh renamed from ci/lib-travisci.sh +0 -0
ci/print-test-failures.sh +1 -1
@@ -3,7 +3,7 @@ # Print output of failing tests # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh # Tracing executed commands would produce too much noise in the loop below. set +x
ci/run-build-and-tests.sh +1 -1
@@ -3,7 +3,7 @@ # Build and test Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh ln -s "$cache_dir/.prove" t/.prove
ci/run-linux32-docker.sh +1 -1
@@ -3,7 +3,7 @@ # Download and run Docker image to build and test 32-bit Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh docker pull daald/ubuntu32:xenial
ci/run-static-analysis.sh +1 -1
@@ -3,7 +3,7 @@ # Perform various static code analysis checks # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh make --jobs=2 coccicheck
ci/run-windows-build.sh +1 -1
@@ -6,7 +6,7 @@ # supported) and a commit hash. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh test $# -ne 2 && echo "Unexpected number of parameters" && exit 1 test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit
ci/test-documentation.sh +1 -1
@@ -3,7 +3,7 @@ # Perform sanity checks on documentation and build it. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh gem install asciidoctor
Signature · 1 line
gitgitgadget
Re: [PATCH v2 01/13] ci: rename the library of common functions
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 5 lines · writes:
From: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
Quoted 7 lines
In the next commits, we will extend this to be able use Azure DevOps, too.
So let's adjust the name to make it more generic.
Signed-off-by Johannes Schindelin <[email protected]>---
With many pieces still shared across these two CI systems, this looks like an excellent move.
I was wondering if the other extreme of moving ci/* to ci/travis/*, introducing ci/azure/* and sharing nothing was needed, but being able to share meaning amount of set-up sounds quite good.
PATCH v2 2/13 ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI.
--- ci/install-dependencies.sh | 3 ++- ci/lib.sh | 44 +++++++++++++++++++++++++++----------- ci/print-test-failures.sh | 2 +- ci/test-documentation.sh | 1 + 4 files changed, 35 insertions(+), 15 deletions(-)
ci/install-dependencies.sh +2 -1
@@ -28,7 +28,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + brew install $BREW_INSTALL_PACKAGES brew link --force gettext brew install caskroom/cask/perforce ;;
ci/lib.sh +31 -13
98 lines not on this page · raw message
ci/print-test-failures.sh +1 -1
@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ] then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
ci/test-documentation.sh +1 -0
@@ -5,6 +5,7 @@ . ${0%/*}/lib.sh +test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtins
Signature · 1 line
gitgitgadget
Re: [PATCH v2 02/13] ci/lib.sh: encapsulate Travis-specific things
Quoted 17 lines · Johannes Schindelin via GitGitGadget
ci/lib.sh +10
-0@@ -1,5 +1,26 @@ # Library of functions shared by all CI scripts +if test true = "$TRAVIS" +then + # We are running within Travis CI + CI_BRANCH="$TRAVIS_BRANCH" + CI_COMMIT="$TRAVIS_COMMIT" + CI_JOB_ID="$TRAVIS_JOB_ID" + CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER" + CI_OS_NAME="$TRAVIS_OS_NAME" + CI_REPO_SLUG="$TRAVIS_REPO_SLUG" +
ci/lib.sh line 22
Quoted 10 lines
ci/lib.sh +10
-0+ cache_dir="$HOME/travis-cache" + + url_for_job_id () { + echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1" + } + + BREW_INSTALL_PACKAGES="git-lfs gettext" + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fi
Please set all these variables ...
Quoted 60 lines
ci/lib.sh +10
-9+ skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building@@ -13,10 +34,10 @@ skip_branch_tip_with_tag () { # we can skip the build because we won't be skipping a build # of a tag. - if TAG=$(git describe --exact-match "$TRAVIS_BRANCH" 2>/dev/null) && - test "$TAG" != "$TRAVIS_BRANCH" + if TAG=$(git describe --exact-match "$CI_BRANCH" 2>/dev/null) && + test "$TAG" != "$CI_BRANCH" then - echo "$(tput setaf 2)Tip of $TRAVIS_BRANCH is exactly at $TAG$(tput sgr0)" + echo "$(tput setaf 2)Tip of $CI_BRANCH is exactly at $TAG$(tput sgr0)" exit 0 fi }@@ -25,7 +46,7 @@ skip_branch_tip_with_tag () { # job if we encounter the same tree again and can provide a useful info # message. save_good_tree () { - echo "$(git rev-parse $TRAVIS_COMMIT^{tree}) $TRAVIS_COMMIT $TRAVIS_JOB_NUMBER $TRAVIS_JOB_ID" >>"$good_trees_file" + 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 mv "$good_trees_file".tmp "$good_trees_file"@@ -35,7 +56,7 @@ save_good_tree () { # successfully before (e.g. because the branch got rebased, changing only # the commit messages). skip_good_tree () { - if ! good_tree_info="$(grep "^$(git rev-parse $TRAVIS_COMMIT^{tree}) " "$good_trees_file")" + 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. # Continue the build job.@@ -45,18 +66,18 @@ skip_good_tree () { echo "$good_tree_info" | { read tree prev_good_commit prev_good_job_number prev_good_job_id - if test "$TRAVIS_JOB_ID" = "$prev_good_job_id" + if test "$CI_JOB_ID" = "$prev_good_job_id" then cat <<-EOF - $(tput setaf 2)Skipping build job for commit $TRAVIS_COMMIT.$(tput sgr0) + $(tput setaf 2)Skipping build job for commit $CI_COMMIT.$(tput sgr0) This commit has already been built and tested successfully by this build job. To force a re-build delete the branch's cache and then hit 'Restart job'. EOF else cat <<-EOF - $(tput setaf 2)Skipping build job for commit $TRAVIS_COMMIT.$(tput sgr0) + $(tput setaf 2)Skipping build job for commit $CI_COMMIT.$(tput sgr0) This commit's tree has already been built and tested successfully in build job $prev_good_job_number for commit $prev_good_commit. - The log of that build job is available at https://travis-ci.org/$TRAVIS_REPO_SLUG/jobs/$prev_good_job_id + The log of that build job is available at $(url_for_job_id $prev_good_job_id) To force a re-build delete the branch's cache and then hit 'Restart job'. EOF fi
ci/lib.sh check_unignored_build_artifacts () · line 103
Quoted 2 lines
ci/lib.sh +0
-0@@ -81,7 +102,6 @@ check_unignored_build_artifacts () # and installing dependencies. set -ex
... after we turn on 'set -x', so the variables' values will be visible in the logs.
(Or move this 'set -ex' to the beginning of the script? Then we could perhaps avoid similar issues in the future.)
Quoted 4 lines
ci/lib.sh +0
-1-cache_dir="$HOME/travis-cache" good_trees_file="$cache_dir/good-trees" mkdir -p "$cache_dir"
Re: [PATCH v2 02/13] ci/lib.sh: encapsulate Travis-specific things
Quoted 8 lines · SZEDER Gábor
Quoted 7 lines · Johannes Schindelin via GitGitGadget
ci/lib.sh +0
-0@@ -1,5 +1,26 @@ # Library of functions shared by all CI scripts
Quoted 8 lines
ci/lib.sh line 22
Quoted 6 lines
ci/lib.sh +6
-0+if test true = "$TRAVIS" +then +... + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fiPlease set all these variables ...
Do you mean "VAR=VAL; export VAR" is kosher, "export VAR=VAL" is not?
Quoted 6 lines
ci/lib.sh check_unignored_build_artifacts () · line 103
Quoted 3 lines
ci/lib.sh +0
-0@@ -81,7 +102,6 @@ check_unignored_build_artifacts () # and installing dependencies. set -ex... after we turn on 'set -x', so the variables' values will be visible in the logs.
Ah, no, you didn't. Although I think both are valid points, I think ci/lib.sh is expected to be used only inside a more predictable environment (e.g. we know the shell used is not a random POSIX shell but one that is happy with "export VAR=VAL"), so it should be OK. Showing the values of these variables in the log may still be good idea.
Quoted 2 lines
(Or move this 'set -ex' to the beginning of the script? Then we could perhaps avoid similar issues in the future.)
Sure (provided that it is an issue to begin with---if we are interested in the value of TRAVIS_BRANCH, for example, being able to see it only because "CI_BRANCH=$TRAVIS_BRANCH" assignment is made feels a bit sideways---we'd be better off explicitly logging anything we are interested in in the longer term, no?).
Re: [PATCH v2 02/13] ci/lib.sh: encapsulate Travis-specific things
Quoted 29 lines · Junio C Hamano
Quoted 8 lines · SZEDER Gábor
Quoted 7 lines · Johannes Schindelin via GitGitGadget
ci/lib.sh +0
-0@@ -1,5 +1,26 @@ # Library of functions shared by all CI scriptsQuoted 8 lines
ci/lib.sh line 22
Quoted 6 lines
ci/lib.sh +6
-0+if test true = "$TRAVIS" +then +... + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fiPlease set all these variables ...
Do you mean "VAR=VAL; export VAR" is kosher, "export VAR=VAL" is not?
Quoted 6 lines
ci/lib.sh check_unignored_build_artifacts () · line 103
Quoted 3 lines
ci/lib.sh +0
-0@@ -81,7 +102,6 @@ check_unignored_build_artifacts () # and installing dependencies. set -ex... after we turn on 'set -x', so the variables' values will be visible in the logs.
Quoted 4 lines
Ah, no, you didn't. Although I think both are valid points, I think
ci/lib.shis expected to be used only inside a more predictable environment (e.g. we know the shell used is not a random POSIX shell but one that is happy with "export VAR=VAL"), so it should be OK.
Yes. Travis CI runs an Ubuntu LTS, where /bin/sh is dash, which understands 'export VAR=val' just fine. I don't know what Linux distro runs on Azure Pipelines, but the build definition in patch 6 explicitly asks for Bash, so that should be fine as well.
Quoted 11 lines
Showing the values of these variables in the log may still be good idea.
Quoted 2 lines
(Or move this 'set -ex' to the beginning of the script? Then we could perhaps avoid similar issues in the future.)
Sure (provided that it is an issue to begin with---if we are interested in the value of
TRAVIS_BRANCH, for example, being able to see it only because "CI_BRANCH=$TRAVIS_BRANCH" assignment is made feels a bit sideways---we'd be better off explicitly logging anything we are interested in in the longer term, no?).
Well, all the $TRAVIS_* and $CI_* variables are not that interessant, because they are only used in the build scripts, and then we can see their substituted values in the build logs. The same applies to the variables $cache_dir and $BREW_INSTALL_PACKAGES as well.
$GIT_PROVE_OPTS and $GIT_TEST_OPTS, however, are only used in 't/Makefile' but not in the build scripts, thus their values don't show up in the build logs.
I run some Travis CI builds with custom $GIT_TEST_OPTS, which, of course, conflicted with this patch, and I messed up the conflict resolution. I think I would have noticed sooner what went wrong, if the value of $GIT_TEST_OPTS were visible in the build logs.
I've found the output with 'set -x' sufficient so far, and don't think that an explicit logging facility is worth it.
Re: [PATCH v2 02/13] ci/lib.sh: encapsulate Travis-specific things
Quoted 12 lines · SZEDER Gábor
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
ci/lib.sh +6
-0+if test true = "$TRAVIS" +then +... + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fi...
$GIT_PROVE_OPTS and $GIT_TEST_OPTS, however, are only used in 't/Makefile' but not in the build scripts, thus their values don't show up in the build logs.
Quoted 7 lines
I run some Travis CI builds with custom $GIT_TEST_OPTS, which, of course, conflicted with this patch, and I messed up the conflict resolution. I think I would have noticed sooner what went wrong, if the value of $GIT_TEST_OPTS were visible in the build logs.
I've found the output with 'set -x' sufficient so far, and don't think that an explicit logging facility is worth it.
That's an interesting perspective. I would have thoguht that the values of these two variables we can see above, that are constants without any substitution or customization, are the least interesting things to see in the log.
PATCH v2 3/13 test-date: add a subcommand to measure times in shell scripts
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use date +%s for that, this will give us only seconds, i.e. very coarse-grained timings.
GNU date supports date +%s.%N (i.e. nanosecond-precision output), but there is no equivalent in BSD date (read: on macOS, we would not be able to obtain precise timings).
So let's introduce test-tool date getnanos, with an optional start time, that outputs preciser values.
Granted, it is a bit pointless to try measuring times accurately in shell scripts, certainly to nanosecond precision. But it is better than second-granularity.
--- t/helper/test-date.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
t/helper/test-date.c +12 -0
@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"" test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n" ;
@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos (const char **argv,struct timeval *now) +{ +double seconds =getnanotime () /1.0e9 ; + +if (*argv) + seconds -=strtod (*argv,NULL ); +printf ("%lf\n" , seconds); +} +int cmd__date (int argc,const char **argv) {struct timeval now;
@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)parse_approxidate (argv+1 , &now); else if (!strcmp(*argv, "timestamp"))parse_approx_timestamp (argv+1 , &now); + else if (!strcmp(*argv, "getnanos")) +getnanos (argv+1 , &now); else if (!strcmp(*argv, "is64bit"))return sizeof (timestamp_t) ==8 ?0 :1 ; else if (!strcmp(*argv, "time_t-is64bit"))
Signature · 1 line
gitgitgadget
PATCH v2 4/13 tests: optionally write results as JUnit-style .xml
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This will come in handy when publishing the results of Git's test suite during an automated Azure DevOps run.
--- t/.gitignore | 1 + t/test-lib.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+)
t/.gitignore +1 -0
@@ -2,3 +2,4 @@ /test-results /.prove /chainlinttmp +/out/
t/test-lib.sh +98 -0
159 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v2 5/13 ci/lib.sh: add support for Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
ci/lib.sh +23 -0
@@ -19,6 +19,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
Signature · 1 line
gitgitgadget
Re: [PATCH v2 05/13] ci/lib.sh: add support for Azure Pipelines
Quoted 16 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)ci/lib.sh +0
-0
ci/lib.sh then · line 19
Quoted 1 line
ci/lib.sh +0
-0@@ -19,6 +19,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext"
So we install these two additional packages in the macOS build jobs on Travis CI ...
Quoted 13 lines
ci/lib.sh +11
-0export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}"
ci/lib.sh then · line 42
Quoted 10 lines
ci/lib.sh +10
-0+ + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES=
... but not on Azure Pipelines. Is this mere oversight or intentional? If it's intentional, then I think the commit message should mention why.
Quoted 8 lines
ci/lib.sh +2
-0+ export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {Signature · 1 line
gitgitgadget
Re: [PATCH v2 05/13] ci/lib.sh: add support for Azure Pipelines
Hi Gábor,
Quoted 41 lines · SZEDER Gábor
Quoted 16 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)ci/lib.sh +0
-0ci/lib.sh then · line 19
Quoted 1 line
ci/lib.sh +0
-0@@ -19,6 +19,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext"So we install these two additional packages in the macOS build jobs on Travis CI ...
Quoted 19 lines
ci/lib.sh +17
-0export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () {
Quoted 8 lines
ci/lib.sh then · line 42
Quoted 4 lines
ci/lib.sh +4
-0+ echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES=... but not on Azure Pipelines. Is this mere oversight or intentional? If it's intentional, then I think the commit message should mention why.
Both packages are already available on Azure Pipelines' VMs. I will mention this in the commit message.
Thanks,
Dscho
Quoted 10 lines
Quoted 9 lines
ci/lib.sh +2
-0+ export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {Signature · 1 line
gitgitgadget
PATCH v2 6/13 Add a build definition for Azure DevOps
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the matrix feature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
--- azure-pipelines.yml | 319 ++++++++++++++++++++++++++++++++++++++++++ ci/mount-fileshare.sh | 26 ++++ 2 files changed, 345 insertions(+) create mode 100644 azure-pipelines.yml create mode 100755 ci/mount-fileshare.sh
azure-pipelines.yml new file +319 -0
@@ -0,0 +1,319 @@ +resources: +- repo: self + fetchDepth: 1 + +phases: +- phase: linux_clang + displayName: linux-clang + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin && + + export CC=clang || exit 1 + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux_gcc + displayName: linux-gcc + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1 + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_clang + displayName: osx-clang + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_gcc + displayName: osx-gcc + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: gettext_poison + displayName: GETTEXT_POISON + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev && + + export jobname=GETTEXT_POISON || exit 1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'gettext-poison' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: windows + displayName: Windows + condition: succeeded() + queue: + name: Hosted VS2017 + timeoutInMinutes: 240 + steps: + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no; c + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\; c + } + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + git init; c + } else { + git status + } + } else { + git init $path; c + cd $path; c + } + git config core.autocrlf false; c + git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + git remote add origin $url; c + } + git fetch --depth=1 $url master; c + git reset --hard FETCH_HEAD; c + git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + init usr\src\build-extra https://github.com/git-for-windows/build-extra 1 + + cd "$(Build.SourcesDirectory)"; c + + $env:HOME = "$(Build.SourcesDirectory)" + $env:MSYSTEM = "MINGW64" + git-sdk-64\git-cmd --command=usr\\bin\\bash.exe -lc @" + . ci/lib.sh + + make -j10 DEVELOPER=1 NO_PERL=1 || exit 1 + NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"--quiet --write-junit-xml\" time make -j15 -k DEVELOPER=1 test || { + NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"-i -v -x\" make -k -C t failed; exit 1 + } + + save_good_tree + "@ + c + + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'build & test' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux32 + displayName: Linux32 + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install \ + apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common && + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && + sudo add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" && + sudo apt-get update && + sudo apt-get -y install docker-ce && + + sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1 + + sudo chmod a+r t/out/TEST-*.xml + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-linux32-docker.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux32' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: static_analysis + displayName: StaticAnalysis + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y coccinelle && + + export jobname=StaticAnalysis && + + ci/run-static-analysis.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-static-analysis.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + +- phase: documentation + displayName: Documentation + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y asciidoc xmlto asciidoctor && + + export ALREADY_HAVE_ASCIIDOCTOR=yes. && + export jobname=Documentation && + + ci/test-documentation.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/test-documentation.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd)
ci/mount-fileshare.sh new file +26 -0
@@ -0,0 +1,26 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint" + +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;; +Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4" +
Signature · 1 line
gitgitgadget
Re: [PATCH v2 06/13] Add a build definition for Azure DevOps
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
Quoted 7 lines
Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 319 ++++++++++++++++++++++++++++++++++++++++++ ci/mount-fileshare.sh | 26 ++++ 2 files changed, 345 insertions(+) create mode 100644 azure-pipelines.yml create mode 100755 ci/mount-fileshare.sh
I wonder if there is a need to keep what is tested by this and Travis in sync in any way, but most of the logic is not defined in these "steps" but implemented in ci/*.sh scripts to be shared, so it would be OK, I guess.
Quoted 6 lines
ci/mount-fileshare.sh new file +0
-0
ci/mount-fileshare.sh line 9
Quoted 9 lines
ci/mount-fileshare.sh new file +9
-0@@ -0,0 +1,26 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint"
Missing closing '>'.
Quoted 7 lines
ci/mount-fileshare.sh new file +7
-0+ +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;;
ci/mount-fileshare.sh line 26
Quoted 10 lines
ci/mount-fileshare.sh new file +10
-0+Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4" +
Trailing blank line.
Thanks.
Re: [PATCH v2 06/13] Add a build definition for Azure DevOps
Hi Junio,
Quoted 17 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
Quoted 7 lines
Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 319 ++++++++++++++++++++++++++++++++++++++++++ ci/mount-fileshare.sh | 26 ++++ 2 files changed, 345 insertions(+) create mode 100644 azure-pipelines.yml create mode 100755 ci/mount-fileshare.sh
Quoted 4 lines
I wonder if there is a need to keep what is tested by this and Travis in sync in any way, but most of the logic is not defined in these "steps" but implemented in ci/*.sh scripts to be shared, so it would be OK, I guess.
Indeed, that was my intention.
These ci scripts are not only useful for Travis and Azure Pipelines, after all, but also a good documentation how to test locally. For example, to repeat Luke's Perforce testing, I could simply use the URLs listed in those ci scripts to get almost the same setup locally (close enough for testing).
So it is not only about sharing, and ease of maintenance, but it is also about documenting.
And yes, sharing means that we do not have to waste brain cycles on keeping things in sync.
Quoted 9 lines
Quoted 9 lines
ci/mount-fileshare.sh new file +3
-0@@ -0,0 +1,26 @@ +#!/bin/sh + +die () {
Quoted 8 lines
ci/mount-fileshare.sh line 9
Quoted 6 lines
ci/mount-fileshare.sh new file +6
-0+ echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint"Missing closing '>'.
Thanks!
Quoted 20 lines
Quoted 7 lines
ci/mount-fileshare.sh new file +7
-0+ +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;;ci/mount-fileshare.sh line 26
Quoted 10 lines
ci/mount-fileshare.sh new file +10
-0+Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4" +Trailing blank line.
Quoted 1 line
Thanks.
Thank you, both issues will be fixed in the next iteration, Dscho
Re: [PATCH v2 06/13] Add a build definition for Azure DevOps
In reply to Johannes Schindelin via GitGitGadgetQuoted 16 lines · Johannes Schindelin via GitGitGadget
azure-pipelines.yml new file +10
-0@@ -0,0 +1,319 @@ +resources: +- repo: self + fetchDepth: 1 + +phases: +- phase: linux_clang + displayName: linux-clang + condition: succeeded() + queue: + name: Hosted Ubuntu 1604
azure-pipelines.yml line 20
Quoted 10 lines
azure-pipelines.yml new file +10
-0+ steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin && + + export CC=clang || exit 1 + + ci/install-dependencies.sh
I think you would want to 'exit 1' when this script fails. This applies to other build jobs (erm, phases?) below as well.
Quoted 20 lines
azure-pipelines.yml new file +20
-0+ ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux_gcc + displayName: linux-gcc
azure-pipelines.yml line 50
Quoted 10 lines
azure-pipelines.yml new file +10
-0+ condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1 +
On Travis CI the Linux GCC build job uses gcc-8 instead of whatever the default is in that old-ish Ubuntu LTS; see 37fa4b3c78 (travis-ci:
run gcc-8 on linux-gcc jobs, 2018-05-19).
Quoted 48 lines
azure-pipelines.yml new file +48
-0+ ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_clang + displayName: osx-clang + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed()
azure-pipelines.yml line 108
Quoted 10 lines
azure-pipelines.yml new file +10
-0+ +- phase: osx_gcc + displayName: osx-gcc + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 +
Here you should 'export CC=gcc', because on macOS 'cc' is 'clang' by default.
Note, however, that setting 'CC' in the environment alone has no effect on the build process, it will still use 'cc'. Keep an eye on where this thread will lead to:
Quoted 19 lines
azure-pipelines.yml new file +19
-0+ ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() +
Re: [PATCH v2 06/13] Add a build definition for Azure DevOps
Hi Gábor,
Quoted 22 lines · SZEDER Gábor
Quoted 21 lines · Johannes Schindelin via GitGitGadget
azure-pipelines.yml new file +15
-0@@ -0,0 +1,319 @@ +resources: +- repo: self + fetchDepth: 1 + +phases: +- phase: linux_clang + displayName: linux-clang + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update &&
Quoted 8 lines
azure-pipelines.yml line 20
Quoted 5 lines
azure-pipelines.yml new file +5
-0+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin && + + export CC=clang || exit 1 + + ci/install-dependencies.shI think you would want to 'exit 1' when this script fails. This applies to other build jobs (erm, phases?) below as well.
True.
FWIW the nomenclature is "build" or "job" or "build job" for the entire run, from what I understand. The "phase" is the individual chunk that is run in an individual agent, i.e. you can have a single job running test on different OSes in separate phases.
Quoted 26 lines
Quoted 26 lines
azure-pipelines.yml new file +26
-0+ ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: linux_gcc + displayName: linux-gcc + condition: succeeded() + queue: + name: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
Quoted 8 lines
azure-pipelines.yml line 50
Quoted 4 lines
azure-pipelines.yml new file +4
-0+ + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1 +On Travis CI the Linux GCC build job uses gcc-8 instead of whatever the default is in that old-ish Ubuntu LTS; see
37fa4b3c78(travis-ci:
run gcc-8 on linux-gcc jobs, 2018-05-19).
I'll add those dependencies explicitly. It does seem, however, from a cursory look at the log, that gcc-8 should not even be picked up, as it is set via the environment variable CC (which, as you point out in below-referenced thread, is not respected):
[...]
2018-10-16T10:00:36.0177072Z ++ '[' linux-gcc = linux-gcc ']' 2018-10-16T10:00:36.0177380Z ++ export CC=gcc-8 2018-10-16T10:00:36.0177630Z ++ CC=gcc-8 2018-10-16T10:00:36.0177917Z ++ case "$jobname"
[...]
(see https://dev.azure.com/git/git/_build/results?buildId=192&view=logs)
Quoted 62 lines
Quoted 48 lines
azure-pipelines.yml new file +48
-0+ ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- phase: osx_clang + displayName: osx-clang + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed()azure-pipelines.yml line 108
Quoted 10 lines
azure-pipelines.yml new file +10
-0+ +- phase: osx_gcc + displayName: osx-gcc + condition: succeeded() + queue: + name: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 +Here you should 'export CC=gcc', because on macOS 'cc' is 'clang' by default.
Quoted 5 lines
Note, however, that setting 'CC' in the environment alone has no effect on the build process, it will still use 'cc'. Keep an eye on where this thread will lead to:
Will do.
Thanks,
Dscho
Quoted 21 lines
Quoted 20 lines
azure-pipelines.yml new file +19
-0+ ci/install-dependencies.sh + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() +
PATCH v2 7/13 tests: introduce `test_atexit`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When running the p4 daemon or git daemon, we want to kill it at the end of the test script.
So far, we do this "manually".
However, in the next few commits we want to teach the test suite to optionally re-run scripts with different options, therefore we will have to have a consistent way to stop daemons.
Let's introduce test_atexit, which is loosely modeled after test_when_finished (but has a broader scope: rather than running the commands after the current test case, run them when the test script finishes, and also run them when the --immediate option is in effect).
--- t/t0000-basic.sh | 18 ++++++++++++++++++ t/test-lib-functions.sh | 29 +++++++++++++++++++++++++++++ t/test-lib.sh | 4 ++++ 3 files changed, 51 insertions(+)
t/t0000-basic.sh +18 -0
@@ -821,6 +821,24 @@ test_expect_success 'tests clean up even on failures' " EOF " +test_expect_success 'test_atexit is run' " + test_must_fail run_sub_test_lib_test \ + atexit-cleanup 'Run atexit commands' -i <<-\\EOF && + test_expect_success 'tests clean up even after a failure' ' + > ../../clean-atexit && + test_atexit rm ../../clean-atexit && + > ../../also-clean-atexit && + test_atexit rm ../../also-clean-atexit && + > ../../dont-clean-atexit && + (exit 1) + ' + test_done + EOF + test_path_exists dont-clean-atexit && + test_path_is_missing clean-atexit && + test_path_is_missing also-clean-atexit +" + test_expect_success 'test_oid setup' ' test_oid_init '
t/test-lib-functions.sh +29 -0
@@ -891,6 +891,35 @@ test_when_finished () { } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" } +# This function can be used to schedule some commands to be run +# unconditionally at the end of the test script, e.g. to stop a daemon: +# +# test_expect_success 'test git daemon' ' +# git daemon & +# daemon_pid=$! && +# test_atexit "kill $daemon_pid" && +# hello world +# ' + +test_atexit () { + # We cannot detect when we are in a subshell in general, but by + # doing so on Bash is better than nothing (the test will + # silently pass on other shells). + test "${BASH_SUBSHELL-0}" = 0 || + error "bug in test script: test_atexit does nothing in a subshell" + test_atexit_cleanup="{ $* + } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup" +} + +test_atexit_handler () { + test : != "$test_atexit_cleanup" || return 0 + + setup_malloc_check + test_eval_ "$test_atexit_cleanup" + test_atexit_cleanup=: + teardown_malloc_check +} + # Most tests can use the created repository, but some may need to create more. # Usage: test_create_repo <directory> test_create_repo () {
t/test-lib.sh +4 -0
@@ -413,6 +413,7 @@ test_external_has_tap=0 die () { code=$? + test_atexit_handler || code=$? if test -n "$GIT_EXIT_OK" then exit $code
@@ -826,9 +827,12 @@ write_junit_xml_testcase () { junit_have_testcase=t } +test_atexit_cleanup=: test_done () { GIT_EXIT_OK=t + test -n "$immediate" || test_atexit_handler + if test -n "$write_junit_xml" && test -n "$junit_xml_path" then test -n "$junit_have_testcase" || {
Signature · 1 line
gitgitgadget
Re: [PATCH v2 07/13] tests: introduce `test_atexit`
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When running the p4 daemon or
git daemon, we want to kill it at the end of the test script.So far, we do this "manually".
Quoted 8 lines
However, in the next few commits we want to teach the test suite to optionally re-run scripts with different options, therefore we will have to have a consistent way to stop daemons.
Let's introduce
test_atexit, which is loosely modeled aftertest_when_finished(but has a broader scope: rather than running the commands after the current test case, run them when the test script finishes, and also run them when the--immediateoption is in effect).
I think killing daemons on failure even with '--immediate' will make life a bit easier. I remember several occasions when I tried to debug a failing test with '--immediate', some daemon stayed alive, and then the next time I run the test it failed during setup.
Besides 'git daemon' and P4, the httpd tests could benefit from this as well.
Quoted 7 lines
t/test-lib-functions.sh +0
-0@@ -891,6 +891,35 @@ test_when_finished () { } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" }
t/test-lib-functions.sh test_when_finished () { · line 902
Quoted 10 lines
t/test-lib-functions.sh +9
-0+# This function can be used to schedule some commands to be run +# unconditionally at the end of the test script, e.g. to stop a daemon: +# +# test_expect_success 'test git daemon' ' +# git daemon & +# daemon_pid=$! && +# test_atexit "kill $daemon_pid" && +# hello world +# '
I think we should add something like this as well:
# Note that these commands will be run even when a test script run
# with '--immediate' fails. Be careful with your commands to minimize # any changes to the failed state.
Quoted 9 lines
t/test-lib-functions.sh +9
-0+ +test_atexit () { + # We cannot detect when we are in a subshell in general, but by + # doing so on Bash is better than nothing (the test will + # silently pass on other shells). + test "${BASH_SUBSHELL-0}" = 0 || + error "bug in test script: test_atexit does nothing in a subshell" + test_atexit_cleanup="{ $* + } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup"
t/test-lib-functions.sh test_when_finished () { · line 921
Quoted 10 lines
t/test-lib-functions.sh +10
-0+} + +test_atexit_handler () { + test : != "$test_atexit_cleanup" || return 0 + + setup_malloc_check + test_eval_ "$test_atexit_cleanup" + test_atexit_cleanup=: + teardown_malloc_check +}
The file 'test-lib-functions.sh' contains helper functions to be used in tests. 'test_atexit_handler' is not such a function, so I think it would be better to add it to 'test-lib.sh'.
t/test-lib.sh test_external_has_tap=0 · line 415
Quoted 12 lines
t/test-lib-functions.sh +1
-0+ # Most tests can use the created repository, but some may need to create more. # Usage: test_create_repo <directory> test_create_repo () {t/test-lib.sh +0
-0@@ -413,6 +413,7 @@ test_external_has_tap=0 die () { code=$?
# Run atexit handlers even when a test script run with # '--immediate' fails.
t/test-lib.sh write_junit_xml_testcase () { · line 834
Quoted 13 lines
t/test-lib.sh +3
-0+ test_atexit_handler || code=$? if test -n "$GIT_EXIT_OK" then exit $code@@ -826,9 +827,12 @@ write_junit_xml_testcase () { junit_have_testcase=t } +test_atexit_cleanup=: test_done () { GIT_EXIT_OK=t + test -n "$immediate" || test_atexit_handler
You mentioned elsewhere [1] that you'll remove the condition to run 'test_atexit_handler' unconditionally. I think this is the right thing to do, because this condition is responsible for the hanging P4 tests I reported in [2].
So, 'lib-git-p4.sh' stores the pid of the 'p4d' process in the file "$TRASH_DIRECTORY/p4d.pid" in 'start_p4d', to be read later in 'kill_p4d' to know which process to kill. When a test script run with '--immediate' ends successfully, and the atexit handlers are run in 'die' above instead of in 'test_done', then you've got the problem that 'test_done' removes the trash directory along with the 'p4d.pid' file before the atexit handlers are run. With the pidfile gone 'kill_p4d' won't know which process to kill, and the 'p4d' process will stay alive.
If that condition is removed, then the atexit handlers will be run before the trash directory is removed, so 'p4d' processes will be stopped as they should even when an '--immediate' run succeeds. Good. Note, however, that in this case 'test_atexit_handler' will be called
twice: first in 'test_done' and then in 'die' as well. This should be fine, because 'test_atexit_handler' resets 'test_atexit_cleanup=:', so the second call will do nothing. Great. Perhaps this would be worth pointing out explicitly in the commit message and/or a comment.
[1] https://public-inbox.org/git/[email protected]/
[2] https://public-inbox.org/git/[email protected]/
Quoted 6 lines
t/test-lib.sh +1
-0+ if test -n "$write_junit_xml" && test -n "$junit_xml_path" then test -n "$junit_have_testcase" || {Signature · 1 line
gitgitgadget
PATCH v2 8/13 git-daemon: use `test_atexit` in the tests
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This makes use of the just-introduced consistent way to specify that a long-running process needs to be terminated at the end of a test script run.
--- t/interop/i5500-git-daemon.sh | 1 - t/lib-git-daemon.sh | 3 +-- t/t5570-git-daemon.sh | 1 - 3 files changed, 1 insertion(+), 4 deletions(-)
t/interop/i5500-git-daemon.sh +0 -1
@@ -37,5 +37,4 @@ test_expect_success "fetch with $VERSION_B" ' test_cmp expect actual ' -stop_git_daemon test_done
t/lib-git-daemon.sh +1 -2
@@ -13,7 +13,6 @@ # # test_expect_success ... # -# stop_git_daemon # test_done test_tristate GIT_TEST_GIT_DAEMON
@@ -43,7 +42,7 @@ start_git_daemon() { mkdir -p "$GIT_DAEMON_DOCUMENT_ROOT_PATH" - trap 'code=$?; stop_git_daemon; (exit $code); die' EXIT + test_atexit 'stop_git_daemon' say >&3 "Starting git daemon ..." mkfifo git_daemon_output
t/t5570-git-daemon.sh +0 -1
@@ -211,5 +211,4 @@ test_expect_success FAKENC 'hostname interpolation works after LF-stripping' ' test_cmp expect actual ' -stop_git_daemon test_done
Signature · 1 line
gitgitgadget
PATCH v2 9/13 git-p4: use `test_atexit` to kill the daemon
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
--- t/lib-git-p4.sh | 10 +--------- t/t0000-basic.sh | 2 ++ t/t9800-git-p4-basic.sh | 4 ---- t/t9801-git-p4-branch.sh | 4 ---- t/t9802-git-p4-filetype.sh | 4 ---- t/t9803-git-p4-shell-metachars.sh | 4 ---- t/t9804-git-p4-label.sh | 4 ---- t/t9805-git-p4-skip-submit-edit.sh | 4 ---- t/t9806-git-p4-options.sh | 5 ----- t/t9807-git-p4-submit.sh | 4 ---- t/t9808-git-p4-chdir.sh | 4 ---- t/t9809-git-p4-client-view.sh | 4 ---- t/t9810-git-p4-rcs.sh | 4 ---- t/t9811-git-p4-label-import.sh | 5 ----- t/t9812-git-p4-wildcards.sh | 4 ---- t/t9813-git-p4-preserve-users.sh | 4 ---- t/t9814-git-p4-rename.sh | 4 ---- t/t9815-git-p4-submit-fail.sh | 4 ---- t/t9816-git-p4-locked.sh | 4 ---- t/t9817-git-p4-exclude.sh | 4 ---- t/t9818-git-p4-block.sh | 4 ---- t/t9819-git-p4-case-folding.sh | 4 ---- t/t9820-git-p4-editor-handling.sh | 4 ---- t/t9821-git-p4-path-variations.sh | 4 ---- t/t9822-git-p4-path-encoding.sh | 4 ---- t/t9823-git-p4-mock-lfs.sh | 4 ---- t/t9824-git-p4-git-lfs.sh | 4 ---- t/t9825-git-p4-handle-utf16-without-bom.sh | 4 ---- t/t9826-git-p4-keep-empty-commits.sh | 4 ---- t/t9827-git-p4-change-filetype.sh | 4 ---- t/t9828-git-p4-map-user.sh | 4 ---- t/t9829-git-p4-jobs.sh | 4 ---- t/t9830-git-p4-symlink-dir.sh | 4 ---- t/t9831-git-p4-triggers.sh | 4 ---- t/t9832-unshelve.sh | 4 ---- t/t9833-errors.sh | 5 ----- 36 files changed, 3 insertions(+), 148 deletions(-)
t/lib-git-p4.sh +1 -9
@@ -74,15 +74,6 @@ cli="$TRASH_DIRECTORY/cli" git="$TRASH_DIRECTORY/git" pidfile="$TRASH_DIRECTORY/p4d.pid" -# Sometimes "prove" seems to hang on exit because p4d is still running -cleanup () { - if test -f "$pidfile" - then - kill -9 $(cat "$pidfile") 2>/dev/null && exit 255 - fi -} -trap cleanup EXIT - # git p4 submit generates a temp file, which will # not get cleaned up if the submission fails. Don't # clutter up /tmp on the test machine.
@@ -141,6 +132,7 @@ start_p4d () { # p4d failed to start return 1 fi + test_atexit kill_p4d # build a p4 user so [email protected] has an entry p4_add_user author
t/t0000-basic.sh +2 -0
@@ -134,6 +134,7 @@ check_sub_test_lib_test_err () { ) } +cat >/dev/null <<\DDD test_expect_success 'pretend we have a fully passing test suite' " run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF && for i in 1 2 3
@@ -820,6 +821,7 @@ test_expect_success 'tests clean up even on failures' " > 1..2 EOF " +DDD test_expect_success 'test_atexit is run' " test_must_fail run_sub_test_lib_test \
t/t9800-git-p4-basic.sh +0 -4
@@ -326,8 +326,4 @@ test_expect_success 'submit from worktree' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9801-git-p4-branch.sh +0 -4
@@ -610,8 +610,4 @@ test_expect_success 'Update a file in git side and submit to P4 using client vie ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9802-git-p4-filetype.sh +0 -4
@@ -333,8 +333,4 @@ test_expect_success SYMLINKS 'empty symlink target' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9803-git-p4-shell-metachars.sh +0 -4
@@ -105,8 +105,4 @@ test_expect_success 'branch with shell char' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9804-git-p4-label.sh +0 -4
@@ -108,8 +108,4 @@ test_expect_failure 'two labels on the same changelist' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9805-git-p4-skip-submit-edit.sh +0 -4
@@ -98,8 +98,4 @@ test_expect_success 'no config, edited' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9806-git-p4-options.sh +0 -5
@@ -300,9 +300,4 @@ test_expect_success 'use --git-dir option and GIT_DIR' ' test_path_is_file "$git"/cli_file2.t ' - -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9807-git-p4-submit.sh +0 -4
@@ -542,8 +542,4 @@ test_expect_success 'submit --update-shelve' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9808-git-p4-chdir.sh +0 -4
@@ -83,8 +83,4 @@ test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9809-git-p4-client-view.sh +0 -4
@@ -836,8 +836,4 @@ test_expect_success 'quotes on both sides' ' git_verify "cdir 1/file11" "cdir 1/file12" ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9810-git-p4-rcs.sh +0 -4
@@ -360,8 +360,4 @@ test_expect_failure 'Add keywords in git which do not match the default p4 value ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9811-git-p4-label-import.sh +0 -5
@@ -259,9 +259,4 @@ test_expect_success 'importing labels with missing revisions' ' ) ' - -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9812-git-p4-wildcards.sh +0 -4
@@ -211,8 +211,4 @@ test_expect_success 'wildcard files requiring keyword scrub' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9813-git-p4-preserve-users.sh +0 -4
@@ -138,8 +138,4 @@ test_expect_success 'not preserving user with mixed authorship' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9814-git-p4-rename.sh +0 -4
@@ -242,8 +242,4 @@ test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \ ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9815-git-p4-submit-fail.sh +0 -4
@@ -422,8 +422,4 @@ test_expect_success 'cleanup chmod after submit cancel' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9816-git-p4-locked.sh +0 -4
@@ -138,8 +138,4 @@ test_expect_failure 'move with lock taken' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9817-git-p4-exclude.sh +0 -4
@@ -64,8 +64,4 @@ test_expect_success 'clone, then sync with exclude' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9818-git-p4-block.sh +0 -4
@@ -146,8 +146,4 @@ test_expect_success 'Clone repo with self-sizing block size' ' test_line_count \> 10 log ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9819-git-p4-case-folding.sh +0 -4
@@ -53,8 +53,4 @@ test_expect_failure 'Clone UC repo with lc name' ' test_must_fail git p4 clone //depot/uc/... ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9820-git-p4-editor-handling.sh +0 -4
@@ -31,8 +31,4 @@ test_expect_success 'EDITOR with options' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9821-git-p4-path-variations.sh +0 -4
@@ -193,8 +193,4 @@ test_expect_success 'Add a new file and clone path with new file (ignorecase)' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9822-git-p4-path-encoding.sh +0 -4
@@ -67,8 +67,4 @@ test_expect_success 'Delete iso8859-1 encoded paths and clone' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9823-git-p4-mock-lfs.sh +0 -4
@@ -185,8 +185,4 @@ test_expect_success 'Run git p4 submit in repo configured with large file system ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9824-git-p4-git-lfs.sh +0 -4
@@ -287,8 +287,4 @@ test_expect_success 'Add big files to repo and store files in LFS based on compr ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9825-git-p4-handle-utf16-without-bom.sh +0 -4
@@ -43,8 +43,4 @@ test_expect_failure 'clone depot with invalid UTF-16 file in non-verbose mode' ' git p4 clone --dest="$git" //depot ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9826-git-p4-keep-empty-commits.sh +0 -4
@@ -127,8 +127,4 @@ test_expect_success 'Clone repo subdir with all history' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9827-git-p4-change-filetype.sh +0 -4
@@ -59,8 +59,4 @@ test_expect_success SYMLINKS 'change symbolic link to file' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9828-git-p4-map-user.sh +0 -4
@@ -54,8 +54,4 @@ test_expect_success 'Clone repo root path with all history' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9829-git-p4-jobs.sh +0 -4
@@ -92,8 +92,4 @@ test_expect_success 'check log message of changelist with more jobs' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9830-git-p4-symlink-dir.sh +0 -4
@@ -36,8 +36,4 @@ test_expect_success 'symlinked directory' ' ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9831-git-p4-triggers.sh +0 -4
@@ -96,8 +96,4 @@ test_expect_success 'submit description with extra info lines from verbose p4 ch ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9832-unshelve.sh +0 -4
@@ -131,8 +131,4 @@ test_expect_success 'try to unshelve the change' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - test_done
t/t9833-errors.sh +0 -5
@@ -72,9 +72,4 @@ test_expect_success 'git operation with expired ticket' ' ) ' -test_expect_success 'kill p4d' ' - kill_p4d -' - - test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
I'm finding that it's leaving p4d processes lying around.
e.g.
$ ./t9820-git-p4-editor-handling.sh <passes> $ ./t9820-git-p4-editor-handling.sh <fails>
And also
$ ./t9800-git-p4-basic.sh <starts running tests, but I get bored easily> Ctrl-C
$ ./t9800-git-p4-basic.sh <fails>
$ ps | grep p4d 21392 pts/1 00:00:00 p4d <<<<<
Luke
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
Hi Luke,
Quoted 11 lines · Luke Diamand
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
I'm finding that it's leaving p4d processes lying around.
That's a bummer!
Quoted 6 lines
e.g.
$ ./t9820-git-p4-editor-handling.sh <passes> $ ./t9820-git-p4-editor-handling.sh <fails>
Since I do not currently have a setup with p4d installed, can you run that with sh -x ... and see whether this code path is hit?
test_done () {
GIT_EXIT_OK=t
+ test -n "$immediate" || test_atexit_handler
+
if test -n "$write_junit_xml" && test -n "$junit_xml_path"
thenQuoted 5 lines
And also
$ ./t9800-git-p4-basic.sh <starts running tests, but I get bored easily> Ctrl-C
Oh, you're right. I think I need to do something in this line:
trap 'exit $?' INT
in t/test-lib.sh, something like
trap 'exit_code=$?; test_atexit_handler; exit $exit_code' INT
would you agree? (And: could you test?)
Thanks,
Dscho
Quoted 9 lines
$ ./t9800-git-p4-basic.sh <fails>$ ps | grep p4d 21392 pts/1 00:00:00 p4d <<<<<Luke
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
Quoted 21 lines · Johannes Schindelin
Hi Luke,
Quoted 11 lines · Luke Diamand
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
I'm finding that it's leaving p4d processes lying around.
That's a bummer!
Quoted 2 lines
e.g.
Quoted 7 lines
Quoted 4 lines
$ ./t9820-git-p4-editor-handling.sh <passes> $ ./t9820-git-p4-editor-handling.sh <fails>Since I do not currently have a setup with p4d installed, can you run that with
sh -x ...and see whether this code path is hit?
All you need to do is to put p4 and p4d in your PATH.
https://www.perforce.com/downloads/helix-core-p4d
https://www.perforce.com/downloads/helix-command-line-client-p4
The server is free to use for a small number of users, you don't need to do anything to make it go.
Review
Quoted 6 lines
test_done() {
GIT_EXIT_OK=t(quoted diff) +2
-0+ test -n "$immediate" || test_atexit_handler +
+ test -n
+ test_atexit_handler ./t9820-git-p4-editor-handling.sh: 764:
./t9820-git-p4-editor-handling.sh: test_atexit_handler: not found
Is that expected?
Quoted 11 lines
if test -n "$write_junit_xml" && test -n "$junit_xml_path" thenQuoted 5 lines
And also
$ ./t9800-git-p4-basic.sh <starts running tests, but I get bored easily> Ctrl-COh, you're right. I think I need to do something in this line:
Quoted 7 lines
trap 'exit $?' INT
in
t/test-lib.sh, something liketrap 'exit_code=$?;
test_atexit_handler; exit $exit_code' INTwould you agree? (And: could you test?)
Not sure.
Send me a patch and I can try it out.
Thanks,
Luke
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
Hi Luke,
Quoted 28 lines · Luke Diamand
Quoted 26 lines · Johannes Schindelin
Hi Luke,
Quoted 11 lines · Luke Diamand
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
I'm finding that it's leaving p4d processes lying around.
That's a bummer!
Quoted 6 lines
e.g.
$ ./t9820-git-p4-editor-handling.sh <passes> $ ./t9820-git-p4-editor-handling.sh <fails>
Quoted 7 lines
Quoted 2 lines
Since I do not currently have a setup with p4d installed, can you run that with
sh -x ...and see whether this code path is hit?All you need to do is to put p4 and p4d in your PATH.
https://www.perforce.com/downloads/helix-core-p4d
https://www.perforce.com/downloads/helix-command-line-client-p4
I did download p4d.exe and p4.exe to $HOME/custom/p4/ (similar to the way ci/install-dependencies.sh does it), from
http://filehost.perforce.com/perforce/r18.1/bin.ntx64/p4d.exe http://filehost.perforce.com/perforce/r18.1/bin.ntx64/p4.exe
and then prefixed PATH with $HOME/custom/p4, just to run t9820. However, it does not work here at all:
-- snip --
[...]
++ git p4 clone '--dest=/usr/src/git/azure-pipelines/t/trash directory.t9820-git-p4-editor-handling/git' //depot
Usage: git-p4 clone [options] //depot/path[@revRange]
[...]
-- snap --
I *think* the reason for that is that the MSYS path mangling kicks in when git.exe is called with the //depot argument (the leading // can be used in MSYS and MSYS2 to indicate that the non-MSYS .exe wants an argument that starts with a single slash, but is not a path that needs to be translated to a Windows path).
So I did the next best thing I could do: try things in the Windows Subsystem for Linux (AKA Bash on Ubuntu on Windows).
Quoted 9 lines
The server is free to use for a small number of users, you don't need to do anything to make it go.
Quoted 5 lines
test_done() {
GIT_EXIT_OK=t+ test -n "$immediate" ||
test_atexit_handler
On a slight tangent: I made up my mind on the test -n "$immediate" part:
I will skip that. The daemon should be stopped also when -i was passed to the test script (to stop at the first failing test case). There is very, very little use in keeping the daemon alive in that case.
The commit message of "tests: introduce test_atexit" already made the case for that, but somehow I had not made up my mind yet.
Quoted 8 lines
Quoted 1 line
+
+ test -n
+test_atexit_handler./t9820-git-p4-editor-handling.sh: 764:
./t9820-git-p4-editor-handling.sh:test_atexit_handler: not foundIs that expected?
No, that is not expected. For me, it looks quite a bit different, though:
-- snip --
[...]
+ test_done
+ GIT_EXIT_OK=t
+ test -n
+ test_atexit_handler
+ test : != { kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :
+ setup_malloc_check
+ MALLOC_CHECK_=3 MALLOC_PERTURB_=165
+ export MALLOC_CHECK_ MALLOC_PERTURB_
+ test_eval_ { kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :
+ test_eval_inner_ { kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :
+ eval
want_trace && set -x
{ kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :+ want_trace
+ test = t
+ kill_p4d
+ cat /home/wsl/git/wip/t/trash directory.t9820-git-p4-editor-handling/p4d.pid
+ pid=20093
+ retry_until_fail kill 20093
+ time_in_seconds
+ cd /
+ /usr/bin/python -c import time; print(int(time.time()))
+ timeout=1539681637
+ kill 20093
+ time_in_seconds
+ cd /
+ /usr/bin/python -c import time; print(int(time.time()))
+ test 1539681577 -gt 1539681637
+ sleep 1
+ true
+ time_in_seconds
+ cd /
+ /usr/bin/python -c import time; print(int(time.time()))
+ test 1539681578 -gt 1539681871
+ sleep 1
+ kill 20093
+ retry_until_fail kill -9 20093
+ time_in_seconds
+ cd /
+ /usr/bin/python -c import time; print(int(time.time()))
+ timeout=1539681638
+ kill -9 20093
+ test_must_fail kill 20093
+ _test_ok=
+ kill 20093
+ exit_code=1
+ test 1 -eq 0
+ test_match_signal 13 1
+ test 1 = 141
+ test 1 = 269
+ return 1
+ test 1 -gt 129
+ test 1 -eq 127
+ test 1 -eq 126
+ return 0
[...]
-- snap --
As you can see, it works quite well over here.
Maybe I could trouble you to fetch the vsts-ci branch from
https://github.com/dscho/git and test things on that one, just in case that anything important got "lost in the mail"?
Quoted 10 lines
Quoted 10 lines
if test -n "$write_junit_xml" && test -n "$junit_xml_path" thenQuoted 5 lines
And also
$ ./t9800-git-p4-basic.sh <starts running tests, but I get bored easily> Ctrl-COh, you're right.
So I tested this in WSL, and the relevant part of the output is this:
-- snip --
[...]
+ eval test_prereq_lazily_UTF8_NFD_TO_NFC=$2
+ test_prereq_lazily_UTF8_NFD_TO_NFC=
# check whether FS converts nfd unicode to nfc
au^CTraceback (most recent call last):
File "/home/virtualbox/git/wip/git-p4", line 4143, in <module>
main()
File "/home/virtualbox/git/wip/git-p4", line 4137, in main
if not cmd.run(args):
File "/home/virtualbox/git/wip/git-p4", line 3925, in run
if not P4Sync.run(self, depotPaths):
File "/home/virtualbox/git/wip/git-p4", line 3824, in run
system(["git", "symbolic-ref", head_ref, self.branch])
File "/home/virtualbox/git/wip/git-p4", line 278, in system
retcode = subprocess.call(cmd, shell=expand)
File "/usr/lib/python2.7/subprocess.py", line 523, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 1392, in wait
pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
File "/usr/lib/python2.7/subprocess.py", line 476, in _eintr_retry_call
return func(*args)
KeyboardInterrupt
+ exit 130
+ die
+ code=130
+ test_atexit_handler
+ test : != { kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :
[...]
-- snap --As you can see, the Ctrl+C managed to call die very well, without my proposed change:
Quoted 11 lines
Quoted 9 lines
I think I need to do something in this line:
trap 'exit $?' INT
in
t/test-lib.sh, something liketrap 'exit_code=$?;
test_atexit_handler; exit $exit_code' INTwould you agree? (And: could you test?)
Not sure.
I *think* what happens is that the INT trap already calls exit 130 alright, and then the EXIT trap comes into effect, as planned.
Just to make sure that it was not Python that caused the exit code 130, I tried it again, and luckily hit a spot where shell code was interpreted:
-- snip --
[...]
+ test_prereq_lazily_LONG_IS_64BIT=
test 8 -le "$(build_option sizeof-long)"
+ test_lazy_^C+ exit 130
+ die
+ code=130
+ test_atexit_handler
+ test : != { kill_p4d
} && (exit "$eval_ret"); eval_ret=$?; :
[...]
-- snap --
Same here. The Ctrl+C triggers an exit 130, this time I am certain that it comes from the INT trap, and that die in turn is most definitely from the EXIT trap, as intended.
My tests were performed with Dash, BTW, not with Bash:
-- snip --
$ dpkg -S $(which sh) diversion by dash from: /bin/sh diversion by dash to: /bin/sh.distrib dash: /bin/sh -- snap --
But I also repeated the tests with Bash, with almost the same result: the only difference was that I did not manage to get the traces of test_atexit_handler being called, but the p4d was no longer alive, so it must have been killed as intended.
Quoted 1 line
Send me a patch and I can try it out.
I would *love* to figure out what is happening in your setup, and to fix it. In my hands, the patches work, though...
Ciao,
Dscho
Quoted 4 lines
Thanks,
Luke
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
In reply to Johannes Schindelin via GitGitGadgetQuoted 13 lines · Johannes Schindelin via GitGitGadget
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
Signed-off-by Johannes Schindelin <[email protected]>---
t/t0000-basic.sh +1
-0@@ -134,6 +134,7 @@ check_sub_test_lib_test_err () { +cat >/dev/null <<\DDD test_expect_success 'pretend we have a fully passing test suite' " run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF && for i in 1 2 3
t/t0000-basic.sh test_expect_success 'tests clean up even on failures' " · line 824
Quoted 4 lines
t/t0000-basic.sh +1
-0@@ -820,6 +821,7 @@ test_expect_success 'tests clean up even on failures' " > 1..2 EOF " +DDD
Is this "DDD" here-doc leftover debugging goop?
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
Hi Eric,
Quoted 6 lines · Eric Sunshine
Quoted 4 lines · Johannes Schindelin via GitGitGadget
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
Quoted 15 lines
t/t0000-basic.sh test_expect_success 'tests clean up even on failures' " · line 824
Quoted 13 lines
Signed-off-by Johannes Schindelin <[email protected]>---
t/t0000-basic.sh +2
-0@@ -134,6 +134,7 @@ check_sub_test_lib_test_err () { +cat >/dev/null <<\DDD test_expect_success 'pretend we have a fully passing test suite' " run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF && for i in 1 2 3@@ -820,6 +821,7 @@ test_expect_success 'tests clean up even on failures' " > 1..2 EOF " +DDDIs this "DDD" here-doc leftover debugging goop?
Oy, oy, oy. This is definitely a left-over from debugging (as you can imagine, it is pretty slow to run t0000-init.sh on Windows, and if I add a test case, the development cycle is much faster with the trick you see aboive). This left-over even made it into Git for Windows' master branch! (Which is the reason I missed it before contributing v2).
Will fix,
Dscho
Re: [PATCH v2 09/13] git-p4: use `test_atexit` to kill the daemon
In reply to Johannes Schindelin via GitGitGadgetQuoted 5 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
This should be more reliable than the current method, and prepares the test suite for a consistent way to clean up before re-running the tests with different options.
This patch makes the test suite hang in all four Travis CI build jobs with P4 installed without any of the P4 tests finishing.
Reverting this patch from the whole patch series makes it work again.
I've also tried to revert only this first hunk of the patch below, because based on the comment I thought it's worth a try, but it didn't really help. It did make a difference: the 300s watchdog timer eventually kicked in, and then the test scripts could finish successfully... but there are a lot of P4 test scripts, and with each taking 300s the build job still timeouted.
All this may (or may not) be related to and be a different symptom of the leftover p4d processes Luke mentioned. I couldn't reproduce any of this on my machine so far.
Quoted 20 lines
t/lib-git-p4.sh +0
-9@@ -74,15 +74,6 @@ cli="$TRASH_DIRECTORY/cli" git="$TRASH_DIRECTORY/git" pidfile="$TRASH_DIRECTORY/p4d.pid" -# Sometimes "prove" seems to hang on exit because p4d is still running -cleanup () { - if test -f "$pidfile" - then - kill -9 $(cat "$pidfile") 2>/dev/null && exit 255 - fi -} -trap cleanup EXIT - # git p4 submit generates a temp file, which will # not get cleaned up if the submission fails. Don't # clutter up /tmp on the test machine.
PATCH v2 10/13 tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the --verbose-log option to get those traces. However, that seems excessive, as we do not need/use the logs in almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with --quiet first, and only if a failure is encountered, try to trace the commands as they are executed.
Of course, we cannot turn on --verbose-log after the fact. So let's just re-run the test with all the same options, adding --verbose-log. And then munging the output file into the JUnit XML on the fly.
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with. Ideally, we would label this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
--- t/test-lib.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
t/test-lib.sh +33 -1
@@ -85,6 +85,13 @@ done,*) test "$(cat "$BASE.exit")" = 0 exit ;; +*' --write-junit-xml '*) + # record how to call this script *with* --verbose-log, in case + # we encounter a breakage + junit_rerun_options_sq="$(printf '%s\n' "$0" --verbose-log -x "$@" | + sed -e "s/'/'\\\\''/g" -e "s/^/'/" -e "s/\$/'/" | + tr '\012' ' ')" + ;; esac # For repeatability, reset the environment to known value.
@@ -446,10 +453,31 @@ test_ok_ () { test_failure_ () { if test -n "$write_junit_xml" then + if test -z "$GIT_TEST_TEE_OUTPUT_FILE" + then + # clean up + test_atexit_handler + + # re-run with --verbose-log + echo "# Re-running: $junit_rerun_options_sq" >&2 + + cd "$TEST_DIRECTORY" && + eval "${TEST_SHELL_PATH}" "$junit_rerun_options_sq" \ + >/dev/null 2>&1 + status=$? + + say_color "" "$(test 0 = $status || + echo "not ")ok $test_count - (re-ran with trace)" + say "1..$test_count" + GIT_EXIT_OK=t + exit $status + fi + junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")" + >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" write_junit_xml_testcase "$1" " $junit_insert" fi
@@ -734,6 +762,10 @@ test_start_ () { if test -n "$write_junit_xml" then junit_start=$(test-tool date getnanos) + + # truncate output + test -z "$GIT_TEST_TEE_OUTPUT_FILE" || + >"$GIT_TEST_TEE_OUTPUT_FILE" fi }
Signature · 1 line
gitgitgadget
Re: [PATCH v2 10/13] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 11 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the
--verbose-logoption to get those traces. However, that seems excessive, as we do not need/use the logs in
As someone who has dug into a few occasional failures found by Travis CI, I'd say that the output of '--verbose-log -x' is not excessive, but downright essential.
Quoted 7 lines
almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed.
Quoted 7 lines
Of course, we cannot turn on
--verbose-logafter the fact. So let's just re-run the test with all the same options, adding--verbose-log. And then munging the output file into the JUnit XML on the fly.Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with.
Any CI system worth its salt should provide as much information about any failures as possible, especially when it was lucky enough to stumble upon a rare and hard to reproduce non-deterministic failure.
Quoted 7 lines
Ideally, we would label
this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.csSigned-off-by Johannes Schindelin <[email protected]>
Re: [PATCH v2 10/13] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Gábor,
Quoted 10 lines · SZEDER Gábor
Quoted 9 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
Quoted 6 lines
Quoted 2 lines
With Travis CI, we passed the
--verbose-logoption to get those traces. However, that seems excessive, as we do not need/use the logs inAs someone who has dug into a few occasional failures found by Travis CI, I'd say that the output of '--verbose-log -x' is not excessive, but downright essential.
I agree that the output is essential for drilling down into failures. This paragraph, however, talks about the general case: where there are *no* failures. See here:
Quoted 11 lines
Quoted 11 lines
almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed.Of course, we cannot turn on
--verbose-logafter the fact. So let's just re-run the test with all the same options, adding--verbose-log. And then munging the output file into the JUnit XML on the fly.
Quoted 7 lines
Quoted 3 lines
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with.
Any CI system worth its salt should provide as much information about any failures as possible, especially when it was lucky enough to stumble upon a rare and hard to reproduce non-deterministic failure.
I would agree with you if more people started to pay attention to our CI failures. And if we had some sort of a development model where a CI failure would halt development on that particular topic until the failure is fixed, with the responsibility assigned to somebody to fix it.
This is not the case here, though. pu is broken for ages, at least on Windows, and even a *single* topic is enough to do that. And this is even worse with flakey tests. I cannot remember *how often* I saw CI failures in t5570-git-daemon.sh, for example. It is rare enough that it is obvious that this is a problem of the *regression test*, rather than a problem of the code that is to be tested.
So I would suggest to go forward with my proposed strategy for the moment, right up until the time when we have had the resources to fix t5570, for starters.
Ciao,
Dscho
Quoted 7 lines
Quoted 6 lines
Ideally, we would label this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.csSigned-off-by Johannes Schindelin <[email protected]>
Re: [PATCH v2 10/13] tests: include detailed trace logs with --write-junit-xml upon failure
Quoted 17 lines · Johannes Schindelin
Hi Gábor,
Quoted 13 lines · SZEDER Gábor
Quoted 11 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the
--verbose-logoption to get those traces. However, that seems excessive, as we do not need/use the logs in
Quoted 7 lines
Quoted 3 lines
As someone who has dug into a few occasional failures found by Travis CI, I'd say that the output of '--verbose-log -x' is not excessive, but downright essential.
I agree that the output is essential for drilling down into failures. This paragraph, however, talks about the general case: where there are *no* failures. See here:
But you don't know in advance whether there will be any failures or not, so it only makes sense to run all tests with '--verbose-log -x' by default, just in case a Heisenbug decides to make an appearance.
Quoted 24 lines
Quoted 11 lines
Quoted 11 lines
almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with
--quietfirst, and only if a failure is encountered, try to trace the commands as they are executed.Of course, we cannot turn on
--verbose-logafter the fact. So let's just re-run the test with all the same options, adding--verbose-log. And then munging the output file into the JUnit XML on the fly.Quoted 7 lines
Quoted 3 lines
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with.
Any CI system worth its salt should provide as much information about any failures as possible, especially when it was lucky enough to stumble upon a rare and hard to reproduce non-deterministic failure.
I would agree with you if more people started to pay attention to our CI failures. And if we had some sort of a development model where a CI failure would halt development on that particular topic until the failure is fixed, with the responsibility assigned to somebody to fix it.
Quoted 6 lines
This is not the case here, though. pu is broken for ages, at least on Windows, and even a *single* topic is enough to do that. And this is even worse with flakey tests. I cannot remember *how often* I saw CI failures in
t5570-git-daemon.sh, for example. It is rare enough that it is obvious that this is a problem of the *regression test*, rather than a problem of the code that is to be tested.
Some occasional failures in t5570 are actually caused by issues in Git on certain platforms:
https://public-inbox.org/git/CAM0VKj=MCS+cmOgzf_XyPeb+qZrFmuMH52-PV_NDMZA9X+rRoA@mail.gmail.com/T/#u
Quoted 3 lines
So I would suggest to go forward with my proposed strategy for the moment, right up until the time when we have had the resources to fix t5570, for starters.
I don't really understand what the occasional failures in t5570 have to do with the amount of information a CI system should gather about failures in general. Or how many people pay attention to it, or what kind of development model we have, for that matter. The way I see it these are unrelated issues, and a CI system should always provide as much information about failures as possible. If only a few people pay attention to it, then for the sake of those few.
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Ideally, we would label this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.csSigned-off-by Johannes Schindelin <[email protected]>
Re: [PATCH v2 10/13] tests: include detailed trace logs with --write-junit-xml upon failure
Hi Gábor,
Quoted 9 lines · SZEDER Gábor
Quoted 3 lines · Johannes Schindelin
So I would suggest to go forward with my proposed strategy for the moment, right up until the time when we have had the resources to fix t5570, for starters.
I don't really understand what the occasional failures in t5570 have to do with the amount of information a CI system should gather about failures in general.
I see it plenty of times that too many CI failures essentially render every developer numb.
If every 3rd CI run causes a failure, and seemingly every of these failures indicates a mistake in the regression test, rather than a regression, developers stop paying attention.
Which is the exact opposite of what I want to achieve here.
Ciao,
Dscho
PATCH v2 11/13 tests: record more stderr with --write-junit-xml in case of failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Sometimes, failures in a test case are actually caused by issues in earlier test cases.
To make it easier to see those issues, let's attach the output from before the failing test case (i.e. stdout/stderr since the previous failing test case, or the start of the test script). This will be visible in the "Attachments" of the details of the failed test.
--- t/test-lib.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
t/test-lib.sh +9 -3
@@ -479,6 +479,9 @@ test_failure_ () { "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")" >"$GIT_TEST_TEE_OUTPUT_FILE" junit_insert="$junit_insert</failure>" + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE.err")")</system-err>" + >"$GIT_TEST_TEE_OUTPUT_FILE.err" write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1))
@@ -763,9 +766,12 @@ test_start_ () { then junit_start=$(test-tool date getnanos) - # truncate output - test -z "$GIT_TEST_TEE_OUTPUT_FILE" || - >"$GIT_TEST_TEE_OUTPUT_FILE" + # append to future <system-err>; truncate output + test -z "$GIT_TEST_TEE_OUTPUT_FILE" || { + cat "$GIT_TEST_TEE_OUTPUT_FILE" \ + >>"$GIT_TEST_TEE_OUTPUT_FILE.err" + >"$GIT_TEST_TEE_OUTPUT_FILE" + } fi }
Signature · 1 line
gitgitgadget
PATCH v2 12/13 README: add a build badge (status of the Azure Pipelines build)
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Just like so many other OSS projects, we now also have a build badge.
--- README.md | 2 ++ 1 file changed, 2 insertions(+)
README.md +2 -0
@@ -1,3 +1,5 @@ +[](https://dev.azure.com/git/git/_build/latest?definitionId=2) + Git - fast, scalable, distributed revision control system =========================================================
Signature · 1 line
gitgitgadget
Re: [PATCH v2 12/13] README: add a build badge (status of the Azure Pipelines build)
README.md line 1
Quoted 7 lines · Johannes Schindelin via GitGitGadget
Just like so many other OSS projects, we now also have a build badge.
Signed-off-by Johannes Schindelin <[email protected]>---
README.md +1
-0@@ -1,3 +1,5 @@ +[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
The first URL is broken "https:/..." rather than "https://...".
Re: [PATCH v2 12/13] README: add a build badge (status of the Azure Pipelines build)
Hi Eric,
Quoted 11 lines · Eric Sunshine
README.md line 1
Quoted 7 lines · Johannes Schindelin via GitGitGadget
Just like so many other OSS projects, we now also have a build badge.
Signed-off-by Johannes Schindelin <[email protected]>---
README.md +1
-0@@ -1,3 +1,5 @@ +[](https://dev.azure.com/git/git/_build/latest?definitionId=2)The first URL is broken "https:/..." rather than "https://...".
I *swear* I fixed this already. Darn.
Thank you,
Dscho
PATCH v2 13/13 travis: fix skipping tagged releases
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When building a PR, TRAVIS_BRANCH refers to the *target branch*. Therefore, if a PR targets master, and master happened to be tagged, we skipped the build by mistake.
Fix this by using TRAVIS_PULL_REQUEST_BRANCH (i.e. the *source branch*) when available, falling back to TRAVIS_BRANCH (i.e. for CI builds, also known as "push builds").
--- ci/lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ci/lib.sh +1 -1
@@ -3,7 +3,7 @@ if test true = "$TRAVIS" then # We are running within Travis CI - CI_BRANCH="$TRAVIS_BRANCH" + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" CI_COMMIT="$TRAVIS_COMMIT" CI_JOB_ID="$TRAVIS_JOB_ID" CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER"
Signature · 1 line
gitgitgadget
Re: [PATCH v2 13/13] travis: fix skipping tagged releases
Quoted 9 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When building a PR,
TRAVIS_BRANCHrefers to the *target branch*. Therefore, if a PR targetsmaster, andmasterhappened to be tagged, we skipped the build by mistake.Fix this by using
TRAVIS_PULL_REQUEST_BRANCH(i.e. the *source branch*) when available, falling back toTRAVIS_BRANCH(i.e. for CI builds, also known as "push builds").
This all makes sense, but this patch is fixing a long-standing issue in our Travis CI build scripts (present since 09f5e9746c (travis-ci:
skip a branch build if equal tag is present, 2017-09-10)), so it should be the first in the series. So it could be picked up and perhaps even graduated faster than the rest of this patch series.
Quoted 20 lines
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/lib.sh +1
-1@@ -3,7 +3,7 @@ if test true = "$TRAVIS" then # We are running within Travis CI - CI_BRANCH="$TRAVIS_BRANCH" + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" CI_COMMIT="$TRAVIS_COMMIT" CI_JOB_ID="$TRAVIS_JOB_ID" CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER"Signature · 1 line
gitgitgadget
Re: [PATCH v2 13/13] travis: fix skipping tagged releases
Hi Junio,
Quoted 11 lines · SZEDER Gábor
Quoted 9 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When building a PR,
TRAVIS_BRANCHrefers to the *target branch*. Therefore, if a PR targetsmaster, andmasterhappened to be tagged, we skipped the build by mistake.Fix this by using
TRAVIS_PULL_REQUEST_BRANCH(i.e. the *source branch*) when available, falling back toTRAVIS_BRANCH(i.e. for CI builds, also known as "push builds").
Quoted 5 lines
This all makes sense, but this patch is fixing a long-standing issue in our Travis CI build scripts (present since
09f5e9746c(travis-ci:
skip a branch build if equal tag is present, 2017-09-10)), so it should be the first in the series. So it could be picked up and perhaps even graduated faster than the rest of this patch series.
Makes sense.
Thanks,
Dscho
Quoted 22 lines
Quoted 21 lines
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/lib.sh +1
-1@@ -3,7 +3,7 @@ if test true = "$TRAVIS" then # We are running within Travis CI - CI_BRANCH="$TRAVIS_BRANCH" + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" CI_COMMIT="$TRAVIS_COMMIT" CI_JOB_ID="$TRAVIS_JOB_ID" CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER"Signature · 1 line
gitgitgadget
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetHi Johannes,
Thanks for putting this together, and offering to build Git on Azure Pipelines. I haven't followed v1 of this series very closely, so please excuse me if my comments have already been addressed, and I missed them in a skim of the last revision.
Quoted 4 lines · Johannes Schindelin via GitGitGadget
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
Agree.
Quoted 4 lines
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
I wonder if Travis' recent announcement [1] affects this at all. To summarize [1], Travis is offering an early version of adding Windows to their list of supported builder operations systems. This brings the list to macOS, Linux, and Windows, which I think satisfies what we would like to regularly build git.git on.
Would we like to abandon Travis as our main CI service for upstream git.git, and build on Azure Pipelines only? If so, I think that this is an OK way to go, but I think that I would be opposed to having more than one build system. (FWIW, we tend to _three_ for Git LFS, and it can be a hassle at times).
I see some benefit to sticking with Travis, since we already have a build configuration that works there. But, you've done the work to "port" that build configuration over to Azure, so perhaps the point is moot.
Quoted 4 lines
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
This would be a concession of [1], in my mind: is it possible to run the tests on Windows in a time such that Travis will not time out?
Quoted 8 lines
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).
That's pretty cool. Travis doesn't support this (to the best of my knowledge).
Thanks,
Taylor
[1]: https://blog.travis-ci.com/2018-10-11-windows-early-release
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Hi Taylor,
Quoted 11 lines · Taylor Blau
Thanks for putting this together, and offering to build Git on Azure Pipelines. I haven't followed v1 of this series very closely, so please excuse me if my comments have already been addressed, and I missed them in a skim of the last revision.
Quoted 4 lines · Johannes Schindelin via GitGitGadget
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
Quoted 8 lines
Agree.
Quoted 4 lines
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
I wonder if Travis' recent announcement [1] affects this at all.
:-)
It did not escape my notice that after years and years of trying to get *anybody* at Travis to listen to my offers to help get this started, the announcement of Azure Pipelines for OSS seemed to finally do the trick (they still don't bother to talk to me, of course).
And to answer your question without a question mark: I do not really think that the Travis announcement affects this here patch series: I have a ton of good experience with Azure Pipelines, use it in Git for Windows for ages, and I am finally able to have it in core Git, too. So I want it, and I spent a lot of time getting there, and I think it probably won't hurt core Git at all (besides, it seems that at least some of the phases are a bit faster on Azure Pipelines than Travis).
Another really good reason for me to do this is that I can prod the Azure Pipelines team directly. And I even get an answer, usually within minutes. Which is a lot faster than the Travis team answers my questions, which is... not yet? (I tried to get in contact with them in late 2015 or early 2016, and I tried again a year later, and then a couple of months later, and I have yet to hear back.)
Also, I am not quite sure about the timeouts on Travis, but at least AppVeyor had rather short timeouts: the Windows build (due to our extensive use of Unix shell scripting in our test suite) takes 1h40m currently, and AppVeyor times out after 20 or 30 minutes. I could imagine that Travis times out after the same time, or maybe 60 minutes, which would still be too short. On Azure Pipelines, the maximum timeout (which can be configured via the azure-pipelines.yml file) is four hours IIRC. Plenty enough even for our test suite on Windows.
Quoted 4 lines
To summarize [1], Travis is offering an early version of adding Windows to their list of supported builder operations systems. This brings the list to macOS, Linux, and Windows, which I think satisfies what we would like to regularly build git.git on.
Honestly, I would love to have also FreeBSD and other platforms being tested. And with Azure Pipelines, I can make that happen (eventually), by adding another pool of VMs (given that I have a free $150/month Azure subscription, I'd use Azure VMs, of course). As long as a platform can run .NET Core software, it can run Azure Pipelines agents.
With Travis, I don't think I can add private agent pools.
Quoted 5 lines
Would we like to abandon Travis as our main CI service for upstream git.git, and build on Azure Pipelines only? If so, I think that this is an OK way to go, but I think that I would be opposed to having more than one build system. (FWIW, we tend to _three_ for Git LFS, and it can be a hassle at times).
This question of abandoning Travis in favor of Azure Pipelines is a bit of a hornets' nest, as I really, really only want to bring the goodness of Azure Pipelines to git.git, and I am *clearly* biased, as I work at Microsoft.
Which is the reason why I did not even hint at it in the cover letter, let alone included a patch to make it so.
My patch series is purely about adding support for running CI/PR builds of
https://github.com/git/git via Azure Pipelines.
Quoted 4 lines
I see some benefit to sticking with Travis, since we already have a build configuration that works there. But, you've done the work to "port" that build configuration over to Azure, so perhaps the point is moot.
It is not so much a port, as an attempt to generalize our ci/* files.
Quoted 7 lines
Quoted 4 lines
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
This would be a concession of [1], in my mind: is it possible to run the tests on Windows in a time such that Travis will not time out?
To be honest, I spent such a lot of time to get things to work on Azure Pipelines, *and* we get a nice view on the test failures there, too (which Travis will probably also offer soon, in response to what Azure Pipelines offer ;-)), I cannot really justify spending time on trying to make things work on Travis' Windows VMs, too. Especially when I have to expect to run into timeout issues anyway.
Quoted 11 lines
Quoted 8 lines
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).That's pretty cool. Travis doesn't support this (to the best of my knowledge).
Exactly.
Plus, if things don't work in Azure Pipelines, I (or one of the other Microsoft employees among the core Git developers) can easily take a shortcut to the team and get things fixed. In my mind, that counts for a lot, too, especially given my own, frustrating personal experience with Travis.
Ciao,
Dscho
Quoted 1 line
[1]: https://blog.travis-ci.com/2018-10-11-windows-early-release
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Quoted 31 lines · Johannes Schindelin
Hi Taylor,
Quoted 11 lines · Taylor Blau
Thanks for putting this together, and offering to build Git on Azure Pipelines. I haven't followed v1 of this series very closely, so please excuse me if my comments have already been addressed, and I missed them in a skim of the last revision.
Quoted 4 lines · Johannes Schindelin via GitGitGadget
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
Quoted 8 lines
Agree.
Quoted 4 lines
The one sad part about this is the Windows support. Travis lacks it, and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
I wonder if Travis' recent announcement [1] affects this at all.
:-)
It did not escape my notice that after years and years of trying to get *anybody* at Travis to listen to my offers to help get this started, the announcement of Azure Pipelines for OSS seemed to finally do the trick (they still don't bother to talk to me, of course).
Quoted 7 lines
And to answer your question without a question mark: I do not really think that the Travis announcement affects this here patch series: I have a ton of good experience with Azure Pipelines, use it in Git for Windows for ages, and I am finally able to have it in core Git, too. So I want it, and I spent a lot of time getting there, and I think it probably won't hurt core Git at all (besides, it seems that at least some of the phases are a bit faster on Azure Pipelines than Travis).
I think that there are fair reasons to prefer Azure Pipelines over Travis. In particular, I am encouraged by the fact that we (1) know that we won't timeout, and (2) can have a standardized CI interface on Git and Git for Windows. Certainly, the Windows support on Azure Pipelines is more developed than that of Travis', so that's another point for Azure.
Quoted 6 lines
Another really good reason for me to do this is that I can prod the Azure Pipelines team directly. And I even get an answer, usually within minutes. Which is a lot faster than the Travis team answers my questions, which is... not yet? (I tried to get in contact with them in late 2015 or early 2016, and I tried again a year later, and then a couple of months later, and I have yet to hear back.)
Certainly a good reason. To be clear/fair, I've sent in a number of support tickets to Travis CI over the years, and have always been responded to in a short amount of time with helpful answers. I think that we would really be fine in either case, TBH.
Quoted 14 lines
Also, I am not quite sure about the timeouts on Travis, but at least AppVeyor had rather short timeouts: the Windows build (due to our extensive use of Unix shell scripting in our test suite) takes 1h40m currently, and AppVeyor times out after 20 or 30 minutes. I could imagine that Travis times out after the same time, or maybe 60 minutes, which would still be too short. On Azure Pipelines, the maximum timeout (which can be configured via the azure-pipelines.yml file) is four hours IIRC. Plenty enough even for our test suite on Windows.
Quoted 4 lines
To summarize [1], Travis is offering an early version of adding Windows to their list of supported builder operations systems. This brings the list to macOS, Linux, and Windows, which I think satisfies what we would like to regularly build git.git on.
Quoted 7 lines
Honestly, I would love to have also FreeBSD and other platforms being tested. And with Azure Pipelines, I can make that happen (eventually), by adding another pool of VMs (given that I have a free $150/month Azure subscription, I'd use Azure VMs, of course). As long as a platform can run .NET Core software, it can run Azure Pipelines agents.
With Travis, I don't think I can add private agent pools.
I think that's right.
Quoted 11 lines
Quoted 5 lines
Would we like to abandon Travis as our main CI service for upstream git.git, and build on Azure Pipelines only? If so, I think that this is an OK way to go, but I think that I would be opposed to having more than one build system. (FWIW, we tend to _three_ for Git LFS, and it can be a hassle at times).
This question of abandoning Travis in favor of Azure Pipelines is a bit of a hornets' nest, as I really, really only want to bring the goodness of Azure Pipelines to git.git, and I am *clearly* biased, as I work at Microsoft.
Quoted 5 lines
Which is the reason why I did not even hint at it in the cover letter, let alone included a patch to make it so.
My patch series is purely about adding support for running CI/PR builds of
https://github.com/git/git via Azure Pipelines.
I think that adding support for one CI system does carry the weight of removing the other, for the sake of having few CI systems running at any given time. In other words, even if you don't intend to start a discussion about removing Travis, those that want run the smallest number of services (including myself) will ask you about it ;-).
But I don't see a benefit to dragging this series through the mud by spending too much time talking about Travis' future. I think that your cover letter does a fine job to address the point, and we can revisit it in the future if more people than just myself are opposed to running >1 CI service.
Quoted 15 lines
Quoted 4 lines
I see some benefit to sticking with Travis, since we already have a build configuration that works there. But, you've done the work to "port" that build configuration over to Azure, so perhaps the point is moot.
It is not so much a port, as an attempt to generalize our ci/* files.
Quoted 7 lines
Quoted 4 lines
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
This would be a concession of [1], in my mind: is it possible to run the tests on Windows in a time such that Travis will not time out?
Quoted 6 lines
To be honest, I spent such a lot of time to get things to work on Azure Pipelines, *and* we get a nice view on the test failures there, too (which Travis will probably also offer soon, in response to what Azure Pipelines offer ;-)), I cannot really justify spending time on trying to make things work on Travis' Windows VMs, too. Especially when I have to expect to run into timeout issues anyway.
Agreed.
Quoted 12 lines
Quoted 11 lines
Quoted 8 lines
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).That's pretty cool. Travis doesn't support this (to the best of my knowledge).
Quoted 7 lines
Exactly.
Plus, if things don't work in Azure Pipelines, I (or one of the other Microsoft employees among the core Git developers) can easily take a shortcut to the team and get things fixed. In my mind, that counts for a lot, too, especially given my own, frustrating personal experience with Travis.
Agreed, and thanks for your response.
Quoted 4 lines
Ciao,
DschoQuoted 1 line
[1]: https://blog.travis-ci.com/2018-10-11-windows-early-release
Thanks,
Taylor
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Quoted 9 lines · Taylor Blau
Quoted 6 lines · Johannes Schindelin
Another really good reason for me to do this is that I can prod the Azure Pipelines team directly. And I even get an answer, usually within minutes. Which is a lot faster than the Travis team answers my questions, which is... not yet? (I tried to get in contact with them in late 2015 or early 2016, and I tried again a year later, and then a couple of months later, and I have yet to hear back.)
Quoted 4 lines
Certainly a good reason. To be clear/fair, I've sent in a number of support tickets to Travis CI over the years, and have always been responded to in a short amount of time with helpful answers. I think that we would really be fine in either case, TBH.
Was this in the context of "I'm this random dude using Travis" or "as you guys know I work for GitHub, your biggest? customer..." ? :)
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
In reply to Taylor BlauQuoted 2 lines · Taylor Blau
Would we like to abandon Travis as our main CI service for upstream git.git, and build on Azure Pipelines only?
It's not only about "upstream git.git", but also about contributors, who might have enabled Travis CI integration on their forks on GitHub. Having a '.travis.yml' and associated 'ci/*' scripts in git.git makes it possible for them to easily build and test their branches on their own.
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
In reply to Johannes Schindelin via GitGitGadget"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 4 lines · writes:
For a long time already, we have Git's source code continuously tested via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
What's the current status of this topic? Has the "p4 daemon gets left behind" one resolved to everybody's satisfaction? I think that one was the only large discussion on the series (aside from "do we want to keep Travis?" subthread, which does not make this series undesirable), modulo your "oy oy oy that is leftover debugging I need to remove in a reroll".
The topic was marked as "On hold, monitoring discussion" and it seems that discussion has quieted down, so the next step is to see an updated series?
Thanks.
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Hi Junio,
Quoted 10 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 4 lines · writes:
For a long time already, we have Git's source code continuously tested via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
What's the current status of this topic? Has the "p4 daemon gets left behind" one resolved to everybody's satisfaction?
No. I was kind of waiting for Luke's answer, and in the alternative I hoped to find some time to work on trying to reproduce his issues on my system (but I failed to find said time so far).
Quoted 8 lines
I think that one was the only large discussion on the series (aside from "do we want to keep Travis?" subthread, which does not make this series undesirable), modulo your "oy oy oy that is leftover debugging I need to remove in a reroll".
The topic was marked as "On hold, monitoring discussion" and it seems that discussion has quieted down, so the next step is to see an updated series?
I really think that I have to figure out what causes those p4d issues before I can give you that updated. I *am* interested, to be sure, it's just that other things seem to get in my way all the time.
One thing that keeps getting in my way, for example, is the performance issue identified in the chain linter. And I do think that I have to take this into consideration for another update to this here patch series, too, by adding --no-chain-lint to the Windows phase. There is a similar thing with --with-dashes, too.
Will keep you updated,
Dscho
Quoted 5 lines
Thanks.
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
In reply to Junio C HamanoHi Junio,
Quoted 8 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 4 lines · writes:
For a long time already, we have Git's source code continuously tested via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
Quoted 6 lines
What's the current status of this topic?
[...]The topic was marked as "On hold, monitoring discussion" and it seems that discussion has quieted down, so the next step is to see an updated series?
See the updated series:
https://public-inbox.org/git/[email protected]/
Thanks,
Dscho
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Quoted 3 lines · Johannes Schindelin
...
See the updated series:
https://public-inbox.org/git/[email protected]/
Thanks.
I see that you are already planning for v4, but I'll find time to take a look at what is posted sometime this week anyway.
Re: [PATCH v2 00/13] Offer to run CI/PR builds in Azure Pipelines
Hi Junio,
Quoted 10 lines · Junio C Hamano
Quoted 3 lines · Johannes Schindelin
...
See the updated series:
https://public-inbox.org/git/[email protected]/Thanks.
I see that you are already planning for v4, but I'll find time to take a look at what is posted sometime this week anyway.
Yes, v4 will ideally have only cosmetic changes apart from the part that fixes the traces of the published failed tests:
-- snipsnap --
15: f678b105f81e ! 15: 7b74987d72a6 tests: include detailed trace logs with --write-junit-xml upon failure
@@ -32,6 +32,38 @@
Signed-off-by: Johannes Schindelin <[email protected]>
+ diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
+ --- a/t/helper/test-path-utils.c
+ +++ b/t/helper/test-path-utils.c
+@@
+ return !!res;
+ }
+
++ if (argc == 4 && !strcmp(argv[1], "skip-n-bytes")) {
++ int fd = open(argv[2], O_RDONLY), offset = atoi(argv[3]);
++ char buffer[65536];
++
++ if (fd < 0)
++ die_errno("could not open '%s'", argv[2]);
++ if (lseek(fd, offset, SEEK_SET) < 0)
++ die_errno("could not skip %d bytes", offset);
++ for (;;) {
++ ssize_t count = read(fd, buffer, sizeof(buffer));
++ if (count < 0)
++ die_errno("could not read '%s'", argv[2]);
++ if (!count)
++ break;
++ if (write(1, buffer, count) < 0)
++ die_errno("could not write to stdout");
++ }
++ close(fd);
++ return 0;
++ }
++
+ fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
+ argv[1] ? argv[1] : "(there was none)");
+ return 1;
+
diff --git a/t/test-lib.sh b/t/test-lib.sh
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -42,7 +74,8 @@
- "$(printf '%s\n' "$@" | sed 1d)")"
+ "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+ then
-+ cut -c "$GIT_TEST_TEE_OFFSET-" <"$GIT_TEST_TEE_OUTPUT_FILE"
++ test-tool path-utils skip-n-bytes \
++ "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET
+ else
+ printf '%s\n' "$@" | sed 1d
+ fi)")"
@@ -56,17 +89,17 @@
fi
test_failure=$(($test_failure + 1))
@@
- write_junit_xml "$(printf '%s\n' \
- " <testcase $junit_attrs>" "$@" " </testcase>")"
- junit_have_testcase=t
-+ if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+ echo >&3 ""
+ maybe_teardown_valgrind
+ maybe_teardown_verbose
++ if test -n "$GIT_TEST_TEE_OFFSET"
+ then
+ GIT_TEST_TEE_OFFSET=$(test-tool path-utils file-size \
+ "$GIT_TEST_TEE_OUTPUT_FILE")
+ fi
}
- test_done () {
+ test_skip () {
@@
date +%Y-%m-%dT%H:%M:%S)\""
write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>"
@@ -74,7 +107,6 @@
+ if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
+ then
+ GIT_TEST_TEE_OFFSET=0
-+ GIT_TEST_TEE_ERR_OFFSET=0
+ fi
fiv3 cover Offer to run CI/PR builds in Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFor a long time already, we have tested Git's source code continuously via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
The one sad part about this is the Windows support. Travis used to lack it (Travis announced some early support for Windows, hot off the press
[https://blog.travis-ci.com/2018-10-11-windows-early-release]), and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
One might ask why we did not use Azure Pipelines directly. There were a couple of reasons for that:
* most notably, Azure Pipelines' build logs could not be viewed anonymously,
* while Azure Pipelines had Linux and Windows agents, it lacked macOS agents,
* etc
The main two reasons no longer apply: macOS agents are available now
[https://docs.microsoft.com/en-us/azure/devops/release-notes/2018/jul-10-vsts]
, and are public projects
[https://docs.microsoft.com/en-us/azure/devops/organizations/public/about-public-projects]
now, i.e. it is possible to configure a Azure Pipelines project so that anybody can view the logs. Since I offered v1, Azure Pipelines has been made available via the GitHub Marketplace, free of cost for open source projects.
I had secured such a public project for Git for Windows already, and I also got one for Git. For now, the latter is hooked up with my personal git.git fork on GitHub, but it is my hope that I convince y'all that these Azure Pipelines builds are a good idea, and then hook it up with
https://github.com/git/git.
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).
But maybe you're not interested as much in the presentation of test failures as in the speed? Well, I got you covered with that, too. As of v3, the test suite is run in parallel on Windows, cutting the overall run time to ~33 minutes (see the latest build
[https://dev.azure.com/git/git/_build/results?buildId=302&view=logs], for example).
This patch series took waaaaaaaay more time than I had originally anticipated, but I think that in particular the advanced display of the test results and the reduction of the overall run time was worth it. Please let me know what you think about this.
Changes since v2:
* Removed left-over debugging code that would skip a good chunk of t0000-init.sh.
* Fixed the URL of the build badge.
* Removed a trailing empty line from, and added a missing closing pointy bracket to, ci/mount-fileshare.sh.
* Moved the "travis: fix skipping tagged releases" commit up to the beginning of the patch series.
* The commit message of "ci/lib.sh: add support for Azure Pipelines" now mentions explicitly that the Homebrew packages that need to be installed on Travis' macOS agents are already installed on Azure Pipelines'.
* Some commands were not guarded by || exit 1, i.e. if they would fail, the build would not have failed.
* We now install gcc-8 for the linux-gcc job.
* We no longer try to re-run failed tests with verbose log. Instead, we simply use the verbose log to begin with. Tests showed that it had a negligible impact on the overall run time.
* The test_atexit_handler function was scratched; It would be the right thing to do, but is actually an independent topic (it was only implemented in v2 to accommodate the "re-run with verbose log on failure" trick)
* We now use a new YAML schema (most notably, "phase" is now known as "job")
* The Windows job contained PowerShell sections that were indented with 3 spaces instead of 2.
* The Windows job is now structured better, by separating different concerns into different "tasks" so that it is easier to see what exactly failed (was it the build? was it the test?)
* The Windows job was split into a job to build Git and 10 parallel jobs to run the test suite with the artifacts built by the first job. This reduces the overall run time from ~1h20 (which was the run time by the Windows job) to ~35 minutes (which is the run time of the linux-gcc job).
* The JUnit XML is now written using a test helper rather than a fragile and probably not even portable sed call.
* Since we needed to determine the file size of the verbose log (to cut out individual test cases' log output), we now introduce a test helper to do that, and use it throughout the test suite (where Perl was used before).
* It would appear that a recent change either in Cygwin or in the Azure VMs causes problems sporadically where the trash directories cannot be removed, but a subsequent rm will succeed. We now simply do that, because it won't harm the common case (where the first rm succeeds already) and because it helps the Windows job succeed pretty reliably.
Changes since v1:
* Removed a superfluous eval.
* Added the commit that fixes the Travis PR builds targeting master that just happens to be tagged (see
https://travis-ci.org/git/git/jobs/424276413 for an incorrectly-skipped build).
* The commit messages and the cover letter now reflect the name change from Visual Studio Team Services to Azure DevOps (and in particular, Azure Pipelines for the automated builds).
* Now we're using test_atexit (which we introduced for that purpose) instead of hard-coding kill_p4d and stop_git_daemon.
* The build should now also succeed for Pull Requests (where secret variables are not available, for security reasons, and as a consequence the file share cannot be mounted).
* The shell scripted parts now use proper && chains.
Johannes Schindelin (21):
travis: fix skipping tagged releases
ci: rename the library of common functions
ci/lib.sh: encapsulate Travis-specific things
ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
ci: use a junction on Windows instead of a symlink
test-date: add a subcommand to measure times in shell scripts
tests: optionally write results as JUnit-style .xml ci/lib.sh: add support for Azure Pipelines
Add a build definition for Azure DevOps
ci: move the Windows job to the top
ci: use git-sdk-64-minimal build artifact
mingw: be more generous when wrapping up the setitimer() emulation
README: add a build badge (status of the Azure Pipelines build)
tests: avoid calling Perl just to determine file sizes
tests: include detailed trace logs with --write-junit-xml upon failure
mingw: try to work around issues with the test cleanup
tests: add t/helper/ to the PATH with --with-dashes
t0061: fix with --with-dashes and RUNTIME_PREFIX
tests: optionally skip bin-wrappers/
ci: speed up Windows phase
ci: parallelize testing on Windows
Makefile | 11 +
README.md | 2 +
azure-pipelines.yml | 344 ++++++++++++++++++++++++++++
ci/install-dependencies.sh | 5 +-
ci/{lib-travisci.sh => lib.sh} | 70 ++++--
ci/make-test-artifacts.sh | 12 +
ci/mount-fileshare.sh | 25 ++
ci/print-test-failures.sh | 4 +-
ci/run-build-and-tests.sh | 9 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-test-slice.sh | 17 ++
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 3 +-
compat/mingw.c | 2 +-
t/.gitignore | 1 +
t/README | 9 +
t/helper/test-date.c | 12 +
t/helper/test-path-utils.c | 43 ++++
t/helper/test-tool.c | 1 +
t/helper/test-tool.h | 1 +
t/helper/test-xml-encode.c | 80 +++++++
t/t0021-conversion.sh | 2 +-
t/t0061-run-command.sh | 3 +-
t/t1050-large.sh | 2 +-
t/t5315-pack-objects-compression.sh | 2 +-
t/t9303-fast-import-compression.sh | 2 +-
t/test-lib.sh | 138 ++++++++++-
28 files changed, 768 insertions(+), 38 deletions(-)
create mode 100644 azure-pipelines.yml
rename ci/{lib-travisci.sh => lib.sh} (58%)
create mode 100755 ci/make-test-artifacts.sh
create mode 100755 ci/mount-fileshare.sh
create mode 100755 ci/run-test-slice.sh
create mode 100644 t/helper/test-xml-encode.cbase-commit: 77556354bb7ac50450e3b28999e3576969869068
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-31%2Fdscho%2Fvsts-ci-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-31/dscho/vsts-ci-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/31
Range-diff vs v2:
-: ---------- > 1: 75ec97b392 travis: fix skipping tagged releases
1: c963184510 = 2: d520f45108 ci: rename the library of common functions
2: 815152e0f5 ! 3: 06fa564386 ci/lib.sh: encapsulate Travis-specific things
@@ -28,10 +28,14 @@
@@
# Library of functions shared by all CI scripts
+-# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we
+-# want here. We want the source branch instead.
+-TRAVIS_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
+if test true = "$TRAVIS"
+then
-+ # We are running within Travis CI
-+ CI_BRANCH="$TRAVIS_BRANCH"
++ # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not
++ # what we want here. We want the source branch instead.
++ CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
+ CI_COMMIT="$TRAVIS_COMMIT"
+ CI_JOB_ID="$TRAVIS_JOB_ID"
+ CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER"
@@ -48,10 +52,9 @@
+ export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save"
+ export GIT_TEST_OPTS="--verbose-log -x --immediate"
+fi
-+
+
skip_branch_tip_with_tag () {
# Sometimes, a branch is pushed at the same time the tag that points
- # at the same commit as the tip of the branch is pushed, and building
@@
# we can skip the build because we won't be skipping a build
# of a tag.
-: ---------- > 4: 52fb8e72fb ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
-: ---------- > 5: a35bc43a04 ci: use a junction on Windows instead of a symlink
3: 52337f1875 = 6: 16090ff67c test-date: add a subcommand to measure times in shell scripts
4: cf4c5ae470 ! 7: 272c0c0446 tests: optionally write results as JUnit-style .xml
@@ -5,8 +5,26 @@
This will come in handy when publishing the results of Git's test suite
during an automated Azure DevOps run.
+ Note: we need to make extra sure that invalid UTF-8 encoding is turned
+ into valid UTF-8 (using the Replacement Character, \uFFFD) because
+ t9902's trace contains such invalid byte sequences, and the task in the
+ Azure Pipeline that uploads the test results would refuse to do anything
+ if it was asked to parse an .xml file with invalid UTF-8 in it.
+
Signed-off-by: Johannes Schindelin <[email protected]>
+ diff --git a/Makefile b/Makefile
+ --- a/Makefile
+ +++ b/Makefile
+@@
+ TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
+ TEST_BUILTINS_OBJS += test-subprocess.o
+ TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
++TEST_BUILTINS_OBJS += test-xml-encode.o
+ TEST_BUILTINS_OBJS += test-wildmatch.o
+ TEST_BUILTINS_OBJS += test-windows-named-pipe.o
+ TEST_BUILTINS_OBJS += test-write-cache.o
+
diff --git a/t/.gitignore b/t/.gitignore
--- a/t/.gitignore
+++ b/t/.gitignore
@@ -16,11 +34,121 @@
/chainlinttmp
+/out/
+ diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
+ --- a/t/helper/test-tool.c
+ +++ b/t/helper/test-tool.c
+@@
+ { "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
+ { "subprocess", cmd__subprocess },
+ { "urlmatch-normalization", cmd__urlmatch_normalization },
++ { "xml-encode", cmd__xml_encode },
+ { "wildmatch", cmd__wildmatch },
+ #ifdef GIT_WINDOWS_NATIVE
+ { "windows-named-pipe", cmd__windows_named_pipe },
+
+ diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
+ --- a/t/helper/test-tool.h
+ +++ b/t/helper/test-tool.h
+@@
+ int cmd__submodule_nested_repo_config(int argc, const char **argv);
+ int cmd__subprocess(int argc, const char **argv);
+ int cmd__urlmatch_normalization(int argc, const char **argv);
++int cmd__xml_encode(int argc, const char **argv);
+ int cmd__wildmatch(int argc, const char **argv);
+ #ifdef GIT_WINDOWS_NATIVE
+ int cmd__windows_named_pipe(int argc, const char **argv);
+
+ diff --git a/t/helper/test-xml-encode.c b/t/helper/test-xml-encode.c
+ new file mode 100644
+ --- /dev/null
+ +++ b/t/helper/test-xml-encode.c
+@@
++#include "test-tool.h"
++
++static const char *utf8_replace_character = "�";
++
++/*
++ * Encodes (possibly incorrect) UTF-8 on <stdin> to <stdout>, to be embedded
++ * in an XML file.
++ */
++int cmd__xml_encode(int argc, const char **argv)
++{
++ unsigned char buf[1024], tmp[4], *tmp2 = NULL;
++ ssize_t cur = 0, len = 1, remaining = 0;
++ unsigned char ch;
++
++ for (;;) {
++ if (++cur == len) {
++ len = xread(0, buf, sizeof(buf));
++ if (!len)
++ return 0;
++ if (len < 0)
++ die_errno("Could not read <stdin>");
++ cur = 0;
++ }
++ ch = buf[cur];
++
++ if (tmp2) {
++ if ((ch & 0xc0) != 0x80) {
++ fputs(utf8_replace_character, stdout);
++ tmp2 = 0;
++ cur--;
++ continue;
++ }
++ *tmp2 = ch;
++ tmp2++;
++ if (--remaining == 0) {
++ fwrite(tmp, tmp2 - tmp, 1, stdout);
++ tmp2 = 0;
++ }
++ continue;
++ }
++
++ if (!(ch & 0x80)) {
++ /* 0xxxxxxx */
++ if (ch == '&')
++ fputs("&", stdout);
++ else if (ch == '\'')
++ fputs("'", stdout);
++ else if (ch == '"')
++ fputs(""", stdout);
++ else if (ch == '<')
++ fputs("<", stdout);
++ else if (ch == '>')
++ fputs(">", stdout);
++ else if (ch >= 0x20)
++ fputc(ch, stdout);
++ else if (ch == 0x09 || ch == 0x0a || ch == 0x0d)
++ fprintf(stdout, "&#x%02x;", ch);
++ else
++ fputs(utf8_replace_character, stdout);
++ } else if ((ch & 0xe0) == 0xc0) {
++ /* 110XXXXx 10xxxxxx */
++ tmp[0] = ch;
++ remaining = 1;
++ tmp2 = tmp + 1;
++ } else if ((ch & 0xf0) == 0xe0) {
++ /* 1110XXXX 10Xxxxxx 10xxxxxx */
++ tmp[0] = ch;
++ remaining = 2;
++ tmp2 = tmp + 1;
++ } else if ((ch & 0xf8) == 0xf0) {
++ /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
++ tmp[0] = ch;
++ remaining = 3;
++ tmp2 = tmp + 1;
++ } else
++ fputs(utf8_replace_character, stdout);
++ }
++
++ return 0;
++}
+
diff --git a/t/test-lib.sh b/t/test-lib.sh
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@
- --verbose-log)
+ -V|--verbose-log)
verbose_log=t
shift ;;
+ --write-junit-xml)
@@ -115,14 +243,7 @@
+}
+
+xml_attr_encode () {
-+ # We do not translate CR to 
 because BSD sed does not handle
-+ # \r in the regex. In practice, the output should not even have any
-+ # carriage returns.
-+ printf '%s\n' "$@" |
-+ sed -e 's/&/\&/g' -e "s/'/\'/g" -e 's/"/\"/g' \
-+ -e 's/</\</g' -e 's/>/\>/g' \
-+ -e 's/ /\	/g' -e 's/$/\
/' -e '$s/
$//' |
-+ tr -d '\012\015'
++ printf '%s\n' "$@" | test-tool xml-encode
+}
+
+write_junit_xml_testcase () { 5: 486d1d2518 ! 8: fefab79d46 ci/lib.sh: add support for Azure Pipelines
@@ -6,6 +6,10 @@
variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
+ For example, we do not have to install the git-lfs and gettext packages
+ on Azure Pipelines' macOS agents: they are already installed, and trying
+ to install them again would result in an error.
+
diff --git a/ci/lib.sh b/ci/lib.sh
@@ -15,7 +19,7 @@
BREW_INSTALL_PACKAGES="git-lfs gettext"
export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate"
-+elif test -n "$SYSTEM_TASKDEFINITIONSURI"
++elif test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI"
+then
+ # We are running in Azure Pipelines
+ CI_BRANCH="$BUILD_SOURCEBRANCH"
6: 1a22efe849 ! 9: ddee8ecd8a Add a build definition for Azure DevOps
@@ -28,12 +28,11 @@
+- repo: self
+ fetchDepth: 1
+
-+phases:
-+- phase: linux_clang
++jobs:
++- job: linux_clang
+ displayName: linux-clang
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
@@ -43,7 +42,7 @@
+
+ export CC=clang || exit 1
+
-+ ci/install-dependencies.sh
++ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
@@ -62,19 +61,19 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: linux_gcc
++- job: linux_gcc
+ displayName: linux-gcc
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
++ sudo add-apt-repository ppa:ubuntu-toolchain-r/test &&
+ sudo apt-get update &&
-+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1
++ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2 language-pack-is git-svn gcc-8 || exit 1
+
-+ ci/install-dependencies.sh
++ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
@@ -93,18 +92,17 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: osx_clang
++- job: osx_clang
+ displayName: osx-clang
+ condition: succeeded()
-+ queue:
-+ name: Hosted macOS
++ pool: Hosted macOS
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ export CC=clang
+
-+ ci/install-dependencies.sh
++ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
@@ -123,16 +121,15 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: osx_gcc
++- job: osx_gcc
+ displayName: osx-gcc
+ condition: succeeded()
-+ queue:
-+ name: Hosted macOS
++ pool: Hosted macOS
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ ci/install-dependencies.sh
++ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
@@ -151,11 +148,10 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: gettext_poison
++- job: gettext_poison
+ displayName: GETTEXT_POISON
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
@@ -183,73 +179,81 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: windows
++- job: windows
+ displayName: Windows
+ condition: succeeded()
-+ queue:
-+ name: Hosted VS2017
-+ timeoutInMinutes: 240
++ pool: Hosted
++ timeoutInMinutes: 240
+ steps:
+ - powershell: |
-+ # Helper to check the error level of the latest command (exit with error when appropriate)
-+ function c() { if (!$?) { exit(1) } }
-+
-+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "$(gitfileshare.pwd)") {
-+ net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no; c
-+ cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\; c
-+ }
-+
-+ # Add build agent's MinGit to PATH
-+ $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH
-+
-+ # Helper to initialize (or update) a Git worktree
-+ function init ($path, $url, $set_origin) {
-+ if (Test-Path $path) {
-+ cd $path; c
-+ if (Test-Path .git) {
-+ git init; c
-+ } else {
-+ git status
-+ }
-+ } else {
-+ git init $path; c
-+ cd $path; c
-+ }
-+ git config core.autocrlf false; c
-+ git config core.untrackedCache true; c
-+ if (($set_origin -ne 0) -and !(git config remote.origin.url)) {
-+ git remote add origin $url; c
-+ }
-+ git fetch --depth=1 $url master; c
-+ git reset --hard FETCH_HEAD; c
-+ git clean -df; c
-+ }
-+
-+ # Initialize Git for Windows' SDK
-+ $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64"
-+ init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0
-+ init usr\src\build-extra https://github.com/git-for-windows/build-extra 1
-+
-+ cd "$(Build.SourcesDirectory)"; c
-+
-+ $env:HOME = "$(Build.SourcesDirectory)"
-+ $env:MSYSTEM = "MINGW64"
-+ git-sdk-64\git-cmd --command=usr\\bin\\bash.exe -lc @"
-+ . ci/lib.sh
-+
-+ make -j10 DEVELOPER=1 NO_PERL=1 || exit 1
-+ NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"--quiet --write-junit-xml\" time make -j15 -k DEVELOPER=1 test || {
-+ NO_PERL=1 NO_SVN_TESTS=1 GIT_TEST_OPTS=\"-i -v -x\" make -k -C t failed; exit 1
-+ }
-+
-+ save_good_tree
-+ "@
-+ c
-+
-+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "$(gitfileshare.pwd)") {
-+ cmd /c rmdir "$(Build.SourcesDirectory)\test-cache"
-+ }
-+ displayName: 'build & test'
++ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "$(gitfileshare.pwd)") {
++ net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no
++ cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\
++ }
++ displayName: 'Mount test-cache'
++ env:
++ GITFILESHAREPWD: $(gitfileshare.pwd)
++ - powershell: |
++ # Helper to check the error level of the latest command (exit with error when appropriate)
++ function c() { if (!$?) { exit(1) } }
++
++ # Add build agent's MinGit to PATH
++ $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH
++
++ # Helper to initialize (or update) a Git worktree
++ function init ($path, $url, $set_origin) {
++ if (Test-Path $path) {
++ cd $path; c
++ if (Test-Path .git) {
++ & git init; c
++ } else {
++ & git status
++ }
++ } else {
++ & git init $path; c
++ cd $path; c
++ }
++ & git config core.autocrlf false; c
++ & git config core.untrackedCache true; c
++ if (($set_origin -ne 0) -and !(git config remote.origin.url)) {
++ & git remote add origin $url; c
++ }
++ & git fetch --depth=1 $url master; c
++ & git reset --hard FETCH_HEAD; c
++ & git clean -df; c
++ }
++
++ # Initialize Git for Windows' SDK
++ $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64"
++ init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0
++
++ # Let Git ignore the SDK and the test-cache
++ "/git-sdk-64/n/test-cache/n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude"
++ displayName: 'Initialize the Git for Windows SDK'
++ - powershell: |
++ & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @"
++ export MAKEFLAGS=-j10
++ export DEVELOPER=1
++ export NO_PERL=1
++ export NO_SVN_TESTS=1
++ export GIT_TEST_SKIP_REBASE_P=1
++
++ ci/run-build-and-tests.sh || {
++ ci/print-test-failures.sh
++ exit 1
++ }
++ "@
++ if (!$?) { exit(1) }
++ displayName: 'Build & Test'
++ env:
++ HOME: $(Build.SourcesDirectory)
++ MSYSTEM: MINGW64
++ - powershell: |
++ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "$(gitfileshare.pwd)") {
++ cmd /c rmdir "$(Build.SourcesDirectory)\test-cache"
++ }
++ displayName: 'Unmount test-cache'
++ condition: true
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
@@ -261,29 +265,14 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: linux32
++- job: linux32
+ displayName: Linux32
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
-+ sudo apt-get update &&
-+ sudo apt-get -y install \
-+ apt-transport-https \
-+ ca-certificates \
-+ curl \
-+ software-properties-common &&
-+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &&
-+ sudo add-apt-repository \
-+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
-+ $(lsb_release -cs) \
-+ stable" &&
-+ sudo apt-get update &&
-+ sudo apt-get -y install docker-ce &&
-+
+ sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1
+
+ sudo chmod a+r t/out/TEST-*.xml
@@ -301,11 +290,10 @@
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+
-+- phase: static_analysis
++- job: static_analysis
+ displayName: StaticAnalysis
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
@@ -322,11 +310,10 @@
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+
-+- phase: documentation
++- job: documentation
+ displayName: Documentation
+ condition: succeeded()
-+ queue:
-+ name: Hosted Ubuntu 1604
++ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
@@ -344,6 +331,19 @@
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ diff --git a/ci/lib.sh b/ci/lib.sh
+ --- a/ci/lib.sh
+ +++ b/ci/lib.sh
+@@
+
+ BREW_INSTALL_PACKAGES=
+ export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save"
+- export GIT_TEST_OPTS="--quiet --write-junit-xml"
++ export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml"
+ fi
+
+ skip_branch_tip_with_tag () {
+
diff --git a/ci/mount-fileshare.sh b/ci/mount-fileshare.sh new file mode 100755
--- /dev/null
@@ -357,7 +357,7 @@
+}
+
+test $# = 4 ||
-+die "Usage: $0 <share> <username> <password> <mountpoint" ++die "Usage: $0 <share> <username> <password> <mountpoint>"
+
+mkdir -p "$4" || die "Could not create $4"
+
@@ -374,4 +374,3 @@
+ ;;
+esac ||
+die "Could not mount $4"
-+
7: 12d6137f8d < -: ---------- tests: introduce `test_atexit`
8: 3bb226b79b < -: ---------- git-daemon: use `test_atexit` in the tests
9: 3e2193a73d < -: ---------- git-p4: use `test_atexit` to kill the daemon
10: ae3c42519a < -: ---------- tests: include detailed trace logs with --write-junit-xml upon failure
11: 2466a48aa3 < -: ---------- tests: record more stderr with --write-junit-xml in case of failure
-: ---------- > 10: 58bb8d0469 ci: move the Windows job to the top
-: ---------- > 11: b6bb6a87a3 ci: use git-sdk-64-minimal build artifact
-: ---------- > 12: 2b6ee78f02 mingw: be more generous when wrapping up the setitimer() emulation
12: d112b3fe86 ! 13: df326039d9 README: add a build badge (status of the Azure Pipelines build)
@@ -10,7 +10,7 @@
--- a/README.md
+++ b/README.md
@@
-+[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
++[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
+
Git - fast, scalable, distributed revision control system
=========================================================
13: 0a53f37135 < -: ---------- travis: fix skipping tagged releases
-: ---------- > 14: 0d547db8f7 tests: avoid calling Perl just to determine file sizes
-: ---------- > 15: f678b105f8 tests: include detailed trace logs with --write-junit-xml upon failure
-: ---------- > 16: 8ef674a236 mingw: try to work around issues with the test cleanup
-: ---------- > 17: b503167084 tests: add t/helper/ to the PATH with --with-dashes
-: ---------- > 18: 713910e1dc t0061: fix with --with-dashes and RUNTIME_PREFIX
-: ---------- > 19: 3a77eafb44 tests: optionally skip bin-wrappers/
-: ---------- > 20: fba97133bf ci: speed up Windows phase
-: ---------- > 21: e568349930 ci: parallelize testing on WindowsSignature · 1 line
gitgitgadget
PATCH v3 1/21 travis: fix skipping tagged releases
From: Johannes Schindelin <[email protected]>
When building a PR, TRAVIS_BRANCH refers to the *target branch*. Therefore, if a PR targets master, and master happened to be tagged, we skipped the build by mistake.
Fix this by using TRAVIS_PULL_REQUEST_BRANCH (i.e. the *source branch*) when available, falling back to TRAVIS_BRANCH (i.e. for CI builds, also known as "push builds").
--- ci/lib-travisci.sh | 4 ++++ 1 file changed, 4 insertions(+)
ci/lib-travisci.sh +4 -0
@@ -1,5 +1,9 @@ # Library of functions shared by all CI scripts +# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we +# want here. We want the source branch instead. +TRAVIS_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building
Signature · 1 line
gitgitgadget
Re: [PATCH v3 01/21] travis: fix skipping tagged releases
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 5 lines · writes:
From: Johannes Schindelin <[email protected]>
When building a PR,
TRAVIS_BRANCHrefers to the *target branch*. Therefore, if a PR targetsmaster, andmasterhappened to be tagged, we skipped the build by mistake.
Good spotting.
Quoted 15 lines
Fix this by using
TRAVIS_PULL_REQUEST_BRANCH(i.e. the *source branch*) when available, falling back toTRAVIS_BRANCH(i.e. for CI builds, also known as "push builds").Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib-travisci.sh | 4 ++++ 1 file changed, 4 insertions(+)ci/lib-travisci.sh +0
-0
ci/lib-travisci.sh line 5
Quoted 5 lines
ci/lib-travisci.sh +3
-0@@ -1,5 +1,9 @@ # Library of functions shared by all CI scripts +# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we +# want here. We want the source branch instead. +TRAVIS_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
To those who are familiar with Travis [*1*], I suspect that TRAVIS_BRANCH has a specific meaning (e.g. with PR, it is target branch), and assigning a different value that is taken from another variable with different meanings to TravisCI would confuse them.
Perhaps introduce a new variable, like so...
BRANCH_TO_BUILD="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"and then s/TRAVIS_BRANCH/BRANCH_TO_BUILD/g on the body of the skip_branch_tip_with_tag helper function.
Thanks.
[Footnote]
*1* I obviously am not among them; otherwise we would have caught this while reviewing 09f5e974 ("travis-ci: skip a branch build if equal tag is present", 2017-09-10).
Quoted 3 lines
ci/lib-travisci.sh +0
-0skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building
Re: [PATCH v3 01/21] travis: fix skipping tagged releases
Hi Junio,
Quoted 28 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 14 lines · writes:
Fix this by using
TRAVIS_PULL_REQUEST_BRANCH(i.e. the *source branch*) when available, falling back toTRAVIS_BRANCH(i.e. for CI builds, also known as "push builds").Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib-travisci.sh | 4 ++++ 1 file changed, 4 insertions(+)ci/lib-travisci.sh +0
-0ci/lib-travisci.sh line 5
Quoted 5 lines
ci/lib-travisci.sh +3
-0@@ -1,5 +1,9 @@ # Library of functions shared by all CI scripts +# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we +# want here. We want the source branch instead. +TRAVIS_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"To those who are familiar with Travis [*1*], I suspect that
TRAVIS_BRANCHhas a specific meaning (e.g. with PR, it is target branch), and assigning a different value that is taken from another variable with different meanings to TravisCI would confuse them.
Quoted 6 lines
Perhaps introduce a new variable, like so...
BRANCH_TO_BUILD="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"and then s/TRAVIS_BRANCH/BRANCH_TO_BUILD/g on the body of the
skip_branch_tip_with_taghelper function.
I already introduce such a variable later in the same patch series:CI_BRANCH. It is a good idea to introduce that already here, as it declutters that later patch a bit, I would think.
Will change,
Dscho
Quoted 17 lines
Thanks.
[Footnote]
*1* I obviously am not among them; otherwise we would have caught this while reviewing
09f5e974("travis-ci: skip a branch build if equal tag is present", 2017-09-10).Quoted 3 lines
ci/lib-travisci.sh +0
-0skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building
PATCH v3 2/21 ci: rename the library of common functions
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
In the next commits, we will extend this to be able use Azure DevOps, too.
So let's adjust the name to make it more generic.
---
ci/install-dependencies.sh | 2 +-
ci/{lib-travisci.sh => lib.sh} | 0
ci/print-test-failures.sh | 2 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 2 +-
8 files changed, 7 insertions(+), 7 deletions(-)
rename ci/{lib-travisci.sh => lib.sh} (100%)ci/install-dependencies.sh +1 -1
@@ -3,7 +3,7 @@ # Install dependencies required to build and test Git on Linux and macOS # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
ci/lib.sh renamed from ci/lib-travisci.sh +0 -0
ci/print-test-failures.sh +1 -1
@@ -3,7 +3,7 @@ # Print output of failing tests # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh # Tracing executed commands would produce too much noise in the loop below. set +x
ci/run-build-and-tests.sh +1 -1
@@ -3,7 +3,7 @@ # Build and test Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh ln -s "$cache_dir/.prove" t/.prove
ci/run-linux32-docker.sh +1 -1
@@ -3,7 +3,7 @@ # Download and run Docker image to build and test 32-bit Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh docker pull daald/ubuntu32:xenial
ci/run-static-analysis.sh +1 -1
@@ -3,7 +3,7 @@ # Perform various static code analysis checks # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh make --jobs=2 coccicheck
ci/run-windows-build.sh +1 -1
@@ -6,7 +6,7 @@ # supported) and a commit hash. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh test $# -ne 2 && echo "Unexpected number of parameters" && exit 1 test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit
ci/test-documentation.sh +1 -1
@@ -3,7 +3,7 @@ # Perform sanity checks on documentation and build it. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh gem install asciidoctor
Signature · 1 line
gitgitgadget
PATCH v3 3/21 ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI.
--- ci/install-dependencies.sh | 3 ++- ci/lib.sh | 47 +++++++++++++++++++++++++------------- ci/print-test-failures.sh | 2 +- ci/test-documentation.sh | 1 + 4 files changed, 35 insertions(+), 18 deletions(-)
ci/install-dependencies.sh +2 -1
@@ -37,7 +37,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + brew install $BREW_INSTALL_PACKAGES brew link --force gettext brew install caskroom/cask/perforce ;;
ci/lib.sh +31 -16
101 lines not on this page · raw message
ci/print-test-failures.sh +1 -1
@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ] then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
ci/test-documentation.sh +1 -0
@@ -5,6 +5,7 @@ . ${0%/*}/lib.sh +test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtins
Signature · 1 line
gitgitgadget
PATCH v3 4/21 ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the MAKEFLAGS.
--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ci/run-build-and-tests.sh +1 -1
@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.prove -make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" then
Signature · 1 line
gitgitgadget
PATCH v3 5/21 ci: use a junction on Windows instead of a symlink
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Symbolic links are still not quite as easy to use on Windows as on Linux (for example, on versions older than Windows 10, only administrators can create symlinks, and on Windows 10 you still need to be in developer mode for regular users to have permission), but NTFS junctions can give us a way out.
--- ci/run-build-and-tests.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
ci/run-build-and-tests.sh +4 -1
@@ -5,7 +5,10 @@ . ${0%/*}/lib.sh -ln -s "$cache_dir/.prove" t/.prove +case "$CI_OS_NAME" in +windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; +*) ln -s "$cache_dir/.prove" t/.prove;; +esac make make --quiet test
Signature · 1 line
gitgitgadget
PATCH v3 6/21 test-date: add a subcommand to measure times in shell scripts
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use date +%s for that, this will give us only seconds, i.e. very coarse-grained timings.
GNU date supports date +%s.%N (i.e. nanosecond-precision output), but there is no equivalent in BSD date (read: on macOS, we would not be able to obtain precise timings).
So let's introduce test-tool date getnanos, with an optional start time, that outputs preciser values.
Granted, it is a bit pointless to try measuring times accurately in shell scripts, certainly to nanosecond precision. But it is better than second-granularity.
--- t/helper/test-date.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
t/helper/test-date.c +12 -0
@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"" test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n" ;
@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos (const char **argv,struct timeval *now) +{ +double seconds =getnanotime () /1.0e9 ; + +if (*argv) + seconds -=strtod (*argv,NULL ); +printf ("%lf\n" , seconds); +} +int cmd__date (int argc,const char **argv) {struct timeval now;
@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)parse_approxidate (argv+1 , &now); else if (!strcmp(*argv, "timestamp"))parse_approx_timestamp (argv+1 , &now); + else if (!strcmp(*argv, "getnanos")) +getnanos (argv+1 , &now); else if (!strcmp(*argv, "is64bit"))return sizeof (timestamp_t) ==8 ?0 :1 ; else if (!strcmp(*argv, "time_t-is64bit"))
Signature · 1 line
gitgitgadget
PATCH v3 7/21 tests: optionally write results as JUnit-style .xml
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This will come in handy when publishing the results of Git's test suite during an automated Azure DevOps run.
Note: we need to make extra sure that invalid UTF-8 encoding is turned into valid UTF-8 (using the Replacement Character, \uFFFD) because t9902's trace contains such invalid byte sequences, and the task in the Azure Pipeline that uploads the test results would refuse to do anything if it was asked to parse an .xml file with invalid UTF-8 in it.
--- Makefile | 1 + t/.gitignore | 1 + t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/helper/test-xml-encode.c | 80 +++++++++++++++++++++++++++++++++ t/test-lib.sh | 91 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 t/helper/test-xml-encode.c
Makefile +1 -0
@@ -754,6 +754,7 @@ TEST_BUILTINS_OBJS += test-submodule-config.o TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o TEST_BUILTINS_OBJS += test-subprocess.o TEST_BUILTINS_OBJS += test-urlmatch-normalization.o +TEST_BUILTINS_OBJS += test-xml-encode.o TEST_BUILTINS_OBJS += test-wildmatch.o TEST_BUILTINS_OBJS += test-windows-named-pipe.o TEST_BUILTINS_OBJS += test-write-cache.o
t/.gitignore +1 -0
@@ -2,3 +2,4 @@ /test-results /.prove /chainlinttmp +/out/
t/helper/test-tool.c +1 -0
@@ -49,6 +49,7 @@ static struct test_cmd cmds[] = { { "submodule-nested-repo-config", cmd__submodule_nested_repo_config }, { "subprocess", cmd__subprocess }, { "urlmatch-normalization", cmd__urlmatch_normalization }, + { "xml-encode", cmd__xml_encode }, { "wildmatch", cmd__wildmatch }, #ifdef GIT_WINDOWS_NATIVE { "windows-named-pipe", cmd__windows_named_pipe },
t/helper/test-tool.h +1 -0
@@ -45,6 +45,7 @@ int cmd__submodule_config(int argc, const char **argv);int cmd__submodule_nested_repo_config (int argc,const char **argv);int cmd__subprocess (int argc,const char **argv);int cmd__urlmatch_normalization (int argc,const char **argv); +int cmd__xml_encode (int argc,const char **argv);int cmd__wildmatch (int argc,const char **argv);#ifdef GIT_WINDOWS_NATIVE int cmd__windows_named_pipe (int argc,const char **argv);
t/helper/test-xml-encode.c new file +80 -0
80 lines not on this page · raw message
t/test-lib.sh +91 -0
152 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v3 8/21 ci/lib.sh: add support for Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
For example, we do not have to install the git-lfs and gettext packages on Azure Pipelines' macOS agents: they are already installed, and trying to install them again would result in an error.
--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
ci/lib.sh +23 -0
@@ -20,6 +20,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
Signature · 1 line
gitgitgadget
PATCH v3 9/21 Add a build definition for Azure DevOps
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the matrix feature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
--- azure-pipelines.yml | 306 ++++++++++++++++++++++++++++++++++++++++++ ci/lib.sh | 2 +- ci/mount-fileshare.sh | 25 ++++ 3 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 azure-pipelines.yml create mode 100755 ci/mount-fileshare.sh
azure-pipelines.yml new file +306 -0
@@ -0,0 +1,306 @@ +resources: +- repo: self + fetchDepth: 1 + +jobs: +- job: linux_clang + displayName: linux-clang + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin && + + export CC=clang || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: linux_gcc + displayName: linux-gcc + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo add-apt-repository ppa:ubuntu-toolchain-r/test && + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2 language-pack-is git-svn gcc-8 || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: osx_clang + displayName: osx-clang + condition: succeeded() + pool: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- job: osx_gcc + displayName: osx-gcc + condition: succeeded() + pool: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- job: gettext_poison + displayName: GETTEXT_POISON + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev && + + export jobname=GETTEXT_POISON || exit 1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'gettext-poison' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: windows + displayName: Windows + condition: succeeded() + pool: Hosted + timeoutInMinutes: 240 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + & git init; c + } else { + & git status + } + } else { + & git init $path; c + cd $path; c + } + & git config core.autocrlf false; c + & git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + & git remote add origin $url; c + } + & git fetch --depth=1 $url master; c + & git reset --hard FETCH_HEAD; c + & git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + + # Let Git ignore the SDK and the test-cache + "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Initialize the Git for Windows SDK' + - powershell: | + & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + export MAKEFLAGS=-j10 + export DEVELOPER=1 + export NO_PERL=1 + export NO_SVN_TESTS=1 + export GIT_TEST_SKIP_REBASE_P=1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + "@ + if (!$?) { exit(1) } + displayName: 'Build & Test' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + +- job: linux32 + displayName: Linux32 + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1 + + sudo chmod a+r t/out/TEST-*.xml + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-linux32-docker.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux32' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: static_analysis + displayName: StaticAnalysis + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y coccinelle && + + export jobname=StaticAnalysis && + + ci/run-static-analysis.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-static-analysis.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + +- job: documentation + displayName: Documentation + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y asciidoc xmlto asciidoctor && + + export ALREADY_HAVE_ASCIIDOCTOR=yes. && + export jobname=Documentation && + + ci/test-documentation.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/test-documentation.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd)
ci/lib.sh +1 -1
@@ -42,7 +42,7 @@ then BREW_INSTALL_PACKAGES= export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" - export GIT_TEST_OPTS="--quiet --write-junit-xml" + export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" fi skip_branch_tip_with_tag () {
ci/mount-fileshare.sh new file +25 -0
@@ -0,0 +1,25 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint>" + +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;; +Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4"
Signature · 1 line
gitgitgadget
PATCH v3 10/21 ci: move the Windows job to the top
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
This affects only the Azure Pipelines configuration, not the Travis one, of course, as Travis cannot run our Windows job: 1h20m is distinctly longer than the 50 minute timeout of Travis' free tier.
This commit is best viewed with --color-moved.
--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)
azure-pipelines.yml +86 -86
@@ -3,6 +3,92 @@ resources: fetchDepth: 1 jobs: +- job: windows + displayName: Windows + condition: succeeded() + pool: Hosted + timeoutInMinutes: 240 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + & git init; c + } else { + & git status + } + } else { + & git init $path; c + cd $path; c + } + & git config core.autocrlf false; c + & git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + & git remote add origin $url; c + } + & git fetch --depth=1 $url master; c + & git reset --hard FETCH_HEAD; c + & git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + + # Let Git ignore the SDK and the test-cache + "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Initialize the Git for Windows SDK' + - powershell: | + & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + export MAKEFLAGS=-j10 + export DEVELOPER=1 + export NO_PERL=1 + export NO_SVN_TESTS=1 + export GIT_TEST_SKIP_REBASE_P=1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + "@ + if (!$?) { exit(1) } + displayName: 'Build & Test' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + - job: linux_clang displayName: linux-clang condition: succeeded()
@@ -153,92 +239,6 @@ jobs: publishRunAttachments: false condition: succeededOrFailed() -- job: windows - displayName: Windows - condition: succeeded() - pool: Hosted - timeoutInMinutes: 240 - steps: - - powershell: | - if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { - net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no - cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ - } - displayName: 'Mount test-cache' - env: - GITFILESHAREPWD: $(gitfileshare.pwd) - - powershell: | - # Helper to check the error level of the latest command (exit with error when appropriate) - function c() { if (!$?) { exit(1) } } - - # Add build agent's MinGit to PATH - $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH - - # Helper to initialize (or update) a Git worktree - function init ($path, $url, $set_origin) { - if (Test-Path $path) { - cd $path; c - if (Test-Path .git) { - & git init; c - } else { - & git status - } - } else { - & git init $path; c - cd $path; c - } - & git config core.autocrlf false; c - & git config core.untrackedCache true; c - if (($set_origin -ne 0) -and !(git config remote.origin.url)) { - & git remote add origin $url; c - } - & git fetch --depth=1 $url master; c - & git reset --hard FETCH_HEAD; c - & git clean -df; c - } - - # Initialize Git for Windows' SDK - $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" - init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 - - # Let Git ignore the SDK and the test-cache - "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" - displayName: 'Initialize the Git for Windows SDK' - - powershell: | - & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" - export MAKEFLAGS=-j10 - export DEVELOPER=1 - export NO_PERL=1 - export NO_SVN_TESTS=1 - export GIT_TEST_SKIP_REBASE_P=1 - - ci/run-build-and-tests.sh || { - ci/print-test-failures.sh - exit 1 - } - "@ - if (!$?) { exit(1) } - displayName: 'Build & Test' - env: - HOME: $(Build.SourcesDirectory) - MSYSTEM: MINGW64 - - powershell: | - if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { - cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" - } - displayName: 'Unmount test-cache' - condition: true - env: - GITFILESHAREPWD: $(gitfileshare.pwd) - - task: PublishTestResults@2 - displayName: 'Publish Test Results **/TEST-*.xml' - inputs: - mergeTestResults: true - testRunTitle: 'windows' - platform: Windows - publishRunAttachments: false - condition: succeededOrFailed() - - job: linux32 displayName: Linux32 condition: succeeded()
Signature · 1 line
gitgitgadget
PATCH v3 11/21 ci: use git-sdk-64-minimal build artifact
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Instead of a shallow fetch followed by a sparse checkout, we are better off by using a separate, dedicated Pipeline that bundles the SDK as a build artifact, and then consuming that build artifact here.
In fact, since this artifact will be used a lot, we spent substantial time on figuring out a minimal subset of the Git for Windows SDK, just enough to build and test Git. The result is a size reduction from around 1GB (compressed) to around 55MB (compressed). This also comes with the change where we now call usr\bin\bash.exe directly, as git-cmd.exe is not included in the minimal SDK.
That reduces the time to initialize Git for Windows' SDK from anywhere between 2m30s-7m to a little over 1m.
Note: in theory, we could also use the DownloadBuildArtifacts@0 task here. However, restricted permissions that are in effect when building from forks would let this fail for PR builds, defeating the whole purpose of the Azure Pipelines support for git.git.
--- azure-pipelines.yml | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-)
azure-pipelines.yml +9 -35
@@ -18,44 +18,18 @@ jobs: env: GITFILESHAREPWD: $(gitfileshare.pwd) - powershell: | - # Helper to check the error level of the latest command (exit with error when appropriate) - function c() { if (!$?) { exit(1) } } - - # Add build agent's MinGit to PATH - $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH - - # Helper to initialize (or update) a Git worktree - function init ($path, $url, $set_origin) { - if (Test-Path $path) { - cd $path; c - if (Test-Path .git) { - & git init; c - } else { - & git status - } - } else { - & git init $path; c - cd $path; c - } - & git config core.autocrlf false; c - & git config core.untrackedCache true; c - if (($set_origin -ne 0) -and !(git config remote.origin.url)) { - & git remote add origin $url; c - } - & git fetch --depth=1 $url master; c - & git reset --hard FETCH_HEAD; c - & git clean -df; c - } - - # Initialize Git for Windows' SDK - $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" - init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + $urlbase = "https://dev.azure.com/git-for-windows/git/_apis/build/builds" + $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=22&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id + $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[1].resource.downloadUrl + (New-Object Net.WebClient).DownloadFile($downloadUrl,"git-sdk-64-minimal.zip") + Expand-Archive git-sdk-64-minimal.zip -DestinationPath . -Force + Remove-Item git-sdk-64-minimal.zip # Let Git ignore the SDK and the test-cache - "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" - displayName: 'Initialize the Git for Windows SDK' + "/git-sdk-64-minimal/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Download git-sdk-64-minimal' - powershell: | - & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + & git-sdk-64-minimal\usr\bin\bash.exe -lc @" export MAKEFLAGS=-j10 export DEVELOPER=1 export NO_PERL=1
Signature · 1 line
gitgitgadget
PATCH v3 12/21 mingw: be more generous when wrapping up the setitimer() emulation
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Every once in a while, the Azure Pipeline fails with some semi-random
error: timer thread did not terminate timely
This error message means that the thread that is used to emulate the setitimer() function did not terminate within 1,000 milliseconds.
The most likely explanation (and therefore the one we should assume to be true, according to Occam's Razor) is that the timeout of one second is simply not enough because we try to run so many tasks in parallel.
So let's give it ten seconds instead of only one. That should be enough.
--- compat/mingw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
compat/mingw.c +1 -1
@@ -2100,7 +2100,7 @@ static void stop_timer_thread(void)if (timer_event)SetEvent (timer_event);/* tell thread to terminate */ if (timer_thread) { -int rc =WaitForSingleObject (timer_thread,1000 ); +int rc =WaitForSingleObject (timer_thread,10000 );if (rc ==WAIT_TIMEOUT )error ("timer thread did not terminate timely" );else if (rc !=WAIT_OBJECT_0 )
Signature · 1 line
gitgitgadget
PATCH v3 13/21 README: add a build badge (status of the Azure Pipelines build)
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Just like so many other OSS projects, we now also have a build badge.
--- README.md | 2 ++ 1 file changed, 2 insertions(+)
README.md +2 -0
@@ -1,3 +1,5 @@ +[](https://dev.azure.com/git/git/_build/latest?definitionId=2) + Git - fast, scalable, distributed revision control system =========================================================
Signature · 1 line
gitgitgadget
PATCH v3 14/21 tests: avoid calling Perl just to determine file sizes
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
It is a bit ridiculous to spin up a full-blown Perl instance (especially on Windows, where that means spinning up a full POSIX emulation layer, AKA the MSYS2 runtime) just to tell how large a given file is.
So let's just use the test-tool to do that job instead.
This command will also be used over the next commits, to allow for cutting out individual test cases' verbose log from the file generated via --verbose-log.
--- t/helper/test-path-utils.c | 12 ++++++++++++ t/t0021-conversion.sh | 2 +- t/t1050-large.sh | 2 +- t/t5315-pack-objects-compression.sh | 2 +- t/t9303-fast-import-compression.sh | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-)
t/helper/test-path-utils.c +12 -0
@@ -291,6 +291,18 @@ int cmd__path_utils(int argc, const char **argv)return !!res; } +if (argc >2 && !strcmp (argv[1 ],"file-size" )) { +int res =0 , i; +struct stat st; + +for (i =2 ; i < argc; i++) +if (stat (argv[i], &st)) + res =error_errno ("Cannot stat '%s'" , argv[i]); +else +printf ("%" PRIuMAX"\n" , (uintmax_t )st.st_size); +return !!res; + } +fprintf (stderr,"%s: unknown function name: %s\n" , argv[0 ], argv[1 ] ? argv[1 ] :"(there was none)" );return 1 ;
t/t0021-conversion.sh +1 -1
@@ -24,7 +24,7 @@ generate_random_characters () { } file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } filter_git () {
t/t1050-large.sh +1 -1
@@ -8,7 +8,7 @@ test_description='adding and checking out large blobs' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup '
t/t5315-pack-objects-compression.sh +1 -1
@@ -7,7 +7,7 @@ test_description='pack-object compression configuration' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup '
t/t9303-fast-import-compression.sh +1 -1
@@ -6,7 +6,7 @@ test_description='compression setting of fast-import utility' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } import_large () {
Signature · 1 line
gitgitgadget
PATCH v3 15/21 tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the --verbose-log option to get those traces. However, that seems excessive, as we do not need/use the logs in almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with --quiet first, and only if a failure is encountered, try to trace the commands as they are executed.
Of course, we cannot turn on --verbose-log after the fact. So let's just re-run the test with all the same options, adding --verbose-log. And then munging the output file into the JUnit XML on the fly.
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with. Ideally, we would label this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
--- t/test-lib.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
t/test-lib.sh +21 -1
@@ -503,8 +503,18 @@ test_failure_ () { junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + cut -c "$GIT_TEST_TEE_OFFSET-" <"$GIT_TEST_TEE_OUTPUT_FILE" + else + printf '%s\n' "$@" | sed 1d + fi)")" junit_insert="$junit_insert</failure>" + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" + fi write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1))
@@ -872,6 +882,11 @@ write_junit_xml_testcase () { write_junit_xml "$(printf '%s\n' \ " <testcase $junit_attrs>" "$@" " </testcase>")" junit_have_testcase=t + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=$(test-tool path-utils file-size \ + "$GIT_TEST_TEE_OUTPUT_FILE") + fi } test_done () {
@@ -1153,6 +1168,11 @@ then date +%Y-%m-%dT%H:%M:%S)\"" write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" junit_suite_start=$(test-tool date getnanos) + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=0 + GIT_TEST_TEE_ERR_OFFSET=0 + fi fi # Provide an implementation of the 'yes' utility
Signature · 1 line
gitgitgadget
Re: [PATCH v3 15/21] tests: include detailed trace logs with --write-junit-xml upon failure
Hi,
t/test-lib.sh test_failure_ () { · line 508
Quoted 12 lines · Johannes Schindelin via GitGitGadget
t/test-lib.sh +3
-1@@ -503,8 +503,18 @@ test_failure_ () { junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + cut -c "$GIT_TEST_TEE_OFFSET-" <"$GIT_TEST_TEE_OUTPUT_FILE"
Ooops. This does not work.
The intention of this patch was to remember the file size of the tee output file at the point when the previous test case was done, and skip that part (so that the first thing the user sees is the detailed trace of *just* the failed test case, with the complete trace being attached as Standard_Error_Output.log).
However, I totally misunderstood that cut is *always* line based. So this cut -c (which should have been a cut -b to begin with) is just plain wrong.
And since there is no easy Unix shell tool to just skip a bunch of bytes (dd comes close, but you have to abuse the buffer size to specify the number of bytes, or use buffer size 1, neither of which I like), I will just add a dozen lines to the test-path-utils.c to get problem fixed.
Quoted 25 lines
t/test-lib.sh +13
-0+ else + printf '%s\n' "$@" | sed 1d + fi)")" junit_insert="$junit_insert</failure>" + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" + fi write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1))@@ -872,6 +882,11 @@ write_junit_xml_testcase () { write_junit_xml "$(printf '%s\n' \ " <testcase $junit_attrs>" "$@" " </testcase>")" junit_have_testcase=t + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=$(test-tool path-utils file-size \ + "$GIT_TEST_TEE_OUTPUT_FILE") + fi } test_done () {
t/test-lib.sh then · line 1174
Quoted 7 lines
t/test-lib.sh +4
-0@@ -1153,6 +1168,11 @@ then date +%Y-%m-%dT%H:%M:%S)\"" write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" junit_suite_start=$(test-tool date getnanos) + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=0 + GIT_TEST_TEE_ERR_OFFSET=0
Also, in case anybody wonders, this GIT_TEST_TEE_ERR_OFFSET variable is no longer used, and I should have removed it.
Oh well, I will just queue up the fixes in preparation for v4.
Ciao,
Dscho
Quoted 8 lines
t/test-lib.sh +1
-0+ fi fi # Provide an implementation of the 'yes' utilitySignature · 1 line
gitgitgadget
PATCH v3 16/21 mingw: try to work around issues with the test cleanup
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
It seems that every once in a while in the Git for Windows SDK, there are some transient file locking issues preventing the test clean up to delete the trash directory. Let's be gentle and try again five seconds later, and only error out if it still fails the second time.
This change helps Windows, and does not hurt any other platform (normally, it is highly unlikely that said deletion fails, and if it does, normally it will fail again even 5 seconds later).
--- t/test-lib.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
t/test-lib.sh +5 -1
@@ -970,7 +970,11 @@ test_done () { error "Tests passed but trash directory already removed before test cleanup; aborting" cd "$TRASH_DIRECTORY/.." && - rm -fr "$TRASH_DIRECTORY" || + rm -fr "$TRASH_DIRECTORY" || { + # try again in a bit + sleep 5; + rm -fr "$TRASH_DIRECTORY" + } || error "Tests passed but test cleanup failed; aborting" fi test_at_end_hook_
Signature · 1 line
gitgitgadget
PATCH v3 17/21 tests: add t/helper/ to the PATH with --with-dashes
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
We really need to be able to find the test helpers... Really. This change was forgotten when we moved the test helpers into t/helper/
--- t/test-lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
t/test-lib.sh +1 -1
@@ -1093,7 +1093,7 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" then - PATH="$GIT_BUILD_DIR:$PATH" + PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
Signature · 1 line
gitgitgadget
PATCH v3 18/21 t0061: fix with --with-dashes and RUNTIME_PREFIX
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When building Git with RUNTIME_PREFIX and starting a test helper from t/helper/, it fails to detect the system prefix correctly.
This is the reason that the warning
RUNTIME_PREFIX requested, but prefix computation failed. [...]
to be printed.
In t0061, we did not expect that to happen, and it actually did not happen in the normal case, because bin-wrappers/test-tool specifically sets GIT_TEXTDOMAINDIR (and as a consequence, nothing in test-tool wants to know about the runtime prefix).
However, with --with-dashes, bin-wrappers/test-tool is no longer called, but t/helper/test-tool is called directly.
So let's just ignore the RUNTIME_PREFIX warning.
--- t/t0061-run-command.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
t/t0061-run-command.sh +2 -1
@@ -166,7 +166,8 @@ test_trace () { expect="$1" shift GIT_TRACE=1 test-tool run-command "$@" run-command true 2>&1 >/dev/null | \ - sed -e 's/.* run_command: //' -e '/trace: .*/d' >actual && + sed -e 's/.* run_command: //' -e '/trace: .*/d' \ + -e '/RUNTIME_PREFIX requested/d' >actual && echo "$expect true" >expect && test_cmp expect actual }
Signature · 1 line
gitgitgadget
PATCH v3 19/21 tests: optionally skip bin-wrappers/
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This speeds up the tests by a bit on Windows, where running Unix shell scripts (and spawning processes) is not exactly a cheap operation.
--- t/README | 9 +++++++++ t/test-lib.sh | 19 +++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-)
t/README +9 -0
@@ -170,6 +170,15 @@ appropriately before running "make". implied by other options like --valgrind and GIT_TEST_INSTALLED. +--no-bin-wrappers:: + By default, the test suite uses the wrappers in + `../bin-wrappers/` to execute `git` and friends. With this option, + `../git` and friends are run directly. This is not recommended + in general, as the wrappers contain safeguards to ensure that no + files from an installed Git are used, but can speed up test runs + especially on platforms where running shell scripts is expensive + (most notably, Windows). + --root=<directory>:: Create "trash" directories used to store all temporary data during testing under <directory>, instead of the t/ directory.
t/test-lib.sh +13 -6
@@ -294,6 +294,8 @@ do test -z "$HARNESS_ACTIVE" && quiet=t; shift ;; --with-dashes) with_dashes=t; shift ;; + --no-bin-wrappers) + no_bin_wrappers=t; shift ;; --no-color) color=; shift ;; --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
@@ -1080,16 +1082,21 @@ then PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} else # normal case, use ../bin-wrappers only unless $with_dashes: - git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" - if ! test -x "$git_bin_dir/git" + if test -n "$no_bin_wrappers" then - if test -z "$with_dashes" + with_dashes=t + else + git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" + if ! test -x "$git_bin_dir/git" then - say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" + if test -z "$with_dashes" + then + say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" + fi + with_dashes=t fi - with_dashes=t + PATH="$git_bin_dir:$PATH" fi - PATH="$git_bin_dir:$PATH" GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" then
Signature · 1 line
gitgitgadget
PATCH v3 20/21 ci: speed up Windows phase
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
As Unix shell scripting comes at a hefty price on Windows, we have to see where we can save some time to run the test suite.
Let's skip the chain linting and the bin-wrappers/ redirection on Windows; this seems to shave of anywhere between 10-30% from the overall runtime.
--- ci/lib.sh | 2 ++ 1 file changed, 2 insertions(+)
ci/lib.sh +2 -0
@@ -43,6 +43,8 @@ then BREW_INSTALL_PACKAGES= export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" + test windows_nt != "$CI_OS_NAME" || + GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS" fi skip_branch_tip_with_tag () {
Signature · 1 line
gitgitgadget
PATCH v3 21/21 ci: parallelize testing on Windows
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The fact that Git's test suite is implemented in Unix shell script that is as portable as we can muster, combined with the fact that Unix shell scripting is foreign to Windows (and therefore has to be emulated), results in pretty abysmal speed of the test suite on that platform, for pretty much no other reason than that language choice.
For comparison: while the Linux build & test is typically done within about 8 minutes, the Windows build & test typically lasts about 80 minutes in Azure Pipelines.
To help with that, let's use the Azure Pipeline feature where you can parallelize jobs, make jobs depend on each other, and pass artifacts between them.
The tests are distributed using the following heuristic: listing all test scripts ordered by size in descending order (as a cheap way to estimate the overall run time), every Nth script is run (where N is the total number of parallel jobs), starting at the index corresponding to the parallel job. This slicing is performed by a new function that is added to the test-tool.
To optimize the overall runtime of the entire Pipeline, we need to move the Windows jobs to the beginning (otherwise there would be a very decent chance for the Pipeline to be run only the Windows build, while all the parallel Windows test jobs wait for this single one).
We use Azure Pipelines Artifacts for both the minimal Git for Windows SDK as well as the built executables, as deduplication and caching close to the agents makes that really fast. For comparison: while downloading and unpacking the minimal Git for Windows SDK via PowerShell takes only one minute (down from anywhere between 2.5 to 7 when using a shallow clone), uploading it as Pipeline Artifact takes less than 30s and downloading and unpacking less than 20s (sometimes even as little as only twelve seconds).
--- Makefile | 10 +++++ azure-pipelines.yml | 82 +++++++++++++++++++++++++++++++++----- ci/make-test-artifacts.sh | 12 ++++++ ci/run-test-slice.sh | 17 ++++++++ t/helper/test-path-utils.c | 31 ++++++++++++++ 5 files changed, 143 insertions(+), 9 deletions(-) create mode 100755 ci/make-test-artifacts.sh create mode 100755 ci/run-test-slice.sh
Makefile +10 -0
@@ -2927,6 +2927,16 @@ rpm:: @false .PHONY: rpm +artifacts-tar:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) \ + GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \ + $(NO_INSTALL) $(MOFILES) + $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \ + SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)' + test -n "$(ARTIFACTS_DIRECTORY)" + mkdir -p "$(ARTIFACTS_DIRECTORY)" + $(TAR) czf "$(ARTIFACTS_DIRECTORY)/artifacts.tar.gz" $^ templates/blt/ +.PHONY: artifacts-tar + htmldocs = git-htmldocs-$(GIT_VERSION) manpages = git-manpages-$(GIT_VERSION) .PHONY: dist-doc distclean
azure-pipelines.yml +73 -9
103 lines not on this page · raw message
ci/make-test-artifacts.sh new file +12 -0
@@ -0,0 +1,12 @@ +#!/bin/sh +# +# Build Git and store artifacts for testing +# + +mkdir -p "$1" # in case ci/lib.sh decides to quit early + +. ${0%/*}/lib.sh + +make artifacts-tar ARTIFACTS_DIRECTORY="$1" + +check_unignored_build_artifacts
ci/run-test-slice.sh new file +17 -0
@@ -0,0 +1,17 @@ +#!/bin/sh +# +# Test Git in parallel +# + +. ${0%/*}/lib.sh + +case "$CI_OS_NAME" in +windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; +*) ln -s "$cache_dir/.prove" t/.prove;; +esac + +make --quiet -C t T="$(cd t && + ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh | + tr '\n' ' ')" + +check_unignored_build_artifacts
t/helper/test-path-utils.c +31 -0
@@ -177,6 +177,14 @@ static int is_dotgitmodules(const char *path)return is_hfs_dotgitmodules (path) ||is_ntfs_dotgitmodules (path); } +static int cmp_by_st_size (const void *a,const void *b) +{ +intptr_t x = (intptr_t )((struct string_list_item *)a)->util; +intptr_t y = (intptr_t )((struct string_list_item *)b)->util; + +return x > y ?-1 : (x < y ?+1 :0 ); +} +int cmd__path_utils (int argc,const char **argv) {if (argc ==3 && !strcmp (argv[1 ],"normalize_path_copy" )) {
@@ -303,6 +311,29 @@ int cmd__path_utils(int argc, const char **argv)return !!res; } +if (argc >5 && !strcmp (argv[1 ],"slice-tests" )) { +int res =0 ; +long offset, stride, i; +struct string_list list =STRING_LIST_INIT_NODUP ; +struct stat st; + + offset =strtol (argv[2 ],NULL ,10 ); + stride =strtol (argv[3 ],NULL ,10 ); +if (stride <1 ) + stride =1 ; +for (i =4 ; i < argc; i++) +if (stat (argv[i], &st)) + res =error_errno ("Cannot stat '%s'" , argv[i]); +else +string_list_append (&list, argv[i])->util = + (void *)(intptr_t )st.st_size; +QSORT (list.items, list.nr, cmp_by_st_size); +for (i = offset; i < list.nr; i+= stride) +printf ("%s\n" , list.items[i].string); + +return !!res; + } +fprintf (stderr,"%s: unknown function name: %s\n" , argv[0 ], argv[1 ] ? argv[1 ] :"(there was none)" );return 1 ;
Signature · 1 line
gitgitgadget
v4 cover Offer to run CI/PR builds in Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFor a long time already, we have tested Git's source code continuously via Travis CI, see e.g. https://travis-ci.org/git/git/builds/421738884. It has served us well, and more and more developers actually pay attention and benefit from the testing this gives us.
It is also an invaluable tool for contributors who can validate their code contributions via PRs on GitHub, e.g. to verify that their tests do actually run on macOS (i.e. with the BSD family of Unix tools instead of the GNU one).
The one sad part about this is the Windows support. Travis used to lack it (Travis announced some early support for Windows, hot off the press
[https://blog.travis-ci.com/2018-10-11-windows-early-release]), and we work around that by using Azure Pipelines (the CI part of Azure DevOps, formerly known as Visual Studio Team Services) indirectly: one phase in Travis would trigger a build, wait for its log, and then paste that log.
As Git's Windows builds (and tests!) take quite a bit of time, Travis often timed out, or somehow the trigger did not work, and for security reasons (the Windows builds are performed in a private pool of containers), the Windows builds are completely disabled for Pull Requests on GitHub.
One might ask why we did not use Azure Pipelines directly. There were a couple of reasons for that:
* most notably, Azure Pipelines' build logs could not be viewed anonymously,
* while Azure Pipelines had Linux and Windows agents, it lacked macOS agents,
* etc
The main two reasons no longer apply: macOS agents are available now
[https://docs.microsoft.com/en-us/azure/devops/release-notes/2018/jul-10-vsts]
, and are public projects
[https://docs.microsoft.com/en-us/azure/devops/organizations/public/about-public-projects]
now, i.e. it is possible to configure a Azure Pipelines project so that anybody can view the logs. Since I offered v1, Azure Pipelines has been made available via the GitHub Marketplace, free of cost for open source projects.
I had secured such a public project for Git for Windows already, and I also got one for Git. For now, the latter is hooked up with my personal git.git fork on GitHub, but it is my hope that I convince y'all that these Azure Pipelines builds are a good idea, and then hook it up with
https://github.com/git/git.
As a special treat, this patch series adds the ability to present the outcome of Git's test suite as JUnit-style .xml files. This allows the Azure Pipelines build to present fun diagrams, trends, and makes it a lot easier to drill down to test failures than before. See for example
https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details
[https://dev.azure.com/git/git/_build/results?buildId=113&view=ms.vss-test-web.test-result-details]
(you can click on the label of the failed test, and then see the detailed output in the right pane).
But maybe you're not interested as much in the presentation of test failures as in the speed? Well, I got you covered with that, too. As of v3, the test suite is run in parallel on Windows, cutting the overall run time to ~33 minutes (see one of the latest builds
[https://dev.azure.com/git/git/_build/results?buildId=302&view=logs], for example).
This patch series took waaaaaaaay more time than I had originally anticipated, but I think that in particular the advanced display of the test results and the reduction of the overall run time was worth it. Please let me know what you think about this.
Changes since v3:
* Fixed the incorrect usage of cut -c that resulted in an empty trace when failed tests were published (except if the very first test case in a test script failed, then it was correct by mistake).
* Excluded the previous test case's "ok" (or "not ok") line from the trace published with failed tests.
* Renamed TRAVIS_BRANCH to CI_BRANCH already in the first commit, as we should not override TRAVIS_BRANCH with something that it is not.
* Rebased onto current master to avoid merge conflicts with the recently-merged sg/stress-test branch (no, Junio, I really trust myself more than you to resolve those merge conflicts).
Changes since v2:
* Removed left-over debugging code that would skip a good chunk of t0000-init.sh.
* Fixed the URL of the build badge.
* Removed a trailing empty line from, and added a missing closing pointy bracket to, ci/mount-fileshare.sh.
* Moved the "travis: fix skipping tagged releases" commit up to the beginning of the patch series.
* The commit message of "ci/lib.sh: add support for Azure Pipelines" now mentions explicitly that the Homebrew packages that need to be installed on Travis' macOS agents are already installed on Azure Pipelines'.
* Some commands were not guarded by || exit 1, i.e. if they would fail, the build would not have failed.
* We now install gcc-8 for the linux-gcc job.
* We no longer try to re-run failed tests with verbose log. Instead, we simply use the verbose log to begin with. Tests showed that it had a negligible impact on the overall run time.
* The test_atexit_handler function was scratched; It would be the right thing to do, but is actually an independent topic (it was only implemented in v2 to accommodate the "re-run with verbose log on failure" trick)
* We now use a new YAML schema (most notably, "phase" is now known as "job")
* The Windows job contained PowerShell sections that were indented with 3 spaces instead of 2.
* The Windows job is now structured better, by separating different concerns into different "tasks" so that it is easier to see what exactly failed (was it the build? was it the test?)
* The Windows job was split into a job to build Git and 10 parallel jobs to run the test suite with the artifacts built by the first job. This reduces the overall run time from ~1h20 (which was the run time by the Windows job) to ~35 minutes (which is the run time of the linux-gcc job).
* The JUnit XML is now written using a test helper rather than a fragile and probably not even portable sed call.
* Since we needed to determine the file size of the verbose log (to cut out individual test cases' log output), we now introduce a test helper to do that, and use it throughout the test suite (where Perl was used before).
* It would appear that a recent change either in Cygwin or in the Azure VMs causes problems sporadically where the trash directories cannot be removed, but a subsequent rm will succeed. We now simply do that, because it won't harm the common case (where the first rm succeeds already) and because it helps the Windows job succeed pretty reliably.
Changes since v1:
* Removed a superfluous eval.
* Added the commit that fixes the Travis PR builds targeting master that just happens to be tagged (see
https://travis-ci.org/git/git/jobs/424276413 for an incorrectly-skipped build).
* The commit messages and the cover letter now reflect the name change from Visual Studio Team Services to Azure DevOps (and in particular, Azure Pipelines for the automated builds).
* Now we're using test_atexit (which we introduced for that purpose) instead of hard-coding kill_p4d and stop_git_daemon.
* The build should now also succeed for Pull Requests (where secret variables are not available, for security reasons, and as a consequence the file share cannot be mounted).
* The shell scripted parts now use proper && chains.
Johannes Schindelin (21):
travis: fix skipping tagged releases
ci: rename the library of common functions
ci/lib.sh: encapsulate Travis-specific things
ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
ci: use a junction on Windows instead of a symlink
test-date: add a subcommand to measure times in shell scripts
tests: optionally write results as JUnit-style .xml ci/lib.sh: add support for Azure Pipelines
Add a build definition for Azure DevOps
ci: move the Windows job to the top
ci: use git-sdk-64-minimal build artifact
mingw: be more generous when wrapping up the setitimer() emulation
README: add a build badge (status of the Azure Pipelines build)
tests: avoid calling Perl just to determine file sizes
tests: include detailed trace logs with --write-junit-xml upon failure
mingw: try to work around issues with the test cleanup
tests: add t/helper/ to the PATH with --with-dashes
t0061: fix with --with-dashes and RUNTIME_PREFIX
tests: optionally skip bin-wrappers/
ci: speed up Windows phase
ci: parallelize testing on Windows
Makefile | 11 +
README.md | 2 +
azure-pipelines.yml | 344 ++++++++++++++++++++++++++++
ci/install-dependencies.sh | 5 +-
ci/{lib-travisci.sh => lib.sh} | 85 +++++--
ci/make-test-artifacts.sh | 12 +
ci/mount-fileshare.sh | 25 ++
ci/print-test-failures.sh | 4 +-
ci/run-build-and-tests.sh | 9 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-test-slice.sh | 17 ++
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 3 +-
compat/mingw.c | 2 +-
t/.gitignore | 1 +
t/README | 9 +
t/helper/test-date.c | 12 +
t/helper/test-path-utils.c | 64 ++++++
t/helper/test-tool.c | 1 +
t/helper/test-tool.h | 1 +
t/helper/test-xml-encode.c | 80 +++++++
t/t0021-conversion.sh | 2 +-
t/t0061-run-command.sh | 3 +-
t/t1050-large.sh | 2 +-
t/t5315-pack-objects-compression.sh | 2 +-
t/t9303-fast-import-compression.sh | 2 +-
t/test-lib.sh | 138 ++++++++++-
28 files changed, 796 insertions(+), 46 deletions(-)
create mode 100644 azure-pipelines.yml
rename ci/{lib-travisci.sh => lib.sh} (52%)
create mode 100755 ci/make-test-artifacts.sh
create mode 100755 ci/mount-fileshare.sh
create mode 100755 ci/run-test-slice.sh
create mode 100644 t/helper/test-xml-encode.cbase-commit: 16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-31%2Fdscho%2Fvsts-ci-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-31/dscho/vsts-ci-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/31
Range-diff vs v3:
1: 75ec97b392 < -: ---------- travis: fix skipping tagged releases
-: ---------- > 1: 6ed2f2a35c travis: fix skipping tagged releases
2: d520f45108 = 2: b086f36660 ci: rename the library of common functions
3: 06fa564386 ! 3: 2d0b62f186 ci/lib.sh: encapsulate Travis-specific things
@@ -30,7 +30,7 @@
-# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we
-# want here. We want the source branch instead.
--TRAVIS_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
+-CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
+if test true = "$TRAVIS"
+then
+ # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not
@@ -55,20 +55,6 @@
skip_branch_tip_with_tag () {
# Sometimes, a branch is pushed at the same time the tag that points
-@@
- # we can skip the build because we won't be skipping a build
- # of a tag.
-
-- if TAG=$(git describe --exact-match "$TRAVIS_BRANCH" 2>/dev/null) &&
-- test "$TAG" != "$TRAVIS_BRANCH"
-+ if TAG=$(git describe --exact-match "$CI_BRANCH" 2>/dev/null) &&
-+ test "$TAG" != "$CI_BRANCH"
- then
-- echo "$(tput setaf 2)Tip of $TRAVIS_BRANCH is exactly at $TAG$(tput sgr0)"
-+ echo "$(tput setaf 2)Tip of $CI_BRANCH is exactly at $TAG$(tput sgr0)"
- exit 0
- fi
- }
@@
# job if we encounter the same tree again and can provide a useful info
# message.
4: 52fb8e72fb = 4: 83b92a87e7 ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
5: a35bc43a04 = 5: 6c9eb4e33e ci: use a junction on Windows instead of a symlink
6: 16090ff67c = 6: aa053ed993 test-date: add a subcommand to measure times in shell scripts
7: 272c0c0446 ! 7: 07fb37e0a6 tests: optionally write results as JUnit-style .xml @@ -148,15 +148,15 @@
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@
- -V|--verbose-log)
verbose_log=t
- shift ;;
+ tee=t
+ ;;
+ --write-junit-xml)
+ write_junit_xml=t
-+ shift ;;
- *)
- echo "error: unknown test option '$1'" >&2; exit 1 ;;
- esac
++ ;;
+ --stress)
+ stress=t ;;
+ --stress=*)
@@
# the test_expect_* functions instead.
@@ -278,7 +278,7 @@
+
if test -z "$HARNESS_ACTIVE"
then
- test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
+ mkdir -p "$TEST_RESULTS_DIR"
@@
else
mkdir -p "$TRASH_DIRECTORY"
8: fefab79d46 = 8: 178dc9b789 ci/lib.sh: add support for Azure Pipelines
9: ddee8ecd8a = 9: eaba471b89 Add a build definition for Azure DevOps
10: 58bb8d0469 = 10: 5bdc6a08a8 ci: move the Windows job to the top
11: b6bb6a87a3 = 11: 93eebb74ce ci: use git-sdk-64-minimal build artifact
12: 2b6ee78f02 = 12: 18d76823e5 mingw: be more generous when wrapping up the setitimer() emulation
13: df326039d9 = 13: 5d593acee5 README: add a build badge (status of the Azure Pipelines build)
14: 0d547db8f7 = 14: 3083041e33 tests: avoid calling Perl just to determine file sizes
15: f678b105f8 < -: ---------- tests: include detailed trace logs with --write-junit-xml upon failure
-: ---------- > 15: 1c44d3b8b8 tests: include detailed trace logs with --write-junit-xml upon failure
16: 8ef674a236 = 16: 59c1194ae2 mingw: try to work around issues with the test cleanup
17: b503167084 = 17: 966c412f03 tests: add t/helper/ to the PATH with --with-dashes
18: 713910e1dc = 18: d613c79aff t0061: fix with --with-dashes and RUNTIME_PREFIX
19: 3a77eafb44 ! 19: a198885b76 tests: optionally skip bin-wrappers/
@@ -31,13 +31,13 @@
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@
- test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
+ test -z "$HARNESS_ACTIVE" && quiet=t ;;
--with-dashes)
- with_dashes=t; shift ;;
+ with_dashes=t ;;
+ --no-bin-wrappers)
-+ no_bin_wrappers=t; shift ;;
++ no_bin_wrappers=t ;;
--no-color)
- color=; shift ;;
+ color= ;;
--va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
@@
PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
20: fba97133bf = 20: 6520f4603c ci: speed up Windows phase
21: e568349930 ! 21: 8bdd9804a1 ci: parallelize testing on Windows
@@ -229,7 +229,7 @@ $^
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@
- return !!res;
+ return 0;
}
+ if (argc > 5 && !strcmp(argv[1], "slice-tests")) {Signature · 1 line
gitgitgadget
PATCH v4 1/21 travis: fix skipping tagged releases
From: Johannes Schindelin <[email protected]>
When building a PR, TRAVIS_BRANCH refers to the *target branch*. Therefore, if a PR targets master, and master happened to be tagged, we skipped the build by mistake.
Fix this by using TRAVIS_PULL_REQUEST_BRANCH (i.e. the *source branch*) when available, falling back to TRAVIS_BRANCH (i.e. for CI builds, also known as "push builds").
Let's give it a new variable name, too: CI_BRANCH (as it is different from TRAVIS_BRANCH). This also prepares for the upcoming patches which will make our ci/* code a bit more independent from Travis and open it to other CI systems (in particular to Azure Pipelines).
--- ci/lib-travisci.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
ci/lib-travisci.sh +14 -11
@@ -1,22 +1,25 @@ # Library of functions shared by all CI scripts +# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we +# want here. We want the source branch instead. +CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building # both at the same time is a waste. # - # Travis gives a tagname e.g. v2.14.0 in $TRAVIS_BRANCH when - # the build is triggered by a push to a tag. Let's see if - # $TRAVIS_BRANCH is exactly at a tag, and if so, if it is - # different from $TRAVIS_BRANCH. That way, we can tell if - # we are building the tip of a branch that is tagged and - # we can skip the build because we won't be skipping a build - # of a tag. - - if TAG=$(git describe --exact-match "$TRAVIS_BRANCH" 2>/dev/null) && - test "$TAG" != "$TRAVIS_BRANCH" + # When the build is triggered by a push to a tag, $CI_BRANCH will + # have that tagname, e.g. v2.14.0. Let's see if $CI_BRANCH is + # exactly at a tag, and if so, if it is different from $CI_BRANCH. + # That way, we can tell if we are building the tip of a branch that + # is tagged and we can skip the build because we won't be skipping a + # build of a tag. + + if TAG=$(git describe --exact-match "$CI_BRANCH" 2>/dev/null) && + test "$TAG" != "$CI_BRANCH" then - echo "$(tput setaf 2)Tip of $TRAVIS_BRANCH is exactly at $TAG$(tput sgr0)" + echo "$(tput setaf 2)Tip of $CI_BRANCH is exactly at $TAG$(tput sgr0)" exit 0 fi }
Signature · 1 line
gitgitgadget
Re: [PATCH v4 01/21] travis: fix skipping tagged releases
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
From: Johannes Schindelin <[email protected]>
When building a PR,
TRAVIS_BRANCHrefers to the *target branch*. Therefore, if a PR targetsmaster, andmasterhappened to be tagged, we skipped the build by mistake.
Quoted 8 lines
Fix this by using
TRAVIS_PULL_REQUEST_BRANCH(i.e. the *source branch*) when available, falling back toTRAVIS_BRANCH(i.e. for CI builds, also known as "push builds").Let's give it a new variable name, too:
CI_BRANCH(as it is different fromTRAVIS_BRANCH). This also prepares for the upcoming patches which will make our ci/* code a bit more independent from Travis and open it to other CI systems (in particular to Azure Pipelines).
Makes sense.
PATCH v4 2/21 ci: rename the library of common functions
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
In the next commits, we will extend this to be able use Azure DevOps, too.
So let's adjust the name to make it more generic.
---
ci/install-dependencies.sh | 2 +-
ci/{lib-travisci.sh => lib.sh} | 0
ci/print-test-failures.sh | 2 +-
ci/run-build-and-tests.sh | 2 +-
ci/run-linux32-docker.sh | 2 +-
ci/run-static-analysis.sh | 2 +-
ci/run-windows-build.sh | 2 +-
ci/test-documentation.sh | 2 +-
8 files changed, 7 insertions(+), 7 deletions(-)
rename ci/{lib-travisci.sh => lib.sh} (100%)ci/install-dependencies.sh +1 -1
@@ -3,7 +3,7 @@ # Install dependencies required to build and test Git on Linux and macOS # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
ci/lib.sh renamed from ci/lib-travisci.sh +0 -0
ci/print-test-failures.sh +1 -1
@@ -3,7 +3,7 @@ # Print output of failing tests # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh # Tracing executed commands would produce too much noise in the loop below. set +x
ci/run-build-and-tests.sh +1 -1
@@ -3,7 +3,7 @@ # Build and test Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh ln -s "$cache_dir/.prove" t/.prove
ci/run-linux32-docker.sh +1 -1
@@ -3,7 +3,7 @@ # Download and run Docker image to build and test 32-bit Git # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh docker pull daald/ubuntu32:xenial
ci/run-static-analysis.sh +1 -1
@@ -3,7 +3,7 @@ # Perform various static code analysis checks # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh make --jobs=2 coccicheck
ci/run-windows-build.sh +1 -1
@@ -6,7 +6,7 @@ # supported) and a commit hash. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh test $# -ne 2 && echo "Unexpected number of parameters" && exit 1 test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit
ci/test-documentation.sh +1 -1
@@ -3,7 +3,7 @@ # Perform sanity checks on documentation and build it. # -. ${0%/*}/lib-travisci.sh +. ${0%/*}/lib.sh gem install asciidoctor
Signature · 1 line
gitgitgadget
Re: [PATCH v4 02/21] ci: rename the library of common functions
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
From: Johannes Schindelin <[email protected]>
The name is hard-coded to reflect that we use Travis CI for continuous testing.
In the next commits, we will extend this to be able use Azure DevOps, too.
So let's adjust the name to make it more generic.
Yup. If we do not like lib-travis, it is possible to call it lib-ci, but because these are all in ci/ directory already, there is no reason to be extra redundant.
Makes sense.
PATCH v4 3/21 ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI.
--- ci/install-dependencies.sh | 3 ++- ci/lib.sh | 41 ++++++++++++++++++++++++++------------ ci/print-test-failures.sh | 2 +- ci/test-documentation.sh | 1 + 4 files changed, 32 insertions(+), 15 deletions(-)
ci/install-dependencies.sh +2 -1
@@ -37,7 +37,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-time - brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + brew install $BREW_INSTALL_PACKAGES brew link --force gettext brew install caskroom/cask/perforce ;;
ci/lib.sh +28 -13
88 lines not on this page · raw message
ci/print-test-failures.sh +1 -1
@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ] then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
ci/test-documentation.sh +1 -0
@@ -5,6 +5,7 @@ . ${0%/*}/lib.sh +test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtins
Signature · 1 line
gitgitgadget
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
"Johannes Schindelin via GitGitGadget" <[email protected]>
ci/install-dependencies.sh osx-clang|osx-gcc) · line 39
Quoted 8 lines · writes:
ci/install-dependencies.sh +0
-0@@ -37,7 +37,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-time
Isn't this comment now stale?
It would be, under this new arrangement of the code, most natural for Those who want to use gnu-time to arrange it to be somehow added to $BREW_INSTALL_PACKAGES, no?
ci/install-dependencies.sh osx-clang|osx-gcc) · line 41
Quoted 3 lines
ci/install-dependencies.sh +2
-1- brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + brew install $BREW_INSTALL_PACKAGES
It is unclear how this relates to "encapsulate Travis-specific"; it is guessable that perhaps only under Travis we'd use BREW_INSTALL_PACKAGES, but it still is unexplained why under other CIs we don't do lfs or gettext (if that is the plan---that is not clear, either).
Quoted 24 lines
ci/install-dependencies.sh +0
-0brew link --force gettext brew install caskroom/cask/perforce ;;ci/lib.sh +11
-3@@ -1,8 +1,26 @@ # Library of functions shared by all CI scripts -# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we -# want here. We want the source branch instead. -CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +if test true = "$TRAVIS" +then + # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not + # what we want here. We want the source branch instead. + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + CI_COMMIT="$TRAVIS_COMMIT" + CI_JOB_ID="$TRAVIS_JOB_ID" + CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER" + CI_OS_NAME="$TRAVIS_OS_NAME" + CI_REPO_SLUG="$TRAVIS_REPO_SLUG" +
ci/lib.sh line 23
Quoted 10 lines
ci/lib.sh +10
-0+ cache_dir="$HOME/travis-cache" + + url_for_job_id () { + echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1" + } + + BREW_INSTALL_PACKAGES="git-lfs gettext" + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fi
OK. I actually was expecting this to be something like
case "$CI_TYPE" in Travis) ... the reindented travis specific stuff here ... ;; *) echo >&2 "unknown CI_TYPE: $CI_TYPE"; exit 1 ;; esac
to make it equally easy to add not just the second one but the third one.
ci/lib.sh skip_branch_tip_with_tag () { · line 49
Quoted 6 lines
ci/lib.sh +1
-1@@ -28,7 +46,7 @@ skip_branch_tip_with_tag () { # job if we encounter the same tree again and can provide a useful info # message. save_good_tree () { - echo "$(git rev-parse $TRAVIS_COMMIT^{tree}) $TRAVIS_COMMIT $TRAVIS_JOB_NUMBER $TRAVIS_JOB_ID" >>"$good_trees_file" + echo "$(git rev-parse $CI_COMMIT^{tree}) $CI_COMMIT $CI_JOB_NUMBER $CI_JOB_ID" >>"$good_trees_file"
Makes sense. $CI_COMMIT is still coming from $TRAVIS_COMMIT but is that different from "git rev-parse $CI_BRANCH" I wonder (thinking aloud, not suggesting any changes).
ci/print-test-failures.sh do · line 72
Quoted 12 lines
ci/lib.sh +0
-0@@ -38,7 +56,7 @@ save_good_tree () {ci/print-test-failures.sh +1
-1@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ]
I do not quite understand this change.
If this wants to say that "we know how to show failures only when we know the job id", then testing for $CI_JOB_ID would be more appropriate, and if this wants to say that "we know how to show failures only when we are running under travis", then it would be more appropriate to switch on test "$TRAVIS" = true that is used at the beginning of ci/lib.sh (or if you would switch to "case $CI_TYPE" there, use the same construct). I cannot quite make an argument to support the use of $TRAVIS_JOB_ID in either case.
ci/print-test-failures.sh do
Quoted 4 lines
ci/print-test-failures.sh +1
-0+test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtins
OK, BREW_INSTALL_PACKAGES has an assignment in the travis specific section to trigger install of two separate packages, and there is no assignment to ALREADY_HAVE_ASCIIDOCTOR in the travis specific codepath, so we will end up installing asciidoctor here. Makes sense, even though this one too is under-explained just like the other one is.
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Hi Junio,
Quoted 13 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
ci/install-dependencies.sh osx-clang|osx-gcc) · line 39
Quoted 8 lines · writes:
ci/install-dependencies.sh +0
-0@@ -37,7 +37,8 @@ osx-clang|osx-gcc) brew update --quiet # Uncomment this if you want to run perf tests: # brew install gnu-timeIsn't this comment now stale?
No, not really. Actually, not at all.
Quoted 3 lines
It would be, under this new arrangement of the code, most natural for Those who want to use gnu-time to arrange it to be somehow added to $BREW_INSTALL_PACKAGES, no?
The purpose of BREW_INSTALL_PACKAGES is to list the packages necessary to build Git and run its test suite, and the only reason why this is no longer a hard-coded list of packages is that it depends on the CI platform (or more concretely, on the available macOS agents of said CI platform) which packages need to be installed to do so.
The gnu-time package is not such a package, and it is unlikely to be dependent on the particular CI you want to use.
So this spot really is the appropriate place to say that you want to install gnu-time.
Quoted 9 lines
ci/install-dependencies.sh osx-clang|osx-gcc) · line 41
Quoted 3 lines
ci/install-dependencies.sh +2
-1- brew install git-lfs gettext + test -z "$BREW_INSTALL_PACKAGES" || + brew install $BREW_INSTALL_PACKAGESIt is unclear how this relates to "encapsulate Travis-specific"; it is guessable that perhaps only under Travis we'd use
BREW_INSTALL_PACKAGES, but it still is unexplained why under other CIs we don't do lfs or gettext (if that is the plan---that is not clear, either).
I added this paragraph to the commit message:
Also, the configurations of the available agents are different. For example, Travis' and Azure Pipelines' macOS agents are set up differently, so that on Travis, we have to install the git-lfs and gettext Homebrew packages, and on Azure Pipelines we do not need to.
Does that sound good enough?
Quoted 37 lines
Quoted 24 lines
ci/install-dependencies.sh +0
-0brew link --force gettext brew install caskroom/cask/perforce ;;ci/lib.sh +11
-3@@ -1,8 +1,26 @@ # Library of functions shared by all CI scripts -# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we -# want here. We want the source branch instead. -CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +if test true = "$TRAVIS" +then + # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not + # what we want here. We want the source branch instead. + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + CI_COMMIT="$TRAVIS_COMMIT" + CI_JOB_ID="$TRAVIS_JOB_ID" + CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER" + CI_OS_NAME="$TRAVIS_OS_NAME" + CI_REPO_SLUG="$TRAVIS_REPO_SLUG" +ci/lib.sh line 23
Quoted 10 lines
ci/lib.sh +10
-0+ cache_dir="$HOME/travis-cache" + + url_for_job_id () { + echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1" + } + + BREW_INSTALL_PACKAGES="git-lfs gettext" + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fiOK. I actually was expecting this to be something like
Quoted 7 lines
case "$CI_TYPE" in Travis) ... the reindented travis specific stuff here ... ;; *) echo >&2 "unknown CI_TYPE: $CI_TYPE"; exit 1 ;; esacto make it equally easy to add not just the second one but the third one.
That's a very valid point.
There is not actually a CI_TYPE available, so I still use an if construct, but I added an else that will error out if we could not identify the CI platform.
Quoted 10 lines
ci/lib.sh skip_branch_tip_with_tag () { · line 49
Quoted 6 lines
ci/lib.sh +1
-1@@ -28,7 +46,7 @@ skip_branch_tip_with_tag () { # job if we encounter the same tree again and can provide a useful info # message. save_good_tree () { - echo "$(git rev-parse $TRAVIS_COMMIT^{tree}) $TRAVIS_COMMIT $TRAVIS_JOB_NUMBER $TRAVIS_JOB_ID" >>"$good_trees_file" + echo "$(git rev-parse $CI_COMMIT^{tree}) $CI_COMMIT $CI_JOB_NUMBER $CI_JOB_ID" >>"$good_trees_file"Makes sense. $CI_COMMIT is still coming from $TRAVIS_COMMIT but is that different from "git rev-parse $CI_BRANCH" I wonder (thinking aloud, not suggesting any changes).
Actually, I found out the hard way (a succeeding build that was a false negative) that TRAVIS_COMMIT does, at least sometimes, refer to the *merge* commit merging e.g. pu into master (which does not make sense at all to me, because that's neither what you did nor what you asked Travis to do for you).
So no, we need to use TRAVIS_COMMIT here lest we record a tree that was not tested.
Quoted 15 lines
ci/print-test-failures.sh do · line 72
Quoted 12 lines
ci/lib.sh +0
-0@@ -38,7 +56,7 @@ save_good_tree () {ci/print-test-failures.sh +1
-1@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ]I do not quite understand this change.
Quoted 8 lines
If this wants to say that "we know how to show failures only when we know the job id", then testing for $CI_JOB_ID would be more appropriate, and if this wants to say that "we know how to show failures only when we are running under travis", then it would be more appropriate to switch on test "$TRAVIS" = true that is used at the beginning of
ci/lib.sh(or if you would switch to "case $CI_TYPE" there, use the same construct). I cannot quite make an argument to support the use of $TRAVIS_JOB_ID in either case.
I tried to be cheap and *not* introduce that CI_TYPE variable. But you are correct, it is the right thing to do.
Quoted 11 lines
ci/print-test-failures.sh do
Quoted 4 lines
ci/print-test-failures.sh +1
-0+test -n "$ALREADY_HAVE_ASCIIDOCTOR" || gem install asciidoctor make check-builtinsOK,
BREW_INSTALL_PACKAGEShas an assignment in the travis specific section to trigger install of two separate packages, and there is no assignment toALREADY_HAVE_ASCIIDOCTORin the travis specific codepath, so we will end up installing asciidoctor here. Makes sense, even though this one too is under-explained just like the other one is.
Hopefully the added paragraph (which says "for example" and then uses the Homebrew packages as example) is enough to make the reader not puzzled about this here change, too?
Ciao,
Dscho
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Quoted 6 lines · Johannes Schindelin
No, not really. Actually, not at all.
Quoted 3 lines
It would be, under this new arrangement of the code, most natural for Those who want to use gnu-time to arrange it to be somehow added to $BREW_INSTALL_PACKAGES, no?
Quoted 8 lines
The purpose of
BREW_INSTALL_PACKAGESis to list the packages necessary to build Git and run its test suite, and the only reason why this is no longer a hard-coded list of packages is that it depends on the CI platform (or more concretely, on the available macOS agents of said CI platform) which packages need to be installed to do so.The gnu-time package is not such a package, and it is unlikely to be dependent on the particular CI you want to use.
Those who want to do perf tests in the current setup would need to install gnu-time because the current setup is only Travis, whose macOS agent does not have it preinstalled. Other CI platforms' macOS agents may already have it, they may not want to get an error by trying to install it there. I am not sure how that is different from the situation for gettext etc.?
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Hi Junio,
Quoted 17 lines · Junio C Hamano
Quoted 6 lines · Johannes Schindelin
No, not really. Actually, not at all.
Quoted 3 lines
It would be, under this new arrangement of the code, most natural for Those who want to use gnu-time to arrange it to be somehow added to $BREW_INSTALL_PACKAGES, no?
Quoted 8 lines
The purpose of
BREW_INSTALL_PACKAGESis to list the packages necessary to build Git and run its test suite, and the only reason why this is no longer a hard-coded list of packages is that it depends on the CI platform (or more concretely, on the available macOS agents of said CI platform) which packages need to be installed to do so.The gnu-time package is not such a package, and it is unlikely to be dependent on the particular CI you want to use.
Quoted 6 lines
Those who want to do perf tests in the current setup would need to install gnu-time because the current setup is only Travis, whose macOS agent does not have it preinstalled. Other CI platforms' macOS agents may already have it, they may not want to get an error by trying to install it there. I am not sure how that is different from the situation for gettext etc.?
The big difference is that gettext is needed to build Git and run its test suite. While gnu-time is only needed if you want to run the perf tests, which is not a part of the CI configuration we have, neither Travis nor Azure Pipelines.
So as long as we do not run the perf tests as part of the CI runs, that optional dependency should *not* be included in *CI_TYPE* specific sections of the code.
Since the perf test reference in this comment that you keep talking about is so clearly intended for some human being who wants to run the scripts in ci/ interactively (which pretty much contradicts the "ci" in the name a bit), I would even argue that it already is too hidden in the depths of the scripts to be useful. But sticking it even deeper into the CI_TYPE-specific sections? That would make it *even harder* to find!
So no, I think this suggestion to move that comment into exactly those sections (and of course, repeat it, identically, because with this here patch series we support *two* CI types) is something that we really want to let slide.
Ciao,
Dscho
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Quoted 8 lines · Johannes Schindelin
The big difference is that gettext is needed to build Git and run its test suite. While gnu-time is only needed if you want to run the perf tests, which is not a part of the CI configuration we have, neither Travis nor Azure Pipelines.
So as long as we do not run the perf tests as part of the CI runs, that optional dependency should *not* be included in *CI_TYPE* specific sections of the code.
Ah, in that case, I do not think it makes much sense to even keep that comment. As you said, ci/ is about running tests under CI platform, and the scripts are not designed to be run manually with tweaks, and none of our CI integration runs the perf thing, there is no point to even mention it.
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Hi Junio,
Quoted 11 lines · Junio C Hamano
Quoted 8 lines · Johannes Schindelin
The big difference is that gettext is needed to build Git and run its test suite. While gnu-time is only needed if you want to run the perf tests, which is not a part of the CI configuration we have, neither Travis nor Azure Pipelines.
So as long as we do not run the perf tests as part of the CI runs, that optional dependency should *not* be included in *CI_TYPE* specific sections of the code.
Quoted 5 lines
Ah, in that case, I do not think it makes much sense to even keep that comment. As you said, ci/ is about running tests under CI platform, and the scripts are not designed to be run manually with tweaks, and none of our CI integration runs the perf thing, there is no point to even mention it.
Well, yes and no.
Yes, it does not make much sense to cater to interactive usage when we target a CI system.
But yes, it *does* make sense to let users run those ci/ scripts in case they want to investigate test failures. Take, for example, a Windows user contributing patches that end up failing on Ubuntu with clang. Then they can install Ubuntu from the Windows Store, run those scripts in ci/ to painlessly get the necessary packages (without spending extra time to research which ones, and how to install them on Ubuntu in the first place), and they have a pretty good head start at debugging this interactively.
Likewise, I take the comment about perf testing as a seedling for testing performance in a controlled, repeatable and automated manner. As such, it would probably make less sense to step on that seedling and crush it; Instead, we will want to keep the comment there because it does no evil and at the same time is kind of a placeholder for something beautiful to come.
Ciao,
Dscho
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
In reply to Johannes Schindelin via GitGitGadgetQuoted 30 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI.
Signed-off-by Johannes Schindelin <[email protected]>---
ci/lib.sh +11
-3@@ -1,8 +1,26 @@ # Library of functions shared by all CI scripts -# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we -# want here. We want the source branch instead. -CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +if test true = "$TRAVIS" +then + # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not + # what we want here. We want the source branch instead. + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + CI_COMMIT="$TRAVIS_COMMIT" + CI_JOB_ID="$TRAVIS_JOB_ID" + CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER" + CI_OS_NAME="$TRAVIS_OS_NAME" + CI_REPO_SLUG="$TRAVIS_REPO_SLUG" +
ci/lib.sh line 23
Quoted 10 lines
ci/lib.sh +10
-0+ cache_dir="$HOME/travis-cache" + + url_for_job_id () { + echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1" + } + + BREW_INSTALL_PACKAGES="git-lfs gettext" + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fi
Please set these variables after 'set -x' has been turned on, so the values will be visible in the logs.
ci/print-test-failures.sh do · line 72
Quoted 10 lines
ci/print-test-failures.sh +1
-1@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ]
Nit: if [ -n "$TRAVIS_JOB_ID" ] && [ $combined_trash_size -gt 0 ]
More importantly: is this necessary, because on Azure Pipelines there is no URL from where the logs could be downloaded conveniently and reliably? I wonder whether it's worth to spend the extra effort in preparing the base64-encoded trash directories of failed tests in the first place.
Quoted 3 lines
ci/print-test-failures.sh +0
-0then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
Re: [PATCH v4 03/21] ci/lib.sh: encapsulate Travis-specific things
Hi Gábor,
Quoted 46 lines · SZEDER Gábor
Quoted 30 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI.
Signed-off-by Johannes Schindelin <[email protected]>---
ci/lib.sh +11
-3@@ -1,8 +1,26 @@ # Library of functions shared by all CI scripts -# When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not what we -# want here. We want the source branch instead. -CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" +if test true = "$TRAVIS" +then + # When building a PR, TRAVIS_BRANCH refers to the *target* branch. Not + # what we want here. We want the source branch instead. + CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" + CI_COMMIT="$TRAVIS_COMMIT" + CI_JOB_ID="$TRAVIS_JOB_ID" + CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER" + CI_OS_NAME="$TRAVIS_OS_NAME" + CI_REPO_SLUG="$TRAVIS_REPO_SLUG" +ci/lib.sh line 23
Quoted 10 lines
ci/lib.sh +10
-0+ cache_dir="$HOME/travis-cache" + + url_for_job_id () { + echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1" + } + + BREW_INSTALL_PACKAGES="git-lfs gettext" + export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" + export GIT_TEST_OPTS="--verbose-log -x --immediate" +fiPlease set these variables after 'set -x' has been turned on, so the values will be visible in the logs.
Quoted 1 line
Oooops. Sorry, I overlooked this! I'm sorry. Will fix.
The fix will actually be squashed into 1/21 ("travis: fix skipping tagged releases") because due to the re-ordering requested by Junio, this is now the first offender.
Quoted 13 lines
ci/print-test-failures.sh do · line 72
Quoted 10 lines
ci/print-test-failures.sh +1
-1@@ -69,7 +69,7 @@ do fi done -if [ $combined_trash_size -gt 0 ] +if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ]Nit: if [ -n "$TRAVIS_JOB_ID" ] && [ $combined_trash_size -gt 0 ]
Quoted 5 lines
More importantly: is this necessary, because on Azure Pipelines there is no URL from where the logs could be downloaded conveniently and reliably? I wonder whether it's worth to spend the extra effort in preparing the base64-encoded trash directories of failed tests in the first place.
You're right, of course. There *should* be a way to extract these from the log even on Azure Pipelines. I did find the API to get the logs, but it seems that at least for the moment, there is no environment variable specifying the number of the current task (on Azure Pipelines, the logs are split by task). So I could not actually figure out any way to generate the Azure Pipelines equivalent of this URL:
https://api.travis-ci.org/v3/job/$TRAVIS_JOB_ID/log.txt
But then, this code (which builds tar files of the trash directories of the failed tests and then logs a base64 version of it) simply is a workaround in the first place, accommodating for the fact that Travis does not offer build artifacts. But Azure Pipelines does. So that's what I am doing with those trash directories now: publish them as build artifacts (which can be downloaded conveniently as .zip files from the web page showing the build result).
Thanks for helping me improve this patch series!
Dscho
Quoted 5 lines
Quoted 3 lines
ci/print-test-failures.sh +0
-0then echo "------------------------------------------------------------------------" echo "Trash directories embedded in this log can be extracted by running:"
PATCH v4 4/21 ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the MAKEFLAGS.
--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ci/run-build-and-tests.sh +1 -1
@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.prove -make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" then
Signature · 1 line
gitgitgadget
Re: [PATCH v4 04/21] ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 16 lines · writes:
From: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the
MAKEFLAGS.Signed-off-by Johannes Schindelin <[email protected]>--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/run-build-and-tests.sh +0
-0
ci/run-build-and-tests.sh line 13
Quoted 8 lines
ci/run-build-and-tests.sh +1
-1@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.prove -make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" then
As there is no assignment to MAKEFLAGS in this patch, is it intended for this step to change behaviour (possibly with the intention to add "default 2 jobs at least under travis" back later in the series)? Not that it matters too much, but it is unnerving to see that the proposed log message promising "it is easy enough" while not actually doing so, without expressing an intention.
Re: [PATCH v4 04/21] ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
Quoted 22 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 19 lines · writes:
From: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the
MAKEFLAGS.Signed-off-by Johannes Schindelin <[email protected]>--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/run-build-and-tests.sh +0
-0@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.prove
Quoted 12 lines
ci/run-build-and-tests.sh line 13
Quoted 5 lines
ci/run-build-and-tests.sh +1
-1-make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" thenAs there is no assignment to MAKEFLAGS in this patch, is it intended for this step to change behaviour (possibly with the intention to add "default 2 jobs at least under travis" back later in the series)? Not that it matters too much, but it is unnerving to see that the proposed log message promising "it is easy enough" while not actually doing so, without expressing an intention.
Furthermore, there are several other 'ci/run-<something>.sh' scripts that still run 'make -j N'.
Re: [PATCH v4 04/21] ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
Hi Gábor,
Quoted 36 lines · SZEDER Gábor
Quoted 22 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 19 lines · writes:
From: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the
MAKEFLAGS.Signed-off-by Johannes Schindelin <[email protected]>--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/run-build-and-tests.sh +0
-0@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.proveQuoted 12 lines
ci/run-build-and-tests.sh line 13
Quoted 5 lines
ci/run-build-and-tests.sh +1
-1-make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" thenAs there is no assignment to MAKEFLAGS in this patch, is it intended for this step to change behaviour (possibly with the intention to add "default 2 jobs at least under travis" back later in the series)? Not that it matters too much, but it is unnerving to see that the proposed log message promising "it is easy enough" while not actually doing so, without expressing an intention.
Quoted 2 lines
Furthermore, there are several other 'ci/run-<something>.sh' scripts that still run 'make -j N'.
Indeed. I removed those --jobs=2 options from those.
Granted, I did not audit whether there were make calls that did not have any -j option, but I think it would be safe to parallelize all of them via MAKEFLAGS.
Ciao,
Dscho
Re: [PATCH v4 04/21] ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
In reply to Junio C HamanoHi Junio,
Quoted 22 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 19 lines · writes:
From: Johannes Schindelin <[email protected]>
Let's not decide in the generic ci/ script how many jobs to run in parallel; it is easy enough to hand that information down via the
MAKEFLAGS.Signed-off-by Johannes Schindelin <[email protected]>--- ci/run-build-and-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)ci/run-build-and-tests.sh +0
-0@@ -7,7 +7,7 @@ ln -s "$cache_dir/.prove" t/.prove
Quoted 12 lines
ci/run-build-and-tests.sh line 13
Quoted 5 lines
ci/run-build-and-tests.sh +1
-1-make --jobs=2 +make make --quiet test if test "$jobname" = "linux-gcc" thenAs there is no assignment to MAKEFLAGS in this patch, is it intended for this step to change behaviour (possibly with the intention to add "default 2 jobs at least under travis" back later in the series)? Not that it matters too much, but it is unnerving to see that the proposed log message promising "it is easy enough" while not actually doing so, without expressing an intention.
I was under the incorrect impression that Travis already configured a MAKEFLAGS=--jobs=<n> by default (I got fooled by the GIT_PROVE_OPTS setting that configures that --jobs option).
But the spirit of the change is still correct, I would think, so I made the change more complete by actually setting MAKEFLAGS in the CI-specific sections, and by removing the explicit --jobs=2 parameters in the scripts.
Ciao,
Dscho
PATCH v4 5/21 ci: use a junction on Windows instead of a symlink
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Symbolic links are still not quite as easy to use on Windows as on Linux (for example, on versions older than Windows 10, only administrators can create symlinks, and on Windows 10 you still need to be in developer mode for regular users to have permission), but NTFS junctions can give us a way out.
--- ci/run-build-and-tests.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
ci/run-build-and-tests.sh +4 -1
@@ -5,7 +5,10 @@ . ${0%/*}/lib.sh -ln -s "$cache_dir/.prove" t/.prove +case "$CI_OS_NAME" in +windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; +*) ln -s "$cache_dir/.prove" t/.prove;; +esac make make --quiet test
Signature · 1 line
gitgitgadget
PATCH v4 6/21 test-date: add a subcommand to measure times in shell scripts
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use date +%s for that, this will give us only seconds, i.e. very coarse-grained timings.
GNU date supports date +%s.%N (i.e. nanosecond-precision output), but there is no equivalent in BSD date (read: on macOS, we would not be able to obtain precise timings).
So let's introduce test-tool date getnanos, with an optional start time, that outputs preciser values.
Granted, it is a bit pointless to try measuring times accurately in shell scripts, certainly to nanosecond precision. But it is better than second-granularity.
--- t/helper/test-date.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
t/helper/test-date.c +12 -0
@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"" test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n" ;
@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos (const char **argv,struct timeval *now) +{ +double seconds =getnanotime () /1.0e9 ; + +if (*argv) + seconds -=strtod (*argv,NULL ); +printf ("%lf\n" , seconds); +} +int cmd__date (int argc,const char **argv) {struct timeval now;
@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)parse_approxidate (argv+1 , &now); else if (!strcmp(*argv, "timestamp"))parse_approx_timestamp (argv+1 , &now); + else if (!strcmp(*argv, "getnanos")) +getnanos (argv+1 , &now); else if (!strcmp(*argv, "is64bit"))return sizeof (timestamp_t) ==8 ?0 :1 ; else if (!strcmp(*argv, "time_t-is64bit"))
Signature · 1 line
gitgitgadget
Re: [PATCH v4 06/21] test-date: add a subcommand to measure times in shell scripts
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
From: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use
date +%sfor that, this will give us only seconds, i.e. very coarse-grained timings.
Quoted 6 lines
GNU
datesupportsdate +%s.%N(i.e. nanosecond-precision output), but there is no equivalent in BSDdate(read: on macOS, we would not be able to obtain precise timings).So let's introduce
test-tool date getnanos, with an optional start time, that outputs preciser values.
I think the goal to have our own stopwatch so that we do not have to worry about differences among system-provided ones makes sense.
The only thing that may become an issue is how widely available getnanotime() is. As "test-date" itself is built on any platform an end-user/developer runs our tests, which is wider set of platforms than what we run Travis and other CIs on, unconditionally relying on its availability might pose an issue. I dunno.
Quoted 37 lines
t/helper/test-date.c +12
-0@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"" test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n" ;@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos (const char **argv,struct timeval *now) +{ +double seconds =getnanotime () /1.0e9 ; + +if (*argv) + seconds -=strtod (*argv,NULL ); +printf ("%lf\n" , seconds); +} +int cmd__date (int argc,const char **argv) {struct timeval now;@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)parse_approxidate (argv+1 , &now); else if (!strcmp(*argv, "timestamp"))parse_approx_timestamp (argv+1 , &now); + else if (!strcmp(*argv, "getnanos")) +getnanos (argv+1 , &now); else if (!strcmp(*argv, "is64bit"))return sizeof (timestamp_t) ==8 ?0 :1 ; else if (!strcmp(*argv, "time_t-is64bit"))
Re: [PATCH v4 06/21] test-date: add a subcommand to measure times in shell scripts
Hi Junio,
Quoted 16 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 13 lines · writes:
From: Johannes Schindelin <[email protected]>
In the next commit, we want to teach Git's test suite to optionally output test results in JUnit-style .xml files. These files contain information about the time spent. So we need a way to measure time.
While we could use
date +%sfor that, this will give us only seconds, i.e. very coarse-grained timings.GNU
datesupportsdate +%s.%N(i.e. nanosecond-precision output), but there is no equivalent in BSDdate(read: on macOS, we would not be able to obtain precise timings).
Quoted 5 lines
Quoted 2 lines
So let's introduce
test-tool date getnanos, with an optional start time, that outputs preciser values.I think the goal to have our own stopwatch so that we do not have to worry about differences among system-provided ones makes sense.
And so that we do not have to worry about all kinds of unportable shell commands. That was my main motivation here, TBH.
Quoted 5 lines
The only thing that may become an issue is how widely available
getnanotime()is. As "test-date" itself is built on any platform an end-user/developer runs our tests, which is wider set of platforms than what we run Travis and other CIs on, unconditionally relying on its availability might pose an issue. I dunno.
Well, getnanotime() itself looks (I checked) at highres_nanos()' output, which can be 0 on unsuported platforms, and falls back to gettimeofday_nanos(). The worst that can happen there, as far as I can tell, is that the platform has a certain granularity (which is true of highres_nanos(), too), and that granularity can be 1 second. Which is not very good, but if that's the best the platform can provide, I am prepared to take it. Which is exactly what this patch does.
Do you have any splendid idea how to improve this approach?
Ciao,
Dscho
Re: [PATCH v4 06/21] test-date: add a subcommand to measure times in shell scripts
In reply to Junio C HamanoQuoted 8 lines · Junio C Hamano
I think the goal to have our own stopwatch so that we do not have to worry about differences among system-provided ones makes sense.
The only thing that may become an issue is how widely available
getnanotime()is. As "test-date" itself is built on any platform an end-user/developer runs our tests, which is wider set of platforms than what we run Travis and other CIs on, unconditionally relying on its availability might pose an issue.
Sorry for a false alarm, as the codebase in many places like fsmonitor, progress, trace and wt-status have been assuming getnanotime() to be available for quite some time, and this is just another user of the same function.
Re: [PATCH v4 06/21] test-date: add a subcommand to measure times in shell scripts
Quoted 11 lines · Junio C Hamano
Quoted 8 lines · Junio C Hamano
I think the goal to have our own stopwatch so that we do not have to worry about differences among system-provided ones makes sense.
The only thing that may become an issue is how widely available
getnanotime()is. As "test-date" itself is built on any platform an end-user/developer runs our tests, which is wider set of platforms than what we run Travis and other CIs on, unconditionally relying on its availability might pose an issue.
Quoted 4 lines
Sorry for a false alarm, as the codebase in many places like fsmonitor, progress, trace and wt-status have been assuming
getnanotime()to be available for quite some time, and this is just another user of the same function.
And there was yet another misunderstanding on my part. I thought that the mention of getnanotime() was about
https://www.freebsd.org/cgi/man.cgi?query=getnanotime&sektion=9
and I did not realize that the hits I saw in "git grep getnanotime" were referring to an unrelated function trace.c::getnanotime() of our own. Of course, it is safe to use that function in the tests ;-)
Again, sorry for the false alarm.
We _might_ get a complaint from freebsd devs when they want to use their getnanotime(9) to implement highres_nanos(), and the cleanest solution to that complaint will be to rename our own getnanotime() to git_nanotime() or something, but (1) that is totally outside the scope of this series that adds one more caller to the function and
(2) we can do that when we actually get such a complaint.
PATCH v4 7/21 tests: optionally write results as JUnit-style .xml
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This will come in handy when publishing the results of Git's test suite during an automated Azure DevOps run.
Note: we need to make extra sure that invalid UTF-8 encoding is turned into valid UTF-8 (using the Replacement Character, \uFFFD) because t9902's trace contains such invalid byte sequences, and the task in the Azure Pipeline that uploads the test results would refuse to do anything if it was asked to parse an .xml file with invalid UTF-8 in it.
--- Makefile | 1 + t/.gitignore | 1 + t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/helper/test-xml-encode.c | 80 +++++++++++++++++++++++++++++++++ t/test-lib.sh | 91 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 t/helper/test-xml-encode.c
Makefile +1 -0
@@ -754,6 +754,7 @@ TEST_BUILTINS_OBJS += test-submodule-config.o TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o TEST_BUILTINS_OBJS += test-subprocess.o TEST_BUILTINS_OBJS += test-urlmatch-normalization.o +TEST_BUILTINS_OBJS += test-xml-encode.o TEST_BUILTINS_OBJS += test-wildmatch.o TEST_BUILTINS_OBJS += test-windows-named-pipe.o TEST_BUILTINS_OBJS += test-write-cache.o
t/.gitignore +1 -0
@@ -2,3 +2,4 @@ /test-results /.prove /chainlinttmp +/out/
t/helper/test-tool.c +1 -0
@@ -49,6 +49,7 @@ static struct test_cmd cmds[] = { { "submodule-nested-repo-config", cmd__submodule_nested_repo_config }, { "subprocess", cmd__subprocess }, { "urlmatch-normalization", cmd__urlmatch_normalization }, + { "xml-encode", cmd__xml_encode }, { "wildmatch", cmd__wildmatch }, #ifdef GIT_WINDOWS_NATIVE { "windows-named-pipe", cmd__windows_named_pipe },
t/helper/test-tool.h +1 -0
@@ -45,6 +45,7 @@ int cmd__submodule_config(int argc, const char **argv);int cmd__submodule_nested_repo_config (int argc,const char **argv);int cmd__subprocess (int argc,const char **argv);int cmd__urlmatch_normalization (int argc,const char **argv); +int cmd__xml_encode (int argc,const char **argv);int cmd__wildmatch (int argc,const char **argv);#ifdef GIT_WINDOWS_NATIVE int cmd__windows_named_pipe (int argc,const char **argv);
t/helper/test-xml-encode.c new file +80 -0
80 lines not on this page · raw message
t/test-lib.sh +91 -0
152 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v4 8/21 ci/lib.sh: add support for Azure Pipelines
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
For example, we do not have to install the git-lfs and gettext packages on Azure Pipelines' macOS agents: they are already installed, and trying to install them again would result in an error.
--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
ci/lib.sh +23 -0
@@ -20,6 +20,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
Signature · 1 line
gitgitgadget
Re: [PATCH v4 08/21] ci/lib.sh: add support for Azure Pipelines
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
From: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
For example, we do not have to install the git-lfs and gettext packages on Azure Pipelines' macOS agents: they are already installed, and trying to install them again would result in an error.
The rationale in the second paragraph is shared with the earlier one that introduced BREW_INSTALL_PACKAGES variable in the first place. It would have made more sense if it was explained there (i.e. say "in environments other than Travis, some packages may be pre installed and asking to install them again may cause failure, so make it configurable what to install")---that way, the explanation in this step's log message can just say "Because Azure pipeline's macOS agents already have git-lfs and gettext installed, unlike Travis, we can leave BREW_INSTALL_PACKAGES empty".
Quoted 39 lines
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)ci/lib.sh +23
-0@@ -20,6 +20,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
Re: [PATCH v4 08/21] ci/lib.sh: add support for Azure Pipelines
Hi Junio,
Quoted 13 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
From: Johannes Schindelin <[email protected]>
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees).
For example, we do not have to install the git-lfs and gettext packages on Azure Pipelines' macOS agents: they are already installed, and trying to install them again would result in an error.
Quoted 9 lines
The rationale in the second paragraph is shared with the earlier one that introduced
BREW_INSTALL_PACKAGESvariable in the first place. It would have made more sense if it was explained there (i.e. say "in environments other than Travis, some packages may be pre installed and asking to install them again may cause failure, so make it configurable what to install")---that way, the explanation in this step's log message can just say "Because Azure pipeline's macOS agents already have git-lfs and gettext installed, unlike Travis, we can leaveBREW_INSTALL_PACKAGESempty".
Makes sense.
Will do that,
Dscho
Quoted 41 lines
Quoted 40 lines
Signed-off-by Johannes Schindelin <[email protected]>--- ci/lib.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)ci/lib.sh +23
-0@@ -20,6 +20,29 @@ then BREW_INSTALL_PACKAGES="git-lfs gettext" export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" export GIT_TEST_OPTS="--verbose-log -x --immediate" +elif test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" +then + # We are running in Azure Pipelines + CI_BRANCH="$BUILD_SOURCEBRANCH" + CI_COMMIT="$BUILD_SOURCEVERSION" + CI_JOB_ID="$BUILD_BUILDID" + CI_JOB_NUMBER="$BUILD_BUILDNUMBER" + CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" + test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx + CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + CC="${CC:-gcc}" + + # use a subdirectory of the cache dir (because the file share is shared + # among *all* phases) + cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" + + url_for_job_id () { + echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1" + } + + BREW_INSTALL_PACKAGES= + export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" + export GIT_TEST_OPTS="--quiet --write-junit-xml" fi skip_branch_tip_with_tag () {
PATCH v4 9/21 Add a build definition for Azure DevOps
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the matrix feature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).
Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
--- azure-pipelines.yml | 306 ++++++++++++++++++++++++++++++++++++++++++ ci/lib.sh | 2 +- ci/mount-fileshare.sh | 25 ++++ 3 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 azure-pipelines.yml create mode 100755 ci/mount-fileshare.sh
azure-pipelines.yml new file +306 -0
@@ -0,0 +1,306 @@ +resources: +- repo: self + fetchDepth: 1 + +jobs: +- job: linux_clang + displayName: linux-clang + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin && + + export CC=clang || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: linux_gcc + displayName: linux-gcc + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo add-apt-repository ppa:ubuntu-toolchain-r/test && + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2 language-pack-is git-svn gcc-8 || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: osx_clang + displayName: osx-clang + condition: succeeded() + pool: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + export CC=clang + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- job: osx_gcc + displayName: osx-gcc + condition: succeeded() + pool: Hosted macOS + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + +- job: gettext_poison + displayName: GETTEXT_POISON + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev && + + export jobname=GETTEXT_POISON || exit 1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-build-and-tests.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'gettext-poison' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: windows + displayName: Windows + condition: succeeded() + pool: Hosted + timeoutInMinutes: 240 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + & git init; c + } else { + & git status + } + } else { + & git init $path; c + cd $path; c + } + & git config core.autocrlf false; c + & git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + & git remote add origin $url; c + } + & git fetch --depth=1 $url master; c + & git reset --hard FETCH_HEAD; c + & git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + + # Let Git ignore the SDK and the test-cache + "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Initialize the Git for Windows SDK' + - powershell: | + & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + export MAKEFLAGS=-j10 + export DEVELOPER=1 + export NO_PERL=1 + export NO_SVN_TESTS=1 + export GIT_TEST_SKIP_REBASE_P=1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + "@ + if (!$?) { exit(1) } + displayName: 'Build & Test' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + +- job: linux32 + displayName: Linux32 + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1 + + sudo chmod a+r t/out/TEST-*.xml + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-linux32-docker.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux32' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + +- job: static_analysis + displayName: StaticAnalysis + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y coccinelle && + + export jobname=StaticAnalysis && + + ci/run-static-analysis.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/run-static-analysis.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + +- job: documentation + displayName: Documentation + condition: succeeded() + pool: Hosted Ubuntu 1604 + steps: + - bash: | + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1 + + sudo apt-get update && + sudo apt-get install -y asciidoc xmlto asciidoctor && + + export ALREADY_HAVE_ASCIIDOCTOR=yes. && + export jobname=Documentation && + + ci/test-documentation.sh || exit 1 + + test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1 + displayName: 'ci/test-documentation.sh' + env: + GITFILESHAREPWD: $(gitfileshare.pwd)
ci/lib.sh +1 -1
@@ -42,7 +42,7 @@ then BREW_INSTALL_PACKAGES= export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" - export GIT_TEST_OPTS="--quiet --write-junit-xml" + export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" fi skip_branch_tip_with_tag () {
ci/mount-fileshare.sh new file +25 -0
@@ -0,0 +1,25 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +test $# = 4 || +die "Usage: $0 <share> <username> <password> <mountpoint>" + +mkdir -p "$4" || die "Could not create $4" + +case "$(uname -s)" in +Linux) + sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4" + ;; +Darwin) + pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" && + mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4" + ;; +*) + die "No support for $(uname -s)" + ;; +esac || +die "Could not mount $4"
Signature · 1 line
gitgitgadget
Re: [PATCH v4 09/21] Add a build definition for Azure DevOps
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 17 lines · writes:
From: Johannes Schindelin <[email protected]>
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the
matrixfeature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
Quoted 3 lines
Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 306 ++++++++++++++++++++++++++++++++++++++++++
Way-overlong line in this file bothers me somewhat, but let's say these are not for human consumption and it is OK ;-)
ci/lib.sh then · line 46
Quoted 11 lines
ci/lib.sh +1
-1@@ -42,7 +42,7 @@ then BREW_INSTALL_PACKAGES= export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" - export GIT_TEST_OPTS="--quiet --write-junit-xml" + export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" fi
Interesting to see this change here, not in the previous step. If we stopped at 08/21, did we even have a chance to enter this elif block? If not, it probably is sane to squash this hunk to the previous one that introduced the elif block.
Re: [PATCH v4 09/21] Add a build definition for Azure DevOps
Hi Junio,
Quoted 20 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 17 lines · writes:
From: Johannes Schindelin <[email protected]>
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml.
To make things a bit easier to understand, we refrain from using the
matrixfeature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS).Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc.
Quoted 6 lines
Quoted 3 lines
Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 306 ++++++++++++++++++++++++++++++++++++++++++Way-overlong line in this file bothers me somewhat, but let's say these are not for human consumption and it is OK ;-)
Right ;-)
Quoted 6 lines
Quoted 6 lines
ci/lib.sh +0
-0@@ -42,7 +42,7 @@ then
Quoted 10 lines
ci/lib.sh then · line 46
Quoted 5 lines
ci/lib.sh +1
-1BREW_INSTALL_PACKAGES= export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" - export GIT_TEST_OPTS="--quiet --write-junit-xml" + export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" fiInteresting to see this change here, not in the previous step. If we stopped at 08/21, did we even have a chance to enter this elif block? If not, it probably is sane to squash this hunk to the previous one that introduced the elif block.
Oh my. You're right. I think I just picked the wrong commit to make this fixup.
Will squash as suggested,
Dscho
PATCH v4 10/21 ci: move the Windows job to the top
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
This affects only the Azure Pipelines configuration, not the Travis one, of course, as Travis cannot run our Windows job: 1h20m is distinctly longer than the 50 minute timeout of Travis' free tier.
This commit is best viewed with --color-moved.
--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)
azure-pipelines.yml +86 -86
@@ -3,6 +3,92 @@ resources: fetchDepth: 1 jobs: +- job: windows + displayName: Windows + condition: succeeded() + pool: Hosted + timeoutInMinutes: 240 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - powershell: | + # Helper to check the error level of the latest command (exit with error when appropriate) + function c() { if (!$?) { exit(1) } } + + # Add build agent's MinGit to PATH + $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH + + # Helper to initialize (or update) a Git worktree + function init ($path, $url, $set_origin) { + if (Test-Path $path) { + cd $path; c + if (Test-Path .git) { + & git init; c + } else { + & git status + } + } else { + & git init $path; c + cd $path; c + } + & git config core.autocrlf false; c + & git config core.untrackedCache true; c + if (($set_origin -ne 0) -and !(git config remote.origin.url)) { + & git remote add origin $url; c + } + & git fetch --depth=1 $url master; c + & git reset --hard FETCH_HEAD; c + & git clean -df; c + } + + # Initialize Git for Windows' SDK + $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" + init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + + # Let Git ignore the SDK and the test-cache + "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Initialize the Git for Windows SDK' + - powershell: | + & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + export MAKEFLAGS=-j10 + export DEVELOPER=1 + export NO_PERL=1 + export NO_SVN_TESTS=1 + export GIT_TEST_SKIP_REBASE_P=1 + + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + "@ + if (!$?) { exit(1) } + displayName: 'Build & Test' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + - job: linux_clang displayName: linux-clang condition: succeeded()
@@ -153,92 +239,6 @@ jobs: publishRunAttachments: false condition: succeededOrFailed() -- job: windows - displayName: Windows - condition: succeeded() - pool: Hosted - timeoutInMinutes: 240 - steps: - - powershell: | - if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { - net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no - cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ - } - displayName: 'Mount test-cache' - env: - GITFILESHAREPWD: $(gitfileshare.pwd) - - powershell: | - # Helper to check the error level of the latest command (exit with error when appropriate) - function c() { if (!$?) { exit(1) } } - - # Add build agent's MinGit to PATH - $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH - - # Helper to initialize (or update) a Git worktree - function init ($path, $url, $set_origin) { - if (Test-Path $path) { - cd $path; c - if (Test-Path .git) { - & git init; c - } else { - & git status - } - } else { - & git init $path; c - cd $path; c - } - & git config core.autocrlf false; c - & git config core.untrackedCache true; c - if (($set_origin -ne 0) -and !(git config remote.origin.url)) { - & git remote add origin $url; c - } - & git fetch --depth=1 $url master; c - & git reset --hard FETCH_HEAD; c - & git clean -df; c - } - - # Initialize Git for Windows' SDK - $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" - init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 - - # Let Git ignore the SDK and the test-cache - "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" - displayName: 'Initialize the Git for Windows SDK' - - powershell: | - & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" - export MAKEFLAGS=-j10 - export DEVELOPER=1 - export NO_PERL=1 - export NO_SVN_TESTS=1 - export GIT_TEST_SKIP_REBASE_P=1 - - ci/run-build-and-tests.sh || { - ci/print-test-failures.sh - exit 1 - } - "@ - if (!$?) { exit(1) } - displayName: 'Build & Test' - env: - HOME: $(Build.SourcesDirectory) - MSYSTEM: MINGW64 - - powershell: | - if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { - cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" - } - displayName: 'Unmount test-cache' - condition: true - env: - GITFILESHAREPWD: $(gitfileshare.pwd) - - task: PublishTestResults@2 - displayName: 'Publish Test Results **/TEST-*.xml' - inputs: - mergeTestResults: true - testRunTitle: 'windows' - platform: Windows - publishRunAttachments: false - condition: succeededOrFailed() - - job: linux32 displayName: Linux32 condition: succeeded()
Signature · 1 line
gitgitgadget
Re: [PATCH v4 10/21] ci: move the Windows job to the top
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
From: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
Is the reason why Windows job gets started first is to make sure that it, which is known to take the longest time, never has to wait before starting while other jobs run, in case there is limited parallelism? The last part of this sentence is what readers of this step will need in order to be convinced by the justification given, because (1) if the jobs run totally serially, the order does not matter much---if anything, running shorter jobs first would give results from more jobs sooner, and (2) if the jobs run totally in parallel, the order does not matter as long as we have enough parallelism.
Quoted 6 lines
This commit is best viewed with
--color-moved.Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)
For those who are seeing this azure-pipelines series for the first time, it would probably be unclear what the point of adding an entire file in 09/21 and them moving lines around in 10/21 is. If somebody asked me why, I wouldn't be able to explain why it is a good idea.
Would it hurt readability if these two steps are combined?
Re: [PATCH v4 10/21] ci: move the Windows job to the top
Hi Junio,
Quoted 10 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
From: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
Quoted 4 lines
Is the reason why Windows job gets started first is to make sure that it, which is known to take the longest time, never has to wait before starting while other jobs run, in case there is limited parallelism?
Yes, in order to optimize the overall run time. Like, if you have N jobs, and you know that one of them takes longer than the other combined, it really only makes sense to start that one as first one.
Quoted 7 lines
The last part of this sentence is what readers of this step will need in order to be convinced by the justification given, because (1) if the jobs run totally serially, the order does not matter much---if anything, running shorter jobs first would give results from more jobs sooner, and (2) if the jobs run totally in parallel, the order does not matter as long as we have enough parallelism.
Right, I think I totally forgot to mention that Azure Pipelines offers 10 parallel jobs to open source projects for free. Which means that we will run up to 10 jobs in parallel, as long as no other build is running, of course.
Will adjust the commit message.
Quoted 7 lines
Quoted 6 lines
This commit is best viewed with
--color-moved.Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)
Quoted 7 lines
For those who are seeing this azure-pipelines series for the first time, it would probably be unclear what the point of adding an entire file in 09/21 and them moving lines around in 10/21 is. If somebody asked me why, I wouldn't be able to explain why it is a good idea.
Would it hurt readability if these two steps are combined?
The thing is, I tried (of course) to replicate the Travis configuration as closely as possible. And the Windows job was in a specific location there.
However, I just realized that I *added* the Windows job to the Pipelines right from the start, and that is definitely not on par with Travis, as the Travis configuration did not define a Windows job (instead it has code to trigger a dedicated Azure Pipeline).
So what I will do instead is to
- *not* add the Windows-specific part in the commit that adds the initial Azure Pipelines support, and
- explain in the commit message of that commit that the idea is to imitate our existing Travis configuration as closely as possible.
Ciao,
Dscho
Re: [PATCH v4 10/21] ci: move the Windows job to the top
In reply to Johannes Schindelin via GitGitGadget"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
From: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
Is the reason why Windows job gets started first is to make sure that it, which is known to take the longest time, never has to wait before starting while other jobs run, in case there is limited parallelism? The last part of this sentence is what readers of this step will need in order to be convinced by the justification given, because (1) if the jobs run totally serially, the order does not matter much---if anything, running shorter jobs first would give results from more jobs sooner, and (2) if the jobs run totally in parallel, the order does not matter as long as we have enough parallelism.
Quoted 6 lines
This commit is best viewed with
--color-moved.Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)
For those who are seeing this azure-pipelines series for the first time, it would probably be unclear what the point of adding an entire file in 09/21 and them moving lines around in 10/21 is. If somebody asked me why, I wouldn't be able to explain why it is a good idea.
The same comment applies to 11/21.
Would it hurt readability if these steps are combined?
If 09/21 were "copy travis.yml to create a moral-equivalent set-up for azure.yml", then it is an entirely different story (i.e. "we start from an equivalent setup as we have, and then tweak to match our needs better, and we can view the tweak easier as a separate step"), but I did not get the impression that it was what happened there in 09/21.
Re: [PATCH v4 10/21] ci: move the Windows job to the top
Hi Junio,
Quoted 10 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
From: Johannes Schindelin <[email protected]>
The Windows job currently takes a whopping ~1h20m to complete. Which is *far* longer than the next-longest job takes (linux-gcc, ~35m). As such, it makes sense to start the Windows job first, to minimize the overall run time (which is now pretty safely the run time of the Windows job).
Quoted 10 lines
Is the reason why Windows job gets started first is to make sure that it, which is known to take the longest time, never has to wait before starting while other jobs run, in case there is limited parallelism? The last part of this sentence is what readers of this step will need in order to be convinced by the justification given, because (1) if the jobs run totally serially, the order does not matter much---if anything, running shorter jobs first would give results from more jobs sooner, and (2) if the jobs run totally in parallel, the order does not matter as long as we have enough parallelism.
See my response to the other mail you sent (which seemed to be a first draft of this mail I am replying to?).
Quoted 15 lines
Quoted 6 lines
This commit is best viewed with
--color-moved.Signed-off-by Johannes Schindelin <[email protected]>--- azure-pipelines.yml | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-)For those who are seeing this azure-pipelines series for the first time, it would probably be unclear what the point of adding an entire file in 09/21 and them moving lines around in 10/21 is. If somebody asked me why, I wouldn't be able to explain why it is a good idea.
The same comment applies to 11/21.
Quoted 8 lines
Would it hurt readability if these steps are combined?
If 09/21 were "copy travis.yml to create a moral-equivalent set-up for azure.yml", then it is an entirely different story (i.e. "we start from an equivalent setup as we have, and then tweak to match our needs better, and we can view the tweak easier as a separate step"), but I did not get the impression that it was what happened there in 09/21.
Indeed, that *was* the intention. I tried to clarify that, by just *not* adding the Windows-specific part in the commit that adds azure-pipelines.yml, as it really should imitate .travis.yml closely.
Ciao,
Dscho
PATCH v4 11/21 ci: use git-sdk-64-minimal build artifact
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Instead of a shallow fetch followed by a sparse checkout, we are better off by using a separate, dedicated Pipeline that bundles the SDK as a build artifact, and then consuming that build artifact here.
In fact, since this artifact will be used a lot, we spent substantial time on figuring out a minimal subset of the Git for Windows SDK, just enough to build and test Git. The result is a size reduction from around 1GB (compressed) to around 55MB (compressed). This also comes with the change where we now call usr\bin\bash.exe directly, as git-cmd.exe is not included in the minimal SDK.
That reduces the time to initialize Git for Windows' SDK from anywhere between 2m30s-7m to a little over 1m.
Note: in theory, we could also use the DownloadBuildArtifacts@0 task here. However, restricted permissions that are in effect when building from forks would let this fail for PR builds, defeating the whole purpose of the Azure Pipelines support for git.git.
--- azure-pipelines.yml | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-)
azure-pipelines.yml +9 -35
@@ -18,44 +18,18 @@ jobs: env: GITFILESHAREPWD: $(gitfileshare.pwd) - powershell: | - # Helper to check the error level of the latest command (exit with error when appropriate) - function c() { if (!$?) { exit(1) } } - - # Add build agent's MinGit to PATH - $env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH - - # Helper to initialize (or update) a Git worktree - function init ($path, $url, $set_origin) { - if (Test-Path $path) { - cd $path; c - if (Test-Path .git) { - & git init; c - } else { - & git status - } - } else { - & git init $path; c - cd $path; c - } - & git config core.autocrlf false; c - & git config core.untrackedCache true; c - if (($set_origin -ne 0) -and !(git config remote.origin.url)) { - & git remote add origin $url; c - } - & git fetch --depth=1 $url master; c - & git reset --hard FETCH_HEAD; c - & git clean -df; c - } - - # Initialize Git for Windows' SDK - $sdk_path = "$(Build.SourcesDirectory)\git-sdk-64" - init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0 + $urlbase = "https://dev.azure.com/git-for-windows/git/_apis/build/builds" + $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=22&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id + $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[1].resource.downloadUrl + (New-Object Net.WebClient).DownloadFile($downloadUrl,"git-sdk-64-minimal.zip") + Expand-Archive git-sdk-64-minimal.zip -DestinationPath . -Force + Remove-Item git-sdk-64-minimal.zip # Let Git ignore the SDK and the test-cache - "/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" - displayName: 'Initialize the Git for Windows SDK' + "/git-sdk-64-minimal/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Download git-sdk-64-minimal' - powershell: | - & "git-sdk-64\git-cmd.exe" --command=usr\\bin\\bash.exe -lc @" + & git-sdk-64-minimal\usr\bin\bash.exe -lc @" export MAKEFLAGS=-j10 export DEVELOPER=1 export NO_PERL=1
Signature · 1 line
gitgitgadget
PATCH v4 12/21 mingw: be more generous when wrapping up the setitimer() emulation
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Every once in a while, the Azure Pipeline fails with some semi-random
error: timer thread did not terminate timely
This error message means that the thread that is used to emulate the setitimer() function did not terminate within 1,000 milliseconds.
The most likely explanation (and therefore the one we should assume to be true, according to Occam's Razor) is that the timeout of one second is simply not enough because we try to run so many tasks in parallel.
So let's give it ten seconds instead of only one. That should be enough.
--- compat/mingw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
compat/mingw.c +1 -1
@@ -2100,7 +2100,7 @@ static void stop_timer_thread(void)if (timer_event)SetEvent (timer_event);/* tell thread to terminate */ if (timer_thread) { -int rc =WaitForSingleObject (timer_thread,1000 ); +int rc =WaitForSingleObject (timer_thread,10000 );if (rc ==WAIT_TIMEOUT )error ("timer thread did not terminate timely" );else if (rc !=WAIT_OBJECT_0 )
Signature · 1 line
gitgitgadget
PATCH v4 13/21 README: add a build badge (status of the Azure Pipelines build)
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Just like so many other OSS projects, we now also have a build badge.
--- README.md | 2 ++ 1 file changed, 2 insertions(+)
README.md +2 -0
@@ -1,3 +1,5 @@ +[](https://dev.azure.com/git/git/_build/latest?definitionId=2) + Git - fast, scalable, distributed revision control system =========================================================
Signature · 1 line
gitgitgadget
PATCH v4 14/21 tests: avoid calling Perl just to determine file sizes
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
It is a bit ridiculous to spin up a full-blown Perl instance (especially on Windows, where that means spinning up a full POSIX emulation layer, AKA the MSYS2 runtime) just to tell how large a given file is.
So let's just use the test-tool to do that job instead.
This command will also be used over the next commits, to allow for cutting out individual test cases' verbose log from the file generated via --verbose-log.
--- t/helper/test-path-utils.c | 12 ++++++++++++ t/t0021-conversion.sh | 2 +- t/t1050-large.sh | 2 +- t/t5315-pack-objects-compression.sh | 2 +- t/t9303-fast-import-compression.sh | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-)
t/helper/test-path-utils.c +12 -0
@@ -291,6 +291,18 @@ int cmd__path_utils(int argc, const char **argv)return !!res; } +if (argc >2 && !strcmp (argv[1 ],"file-size" )) { +int res =0 , i; +struct stat st; + +for (i =2 ; i < argc; i++) +if (stat (argv[i], &st)) + res =error_errno ("Cannot stat '%s'" , argv[i]); +else +printf ("%" PRIuMAX"\n" , (uintmax_t )st.st_size); +return !!res; + } +fprintf (stderr,"%s: unknown function name: %s\n" , argv[0 ], argv[1 ] ? argv[1 ] :"(there was none)" );return 1 ;
t/t0021-conversion.sh +1 -1
@@ -24,7 +24,7 @@ generate_random_characters () { } file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } filter_git () {
t/t1050-large.sh +1 -1
@@ -8,7 +8,7 @@ test_description='adding and checking out large blobs' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup '
t/t5315-pack-objects-compression.sh +1 -1
@@ -7,7 +7,7 @@ test_description='pack-object compression configuration' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup '
t/t9303-fast-import-compression.sh +1 -1
@@ -6,7 +6,7 @@ test_description='compression setting of fast-import utility' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } import_large () {
Signature · 1 line
gitgitgadget
PATCH v4 15/21 tests: include detailed trace logs with --write-junit-xml upon failure
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The JUnit XML format lends itself to be presented in a powerful UI, where you can drill down to the information you are interested in very quickly.
For test failures, this usually means that you want to see the detailed trace of the failing tests.
With Travis CI, we passed the --verbose-log option to get those traces. However, that seems excessive, as we do not need/use the logs in almost all of those cases: only when a test fails do we have a way to include the trace.
So let's do something different when using Azure DevOps: let's run all the tests with --quiet first, and only if a failure is encountered, try to trace the commands as they are executed.
Of course, we cannot turn on --verbose-log after the fact. So let's just re-run the test with all the same options, adding --verbose-log. And then munging the output file into the JUnit XML on the fly.
Note: there is an off chance that re-running the test in verbose mode "fixes" the failures (and this does happen from time to time!). That is a possibility we should be able to live with. Ideally, we would label this as "Passed upon rerun", and Azure Pipelines even know about that outcome, but it is not available when using the JUnit XML format for now:
https://github.com/Microsoft/azure-pipelines-agent/blob/master/src/Agent.Worker/TestResults/JunitResultReader.cs
--- t/helper/test-path-utils.c | 21 +++++++++++++++++++++ t/test-lib.sh | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-)
t/helper/test-path-utils.c +21 -0
@@ -303,6 +303,27 @@ int cmd__path_utils(int argc, const char **argv)return !!res; } +if (argc ==4 && !strcmp (argv[1 ],"skip-n-bytes" )) { +int fd =open (argv[2 ],O_RDONLY ), offset =atoi (argv[3 ]); +char buffer[65536 ]; + +if (fd <0 ) +die_errno ("could not open '%s'" , argv[2 ]); +if (lseek (fd, offset,SEEK_SET ) <0 ) +die_errno ("could not skip %d bytes" , offset); +for (;;) { +ssize_t count =read (fd, buffer,sizeof (buffer)); +if (count <0 ) +die_errno ("could not read '%s'" , argv[2 ]); +if (!count) +break ; +if (write (1 , buffer, count) <0 ) +die_errno ("could not write to stdout" ); + } +close (fd); +return 0 ; + } +fprintf (stderr,"%s: unknown function name: %s\n" , argv[0 ], argv[1 ] ? argv[1 ] :"(there was none)" );return 1 ;
t/test-lib.sh +21 -1
@@ -639,8 +639,19 @@ test_failure_ () { junit_insert="<failure message=\"not ok $test_count -" junit_insert="$junit_insert $(xml_attr_encode "$1")\">" junit_insert="$junit_insert $(xml_attr_encode \ - "$(printf '%s\n' "$@" | sed 1d)")" + "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + test-tool path-utils skip-n-bytes \ + "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET + else + printf '%s\n' "$@" | sed 1d + fi)")" junit_insert="$junit_insert</failure>" + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" + fi write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1))
@@ -931,6 +942,11 @@ test_finish_ () { echo >&3 "" maybe_teardown_valgrind maybe_teardown_verbose + if test -n "$GIT_TEST_TEE_OFFSET" + then + GIT_TEST_TEE_OFFSET=$(test-tool path-utils file-size \ + "$GIT_TEST_TEE_OUTPUT_FILE") + fi } test_skip () {
@@ -1280,6 +1296,10 @@ then date +%Y-%m-%dT%H:%M:%S)\"" write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" junit_suite_start=$(test-tool date getnanos) + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=0 + fi fi # Provide an implementation of the 'yes' utility
Signature · 1 line
gitgitgadget
PATCH v4 16/21 mingw: try to work around issues with the test cleanup
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
It seems that every once in a while in the Git for Windows SDK, there are some transient file locking issues preventing the test clean up to delete the trash directory. Let's be gentle and try again five seconds later, and only error out if it still fails the second time.
This change helps Windows, and does not hurt any other platform (normally, it is highly unlikely that said deletion fails, and if it does, normally it will fail again even 5 seconds later).
--- t/test-lib.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
t/test-lib.sh +5 -1
@@ -1104,7 +1104,11 @@ test_done () { error "Tests passed but trash directory already removed before test cleanup; aborting" cd "$TRASH_DIRECTORY/.." && - rm -fr "$TRASH_DIRECTORY" || + rm -fr "$TRASH_DIRECTORY" || { + # try again in a bit + sleep 5; + rm -fr "$TRASH_DIRECTORY" + } || error "Tests passed but test cleanup failed; aborting" fi test_at_end_hook_
Signature · 1 line
gitgitgadget
PATCH v4 17/21 tests: add t/helper/ to the PATH with --with-dashes
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
We really need to be able to find the test helpers... Really. This change was forgotten when we moved the test helpers into t/helper/
--- t/test-lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
t/test-lib.sh +1 -1
@@ -1227,7 +1227,7 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" then - PATH="$GIT_BUILD_DIR:$PATH" + PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
Signature · 1 line
gitgitgadget
Re: [PATCH v4 17/21] tests: add t/helper/ to the PATH with --with-dashes
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
From: Johannes Schindelin <[email protected]>
We really need to be able to find the test helpers... Really. This change was forgotten when we moved the test helpers into t/helper/
Signed-off-by Johannes Schindelin <[email protected]>--- t/test-lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
It is unfortunate that --with-dashes is needed for valgrind and GIT_TEST_INSTALLED. Otherwise I do not see why we care about keeping the option working.
Does any or your test matrix entry actually use --with-dashes and rely on it working, or is it just the stuff that implicitly depend on it?
Thanks.
Quoted 14 lines
t/test-lib.sh +1
-1@@ -1227,7 +1227,7 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" then - PATH="$GIT_BUILD_DIR:$PATH" + PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt