• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1name: Tests
2
3# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because
4# it prevents to mark a job as mandatory. A PR cannot be merged if a job is
5# mandatory but not scheduled because of "paths-ignore".
6on:
7  workflow_dispatch:
8  push:
9    branches:
10    - 'main'
11    - '3.11'
12    - '3.10'
13    - '3.9'
14    - '3.8'
15    - '3.7'
16  pull_request:
17    branches:
18    - 'main'
19    - '3.11'
20    - '3.10'
21    - '3.9'
22    - '3.8'
23    - '3.7'
24
25permissions:
26  contents: read
27
28concurrency:
29  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
30  cancel-in-progress: true
31
32jobs:
33  check_source:
34    name: 'Check for source changes'
35    runs-on: ubuntu-latest
36    timeout-minutes: 10
37    outputs:
38      run_tests: ${{ steps.check.outputs.run_tests }}
39      run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
40      config_hash: ${{ steps.config_hash.outputs.hash }}
41    steps:
42      - uses: actions/checkout@v3
43      - name: Check for source changes
44        id: check
45        run: |
46          if [ -z "$GITHUB_BASE_REF" ]; then
47            echo "run_tests=true" >> $GITHUB_OUTPUT
48            echo "run_ssl_tests=true" >> $GITHUB_OUTPUT
49          else
50            git fetch origin $GITHUB_BASE_REF --depth=1
51            # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
52            # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
53            # but it requires to download more commits (this job uses
54            # "git fetch --depth=1").
55            #
56            # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
57            # 2.26, but Git 2.28 is stricter and fails with "no merge base".
58            #
59            # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
60            # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
61            # into the PR branch anyway.
62            #
63            # https://github.com/python/core-workflow/issues/373
64            git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
65            git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo "run_ssl_tests=true" >> $GITHUB_OUTPUT || true
66          fi
67      - name: Compute hash for config cache key
68        id: config_hash
69        run: |
70          echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
71
72  check_abi:
73    name: 'Check if the ABI has changed'
74    runs-on: ubuntu-20.04
75    needs: check_source
76    if: needs.check_source.outputs.run_tests == 'true'
77    steps:
78      - uses: actions/checkout@v2
79      - uses: actions/setup-python@v2
80      - name: Install Dependencies
81        run: |
82            sudo ./.github/workflows/posix-deps-apt.sh
83            sudo apt-get install -yq abigail-tools
84      - name: Build CPython
85        env:
86          CFLAGS: -g3 -O0
87        run: |
88          # Build Python with the libpython dynamic library
89          ./configure --enable-shared
90          make -j4
91      - name: Check for changes in the ABI
92        id: check
93        run: |
94          if ! make check-abidump; then
95            echo "Generated ABI file is not up to date."
96            echo "Please, add the release manager of this branch as a reviewer of this PR."
97            echo ""
98            echo "The up to date ABI file should be attached to this build as an artifact."
99            echo ""
100            echo "To learn more about this check: https://devguide.python.org/setup/#regenerate-the-abi-dump"
101            echo ""
102            exit 1
103          fi
104      - name: Generate updated ABI files
105        if: ${{ failure() && steps.check.conclusion == 'failure' }}
106        run: |
107          make regen-abidump
108      - uses: actions/upload-artifact@v3
109        name: Publish updated ABI files
110        if: ${{ failure() && steps.check.conclusion == 'failure' }}
111        with:
112          name: abi-data
113          path: ./Doc/data/*.abi
114
115  check_generated_files:
116    name: 'Check if generated files are up to date'
117    runs-on: ubuntu-latest
118    timeout-minutes: 60
119    needs: check_source
120    if: needs.check_source.outputs.run_tests == 'true'
121    steps:
122      - uses: actions/checkout@v3
123      - name: Restore config.cache
124        uses: actions/cache@v3
125        with:
126          path: config.cache
127          key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
128      - uses: actions/setup-python@v3
129      - name: Install Dependencies
130        run: sudo ./.github/workflows/posix-deps-apt.sh
131      - name: Add ccache to PATH
132        run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
133      - name: Configure ccache action
134        uses: hendrikmuhs/ccache-action@v1.2
135      - name: Check Autoconf version 2.69 and aclocal 1.16.3
136        run: |
137          grep "Generated by GNU Autoconf 2.69" configure
138          grep "aclocal 1.16.3" aclocal.m4
139          grep -q "runstatedir" configure
140          grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
141      - name: Configure CPython
142        run: |
143          # Build Python with the libpython dynamic library
144          ./configure --config-cache --with-pydebug --enable-shared
145      - name: Regenerate autoconf files with container image
146        run: make regen-configure
147      - name: Build CPython
148        run: |
149          # Deepfreeze will usually cause global objects to be added or removed,
150          # so we run it before regen-global-objects gets rum (in regen-all).
151          make regen-deepfreeze
152          make -j4 regen-all
153          make regen-stdlib-module-names
154      - name: Check for changes
155        run: |
156          git add -u
157          changes=$(git status --porcelain)
158          # Check for changes in regenerated files
159          if test -n "$changes"; then
160            echo "Generated files not up to date."
161            echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)"
162            echo "configure files must be regenerated with a specific version of autoconf."
163            echo "$changes"
164            echo ""
165            git diff --staged || true
166            exit 1
167          fi
168      - name: Check exported libpython symbols
169        run: make smelly
170      - name: Check limited ABI symbols
171        run: make check-limited-abi
172
173  build_win32:
174    name: 'Windows (x86)'
175    runs-on: windows-latest
176    timeout-minutes: 60
177    needs: check_source
178    if: needs.check_source.outputs.run_tests == 'true'
179    env:
180       IncludeUwp: 'true'
181    steps:
182    - uses: actions/checkout@v3
183    - name: Build CPython
184      run: .\PCbuild\build.bat -e -d -p Win32
185    - name: Display build info
186      run: .\python.bat -m test.pythoninfo
187    - name: Tests
188      run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
189
190  build_win_amd64:
191    name: 'Windows (x64)'
192    runs-on: windows-latest
193    timeout-minutes: 60
194    needs: check_source
195    if: needs.check_source.outputs.run_tests == 'true'
196    env:
197       IncludeUwp: 'true'
198    steps:
199    - uses: actions/checkout@v3
200    - name: Register MSVC problem matcher
201      run: echo "::add-matcher::.github/problem-matchers/msvc.json"
202    - name: Build CPython
203      run: .\PCbuild\build.bat -e -d -p x64
204    - name: Display build info
205      run: .\python.bat -m test.pythoninfo
206    - name: Tests
207      run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
208
209  build_macos:
210    name: 'macOS'
211    runs-on: macos-latest
212    timeout-minutes: 60
213    needs: check_source
214    if: needs.check_source.outputs.run_tests == 'true'
215    env:
216      HOMEBREW_NO_ANALYTICS: 1
217      HOMEBREW_NO_AUTO_UPDATE: 1
218      HOMEBREW_NO_INSTALL_CLEANUP: 1
219      PYTHONSTRICTEXTENSIONBUILD: 1
220    steps:
221    - uses: actions/checkout@v3
222    - name: Restore config.cache
223      uses: actions/cache@v3
224      with:
225        path: config.cache
226        key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
227    - name: Install Homebrew dependencies
228      run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk
229    - name: Configure CPython
230      run: |
231        CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
232        LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \
233        PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
234        ./configure \
235          --config-cache \
236          --with-pydebug \
237          --prefix=/opt/python-dev \
238          --with-openssl="$(brew --prefix openssl@1.1)"
239    - name: Build CPython
240      run: make -j4
241    - name: Display build info
242      run: make pythoninfo
243    - name: Tests
244      run: make buildbottest TESTOPTS="-j4 -uall,-cpu"
245
246  build_ubuntu:
247    name: 'Ubuntu'
248    runs-on: ubuntu-20.04
249    timeout-minutes: 60
250    needs: check_source
251    if: needs.check_source.outputs.run_tests == 'true'
252    env:
253      OPENSSL_VER: 1.1.1u
254      PYTHONSTRICTEXTENSIONBUILD: 1
255    steps:
256    - uses: actions/checkout@v3
257    - name: Register gcc problem matcher
258      run: echo "::add-matcher::.github/problem-matchers/gcc.json"
259    - name: Install Dependencies
260      run: sudo ./.github/workflows/posix-deps-apt.sh
261    - name: Configure OpenSSL env vars
262      run: |
263        echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
264        echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
265        echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
266    - name: 'Restore OpenSSL build'
267      id: cache-openssl
268      uses: actions/cache@v3
269      with:
270        path: ./multissl/openssl/${{ env.OPENSSL_VER }}
271        key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
272    - name: Install OpenSSL
273      if: steps.cache-openssl.outputs.cache-hit != 'true'
274      run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
275    - name: Add ccache to PATH
276      run: |
277        echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
278    - name: Configure ccache action
279      uses: hendrikmuhs/ccache-action@v1.2
280    - name: Setup directory envs for out-of-tree builds
281      run: |
282        echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV
283        echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV
284    - name: Create directories for read-only out-of-tree builds
285      run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR
286    - name: Bind mount sources read-only
287      run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR
288    - name: Restore config.cache
289      uses: actions/cache@v3
290      with:
291        path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
292        key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
293    - name: Configure CPython out-of-tree
294      working-directory: ${{ env.CPYTHON_BUILDDIR }}
295      run: |
296        ../cpython-ro-srcdir/configure \
297          --config-cache \
298          --with-pydebug \
299          --with-openssl=$OPENSSL_DIR
300    - name: Build CPython out-of-tree
301      working-directory: ${{ env.CPYTHON_BUILDDIR }}
302      run: make -j4
303    - name: Display build info
304      working-directory: ${{ env.CPYTHON_BUILDDIR }}
305      run: make pythoninfo
306    - name: Remount sources writable for tests
307      # some tests write to srcdir, lack of pyc files slows down testing
308      run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw
309    - name: Tests
310      working-directory: ${{ env.CPYTHON_BUILDDIR }}
311      run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
312
313  build_ubuntu_ssltests:
314    name: 'Ubuntu SSL tests with OpenSSL'
315    runs-on: ubuntu-20.04
316    timeout-minutes: 60
317    needs: check_source
318    if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true'
319    strategy:
320      fail-fast: false
321      matrix:
322        openssl_ver: [1.1.1u, 3.0.9, 3.1.1]
323    env:
324      OPENSSL_VER: ${{ matrix.openssl_ver }}
325      MULTISSL_DIR: ${{ github.workspace }}/multissl
326      OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
327      LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
328    steps:
329    - uses: actions/checkout@v3
330    - name: Restore config.cache
331      uses: actions/cache@v3
332      with:
333        path: config.cache
334        key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
335    - name: Register gcc problem matcher
336      run: echo "::add-matcher::.github/problem-matchers/gcc.json"
337    - name: Install Dependencies
338      run: sudo ./.github/workflows/posix-deps-apt.sh
339    - name: Configure OpenSSL env vars
340      run: |
341        echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
342        echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
343        echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
344    - name: 'Restore OpenSSL build'
345      id: cache-openssl
346      uses: actions/cache@v3
347      with:
348        path: ./multissl/openssl/${{ env.OPENSSL_VER }}
349        key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
350    - name: Install OpenSSL
351      if: steps.cache-openssl.outputs.cache-hit != 'true'
352      run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
353    - name: Add ccache to PATH
354      run: |
355        echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
356    - name: Configure ccache action
357      uses: hendrikmuhs/ccache-action@v1.2
358    - name: Configure CPython
359      run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR
360    - name: Build CPython
361      run: make -j4
362    - name: Display build info
363      run: make pythoninfo
364    - name: SSL tests
365      run: ./python Lib/test/ssltests.py
366
367  build_asan:
368    name: 'Address sanitizer'
369    runs-on: ubuntu-20.04
370    timeout-minutes: 60
371    needs: check_source
372    if: needs.check_source.outputs.run_tests == 'true'
373    env:
374      OPENSSL_VER: 1.1.1u
375      PYTHONSTRICTEXTENSIONBUILD: 1
376      ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
377    steps:
378    - uses: actions/checkout@v3
379    - name: Restore config.cache
380      uses: actions/cache@v3
381      with:
382        path: config.cache
383        key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
384    - name: Register gcc problem matcher
385      run: echo "::add-matcher::.github/problem-matchers/gcc.json"
386    - name: Install Dependencies
387      run: sudo ./.github/workflows/posix-deps-apt.sh
388    - name: Set up GCC-10 for ASAN
389      uses: egor-tensin/setup-gcc@v1
390      with:
391        version: 10
392    - name: Configure OpenSSL env vars
393      run: |
394        echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
395        echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
396        echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
397    - name: 'Restore OpenSSL build'
398      id: cache-openssl
399      uses: actions/cache@v3
400      with:
401        path: ./multissl/openssl/${{ env.OPENSSL_VER }}
402        key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
403    - name: Install OpenSSL
404      if: steps.cache-openssl.outputs.cache-hit != 'true'
405      run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
406    - name: Add ccache to PATH
407      run: |
408        echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
409    - name: Configure ccache action
410      uses: hendrikmuhs/ccache-action@v1.2
411    - name: Configure CPython
412      run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
413    - name: Build CPython
414      run: make -j4
415    - name: Display build info
416      run: make pythoninfo
417    - name: Tests
418      run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
419