name: El SDK Release on: push: branches: - main pull_request: branches: - main jobs: build-and-release: runs-on: ubuntu-latest defaults: run: working-directory: lang steps: - name: Checkout uses: actions/checkout@v4 - name: Enforce source branch (main <- stage only) if: github.event_name == 'pull_request' run: | SOURCE="${GITHUB_HEAD_REF}" if [ "${SOURCE}" != "stage" ]; then echo "ERROR: Main branch only accepts PRs from 'stage'. Source was: '${SOURCE}'" exit 1 fi echo "Source branch check passed: ${SOURCE} -> main" - name: Install build dependencies run: | apt-get update -qq apt-get install -y gcc libcurl4-openssl-dev # Gen2: compile the bootstrap C source into a working elc binary - name: Build elc from bootstrap (gen2) run: | # -Wl,--allow-multiple-definition: elc-bootstrap.c and el_runtime.c both define # is_digit/is_whitespace; bootstrap predates the text-processing primitives commit gcc -O2 \ -I el-compiler/runtime \ dist/elc-bootstrap.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lpthread -lm \ -Wl,--allow-multiple-definition \ -o dist/elc-gen2 chmod +x dist/elc-gen2 echo "gen2 elc built" dist/elc-gen2 --version || true # Gen3: use gen2 to compile the El compiler from its own El source (self-host) - name: Self-host compile El compiler with gen2 (gen3) run: | mkdir -p dist/platform dist/elc-gen2 el-compiler/src/compiler.el > dist/elc-gen3.c gcc -O2 \ -I el-compiler/runtime \ dist/elc-gen3.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lpthread -lm \ -o dist/platform/elc chmod +x dist/platform/elc echo "gen3 (self-hosted) elc built" dist/platform/elc --version || true # Build elb binary - name: Build elb run: | mkdir -p dist/bin dist/platform/elc elb.el > dist/elb.c gcc -O2 \ -I el-compiler/runtime \ dist/elb.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lpthread -lm \ -o dist/bin/elb chmod +x dist/bin/elb echo "elb built" # Build epm binary (epm lives at repo root, not inside lang/) - name: Build epm run: | dist/platform/elc ../epm/src/epm.el > dist/epm.c gcc -O2 \ -I el-compiler/runtime \ dist/epm.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lpthread -lm \ -o dist/bin/epm chmod +x dist/bin/epm echo "epm built" # Build el-install binary - name: Build el-install run: | dist/platform/elc tools/install/el-install.el > dist/el-install.c gcc -O2 \ -I el-compiler/runtime \ dist/el-install.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lpthread -lm \ -o dist/bin/el-install chmod +x dist/bin/el-install echo "el-install built" - name: Run tests - text run: | ELC="$(pwd)/dist/platform/elc" \ EL_HOME="$(pwd)" \ bash tests/text/run.sh - name: Run tests - calendar run: | ELC="$(pwd)/dist/platform/elc" \ EL_HOME="$(pwd)" \ bash tests/calendar/run.sh - name: Run tests - time run: | ELC="$(pwd)/dist/platform/elc" \ EL_HOME="$(pwd)" \ bash tests/time/run.sh - name: Run tests - html_sanitizer run: | ELC="$(pwd)/dist/platform/elc" \ EL_HOME="$(pwd)" \ bash tests/html_sanitizer/run.sh # Native El test suites (elc --test, compile-link-run) - name: Run tests - native (core) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_core.el > /tmp/el_native_core.c gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_core /tmp/el_native_core - name: Run tests - native (text) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_text.el > /tmp/el_native_text.c gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_text /tmp/el_native_text - name: Run tests - native (string) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_string.el > /tmp/el_native_string.c gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_string /tmp/el_native_string - name: Run tests - native (math) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_math.el > /tmp/el_native_math.c gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_math /tmp/el_native_math - name: Run tests - native (state) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_state.el > /tmp/el_native_state.c gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_state /tmp/el_native_state - name: Run tests - native (time) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_time.el > /tmp/el_native_time.c gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_time /tmp/el_native_time - name: Run tests - native (json) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_json.el > /tmp/el_native_json.c gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_json /tmp/el_native_json - name: Run tests - native (env) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_env.el > /tmp/el_native_env.c gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_env /tmp/el_native_env - name: Run tests - native (fs) run: | set -euo pipefail ELC="$(pwd)/dist/platform/elc" RUNTIME="$(pwd)/el-compiler/runtime" "$ELC" --test tests/native/test_fs.el > /tmp/el_native_fs.c gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c "$RUNTIME/el_runtime.c" \ -lcurl -lpthread -lm -o /tmp/el_native_fs /tmp/el_native_fs # Bundle the SDK tarball - runs from the repo root to reference lang/ paths correctly - name: Bundle SDK tarball if: github.event_name == 'push' working-directory: ${{ github.workspace }} run: | mkdir -p dist/sdk/bin dist/sdk/runtime cp lang/dist/platform/elc dist/sdk/bin/elc cp lang/dist/bin/elb dist/sdk/bin/elb cp lang/dist/bin/epm dist/sdk/bin/epm cp lang/el-compiler/runtime/el_runtime.c dist/sdk/runtime/ cp lang/el-compiler/runtime/el_runtime.h dist/sdk/runtime/ cp lang/runtime/*.el dist/sdk/runtime/ tar -czf dist/el-sdk-latest.tar.gz -C dist/sdk . echo "SDK tarball bundled: dist/el-sdk-latest.tar.gz" ls -lh dist/el-sdk-latest.tar.gz # Publish / update the `latest` release with all SDK assets - name: Publish latest release if: github.event_name == 'push' working-directory: ${{ github.workspace }} env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_API: https://git.neuralplatform.ai/api/v1 REPO: neuron-technologies/el run: | EXISTING_ID=$(curl -sf \ -H "Authorization: token ${GITEA_TOKEN}" \ "${GITEA_API}/repos/${REPO}/releases/tags/latest" \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['id'])" 2>/dev/null || true) if [ -n "${EXISTING_ID}" ]; then echo "Deleting existing release id=${EXISTING_ID}" curl -sf -X DELETE \ -H "Authorization: token ${GITEA_TOKEN}" \ "${GITEA_API}/repos/${REPO}/releases/${EXISTING_ID}" fi curl -sf -X DELETE \ -H "Authorization: token ${GITEA_TOKEN}" \ "${GITEA_API}/repos/${REPO}/tags/latest" || true RELEASE_ID=$(curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${GITEA_API}/repos/${REPO}/releases" \ -d "{ \"tag_name\": \"latest\", \"name\": \"El SDK (latest)\", \"body\": \"Latest El SDK build from commit ${GITHUB_SHA}.\nBuilt $(date -u +%Y-%m-%dT%H:%M:%SZ).\", \"draft\": false, \"prerelease\": false }" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") echo "Created release id=${RELEASE_ID}" upload_asset() { local filepath="$1" local name="$2" echo "Uploading ${name}..." curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -F "attachment=@${filepath};filename=${name}" \ "${GITEA_API}/repos/${REPO}/releases/${RELEASE_ID}/assets" } # Per-file assets (downstream CI needs these individually) upload_asset lang/dist/platform/elc elc upload_asset lang/el-compiler/runtime/el_runtime.c el_runtime.c upload_asset lang/el-compiler/runtime/el_runtime.h el_runtime.h # SDK bundle and installer binary upload_asset dist/el-sdk-latest.tar.gz el-sdk-latest.tar.gz upload_asset lang/dist/bin/el-install el-install echo "Release published successfully" - name: Publish El SDK to Artifact Registry (prod) if: github.event_name == 'push' env: GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }} run: | echo "${GCP_SA_KEY}" > /tmp/gcp-key.json apt-get install -y -qq apt-transport-https ca-certificates gnupg curl curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" > /etc/apt/sources.list.d/google-cloud-sdk.list apt-get update -qq && apt-get install -y google-cloud-cli gcloud auth activate-service-account --key-file=/tmp/gcp-key.json gcloud config set project neuron-785695 VERSION="${GITEA_SHA:0:8}" gcloud artifacts generic upload \ --repository=foundation-prod \ --location=us-central1 \ --project=neuron-785695 \ --package=el/elc \ --version="${VERSION}" \ --source=dist/platform/elc gcloud artifacts generic upload \ --repository=foundation-prod \ --location=us-central1 \ --project=neuron-785695 \ --package=el/el_runtime.c \ --version="${VERSION}" \ --source=el-compiler/runtime/el_runtime.c gcloud artifacts generic upload \ --repository=foundation-prod \ --location=us-central1 \ --project=neuron-785695 \ --package=el/el_runtime.h \ --version="${VERSION}" \ --source=el-compiler/runtime/el_runtime.h echo "Published El SDK version=${VERSION} to foundation-prod" rm -f /tmp/gcp-key.json - name: Dispatch el-sdk-updated to downstream repos if: github.event_name == 'push' env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_API: https://git.neuralplatform.ai/api/v1 run: | for repo in neuron-technologies/forge; do curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${GITEA_API}/repos/${repo}/dispatches" \ -d "{ \"type\": \"el-sdk-updated\", \"inputs\": {\"el_version\": \"latest\", \"commit\": \"${GITHUB_SHA}\"} }" && echo "Dispatched to ${repo}" || echo "Warning: dispatch to ${repo} failed" done