Skip to content

Commit ab74f44

Browse files
tverbeirenhcannoodt
authored andcommitted
GraalVM builds for native binaries (#874)
* Add GraalVM build target * Update Github Actions WF * Revert version introspection logic * fix macos image definitions and copying of the release assets --------- Co-authored-by: Hendrik Cannoodt <hendrik.cannoodt@gmail.com>
1 parent c151429 commit ab74f44

3 files changed

Lines changed: 168 additions & 11 deletions

File tree

.github/workflows/prep_release.yml

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ name: Prepare Viash Release
22

33
on:
44
workflow_dispatch:
5-
5+
66
jobs:
7-
build-and-release:
7+
build-jar:
88
runs-on: ubuntu-latest
99

1010
permissions:
11-
contents: write
11+
contents: read
12+
13+
outputs:
14+
viash_version: ${{ steps.get_version.outputs.viash_version }}
15+
changelog_section: ${{ steps.get_version.outputs.changelog_section }}
1216

1317
steps:
1418
- name: Checkout code
@@ -43,26 +47,142 @@ jobs:
4347
echo "Detected Viash version: $viash_version"
4448
echo "Detected Viash minor version: $viash_minor_version"
4549
echo "viash_version=$viash_version" >> "$GITHUB_OUTPUT"
46-
50+
4751
# fetch relevant changelog section
4852
changelog_section=$(awk "/# Viash ${viash_version}.*/{flag=1;print;next}/^# /{flag=0}flag" CHANGELOGS/CHANGELOG_${viash_minor_version}.md)
49-
53+
5054
echo "changelog_section<<GITHUB_EOF" >> "$GITHUB_OUTPUT"
5155
echo "$changelog_section" >> "$GITHUB_OUTPUT"
5256
echo "GITHUB_EOF" >> "$GITHUB_OUTPUT"
5357
58+
- name: Extract fat JAR
59+
run: |
60+
cp target/viash.jar viash.jar
61+
62+
- name: Upload JAR artifact
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: fat-jar
66+
path: viash.jar
67+
retention-days: 1
68+
69+
- name: Upload release assets
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: release-assets
73+
path: |
74+
bin/viash
75+
bin/schema.json
76+
bin/viash_install
77+
retention-days: 1
78+
79+
build-native:
80+
needs: build-jar
81+
strategy:
82+
fail-fast: false
83+
matrix:
84+
include:
85+
- os: macos-15-intel
86+
label: macos-x86_64
87+
- os: macos-15
88+
label: macos-aarch64
89+
- os: ubuntu-latest
90+
label: linux-x86_64
91+
- os: ubuntu-24.04-arm
92+
label: linux-aarch64
93+
94+
runs-on: ${{ matrix.os }}
95+
96+
permissions:
97+
contents: read
98+
99+
steps:
100+
- name: Download JAR
101+
uses: actions/download-artifact@v4
102+
with:
103+
name: fat-jar
104+
105+
- name: Set up GraalVM
106+
uses: graalvm/setup-graalvm@v1
107+
with:
108+
java-version: '21'
109+
distribution: 'graalvm'
110+
111+
- name: Build native image
112+
run: |
113+
native-image -jar viash.jar \
114+
--no-fallback \
115+
-H:+ReportExceptionStackTraces \
116+
--initialize-at-build-time=scala,org.rogach.scallop \
117+
--enable-url-protocols=https \
118+
-o viash
119+
120+
- name: Smoke test
121+
run: |
122+
./viash --version
123+
124+
- name: Upload native binary
125+
uses: actions/upload-artifact@v4
126+
with:
127+
name: viash-${{ matrix.label }}
128+
path: viash
129+
retention-days: 1
130+
131+
create-release:
132+
needs: [build-jar, build-native]
133+
runs-on: ubuntu-latest
134+
135+
permissions:
136+
contents: write
137+
138+
steps:
139+
- name: Download release assets
140+
uses: actions/download-artifact@v4
141+
with:
142+
name: release-assets
143+
path: release-assets
144+
merge-multiple: true
145+
146+
- name: Download native binaries
147+
uses: actions/download-artifact@v4
148+
with:
149+
pattern: viash-*
150+
path: native-binaries
151+
merge-multiple: false
152+
153+
- name: Prepare release files
154+
run: |
155+
mkdir -p release
156+
157+
# JAR-based executable (backward compatible)
158+
cp release-assets/viash release/viash
159+
cp release-assets/schema.json release/schema.json
160+
cp release-assets/viash_install release/viash_install
161+
162+
# Native binaries with platform suffixes
163+
cp native-binaries/viash-linux-x86_64/viash release/viash-linux-x86_64
164+
cp native-binaries/viash-linux-aarch64/viash release/viash-linux-aarch64
165+
cp native-binaries/viash-macos-x86_64/viash release/viash-macos-x86_64
166+
cp native-binaries/viash-macos-aarch64/viash release/viash-macos-aarch64
167+
168+
chmod +x release/viash-*
169+
54170
- name: Create release
55171
uses: softprops/action-gh-release@v2
56172
env:
57173
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58174
with:
59-
tag_name: ${{ steps.get_version.outputs.viash_version }}
175+
tag_name: ${{ needs.build-jar.outputs.viash_version }}
60176
target_commitish: ${{ github.sha }}
61-
name: Viash ${{ steps.get_version.outputs.viash_version }}
62-
body: ${{ steps.get_version.outputs.changelog_section }}
177+
name: Viash ${{ needs.build-jar.outputs.viash_version }}
178+
body: ${{ needs.build-jar.outputs.changelog_section }}
63179
draft: true
64180
fail_on_unmatched_files: true
65181
files: |
66-
bin/viash
67-
bin/schema.json
68-
bin/viash_install
182+
release/viash
183+
release/schema.json
184+
release/viash_install
185+
release/viash-linux-x86_64
186+
release/viash-linux-aarch64
187+
release/viash-macos-x86_64
188+
release/viash-macos-aarch64

build.sbt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,41 @@ generateWorkflowHelper := {
7878
streams.value.log.info(s"Generated WorkflowHelper.nf at ${wfHelper.toAbsolutePath}")
7979
}
8080

81+
// Generate BuildInfo.scala with name and version baked in at compile time.
82+
// The JAR manifest approach doesn't work in GraalVM native binaries.
83+
Compile / sourceGenerators += Def.task {
84+
val file = (Compile / sourceManaged).value / "io" / "viash" / "BuildInfo.scala"
85+
IO.write(file,
86+
s"""package io.viash
87+
|
88+
|object BuildInfo {
89+
| val name: String = "${name.value}"
90+
| val version: String = "${version.value}"
91+
|}
92+
|""".stripMargin)
93+
Seq(file)
94+
}.taskValue
95+
8196
assembly := ((assembly) dependsOn generateWorkflowHelper).value
8297
Test / testOptions := ((Test / testOptions) dependsOn generateWorkflowHelper).value
98+
99+
// GraalVM native-image configuration
100+
enablePlugins(NativeImagePlugin)
101+
102+
Compile / mainClass := Some("io.viash.Main")
103+
104+
nativeImageJvm := "graalvm-java21"
105+
nativeImageVersion := "21.0.2"
106+
Global / excludeLintKeys ++= Set(nativeImageJvm, nativeImageVersion)
107+
108+
nativeImageOptions ++= Seq(
109+
"--no-fallback",
110+
"-H:+ReportExceptionStackTraces",
111+
// Scala 3 lazy vals use reflection for bitmap fields (scala/scala3#13985).
112+
// Initializing at build time lets reflection resolve during the build.
113+
"--initialize-at-build-time=scala,org.rogach.scallop",
114+
// viash downloads remote resources and version binaries over HTTPS
115+
"--enable-url-protocols=https",
116+
)
117+
118+
nativeImage := ((nativeImage) dependsOn generateWorkflowHelper).value

project/plugins.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.1")
22
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.1.0")
33
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.9.0")
4+
addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.4")

0 commit comments

Comments
 (0)