test_r_package.sh 7.52 KB
Newer Older
1
2
3
#!/bin/bash

# set up R environment
4
CRAN_MIRROR="https://cloud.r-project.org/"
5
6
R_LIB_PATH=~/Rlib
mkdir -p $R_LIB_PATH
7
export R_LIBS=$R_LIB_PATH
8
9
export PATH="$R_LIB_PATH/R/bin:$PATH"

10
11
12
13
14
15
16
17
18
19
20
# Get details needed for installing R components
#
# NOTES:
#    * Linux builds on Azure use a container and don't need these details
if ! { [[ $AZURE == "true" ]] && [[ $OS_NAME == "linux" ]]; }; then
    R_MAJOR_VERSION=( ${R_VERSION//./ } )
    if [[ "${R_MAJOR_VERSION}" == "3" ]]; then
        export R_MAC_VERSION=3.6.3
        export R_LINUX_VERSION="3.6.3-1bionic"
        export R_APT_REPO="bionic-cran35/"
    elif [[ "${R_MAJOR_VERSION}" == "4" ]]; then
Nikita Titov's avatar
Nikita Titov committed
21
22
        export R_MAC_VERSION=4.0.2
        export R_LINUX_VERSION="4.0.2-1.1804.0"
23
24
25
26
27
28
29
        export R_APT_REPO="bionic-cran40/"
    else
        echo "Unrecognized R version: ${R_VERSION}"
        exit -1
    fi
fi

30
31
32
33
34
35
# installing precompiled R for Ubuntu
# https://cran.r-project.org/bin/linux/ubuntu/#installation
# adding steps from https://stackoverflow.com/a/56378217/3986677 to get latest version
#
# This only needs to get run on Travis because R environment for Linux
# used by Azure pipelines is set up in https://github.com/guolinke/lightgbm-ci-docker
36
if [[ $AZURE != "true" ]] && [[ $OS_NAME == "linux" ]]; then
37
38
39
    sudo apt-key adv \
        --keyserver keyserver.ubuntu.com \
        --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
40
    sudo add-apt-repository \
41
        "deb https://cloud.r-project.org/bin/linux/ubuntu ${R_APT_REPO}"
42
43
44
45
    sudo apt-get update
    sudo apt-get install \
        --no-install-recommends \
        -y \
46
            r-base-dev=${R_LINUX_VERSION} \
47
48
49
50
51
52
            texinfo \
            texlive-latex-recommended \
            texlive-fonts-recommended \
            texlive-fonts-extra \
            qpdf \
            || exit -1
53
54
55
56
57
58
59
60
61
62

    # https://github.com/r-lib/actions/issues/111
    if [[ $R_BUILD_TYPE == "cran" ]]; then
        sudo apt-get install \
            --no-install-recommends \
            -y \
                autoconf=$(cat R-package/AUTOCONF_UBUNTU_VERSION) \
                devscripts \
                || exit -1
    fi
63
64
65
66
fi

# Installing R precompiled for Mac OS 10.11 or higher
if [[ $OS_NAME == "macos" ]]; then
67
68
69
70
71
    if [[ $R_BUILD_TYPE == "cran" ]]; then
        brew install \
            automake \
            checkbashisms
    fi
72
73
74
    brew install qpdf
    brew cask install basictex
    export PATH="/Library/TeX/texbin:$PATH"
75
76
    sudo tlmgr --verify-repo=none update --self
    sudo tlmgr --verify-repo=none install inconsolata helvetic
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

    wget -q https://cran.r-project.org/bin/macosx/R-${R_MAC_VERSION}.pkg -O R.pkg
    sudo installer \
        -pkg $(pwd)/R.pkg \
        -target /

    # Fix "duplicate libomp versions" issue on Mac
    # by replacing the R libomp.dylib with a symlink to the one installed with brew
    if [[ $COMPILER == "clang" ]]; then
        ver_arr=( ${R_MAC_VERSION//./ } )
        R_MAJOR_MINOR="${ver_arr[0]}.${ver_arr[1]}"
        sudo ln -sf \
            "$(brew --cellar libomp)"/*/lib/libomp.dylib \
            /Library/Frameworks/R.framework/Versions/${R_MAJOR_MINOR}/Resources/lib/libomp.dylib
    fi
fi

conda install \
    -y \
    -q \
    --no-deps \
        pandoc

# Manually install Depends and Imports libraries + 'testthat'
# to avoid a CI-time dependency on devtools (for devtools::install_deps())
102
103
104
105
packages="c('data.table', 'jsonlite', 'Matrix', 'R6', 'testthat')"
if [[ $OS_NAME == "macos" ]]; then
    packages+=", type = 'binary'"
fi
106
Rscript --vanilla -e "install.packages(${packages}, repos = '${CRAN_MIRROR}', lib = '${R_LIB_PATH}', dependencies = c('Depends', 'Imports', 'LinkingTo'))" || exit -1
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
if [[ $TASK == "r-package-check-docs" ]]; then
    Rscript build_r.R || exit -1
    Rscript --vanilla -e "install.packages('roxygen2', repos = '${CRAN_MIRROR}', lib = '${R_LIB_PATH}', dependencies = c('Depends', 'Imports', 'LinkingTo'))" || exit -1
    Rscript --vanilla -e "roxygen2::roxygenize('R-package/', load = 'installed')" || exit -1
    num_doc_files_changed=$(
        git diff --name-only | grep -E "\.Rd|NAMESPACE" | wc -l
    )
    if [[ ${num_doc_files_changed} -gt 0 ]]; then
        echo "Some R documentation files have changed. Please re-generate them and commit those changes."
        echo ""
        echo "    Rscript build_r.R"
        echo "    Rscript -e \"roxygen2::roxygenize('R-package/', load = 'installed')\""
        echo ""
        exit -1
    fi
    exit 0
fi

126
127
128
129
cd ${BUILD_DIRECTORY}

PKG_TARBALL="lightgbm_${LGB_VER}.tar.gz"
LOG_FILE_NAME="lightgbm.Rcheck/00check.log"
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
if [[ $R_BUILD_TYPE == "cmake" ]]; then
    Rscript build_r.R --skip-install || exit -1
elif [[ $R_BUILD_TYPE == "cran" ]]; then

    # on Linux, we recreate configure in CI to test if
    # a change in a PR has changed configure.ac
    if [[ $OS_NAME == "linux" ]]; then
        cp VERSION.txt R-package/src/VERSION.txt
        cd ${BUILD_DIRECTORY}/R-package
        autoconf \
            --output configure \
                configure.ac \
        || exit -1
        cd ${BUILD_DIRECTORY}

        num_files_changed=$(
            git diff --name-only | wc -l
        )
        if [[ ${num_files_changed} -gt 0 ]]; then
            echo "'configure' in the R package has changed. Please recreate it and commit the changes."
            echo "Changed files:"
            git diff --compact-summary
            echo "See R-package/README.md for details on how to recreate this script."
            echo ""
            exit -1
        fi
    fi

    ./build-cran-package.sh || exit -1

    # Test CRAN source .tar.gz in a directory that is not this repo or below it.
    # When people install.packages('lightgbm'), they won't have the LightGBM
    # git repo around. This is to protect against the use of relative paths
    # like ../../CMakeLists.txt that would only work if you are in the repo
    R_CMD_CHECK_DIR="${HOME}/tmp-r-cmd-check/"
    mkdir -p ${R_CMD_CHECK_DIR}
    mv ${PKG_TARBALL} ${R_CMD_CHECK_DIR}
    cd ${R_CMD_CHECK_DIR}
fi
169
170
171

# fails tests if either ERRORs or WARNINGs are thrown by
# R CMD CHECK
172
check_succeeded="yes"
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
(
    R CMD check ${PKG_TARBALL} \
        --as-cran \
    || check_succeeded="no"
) &

# R CMD check suppresses output, some CIs kill builds after
# a few minutes with no output. This trick gives R CMD check more time
#     * https://github.com/travis-ci/travis-ci/issues/4190#issuecomment-169987525
#     * https://stackoverflow.com/a/29890106/3986677
CHECK_PID=$!
while kill -0 ${CHECK_PID} >/dev/null 2>&1; do
    echo -n -e " \b"
    sleep 5
done
188
189

echo "R CMD check build logs:"
190
191
BUILD_LOG_FILE=lightgbm.Rcheck/00install.out
cat ${BUILD_LOG_FILE}
192
193
194
195

if [[ $check_succeeded == "no" ]]; then
    exit -1
fi
196
197
198
199
200
201

if grep -q -R "WARNING" "$LOG_FILE_NAME"; then
    echo "WARNINGS have been found by R CMD check!"
    exit -1
fi

202
203
204
205
206
if [[ $OS_NAME == "linux" ]] && [[ $R_BUILD_TYPE == "cran" ]]; then
    ALLOWED_CHECK_NOTES=2
else
    ALLOWED_CHECK_NOTES=1
fi
207
208
209
210
211
212
213
214
215
NUM_CHECK_NOTES=$(
    cat ${LOG_FILE_NAME} \
        | grep -e '^Status: .* NOTE.*' \
        | sed 's/[^0-9]*//g'
)
if [[ ${NUM_CHECK_NOTES} -gt ${ALLOWED_CHECK_NOTES} ]]; then
    echo "Found ${NUM_CHECK_NOTES} NOTEs from R CMD check. Only ${ALLOWED_CHECK_NOTES} are allowed"
    exit -1
fi
216
217
218
219
220
221
222
223
224
225
226
227
228
229

# this check makes sure that CI builds of the CRAN package on Mac
# actually use OpenMP
if [[ $OS_NAME == "macos" ]] && [[ $R_BUILD_TYPE == "cran" ]]; then
    omp_working=$(
        cat $BUILD_LOG_FILE \
        | grep -E "checking whether OpenMP will work .*yes" \
        | wc -l
    )
    if [[ $omp_working -ne 1 ]]; then
        echo "OpenMP was not found, and should be when testing the CRAN package on macOS"
        exit -1
    fi
fi