Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitHub action to build wheels with cibuildwheel #8

Merged
merged 71 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ec442d9
Add github action to build wheels for cling
finsberg Jan 28, 2023
cb3016f
Add some default cibuildwheel configurations to pyproject.toml
finsberg Jan 28, 2023
217b507
Do not exit with exit code 2 is fail to apply patch
finsberg Jan 28, 2023
78761c8
Build on python3.6 and add matrix of different platforms and archs
finsberg Jan 29, 2023
34ab16e
Use python3.9 instead
finsberg Jan 29, 2023
16856f6
Add some more options to build matrix
finsberg Jan 29, 2023
2e14f1c
Only use cibw.build
finsberg Jan 29, 2023
c3c6330
Specify arch
finsberg Jan 29, 2023
6b977fb
Set arch via CIBW environment variable
finsberg Jan 29, 2023
6f9cf09
Fix typo
finsberg Jan 29, 2023
3877a34
Set MACOSX_DEPLOYMENT_TARGET for arm mac
finsberg Jan 29, 2023
20810d9
print-build-identifiers in separate step
finsberg Jan 29, 2023
7ae239c
Add test command and remove unused options
finsberg Jan 29, 2023
ad31b6e
Change test command to a simple import
finsberg Jan 30, 2023
54080a2
Try to set LD_LIBRARY_PATH for auditwheel
finsberg Jan 30, 2023
7a84846
Turn off auditwheel for now
finsberg Jan 31, 2023
d3fa8c9
Use oldest possible version of python / pypy
finsberg Jan 31, 2023
5b94869
Setup QEMU on linux
finsberg Jan 31, 2023
622462d
Use CIBW_ARCHS_WINDOWS
finsberg Jan 31, 2023
0d6baa5
Set timeout minutes to 600
finsberg Feb 1, 2023
7bee771
Change name of windows os and move timeout-minutes do different location
finsberg Feb 2, 2023
71d4e6a
Change test command to use double quotes
finsberg Feb 3, 2023
77369b4
Merge remote-tracking branch 'wlav/master' into build-wheels-with-cib…
finsberg Feb 6, 2023
e5203fc
Add back sys.exit in create_src_directory.py
finsberg Feb 6, 2023
a200b9f
Try with circle ci instead of github actions
finsberg Feb 16, 2023
3da31ae
Use python3 -m
finsberg Feb 16, 2023
4b9b944
Only build one python version
finsberg Feb 16, 2023
f9df96e
Update before-all command
finsberg Feb 16, 2023
072a6ad
Do not exit if applying patch didn't succeed
finsberg Feb 16, 2023
3126267
Use virtual environment
finsberg Feb 16, 2023
e06c60e
Try to build for python39 instead
finsberg Feb 16, 2023
2c173fd
Try to add numpy as a build requirements
finsberg Feb 16, 2023
b69bac9
Add path to checkout
finsberg Feb 16, 2023
5c33084
Try with 'cd cling' again
finsberg Feb 16, 2023
3881a55
Move back to path
finsberg Feb 16, 2023
3ea620b
Add ls + pwd
finsberg Feb 16, 2023
382aab6
Try to add cling as argument to cibuildwheel
finsberg Feb 17, 2023
26f33ca
Remove checkout path#
finsberg Feb 17, 2023
4cfec39
Install newer C++ compiler for linux
finsberg Feb 17, 2023
1b03175
Use clang instead
finsberg Feb 17, 2023
4fab1bd
Try to use a different image
finsberg Feb 17, 2023
ab28585
Try to install clang
finsberg Feb 17, 2023
2fa7269
Try to use clang-12 instead
finsberg Feb 17, 2023
9874e0b
Try to just update libc++
finsberg Feb 17, 2023
5372ddb
Skip update
finsberg Feb 17, 2023
89527c2
Try to set c++20 std
finsberg Feb 17, 2023
533754b
Try to upgrade c++ compiler
finsberg Feb 17, 2023
be35e39
Use c++20 for manylinux as well
finsberg Feb 17, 2023
6accdf6
Use more resources
finsberg Feb 17, 2023
0e2bb10
Force stdcxx=20
finsberg Feb 19, 2023
bf2de7a
Only run manylinux x86_84 + aarch
finsberg Feb 20, 2023
99cd8aa
Be more explicit about which wheels we are building
finsberg Feb 20, 2023
6e81952
Merge remote-tracking branch 'wlav/master' into build-wheels-with-cib…
finsberg Mar 9, 2023
dae2d91
Turn on building all wheels and only build aarch64 wheels on circleci
finsberg Mar 9, 2023
9095eca
Update commands on github action to not cd into cling directory
finsberg Mar 9, 2023
efb2a99
Skip building some of the wheels
finsberg Mar 9, 2023
1065402
Try to set MACOSX_DEPLOYMENT_TARGET to 10.15 also for amd
finsberg Mar 9, 2023
230004e
Start working on connecting github actions with circleci
finsberg Mar 9, 2023
fc809b5
Add now commit to try to trigger workflow dispatch
finsberg Mar 9, 2023
e88e52f
Add version in circleci workflow
finsberg Mar 9, 2023
131b39d
Add script for interacting with circleci API
finsberg Mar 10, 2023
63ef783
Use python 3.10
finsberg Mar 10, 2023
b842d88
Add secret token
finsberg Mar 10, 2023
a7dc068
Add some delay between commands
finsberg Mar 10, 2023
560773a
Add missing curly braces
finsberg Mar 10, 2023
9868c98
Rename job-id to job-number
finsberg Mar 10, 2023
561c66f
Update path for built wheels in github action
finsberg Mar 10, 2023
40a7af6
Update GITHUB_OUTPUT to share data between jobs
finsberg Mar 10, 2023
ccf4941
Try with outputs again
finsberg Mar 10, 2023
b406bf8
Make sure to provde token to artifact command
finsberg Mar 10, 2023
a424091
Remove extra right paren
finsberg Mar 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: 2.1

parameters:
build_aarch64_wheel:
description: "Whether to build aarch64 wheel on CircleCI"
default: false
type: boolean


jobs:
linux-aarch64-wheels:
working_directory: ~/linux-aarch64-wheels
machine:
image: ubuntu-2004:2022.04.1
# resource_class is what tells CircleCI to use an ARM worker for native arm builds
# https://circleci.com/product/features/resource-classes/
resource_class: arm.large
environment:
STDCXX: 20
MAKE_NPROCS: 4
steps:
- checkout
- run:
name: Build the Linux aarch64 wheels.
command: |
python3 -m venv venv
. venv/bin/activate
python3 -m pip install pip --upgrade
python3 -m pip install cibuildwheel==2.12.0
python3 -m cibuildwheel cling --print-build-identifiers
python3 -m cibuildwheel cling --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/


workflows:
version: 2
build-aarch64-wheels:
when: << pipeline.parameters.build_aarch64_wheel >>
jobs:
- linux-aarch64-wheels

166 changes: 166 additions & 0 deletions .github/workflows/cling-wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
name: Build and upload to PyPI

on: [push]

jobs:
build-aarch64-wheels:
runs-on: ubuntu-latest
outputs:
job_number: ${{ steps.aarch64-job-number.outputs.job_number }}
steps:
- uses: actions/checkout@v3

- name: Setup python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Trigger circleci build for ARM
id: aarch64-job-number
run: |
export JOB_NUMBER=$(python3 circleci.py job --token ${{ secrets.CIRCLE_API_TOKEN }})
echo "job_number=$JOB_NUMBER" >> $GITHUB_OUTPUT

build_wheels:
name: Build wheels on ${{ matrix.cibw.build }}
runs-on: ${{ matrix.os }}

env:
CIBW_BUILD: "${{ matrix.cibw.build || '*' }}"
CIBW_ARCHS_LINUX: "${{ matrix.cibw.arch || 'auto' }}"
CIBW_ARCHS_MACOS: "${{ matrix.cibw.arch || 'auto' }}"
CIBW_ARCHS_WINDOWS: "${{ matrix.cibw.arch || 'auto' }}"

strategy:
fail-fast: false
matrix:
include:
- os: macos-11
name: mac-cpython
cibw:
arch: x86_64
build: "cp36-macosx_x86_64"

- os: macos-11
name: mac-cpython-arm
cibw:
arch: arm64
build: "cp38-macosx_arm64"

- os: macos-11
name: mac-pypy
cibw:
arch: x86_64
build: "pp37-macosx_x86_64"

- os: ubuntu-20.04
name: manylinux-x86_64
cibw:
arch: x86_64
build: "cp36-manylinux_x86_64"


- os: ubuntu-20.04
name: manylinux-i686
cibw:
arch: i686
build: "cp36-manylinux_i686"

- os: ubuntu-20.04
name: manylinux-pypy-x86_64
cibw:
arch: x86_64
build: "pp37-manylinux_x86_64"

- os: windows-2019
name: win32
cibw:
arch: x86
build: "cp36-win32"

- os: windows-2019
name: win_amd64
cibw:
arch: AMD64
build: "cp36-win_amd64"

- os: windows-2019
name: win32-arm64
cibw:
arch: ARM64
build: "cp39-win_arm64"


steps:
- uses: actions/checkout@v3

- name: setup python
uses: actions/setup-python@v4
with:
python-version: "3.9"
architecture: ${{ matrix.architecture }}

- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v2
with:
platforms: all

- name: customize mac-arm-64
if: contains(matrix.os, 'macos') && matrix.cibw.arch == 'arm64'
run: |
echo 'MACOSX_DEPLOYMENT_TARGET=10.15' >> "$GITHUB_ENV"


- name: Install cibuildwheel
run: |
python -m pip install cibuildwheel==2.12.0

- name: list target wheels
run: |
python -m cibuildwheel cling --print-build-identifiers

- name: Build wheels
timeout-minutes: 600
run: |
python -m cibuildwheel cling --output-dir wheelhouse

- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl

build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Build sdist
run: cd cling && pipx run build --sdist

- uses: actions/upload-artifact@v3
with:
path: ./cling/dist/*.tar.gz

upload_aarch64_wheel:
needs: [build_wheels, build-aarch64-wheels] # Just wait until this workflow is done - then aarch64 should be done
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup python
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Get wheel from CircleCI artifact
env:
JOB_NUMBER: ${{ needs.build-aarch64-wheels.outputs.job_number }}
run: |
export WHEEL_PATH=$(python circleci.py artifact --job-number $JOB_NUMBER --token ${{ secrets.CIRCLE_API_TOKEN }})
echo "wheel_path=$WHEEL_PATH" >> $GITHUB_ENV

- uses: actions/upload-artifact@v3
with:
path: ${{ env.wheel_path }}
138 changes: 138 additions & 0 deletions circleci.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import http.client
from typing import Sequence
import argparse
import os
import urllib.request
from pathlib import Path
import time
import json


def get_artifact(
token: str,
vcs: str = "github",
org: str = "finsberg",
project: str = "cppyy-backend",
job_number: int = 0,
**kwargs,
) -> int:

conn = http.client.HTTPSConnection("circleci.com")

headers = {"Circle-Token": token}

conn.request(
"GET",
f"/api/v2/project/{vcs}/{org}/{project}/{job_number}/artifacts",
headers=headers,
)

res = conn.getresponse()
data = json.loads(res.read().decode("utf-8"))
url = data["items"][0]["url"]
path = Path(data["items"][0]["path"])
path.parent.mkdir(exist_ok=True)

urllib.request.urlretrieve(url, path)
time.sleep(1.0)
print(path)
return 0


def start_job(
token: str,
vcs: str = "github",
org: str = "finsberg",
project: str = "cppyy-backend",
build_aarch64_wheel: bool = True,
branch: str = "build-wheels-with-cibuildwheel",
**kwargs,
) -> int:
import http.client

conn = http.client.HTTPSConnection("circleci.com")

headers = {
"content-type": "application/json",
"Circle-Token": f"{token}",
}

# Start pipeline
payload = {
"branch": branch,
"parameters": {"build_aarch64_wheel": build_aarch64_wheel},
}
conn.request(
"POST",
f"/api/v2/project/{vcs}/{org}/{project}/pipeline",
json.dumps(payload),
headers,
)
res = conn.getresponse()
pipeline_data = json.loads(res.read().decode("utf-8"))
time.sleep(1.0)

# Get pipeline id
conn.request(
"GET",
f"/api/v2/project/{vcs}/{org}/{project}/pipeline/{pipeline_data['number']}",
headers=headers,
)
res = conn.getresponse()
data = json.loads(res.read().decode("utf-8"))

time.sleep(1.0)

# Get workflow id
conn.request(
"GET",
f"/api/v2/pipeline/{data['id']}/workflow",
headers=headers,
)

res = conn.getresponse()
workflow_data = json.loads(res.read().decode("utf-8"))

time.sleep(1.0)

# Get job id
conn.request(
"GET",
f"/api/v2/workflow/{workflow_data['items'][0]['id']}/job",
headers=headers,
)

res = conn.getresponse()
job_data = json.loads(res.read().decode("utf-8"))

print(job_data["items"][0]["job_number"])
return 0


def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser()

parser.add_argument("--token", default=os.environ.get("CIRCLE_API_TOKEN"))
parser.add_argument("mode", choices=["artifact", "job"])
parser.add_argument("--vcs", default="github")
parser.add_argument("--org", default="finsberg")
parser.add_argument("--project", default="cppyy-backend")
parser.add_argument("--job-number", default=0)
parser.add_argument("--build-aarch64-wheel", default=True)

kwargs = vars(parser.parse_args(argv))
mode = kwargs.pop("mode")

if mode == "artifact":
return get_artifact(**kwargs)

if mode == "job":
return start_job(**kwargs)

print("Invaild arguments")
print(f"You entered: {kwargs}")
return 1


if __name__ == "__main__":
raise SystemExit(main())
2 changes: 1 addition & 1 deletion cling/create_src_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def apply(self):
pset = patch.fromfile(fpatch)
if not pset or not pset.apply():
print("Failed to apply patch:", fdiff)
sys.exit(2)
# sys.exit(2)

#
## manylinux1 specific patch, as there a different, older, compiler is used
Expand Down
25 changes: 24 additions & 1 deletion cling/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
[build-system]
requires = ["cmake", "setuptools", "wheel"]
requires = ["cmake", "setuptools", "wheel", "numpy"]

[tool.cibuildwheel]
archs = ["auto"]
build-frontend = "pip"
dependency-versions = "pinned"
build-verbosity = "1"
build = "cp39-manylinux_{x86_64,aarch64} cp39-macosx_{x86_64,arm64} cp39-{win_amd64,win32}"


before-all = "cd cling && python create_src_directory.py"


test-requires = []
test-command = 'python -c "import cppyy_backend"'

[tool.cibuildwheel.linux]
repair-wheel-command = ""
# repair-wheel-command = "LD_LIBRARY_PATH=$PWD/lib auditwheel repair -w {dest_dir} {wheel}"

# mac-arm target is 10.15
[[tool.cibuildwheel.overrides]]
select = "*macos*"
environment = { MACOSX_DEPLOYMENT_TARGET = "10.15" }