From 124ec8dea062e95931d5d2f80633e025aa7733ad Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 15 Mar 2021 09:25:15 -0700
Subject: [PATCH v5] ci: Add continuous integration for github repositories via
 cirrus-ci.

Currently FreeBSD, Linux, macOS and Windows (Visual Studio) are tested.

The main goal of this integration is to make it easier to test in-development
patches across multiple platforms. This includes improving the testing done
automatically by cfbot [1] for commitfest entries.  It is *not* the goal to
supersede the buildfarm.

cirrus-ci [2] was chosen because it was already in use for cfbot, allows using
full VMs, has good OS coverage and allows accessing the full test results
without authentication (like agithub account).  It might be worth adding
support for further CI providers, particularly ones supporting other git
forges, in the future.

To keep CI times tolerable, most platforms use pre-generated images. Some
platforms use containers, others use full VMs.

For instructions on how to enable the CI integration in a repository and
further details src/tools/ci/README

[1] http://cfbot.cputube.org/
[2] https://cirrus-ci.org/

Author: Andres Freund <andres@anarazel.de>
Author: Thomas Munro <tmunro@postgresql.org>
Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-By: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-By: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-By: Thomas Munro <tmunro@postgresql.org>
Reviewed-By: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Discussion: https://postgr.es/m/20211001222752.wrz7erzh4cajvgp6@alap3.anarazel.de
---
 .cirrus.yml                             | 547 ++++++++++++++++++++++++
 src/tools/ci/README                     |  63 +++
 src/tools/ci/cores_backtrace.sh         |  50 +++
 src/tools/ci/gcp_freebsd_repartition.sh |  28 ++
 src/tools/ci/pg_ci_base.conf            |  14 +
 src/tools/ci/windows_build_config.pl    |  13 +
 6 files changed, 715 insertions(+)
 create mode 100644 .cirrus.yml
 create mode 100644 src/tools/ci/README
 create mode 100755 src/tools/ci/cores_backtrace.sh
 create mode 100755 src/tools/ci/gcp_freebsd_repartition.sh
 create mode 100644 src/tools/ci/pg_ci_base.conf
 create mode 100644 src/tools/ci/windows_build_config.pl

diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 00000000000..f49799e9a32
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,547 @@
+# CI configuration file for CI utilizing cirrus-ci.org
+#
+# For instructions on how to enable the CI integration in a repository and
+# further details src/tools/ci/README
+
+
+env:
+  # Source of images / containers
+  GCP_PROJECT: pg-ci-images
+  IMAGE_PROJECT: $GCP_PROJECT
+  CONTAINER_REPO: us-docker.pkg.dev/${GCP_PROJECT}/ci
+
+  # The lower depth accelerates git clone. Use a bit of depth so that
+  # concurrent tasks and retrying older jobs has a chance of working.
+  CIRRUS_CLONE_DEPTH: 500
+  # Useful to be able to analyse what in a script takes long
+  CIRRUS_LOG_TIMESTAMP: true
+
+  CCACHE_MAXSIZE: "250M"
+
+  # target to test, for all but windows
+  CHECK: check-world PROVE_FLAGS=$PROVE_FLAGS
+  CHECKFLAGS: -Otarget
+  PROVE_FLAGS: --timer
+  PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
+  TEMP_CONFIG: ${CIRRUS_WORKING_DIR}/src/tools/ci/pg_ci_base.conf
+  PG_TEST_EXTRA: kerberos ldap ssl
+
+
+# What files to preserve in case tests fail
+on_failure: &on_failure
+  log_artifacts:
+    path: "**/**.log"
+    type: text/plain
+  regress_diffs_artifacts:
+    path: "**/**.diffs"
+    type: text/plain
+  tap_artifacts:
+    path: "**/regress_log_*"
+    type: text/plain
+
+
+task:
+  name: FreeBSD - 13
+
+  env:
+    # FreeBSD on GCP is slow when running with larger number of CPUS /
+    # jobs. Using one more job than cpus seems to work best.
+    CPUS: 2
+    BUILD_JOBS: 3
+    TEST_JOBS: 3
+
+    CCACHE_DIR: /tmp/ccache_dir
+
+  only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\nci-os-only:.*' || $CIRRUS_CHANGE_MESSAGE =~ '.*\nci-os-only:[^\n]*freebsd.*'
+
+  compute_engine_instance:
+    image_project: $IMAGE_PROJECT
+    image: family/pg-ci-freebsd-13-0
+    platform: freebsd
+    cpu: $CPUS
+    memory: 2G
+    disk: 50
+
+  sysinfo_script: |
+    id
+    uname -a
+    ulimit -a -H && ulimit -a -S
+    export
+
+  ccache_cache:
+    folder: $CCACHE_DIR
+  # Workaround around performance issues due to 32KB block size
+  repartition_script: src/tools/ci/gcp_freebsd_repartition.sh
+  create_user_script: |
+    pw useradd postgres
+    chown -R postgres:postgres .
+    mkdir -p ${CCACHE_DIR}
+    chown -R postgres:postgres ${CCACHE_DIR}
+  setup_cores_script: |
+    mkdir -m 770 /tmp/cores
+    chown root:postgres /tmp/cores
+    sysctl kern.corefile='/tmp/cores/%N.%P.core'
+
+  # NB: Intentionally build without --with-llvm. The freebsd image size is
+  # already large enough to make VM startup slow, and even without llvm
+  # freebsd already takes longer than other platforms except for windows.
+  configure_script: |
+    su postgres <<-EOF
+      ./configure \
+        --enable-cassert --enable-debug --enable-tap-tests \
+        --enable-nls \
+        \
+        --with-gssapi \
+        --with-icu \
+        --with-ldap \
+        --with-libxml \
+        --with-libxslt \
+        --with-lz4 \
+        --with-pam \
+        --with-perl \
+        --with-python \
+        --with-ssl=openssl \
+        --with-tcl --with-tclconfig=/usr/local/lib/tcl8.6/ \
+        --with-uuid=bsd \
+        \
+        --with-includes=/usr/local/include \
+        --with-libs=/usr/local/lib \
+        \
+        CC="ccache cc" \
+        CXX="ccache c++" \
+        CFLAGS="-O0 -ggdb"
+    EOF
+  build_script: su postgres -c "gmake -s -j${BUILD_JOBS} world-bin"
+  upload_caches: ccache
+
+  # The use of script avoids make -Otarget complaints about fcntl() on
+  # platforms without support for locking pipes. See also
+  # https://savannah.gnu.org/bugs/?60774
+  # script uses a pseudo-tty, which do support locking.
+  test_world_script:
+    - su postgres -c "time script test.log gmake -s -j${TEST_JOBS} ${CHECK} ${CHECKFLAGS}"
+
+  on_failure:
+    <<: *on_failure
+    cores_script: src/tools/ci/cores_backtrace.sh freebsd /tmp/cores
+
+
+# configure feature flags, shared between the task running the linux tests and
+# the CompilerWarnings task
+LINUX_CONFIGURE_FEATURES: &LINUX_CONFIGURE_FEATURES >-
+  --with-gssapi
+  --with-icu
+  --with-ldap
+  --with-libxml
+  --with-libxslt
+  --with-llvm
+  --with-lz4
+  --with-pam
+  --with-perl
+  --with-python
+  --with-selinux
+  --with-ssl=openssl
+  --with-systemd
+  --with-tcl --with-tclconfig=/usr/lib/tcl8.6/
+  --with-uuid=ossp
+
+
+task:
+  name: Linux - Debian Bullseye
+
+  env:
+    CPUS: 4
+    BUILD_JOBS: 4
+    TEST_JOBS: 8 # experimentally derived to be a decent choice
+
+    CCACHE_DIR: /tmp/ccache_dir
+    DEBUGINFOD_URLS: "https://debuginfod.debian.net"
+
+    LINUX_CONFIGURE_FEATURES: *LINUX_CONFIGURE_FEATURES
+
+  only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\nci-os-only:.*' || $CIRRUS_CHANGE_MESSAGE =~ '.*\nci-os-only:[^\n]*linux.*'
+
+  compute_engine_instance:
+    image_project: $IMAGE_PROJECT
+    image: family/pg-ci-bullseye
+    platform: linux
+    cpu: $CPUS
+    memory: 2G
+
+  ccache_cache:
+    folder: ${CCACHE_DIR}
+
+  sysinfo_script: |
+    id
+    uname -a
+    cat /proc/cmdline
+    ulimit -a -H && ulimit -a -S
+    export
+  create_user_script: |
+    useradd -m postgres
+    chown -R postgres:postgres .
+    mkdir -p ${CCACHE_DIR}
+    chown -R postgres:postgres ${CCACHE_DIR}
+    echo '* - memlock 134217728' > /etc/security/limits.d/postgres.conf
+    su postgres -c "ulimit -l -H && ulimit -l -S"
+  setup_cores_script: |
+    mkdir -m 770 /tmp/cores
+    chown root:postgres /tmp/cores
+    sysctl kernel.core_pattern='/tmp/cores/%e-%s-%p.core'
+
+  configure_script: |
+    su postgres <<-EOF
+      ./configure \
+        --enable-cassert --enable-debug --enable-tap-tests \
+        --enable-nls \
+        \
+        ${LINUX_CONFIGURE_FEATURES} \
+        \
+        CC="ccache gcc" \
+        CXX="ccache g++" \
+        CLANG="ccache clang" \
+        CFLAGS="-O0 -ggdb" \
+        CXXFLAGS="-O0 -ggdb"
+    EOF
+  build_script: su postgres -c "make -s -j${BUILD_JOBS} world-bin"
+  upload_caches: ccache
+
+  test_world_script: |
+    su postgres <<-EOF
+      ulimit -c unlimited # default is 0
+      make -s ${CHECK} ${CHECKFLAGS} -j${TEST_JOBS}
+    EOF
+
+  on_failure:
+    <<: *on_failure
+    cores_script: src/tools/ci/cores_backtrace.sh linux /tmp/cores
+
+
+task:
+  name: macOS - Monterey
+
+  env:
+    CPUS: 12 # always get that much for cirrusci macOS instances
+    BUILD_JOBS: $CPUS
+    TEST_JOBS: $CPUS # already fast enough to not be worth tuning
+
+    CIRRUS_WORKING_DIR: ${HOME}/pgsql/
+    CCACHE_DIR: ${HOME}/ccache
+    HOMEBREW_CACHE: ${HOME}/homebrew-cache
+    PERL5LIB: ${HOME}/perl5/lib/perl5
+
+  only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\nci-os-only:.*' || $CIRRUS_CHANGE_MESSAGE =~ '.*\nci-os-only:[^\n]*(macos|darwin|osx).*'
+
+  osx_instance:
+    image: monterey-base
+
+  sysinfo_script: |
+    id
+    export
+    ulimit -a -H && ulimit -a -S
+
+  setup_cores_script:
+    - mkdir ${HOME}/cores
+    - sudo sysctl kern.corefile="${HOME}/cores/core.%P"
+
+  perl_cache:
+    folder: ~/perl5
+  cpan_install_script:
+    - perl -mIPC::Run -e 1 || cpan -T IPC::Run
+    - perl -mIO::Pty -e 1 || cpan -T IO::Pty
+  upload_caches: perl
+
+
+  # XXX: Could we instead install homebrew into a cached directory? The
+  # homebrew installation takes a good bit of time every time, even if the
+  # packages do not need to be downloaded.
+  homebrew_cache:
+    folder: $HOMEBREW_CACHE
+  homebrew_install_script: |
+    brew install \
+      ccache \
+      icu4c \
+      krb5 \
+      llvm \
+      lz4 \
+      make \
+      openldap \
+      openssl \
+      python \
+      tcl-tk
+
+    brew cleanup -s # to reduce cache size
+  upload_caches: homebrew
+
+  ccache_cache:
+    folder: $CCACHE_DIR
+  configure_script: |
+    brewpath="/usr/local"
+    INCLUDES="${brewpath}/include:${INCLUDES}"
+    LIBS="${brewpath}/lib:${LIBS}"
+
+    for pkg in icu4c krb5 openldap openssl ; do
+      pkgpath="${brewpath}/opt/${pkg}"
+      INCLUDES="${pkgpath}/include:${INCLUDES}"
+      LIBS="${pkgpath}/lib:${LIBS}"
+      PKG_CONFIG_PATH="${pkgpath}/lib/pkgconfig:${PKG_CONFIG_PATH}"
+    done
+
+    export PKG_CONFIG_PATH
+
+    ./configure \
+      --enable-cassert --enable-debug --enable-tap-tests \
+      --enable-nls \
+      \
+      --with-bonjour \
+      --with-gssapi \
+      --with-icu \
+      --with-ldap \
+      --with-libxml \
+      --with-libxslt \
+      --with-lz4 \
+      --with-perl \
+      --with-python \
+      --with-ssl=openssl \
+      --with-tcl --with-tclconfig=${brewpath}/opt/tcl-tk/lib/ \
+      --with-uuid=e2fs \
+      \
+      --prefix=${HOME}/install \
+      --with-includes="${INCLUDES}" \
+      --with-libs="${LIBS}" \
+      \
+      CC="ccache cc" \
+      CXX="ccache c++" \
+      CLANG="ccache ${brewpath}/llvm/bin/ccache" \
+      CFLAGS="-O0 -ggdb" \
+      CXXFLAGS="-O0 -ggdb" \
+      \
+      LLVM_CONFIG=${brewpath}/llvm/bin/llvm-config \
+      PYTHON=python3
+  build_script: gmake -s -j${BUILD_JOBS} world-bin
+  upload_caches: ccache
+
+  test_world_script: |
+    ulimit -c unlimited # default is 0
+    ulimit -n 1024 # default is 256, pretty low
+    # See freebsd use of script for explanation
+    script test.log gmake -s -j${TEST_JOBS} ${CHECK} ${CHECKFLAGS}
+
+  on_failure:
+    <<: *on_failure
+    cores_script: src/tools/ci/cores_backtrace.sh macos "${HOME}/cores"
+
+
+task:
+  name: Windows - Server 2019, VS 2019
+
+  env:
+    # Half the allowed per-user CPU cores
+    CPUS: 4
+
+    # Our windows infrastructure doesn't have test concurrency above the level
+    # of a single vcregress test target. Due to that it using concurrency
+    # within prove is helpful. For other targets it isn't, because two sources
+    # of concurrency can overload machines.
+    #
+    # The concrete choice of 10 is based on a small bit of experimentation and
+    # likely can be improved upon further.
+    PROVE_FLAGS: -j10 --timer
+
+    # The default cirrus working dir is in a directory msbuild complains about
+    CIRRUS_WORKING_DIR: "c:/cirrus"
+    # Avoid re-installing over and over
+    NO_TEMP_INSTALL: 1
+    # git's tar doesn't deal with drive letters, see
+    # https://postgr.es/m/b6782dc3-a7b0-ed56-175f-f8f54cb08d67%40dunslane.net
+    TAR: "c:/windows/system32/tar.exe"
+    # Avoids port conflicts between concurrent tap test runs
+    PG_TEST_USE_UNIX_SOCKETS: 1
+    PG_REGRESS_SOCK_DIR: "c:/cirrus/"
+    # Use parallelism, disable file tracker, we're never going to rebuild...
+    MSBFLAGS: -m -verbosity:minimal /p:TrackFileAccess=false
+
+  only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\nci-os-only:.*' || $CIRRUS_CHANGE_MESSAGE =~ '.*\nci-os-only:[^\n]*windows.*'
+
+  windows_container:
+    image: $CONTAINER_REPO/windows_ci_vs_2019:latest
+    cpu: $CPUS
+    memory: 4G
+
+  sysinfo_script: |
+    chcp
+    systeminfo
+    powershell -Command get-psdrive -psprovider filesystem
+    set
+
+  configure_script:
+    # copy errors out when using forward slashes
+    - copy src\tools\ci\windows_build_config.pl src\tools\msvc\config.pl
+    - vcvarsall x64
+    - perl src/tools/msvc/mkvcbuild.pl
+  build_script:
+    - vcvarsall x64
+    - msbuild %MSBFLAGS% pgsql.sln
+  tempinstall_script:
+    # Installation on windows currently only completely works from src/tools/msvc
+    - cd src/tools/msvc && perl install.pl %CIRRUS_WORKING_DIR%/tmp_install
+
+  test_regress_parallel_script:
+    - perl src/tools/msvc/vcregress.pl check parallel
+  startcreate_script:
+    # paths to binaries need backslashes
+    - tmp_install\bin\pg_ctl.exe initdb -D tmp_check/db -l tmp_check/initdb.log
+    - echo include '%TEMP_CONFIG%' >> tmp_check/db/postgresql.conf
+    - tmp_install\bin\pg_ctl.exe start -D tmp_check/db -l tmp_check/postmaster.log
+  test_pl_script:
+    - perl src/tools/msvc/vcregress.pl plcheck
+  test_isolation_script:
+    - perl src/tools/msvc/vcregress.pl isolationcheck
+  test_modules_script:
+    - perl src/tools/msvc/vcregress.pl modulescheck
+  test_contrib_script:
+    - perl src/tools/msvc/vcregress.pl contribcheck
+  stop_script:
+    - tmp_install\bin\pg_ctl.exe stop -D tmp_check/db -l tmp_check/postmaster.log
+  test_ssl_script:
+    - set with_ssl=openssl
+    - perl src/tools/msvc/vcregress.pl taptest ./src/test/ssl/
+  test_subscription_script:
+    - perl src/tools/msvc/vcregress.pl taptest ./src/test/subscription/
+  test_authentication_script:
+    - perl src/tools/msvc/vcregress.pl taptest ./src/test/authentication/
+  test_recovery_script:
+    - perl src/tools/msvc/vcregress.pl recoverycheck
+  test_bin_script:
+    - perl src/tools/msvc/vcregress.pl bincheck
+  test_pg_upgrade_script:
+    - perl src/tools/msvc/vcregress.pl upgradecheck
+  test_ecpg_script:
+    # tries to build additional stuff
+    - vcvarsall x64
+    # References ecpg_regression.proj in the current dir
+    - cd src/tools/msvc
+    - perl vcregress.pl ecpgcheck
+
+  on_failure: *on_failure
+
+
+task:
+  name: CompilerWarnings
+
+  # To limit unneccessary work only run this once normal linux test succeeded
+  depends_on:
+    - Linux - Debian Bullseye
+
+  env:
+    CPUS: 4
+    BUILD_JOBS: 4
+
+    # Use larger ccache cache, as this task compiles with multiple compilers /
+    # flag combinations
+    CCACHE_SIZE: "1GB"
+    CCACHE_DIR: "/tmp/ccache_dir"
+
+    LINUX_CONFIGURE_FEATURES: *LINUX_CONFIGURE_FEATURES
+
+  # task that did not run, count as a success, so we need to recheck Linux'
+  # condition here ...
+  only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\nci-os-only:.*' || $CIRRUS_CHANGE_MESSAGE =~ '.*\nci-os-only:[^\n]*linux.*'
+
+  container:
+    image: $CONTAINER_REPO/linux_debian_bullseye_ci:latest
+    cpu: $CPUS
+
+  sysinfo_script: |
+    id
+    uname -a
+    cat /proc/cmdline
+    ulimit -a -H && ulimit -a -S
+    gcc -v
+    clang -v
+    export
+
+  ccache_cache:
+    folder: $CCACHE_DIR
+
+  ###
+  # Test that code can be built with gcc/clang without warnings
+  ###
+
+  setup_script: echo "COPT=-Werror" > src/Makefile.custom
+
+  # Trace probes have a history of getting accidentally broken. Use the
+  # different compilers to build with different combinations of dtrace on/off
+  # and cassert on/off.
+
+  # gcc, cassert off, dtrace on
+  always:
+    gcc_warning_script: |
+      time ./configure \
+        --cache gcc.cache \
+        --enable-dtrace \
+        ${LINUX_CONFIGURE_FEATURES} \
+        CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} world-bin
+
+  # gcc, cassert on, dtrace off
+  always:
+    gcc_a_warning_script: |
+      time ./configure \
+        --cache gcc.cache \
+        --enable-cassert \
+        ${LINUX_CONFIGURE_FEATURES} \
+        CC="ccache gcc" CXX="ccache g++" CLANG="ccache clang"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} world-bin
+
+  # clang, cassert off, dtrace off
+  always:
+    clang_warning_script: |
+      time ./configure \
+        --cache clang.cache \
+        ${LINUX_CONFIGURE_FEATURES} \
+        CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} world-bin
+
+  # clang, cassert on, dtrace on
+  always:
+    clang_a_warning_script: |
+      time ./configure \
+        --cache clang.cache \
+        --enable-cassert \
+        --enable-dtrace \
+        ${LINUX_CONFIGURE_FEATURES} \
+        CC="ccache clang" CXX="ccache clang++" CLANG="ccache clang"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} world-bin
+
+  # cross-compile to windows
+  always:
+    mingw_cross_warning_script: |
+      time ./configure \
+        --host=x86_64-w64-mingw32 \
+        --enable-cassert \
+        CC="ccache x86_64-w64-mingw32-gcc" \
+        CXX="ccache x86_64-w64-mingw32-g++"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} world-bin
+
+  ###
+  # Verify docs can be built
+  ###
+  # XXX: Only do this if there have been changes in doc/ since last build
+  always:
+    docs_build_script: |
+      time ./configure \
+        --cache gcc.cache \
+        CC="ccache gcc" \
+        CXX="ccache g++" \
+        CLANG="ccache clang"
+      make -s -j${BUILD_JOBS} clean
+      time make -s -j${BUILD_JOBS} -C doc
+
+  always:
+    upload_caches: ccache
diff --git a/src/tools/ci/README b/src/tools/ci/README
new file mode 100644
index 00000000000..0a7cf022fbd
--- /dev/null
+++ b/src/tools/ci/README
@@ -0,0 +1,63 @@
+Postgres Continuous Integration (CI)
+====================================
+
+Postgres has two forms of CI:
+
+1) All supported branches in the main postgres repository are continuously
+   tested via the the the buildfarm. As this covers only the main repository,
+   it cannot be used during development of features.
+
+   For details see https://buildfarm.postgresql.org/
+
+2) For not yet merged development work, CI can be enabled for some git hosting
+   providers. This allows developers to test patches on a number of platforms
+   before they are merged (or even submitted).
+
+
+Configuring CI on personal repositories
+=======================================
+
+Currently postgres contains CI support utilizing cirrus-ci. cirrus-ci
+currently is only available for github.
+
+
+Enabling cirrus-ci in a github repository
+=========================================
+
+To enable cirrus-ci on a repository, go to
+https://github.com/marketplace/cirrus-ci and select "Public
+Repositories". Then "Install it for free" and "Complete order". The next page
+allows to configure which repositories cirrus-ci has access too. Choose the
+relevant repository and "Install".
+
+See also https://cirrus-ci.org/guide/quick-start/
+
+Once enabled on a repository, future commits and pull-requests in that
+repository will automatically trigger CI builds. These are visible from the
+commit history / PRs, and can also be viewed in the cirrus-ci UI at
+https://cirrus-ci.com/github/<username>/<reponame>/
+
+
+Images used for CI
+==================
+
+To keep CI times tolerable, most platforms use pre-generated images. Some
+platforms use containers, others use full VMs. Images for both are generated
+separately from CI runs, otherwise each git repository that is being tested
+would need to build its own set of containers, which would be wasteful (both
+in space and time.
+
+These images are built, on a daily basis, from the specifications in
+github.com/anarazel/pg-vm-images/
+
+
+Controlling CI via commit messages
+==================================
+
+The behavior of CI can be controlled by special content in commit
+messages. Currently the following controls are available:
+
+- ci-os-only: {(freebsd|linux|macos|windows)}
+
+  Only runs CI on operating systems specified. This can be useful when
+  addressing portability issues affecting only a subset of platforms.
diff --git a/src/tools/ci/cores_backtrace.sh b/src/tools/ci/cores_backtrace.sh
new file mode 100755
index 00000000000..28d3cecfc67
--- /dev/null
+++ b/src/tools/ci/cores_backtrace.sh
@@ -0,0 +1,50 @@
+#! /bin/sh
+
+if [ $# -ne 2 ]; then
+    echo "cores_backtrace.sh <os> <directory>"
+    exit 1
+fi
+
+os=$1
+directory=$2
+
+case $os in
+    freebsd|linux|macos)
+    ;;
+    *)
+        echo "unsupported operating system ${os}"
+        exit 1
+    ;;
+esac
+
+first=1
+for corefile in $(find "$directory" -type f) ; do
+    if [ "$first" -eq 1 ]; then
+        first=0
+    else
+        # to make it easier to separate the different crash reports
+        echo -e '\n\n'
+    fi
+
+    if [ "$os" = 'macos' ]; then
+        lldb -c $corefile --batch -o 'thread backtrace all' -o 'quit'
+    else
+        auxv=$(gdb --quiet --core ${corefile} --batch -ex 'info auxv' 2>/dev/null)
+        if [ $? -ne 0 ]; then
+            echo "could not process ${corefile}"
+            continue
+        fi
+
+        if [ "$os" = 'freebsd' ]; then
+            binary=$(echo "$auxv" | grep AT_EXECPATH | perl -pe "s/^.*\"(.*)\"\$/\$1/g")
+        elif [ "$os" = 'linux' ]; then
+            binary=$(echo "$auxv" | grep AT_EXECFN | perl -pe "s/^.*\"(.*)\"\$/\$1/g")
+        else
+            echo 'should not get here'
+            exit 1
+        fi
+
+        echo "dumping ${corefile} for ${binary}"
+        gdb --batch --quiet -ex "thread apply all bt full" -ex "quit" "$binary" "$corefile" 2>/dev/null
+    fi
+done
diff --git a/src/tools/ci/gcp_freebsd_repartition.sh b/src/tools/ci/gcp_freebsd_repartition.sh
new file mode 100755
index 00000000000..2d5e1738998
--- /dev/null
+++ b/src/tools/ci/gcp_freebsd_repartition.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -e
+set -x
+
+# The default filesystem on freebsd gcp images is very slow to run tests on,
+# due to its 32KB block size
+#
+# XXX: It'd probably better to fix this in the image, using something like
+# https://people.freebsd.org/~lidl/blog/re-root.html
+
+# fix backup partition table after resize
+gpart recover da0
+gpart show da0
+# kill swap, so we can delete a partition
+swapoff -a || true
+# (apparently we can only have 4!?)
+gpart delete -i 3 da0
+gpart add -t freebsd-ufs -l data8k -a 4096 da0
+gpart show da0
+newfs -U -b 8192 /dev/da0p3
+
+# Migrate working directory
+du -hs $CIRRUS_WORKING_DIR
+mv $CIRRUS_WORKING_DIR $CIRRUS_WORKING_DIR.orig
+mkdir $CIRRUS_WORKING_DIR
+mount -o noatime /dev/da0p3 $CIRRUS_WORKING_DIR
+cp -r $CIRRUS_WORKING_DIR.orig/* $CIRRUS_WORKING_DIR/
diff --git a/src/tools/ci/pg_ci_base.conf b/src/tools/ci/pg_ci_base.conf
new file mode 100644
index 00000000000..d8faa9c26c1
--- /dev/null
+++ b/src/tools/ci/pg_ci_base.conf
@@ -0,0 +1,14 @@
+# Tends to produce too many core files, taking a long time
+restart_after_crash = false
+
+# So that tests using the "manually" started postgres on windows can use
+# prepared statements
+max_prepared_transactions = 10
+
+# Settings that make logs more useful
+log_autovacuum_min_duration = 0
+log_checkpoints = true
+log_connections = true
+log_disconnections = true
+log_line_prefix = '%m [%p][%b] %q[%a][%v:%x] '
+log_lock_waits = true
diff --git a/src/tools/ci/windows_build_config.pl b/src/tools/ci/windows_build_config.pl
new file mode 100644
index 00000000000..b0d4360c748
--- /dev/null
+++ b/src/tools/ci/windows_build_config.pl
@@ -0,0 +1,13 @@
+use strict;
+use warnings;
+
+our $config;
+
+$config->{"tap_tests"} = 1;
+$config->{"asserts"} = 1;
+
+$config->{"openssl"} = "c:/openssl/1.1/";
+$config->{"perl"} = "c:/strawberry/$ENV{DEFAULT_PERL_VERSION}/perl/";
+$config->{"python"} = "c:/python/";
+
+1;
-- 
2.23.0.385.gbc12974a89

