Skip to content

Commit 7904b4f

Browse files
authored
Merge pull request #1 from virtualcell/add-java-to-ci
start Github Action to build native shared libs
2 parents 2ffc4ca + 86f3abb commit 7904b4f

File tree

15 files changed

+223
-93
lines changed

15 files changed

+223
-93
lines changed

.github/workflows/main.yml

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,100 @@ jobs:
1919
path: ~/.cache/pre-commit
2020
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
2121

22-
- name: Set up the environment
23-
uses: ./.github/actions/setup-poetry-env
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.11"
25+
26+
- uses: abatilo/actions-poetry@v3
27+
28+
- name: Install python dependencies
29+
run: poetry install --no-interaction
2430

2531
- name: Run checks
2632
run: make check
2733

2834
tests-and-type-check:
29-
runs-on: ubuntu-latest
3035
strategy:
31-
matrix:
32-
python-version: ["3.9", "3.10", "3.11", "3.12"]
36+
matrix: # python-version: ["3.9", "3.10", "3.11", "3.12"]
37+
python-version: ["3.11", "3.12"]
38+
# os: [macos-13, windows-latest, ubuntu-latest, macos-14]
39+
os: [ubuntu-latest, macos-14]
3340
fail-fast: false
41+
runs-on: ${{ matrix.os }}
3442
defaults:
3543
run:
3644
shell: bash
3745
steps:
3846
- name: Check out
3947
uses: actions/checkout@v4
48+
with:
49+
submodules: true
50+
fetch-depth: 2
4051

41-
- name: Set up the environment
42-
uses: ./.github/actions/setup-poetry-env
52+
- uses: actions/setup-python@v5
4353
with:
4454
python-version: ${{ matrix.python-version }}
4555

56+
- uses: abatilo/actions-poetry@v3
57+
58+
- name: setup graalvm for static native build
59+
uses: graalvm/setup-graalvm@v1
60+
with:
61+
java-version: "23"
62+
distribution: "graalvm-community"
63+
github-token: ${{ secrets.GITHUB_TOKEN }}
64+
components: "native-image"
65+
# native-image-musl: 'true' # Now semi-static by not including libc
66+
native-image-job-reports: "true"
67+
cache: "maven"
68+
69+
- name: build entire project
70+
working-directory: vcell_submodule
71+
run: |
72+
mvn --batch-mode clean install dependency:copy-dependencies -DskipTests=true
73+
74+
- name: test, record, and build/install native library (ubuntu)
75+
working-directory: vcell-native
76+
run: |
77+
mvn --batch-mode clean install
78+
79+
java -agentlib:native-image-agent=config-output-dir=target/recording \
80+
-jar target/vcell-native-1.0-SNAPSHOT.jar \
81+
"src/test/resources/TinySpacialProject_Application0.xml" \
82+
"target/sbml-input"
83+
84+
mvn --batch-mode -P shared-dll package
85+
cp target/libvcell.so ../libvcell/_internal/libs
86+
if: ${{ startsWith(matrix.os, 'ubuntu') }}
87+
88+
- name: test, record, and build/install native library (macos)
89+
working-directory: vcell-native
90+
run: |
91+
mvn --batch-mode clean install
92+
93+
java -agentlib:native-image-agent=config-output-dir=target/recording \
94+
-jar target/vcell-native-1.0-SNAPSHOT.jar \
95+
"src/test/resources/TinySpacialProject_Application0.xml" \
96+
"target/sbml-input"
97+
98+
mvn --batch-mode -P shared-dll package
99+
cp target/libvcell.dylib ../libvcell/_internal/libs
100+
if: ${{ startsWith(matrix.os, 'macos') }}
101+
102+
- name: test, record, and build/install native library (windows)
103+
working-directory: vcell-native
104+
run: |
105+
mvn --batch-mode clean install
106+
107+
java -agentlib:native-image-agent=config-output-dir=target\recording -jar "target\vcell-native-1.0-SNAPSHOT.jar" "src\test\resources\TinySpacialProject_Application0.xml" "target\sbml-input"
108+
109+
mvn --batch-mode -P shared-dll package
110+
cp target/libvcell.dll ../libvcell/_internal/libs
111+
if: ${{ startsWith(matrix.os, 'windows') }}
112+
113+
- name: Install python dependencies
114+
run: poetry install --no-interaction
115+
46116
- name: Run tests
47117
run: poetry run pytest tests --cov --cov-config=pyproject.toml --cov-report=xml
48118

@@ -53,14 +123,26 @@ jobs:
53123
uses: codecov/codecov-action@v4
54124
if: ${{ matrix.python-version == '3.11' }}
55125

126+
- name: Setup tmate
127+
if: failure()
128+
uses: mxschmitt/action-tmate@v3
129+
with:
130+
limit-access-to-actor: true
131+
56132
check-docs:
57133
runs-on: ubuntu-latest
58134
steps:
59135
- name: Check out
60136
uses: actions/checkout@v4
61137

62-
- name: Set up the environment
63-
uses: ./.github/actions/setup-poetry-env
138+
- uses: actions/setup-python@v5
139+
with:
140+
python-version: "3.11"
141+
142+
- uses: abatilo/actions-poetry@v3
143+
144+
- name: Install python dependencies
145+
run: poetry install --no-interaction
64146

65147
- name: Check if documentation can be built
66148
run: poetry run mkdocs build -s

.github/workflows/on-release-main.yml

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,90 @@ on:
77

88
jobs:
99
publish:
10-
runs-on: ubuntu-latest
10+
strategy:
11+
matrix: # python-version: ["3.9", "3.10", "3.11", "3.12"]
12+
python-version: ["3.11", "3.12"]
13+
# os: [macos-13, windows-latest, ubuntu-latest, macos-14]
14+
os: [ubuntu-latest, macos-14]
15+
fail-fast: false
16+
runs-on: ${{ matrix.os }}
17+
defaults:
18+
run:
19+
shell: bash
1120
steps:
1221
- name: Check out
1322
uses: actions/checkout@v4
23+
with:
24+
submodules: true
25+
fetch-depth: 2
1426

15-
- name: Set up the environment
16-
uses: ./.github/actions/setup-poetry-env
27+
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: ${{ matrix.python-version }}
31+
32+
- uses: abatilo/actions-poetry@v3
33+
34+
- name: setup graalvm for static native build
35+
uses: graalvm/setup-graalvm@v1
36+
with:
37+
java-version: "23"
38+
distribution: "graalvm-community"
39+
github-token: ${{ secrets.GITHUB_TOKEN }}
40+
components: "native-image"
41+
# native-image-musl: 'true' # Now semi-static by not including libc
42+
native-image-job-reports: "true"
43+
cache: "maven"
44+
45+
- name: build entire project
46+
working-directory: vcell_submodule
47+
run: |
48+
mvn --batch-mode clean install dependency:copy-dependencies -DskipTests=true
49+
50+
- name: test, record, and build/install native library (ubuntu)
51+
working-directory: vcell-native
52+
run: |
53+
mvn --batch-mode clean install
54+
55+
java -agentlib:native-image-agent=config-output-dir=target/recording \
56+
-jar target/vcell-native-1.0-SNAPSHOT.jar \
57+
"src/test/resources/TinySpacialProject_Application0.xml" \
58+
"target/sbml-input"
59+
60+
mvn --batch-mode -P shared-dll package
61+
cp target/libvcell.so ../libvcell/_internal/libs
62+
if: ${{ startsWith(matrix.os, 'ubuntu') }}
63+
64+
- name: test, record, and build/install native library (macos)
65+
working-directory: vcell-native
66+
run: |
67+
mvn --batch-mode clean install
68+
69+
java -agentlib:native-image-agent=config-output-dir=target/recording \
70+
-jar target/vcell-native-1.0-SNAPSHOT.jar \
71+
"src/test/resources/TinySpacialProject_Application0.xml" \
72+
"target/sbml-input"
73+
74+
mvn --batch-mode -P shared-dll package
75+
cp target/libvcell.dylib ../libvcell/_internal/libs
76+
if: ${{ startsWith(matrix.os, 'macos') }}
77+
78+
- name: test, record, and build/install native library (windows)
79+
working-directory: vcell-native
80+
run: |
81+
mvn --batch-mode clean install
82+
83+
java -agentlib:native-image-agent=config-output-dir=target\recording -jar "target\vcell-native-1.0-SNAPSHOT.jar" "src\test\resources\TinySpacialProject_Application0.xml" "target\sbml-input"
84+
85+
mvn --batch-mode -P shared-dll package
86+
cp target/libvcell.dll ../libvcell/_internal/libs
87+
if: ${{ startsWith(matrix.os, 'windows') }}
88+
89+
- name: Install python dependencies
90+
run: poetry install --no-interaction
91+
92+
- name: Run tests
93+
run: poetry run pytest tests
1794

1895
- name: Export tag
1996
id: vars

.gitmodules

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
[submodule "vcell"]
2-
path = vcell
3-
url = https://github.com/virtualcell/vcell.git
1+
[submodule "vcell_submodule"]
2+
path = vcell_submodule
3+
url = https://github.com/virtualcell/vcell
4+
branch = remove-nativelib

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ check: ## Run code quality tools.
1414
@echo "🚀 Static type checking: Running mypy"
1515
@poetry run mypy
1616
@echo "🚀 Checking for obsolete dependencies: Running deptry"
17-
@poetry run deptry --exclude=.venv --exclude=tests .
17+
@poetry run deptry --exclude=.venv --exclude=tests --exclude=vcell_submodule .
1818

1919
.PHONY: test
2020
test: ## Test the code with pytest

docs/modules.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
::: libvcell.foo
1+
# Modules
2+
3+
## libvcell.libvcell
4+
5+
::: libvcell.libvcell

libvcell/_internal/native_calls.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,33 @@ def vcml_to_finite_volume_input(
2828
ctypes.c_char_p(simulation_name.encode("utf-8")),
2929
ctypes.c_char_p(str(output_dir_path).encode("utf-8")),
3030
)
31-
if json_ptr is None:
32-
raise ValueError("Native function returned null")
33-
json_str: str = ctypes.cast(json_ptr, ctypes.c_char_p).value.decode("utf-8")
31+
32+
value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
33+
if value is None:
34+
logging.error("Failed to convert vcml to finite volume input")
35+
return ReturnValue(success=False, message="Failed to convert vcml to finite volume input")
36+
json_str: str = value.decode("utf-8")
3437
# self.lib.freeString(json_ptr)
3538
return ReturnValue.model_validate_json(json_data=json_str)
3639
except Exception as e:
37-
logging.exception(f"Error in vcml_to_finite_volume_input: {e}")
40+
logging.exception("Error in vcml_to_finite_volume_input()", exc_info=e)
3841
raise
3942

4043
def sbml_to_finite_volume_input(self, sbml_content: str, output_dir_path: Path) -> ReturnValue:
4144
try:
4245
with IsolateManager(self.lib) as isolate_thread:
43-
json_ptr: bytes | None = self.lib.sbmlToFiniteVolumeInput(
46+
json_ptr: ctypes.c_char_p = self.lib.sbmlToFiniteVolumeInput(
4447
isolate_thread,
4548
ctypes.c_char_p(sbml_content.encode("utf-8")),
4649
ctypes.c_char_p(str(output_dir_path).encode("utf-8")),
4750
)
48-
if json_ptr is None:
49-
raise ValueError("Native function returned null")
50-
json_str: str = ctypes.cast(json_ptr, ctypes.c_char_p).value.decode("utf-8")
51+
value: bytes | None = ctypes.cast(json_ptr, ctypes.c_char_p).value
52+
if value is None:
53+
logging.error("Failed to convert sbml to finite volume input")
54+
return ReturnValue(success=False, message="Failed to convert sbml to finite volume input")
55+
json_str: str = value.decode("utf-8")
5156
# self.lib.freeString(json_ptr)
5257
return ReturnValue.model_validate_json(json_data=json_str)
5358
except Exception as e:
54-
logging.exception(f"Error in sbml_to_finite_volume_input: {e}")
59+
logging.exception("Error in sbml_to_finite_volume_input()", exc_info=e)
5560
raise

libvcell/_internal/native_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ class IsolateManager:
4747
isolate: ctypes.c_void_p
4848
isolate_thread: ctypes.c_void_p
4949

50-
def __init__(self, lib: ctypes.CDLL):
50+
def __init__(self, lib: ctypes.CDLL) -> None:
5151
self.lib = lib
5252
self.isolate = ctypes.c_void_p()
5353
self.isolate_thread = ctypes.c_void_p()
5454

55-
def __enter__(self):
55+
def __enter__(self) -> ctypes.c_void_p:
5656
self.lib.graal_create_isolate(None, byref(self.isolate), byref(self.isolate_thread))
5757
return self.isolate_thread
5858

59-
def __exit__(self, exc_type, exc_val, exc_tb):
59+
def __exit__(self, exc_type: type | None, exc_val: Exception, exc_tb: object | None) -> None:
6060
self.lib.graal_tear_down_isolate(self.isolate_thread)

0 commit comments

Comments
 (0)