Skip to content

Native Image

Native Image #84

#
# Copyright (c) 2024 Elide Technologies, Inc.
#
# Licensed under the MIT license (the "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://opensource.org/license/mit/
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
#
name: Native Image
"on":
workflow_dispatch:
inputs:
## Input: Enable Release Targets
release:
description: "Release"
type: boolean
default: false
## Input: Static Linkage
static:
description: "Static"
type: boolean
default: false
## Input: Runner
runner:
description: "Runner"
type: string
default: ubuntu-cipool
## Input: Architecture
arch:
description: "Architecture Tag"
type: choice
options:
- "amd64"
- "arm64"
- "aarch64"
default: amd64
## Input: Operating System
os:
description: "OS Tag"
type: choice
options:
- "linux"
- "darwin"
- "windows"
default: "linux"
## Input: Optimization
opt:
description: "Optimization"
type: choice
options:
- "0"
- "1"
- "2"
- "3"
- "4"
- "b"
- "s"
default: "4"
## Input: PGO
pgo:
description: "PGO"
type: boolean
default: false
## Input: Release Packing
pack:
description: "Pack"
type: boolean
default: false
## Input: Version Override
version:
description: "Version Override"
type: string
default: ""
workflow_call:
inputs:
release:
description: "Release"
type: boolean
default: false
static:
description: "Static"
type: boolean
default: false
runner:
description: "Runner"
type: string
default: ubuntu-cipool
arch:
description: "Architecture Tag"
type: string
default: amd64
os:
description: "OS Tag"
type: string
default: linux
opt:
description: "Optimization"
type: string
default: "4"
pgo:
description: "PGO"
type: boolean
default: false
pack:
description: "Pack"
type: boolean
default: false
version:
description: "Version Override"
type: string
default: ""
outputs:
hashes:
description: "Provenance Hashes"
value: ${{ jobs.gradle.outputs.hashes }}
version:
description: "Release Version"
value: ${{ jobs.gradle.outputs.version }}
secrets:
BUILDLESS_APIKEY:
required: false
description: "Buildless API Key"
BUILDBOT_SERVICE_ACCOUNT:
required: false
description: "GCP Service Account"
BUILDBOT_GHCR_TOKEN:
required: false
description: "GHCR Token"
CODECOV_TOKEN:
required: false
description: "Codecov token"
GRADLE_CONFIGURATION_KEY:
required: false
description: "Gradle cache key"
COSIGN_KEY:
required: false
description: "Cosign Key"
COSIGN_PASSWORD:
required: false
description: "Cosign Password"
SIGNING_KEY:
required: true
description: "GPG Signing Key"
# Do not add `ELIDE_VERSION` here like other workflows, or it may interfere with the release version override.
env:
RUST_BACKTRACE: full
BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }}
permissions:
contents: read
jobs:
##
## Job: Library Build
##
gradle:
name: "Native (${{ inputs.os }}-${{ inputs.arch }})"
runs-on: ${{ inputs.runner }}
permissions:
contents: write
id-token: write
defaults:
run:
shell: bash
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
version: ${{ steps.release-prep.outputs.version }}
platform: ${{ inputs.os }}-${{ inputs.arch }}
releaseArtifact: ${{ steps.pack-artifact.outputs.id }}
builtArtifact: ${{ steps.build-artifact.outputs.id }}
steps:
- name: "Setup: Harden Runner"
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
disable-sudo: false
egress-policy: audit
- name: "Setup: Checkout"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 1
submodules: true
persist-credentials: false
clean: false
token: ${{ secrets.GITHUB_TOKEN }}
- name: "Setup: Packages"
if: contains(inputs.runner, 'ubuntu') || contains(inputs.runner, 'linux')
run: sudo apt-get update && sudo apt-get install -y build-essential libssl-dev libtool libtool-bin
- name: "Setup: Rust"
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 # v1.13.0
with:
toolchain: stable
cache: false # handled by sccache
- name: "Setup: SCCache"
uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
- name: "Setup: Rust Caching"
run: echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
- name: "Setup: GraalVM (Java 25)"
uses: graalvm/setup-graalvm@eec48106e0bf45f2976c2ff0c3e22395cced8243 # v1.4.2
with:
distribution: "graalvm"
java-version: "25"
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: "Setup: PNPM"
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
with:
version: "10.6.2"
- name: "Setup: Node"
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: 23
- name: "Setup: Bun"
uses: step-security/setup-bun@81c6b5758214d7e8b68a403c6a55a040e9b8879a # v2.0.3
with:
bun-version: "1.2.14"
- name: "Setup: uv"
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: "Setup: Dependencies"
run: |
echo "Setting up venv..."
uv venv
echo "Activating venv..."
. .venv/bin/activate
echo "Installing dependencies via Pip..."
uv pip install -r config/requirements.txt
echo PATH=$PATH >> $GITHUB_ENV
echo "Installing dependencies..."
pnpm install
- name: "Setup: Gradle"
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
id: gradlebuild
env:
CI: true
BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }}
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
with:
cache-read-only: true
cache-encryption-key: ${{ secrets.GRADLE_CONFIGURATION_KEY }}
dependency-graph: disabled
gradle-home-cache-cleanup: true
gradle-home-cache-includes: binaryen
caches
jdks
native
native-build-tools
nodejs
notifications
wrapper
yarn
- name: "Setup: Gradle Settings"
run: cp -fv ./.github/workflows/gradle-ci.properties ~/.gradle/gradle.properties
- name: "Setup: Gradle Settings (Globals)"
run: cp -fv /home/ci-agent/gradle-ci.properties ~/.gradle/gradle.properties || echo "No global settings."
- name: "Setup: Cosign"
if: inputs.pack
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
- name: "Build Environment"
run: file Makefile && make info CI=yes 2>&1 | tee build-info.txt
- name: "Overrides: Version"
if: inputs.version != ''
run: |
current_version=$(cat ./.version)
echo "${{ inputs.version }}" > ./.version
echo "${{ inputs.version }}" > ./.release
sed -i "s/elide = \"${current_version}\"/elide = \"${{ inputs.version }}\"/g" gradle/elide.versions.toml
sed -i "s/elide-bin = \"${current_version}\"/elide-bin = \"${{ inputs.version }}\"/g" gradle/elide.versions.toml
sed -i "s/${current_version}/${{ inputs.version }}/g" tools/elide-build/src/main/kotlin/elide/internal/conventions/Constants.kt
- name: "🛠️ Release: Natives"
env:
CI: true
BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
TEST_EXCEPTIONS: true
run: make natives CI=yes
- name: "🛠️ Release: Image"
env:
CI: true
BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
TEST_EXCEPTIONS: true
run: |
./gradlew \
:packages:cli:nativeOptimizedCompile \
-x check \
-x test \
-x jvmTest \
--scan \
--build-cache \
--daemon \
--dependency-verification=off \
--no-configuration-cache \
--stacktrace \
-Pelide.ci=true \
-PbuildSamples=false \
-PbuildDocs=false \
-Pelide.optMode=${{ inputs.opt }} \
-Pelide.stamp=${{ inputs.release }} \
-Pelide.pgo=${{ inputs.pgo }} \
-Pelide.static=${{ inputs.static == true && 'true' || 'false' }} \
-Pelide.release=${{ inputs.release }} \
-Pelide.buildMode=${{ inputs.release == true && 'release' || 'dev' }}
- name: "Setup: Signing Keys"
run: |
cat <(echo -e "${{ secrets.SIGNING_KEY }}") | base64 -d | gpg --batch --import
gpg --list-secret-keys --keyid-format LONG
gpg --export-secret-keys > /home/$(whoami)/.gnupg/secring.gpg
- name: "Artifact: Build Outputs"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
id: build-artifact
with:
name: elide-native-${{ inputs.release == true && 'release' || 'dev' }}-${{ inputs.os }}-${{ inputs.arch }}
path: packages/cli/build/native/nativeOptimizedCompile/**/*.*
- name: "Artifact: Provenance Subject"
id: hash
if: ${{ inputs.os == 'linux' && inputs.release }}
run: |
echo "hashes=$(sha256sum ./packages/cli/build/native/nativeOptimizedCompile/elide | base64 -w0)" >> "$GITHUB_OUTPUT"
- name: "🛠️ Release: Package"
if: inputs.pack
run: bash ./tools/scripts/release/build-release.sh
env:
COSIGN_KEY: ${{ secrets.COSIGN_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_ARGS: "--key env://COSIGN_KEY"
- name: "Release: Prepare"
if: inputs.pack
id: release-prep
run: |
currentVersion=$(cat ./.release)
releaseOverride="${{ inputs.version }}"
version="${releaseOverride:-$currentVersion}"
cd ./packages/cli/build/native/nativeOptimizedCompile/;
mkdir -p "release/${{ inputs.os }}-${{ inputs.arch }}/$version"
cp -fv elide-*.{tgz,txz,zip}* "release/${{ inputs.os }}-${{ inputs.arch }}/$version/"
cp -fv elide.sbom.json "release/${{ inputs.os }}-${{ inputs.arch }}/$version/"
cp -fv elide-build-report.html "release/${{ inputs.os }}-${{ inputs.arch }}/$version/elide.build-report.html"
cd -;
mkdir -p staging/release
mv "packages/cli/build/native/nativeOptimizedCompile/release" "staging/"
echo "version=$version" >> $GITHUB_OUTPUT
tree -L 3 staging/
echo "Release built."
- name: "Artifact: Release Package"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
id: pack-artifact
if: inputs.pack
with:
name: elide-native-${{ inputs.release == true && 'release' || 'dev' }}-${{ inputs.os }}-${{ inputs.arch }}-release.zip
path: staging/**/*.*