summaryrefslogtreecommitdiff
path: root/.github/workflows/wheels.yml
blob: e84da655bf63bd139dcb7728f24ce944c233a97f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
# Workflow to build and test wheels.
# To work on the wheel building infrastructure on a fork, comment out:
#
# if: github.repository == 'numpy/numpy'
#
# in the get_commit_message job. Be sure to include [wheel build] in your commit
# message to trigger the build. All files related to wheel building are located
# at tools/wheels/
name: Wheel builder

on:
  schedule:
  #        ┌───────────── minute (0 - 59)
  #        │  ┌───────────── hour (0 - 23)
  #        │  │ ┌───────────── day of the month (1 - 31)
  #        │  │ │ ┌───────────── month (1 - 12 or JAN-DEC)
  #        │  │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
  #        │  │ │ │ │
  - cron: "42 1 * * 4"
  push:
  pull_request:
  workflow_dispatch:

jobs:
  get_commit_message:
    name: Get commit message
    runs-on: ubuntu-latest
    if: github.repository == 'numpy/numpy'
    outputs:
      message: ${{ steps.commit_message.outputs.message }}
    steps:
      - name: Checkout numpy
        uses: actions/checkout@v2
        # Gets the correct commit message for pull request
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Get commit message
        id: commit_message
        run: |
          set -xe
          COMMIT_MSG=$(git log --no-merges -1 --oneline)
          echo "::set-output name=message::$COMMIT_MSG"
          echo github.ref ${{ github.ref }}

  build_wheels:
    name: Build wheel for ${{ matrix.python }}-${{ matrix.buildplat[1] }}
    needs: get_commit_message
    if: >-
      contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
      github.event_name == 'schedule' ||
      github.event_name == 'workflow_dispatch' ||
      (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
    runs-on: ${{ matrix.buildplat[0] }}
    strategy:
      # Ensure that a wheel builder finishes even if another fails
      fail-fast: false
      matrix:
        # Github Actions doesn't support pairing matrix values together, let's improvise
        # https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
        buildplat:
        - [ubuntu-20.04, manylinux_x86_64]
        - [macos-10.15, macosx_*]
        - [windows-2019, win_amd64]
        - [windows-2019, win32]
        python: ["cp38", "cp39", "cp310"]
        include:
        # manylinux pypy builds
        - buildplat: [ubuntu-20.04, manylinux_x86_64]
          python: "pp38"

        - buildplat: [macos-10.15, macosx_x86_64]
          python: "pp38"

        # Windows PyPy builds
        - buildplat: [windows-2019, win_amd64]
          python: "pp38"
    env:
      IS_32_BIT: ${{ matrix.buildplat[1] == 'win32' }}
      IS_PUSH: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
      IS_SCHEDULE_DISPATCH: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
    steps:
      - name: Checkout numpy
        uses: actions/checkout@v2
        with:
          submodules: true
          # versioneer.py requires the latest tag to be reachable. Here we
          # fetch the complete history to get access to the tags.
          # A shallow clone can work when the following issue is resolved:
          # https://github.com/actions/checkout/issues/338
          fetch-depth: 0

      # Used to push the built wheels
      - uses: actions/setup-python@v2
        with:
          python-version: '3.x'

      - name: Configure mingw for 32-bit builds
        run: |
          # Force 32-bit mingw
          choco uninstall mingw
          choco install -y mingw --forcex86 --force --version=7.3.0
          echo "C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw32\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
          refreshenv
        if: ${{ env.IS_32_BIT == 'true' }}
      - name: Build wheels
        uses: pypa/cibuildwheel@v2.3.0
        env:
          NPY_USE_BLAS_ILP64: ${{ env.IS_32_BIT == 'true' && '0' || '1' }}
          CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
          CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
          CIBW_ENVIRONMENT_LINUX: CFLAGS='-std=c99 -fno-strict-aliasing'
                                  LDFLAGS='-Wl,--strip-debug'
                                  OPENBLAS64_=/usr/local
                                  RUNNER_OS='Linux'
          # MACOS linker doesn't support stripping symbols
          CIBW_ENVIRONMENT_MACOS: CFLAGS='-std=c99 -fno-strict-aliasing'
                                  OPENBLAS64_=/usr/local
                                  CC=clang
                                  CXX=clang++
          CIBW_ENVIRONMENT_WINDOWS: OPENBLAS64_=${{ env.IS_32_BIT == 'false' && 'openblas' || '' }}
                                    OPENBLAS=${{ env.IS_32_BIT == 'true' && 'openblas' || '' }}
                                    CFLAGS='${{ env.IS_32_BIT == 'true' && '-m32' || '' }}'
                                    LDFLAGS='${{ env.IS_32_BIT == 'true' && '-m32' || '' }}'
          # TODO: Add universal2 wheels, we need to fuse them manually
          # instead of going through cibuildwheel
          # This is because cibuildwheel tries to make a fat wheel
          # https://github.com/multi-build/multibuild/blame/devel/README.rst#L541-L565
          # for more info
          CIBW_ARCHS_MACOS: x86_64 arm64
          CIBW_TEST_SKIP: "*_arm64 *_universal2:arm64"
          CIBW_BUILD_VERBOSITY: 3
          CIBW_BEFORE_BUILD: bash {project}/tools/wheels/cibw_before_build.sh {project}
          CIBW_BEFORE_TEST: pip install -r {project}/test_requirements.txt
          CIBW_TEST_COMMAND:  bash {project}/tools/wheels/cibw_test_command.sh {project}

      - uses: actions/upload-artifact@v2
        with:
          name: ${{ matrix.python }}-${{ startsWith(matrix.buildplat[1], 'macosx') && 'macosx' || matrix.buildplat[1] }}
          path: ./wheelhouse/*.whl

      - name: Upload wheels
        if: success()
        shell: bash
        env:
          NUMPY_STAGING_UPLOAD_TOKEN: ${{ secrets.NUMPY_STAGING_UPLOAD_TOKEN }}
          NUMPY_NIGHTLY_UPLOAD_TOKEN: ${{ secrets.NUMPY_NIGHTLY_UPLOAD_TOKEN }}
        run: |
          source tools/wheels/upload_wheels.sh
          set_upload_vars
          # trigger an upload to
          # https://anaconda.org/scipy-wheels-nightly/numpy
          # for cron jobs or "Run workflow" (restricted to main branch).
          # Tags will upload to
          # https://anaconda.org/multibuild-wheels-staging/numpy
          # The tokens were originally generated at anaconda.org
          upload_wheels