Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions .github/actions/add-swap/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Add swap
description: Add a swapfile on Linux, on top of whatever swap the runner image already has.

# Adds to the image's swap rather than replacing it, and fails the job on any error.
# Carrying on without the swap is the failure to avoid: a build that needed it and ran with none would die the way
# it did before, with nothing in the log saying the swap was never there.
inputs:
size-gb:
description: Size of the swapfile to add, in GiB.
required: false
default: "8"
path:
description: Where to create the swapfile. Distinct from the image's own, which stays in use.
required: false
default: /et-swapfile

runs:
using: composite
steps:
- name: Add swap on Linux
if: runner.os == 'Linux'
shell: bash --noprofile --norc -euo pipefail {0}
env:
SWAP_PATH: ${{ inputs.path }}
SWAP_SIZE_GB: ${{ inputs.size-gb }}
run: |
sudo fallocate -l "${SWAP_SIZE_GB}G" "$SWAP_PATH"
sudo chmod 600 "$SWAP_PATH"
sudo mkswap "$SWAP_PATH"
sudo swapon "$SWAP_PATH"
swapon --show
free -h
12 changes: 12 additions & 0 deletions .github/actions/free-disk-space/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,21 @@ description: Reclaim runner disk before the long build and test steps
runs:
using: composite
steps:
# Swap is kept rather than reclaimed.
# The action's default switches it off and deletes the swapfile, which on a 16 GiB runner leaves the link-heavy
# test build nothing to spill into, and the space that would free is not needed.
- name: Free disk space on Linux
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@v1.3.1
with:
swap-storage: false

# Swap on top of whatever the image ships, which on ubuntu-24.04-arm is a 3 GiB /swapfile.
# A test build that outgrows memory then slows down instead of taking the runner with it -- the hosted runner
# is killed outright on exhaustion, reporting a shutdown signal rather than any build error. Root has the room:
# it shows 119G free on the arm runner once the step above has run.
- name: Add swap
uses: ./.github/actions/add-swap

- name: Free disk space on Windows
if: runner.os == 'Windows'
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/k3s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ name: k3s
"on":
pull_request:
paths:
# install-mise-tools and the two actions it runs on Linux before anything else.
- .github/actions/add-swap/**
- .github/actions/free-disk-space/**
- .github/actions/install-mise-tools/**
- .github/workflows/k3s.yaml
# The `k3s-verify` task itself lives here.
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ jobs:
packages: read
runs-on: ${{ matrix.os }}
timeout-minutes: ${{ matrix.timeout }}
# The test build's peak memory is what killed the ubuntu-24.04-arm lane, so this job trims it four ways.
# Line tables keep a panicking test's backtrace pointing at file and line while dropping the rest of the debug
# info the linker has to read and write; incremental caches are never reused by a one-shot build; the hosted
# Ubuntu runners, whose GCC is new enough, link through mold; and the arm lane alone runs three codegen and link
# jobs instead of four. That last one costs wall-clock, so it stays on the lane that needed it -- every other lane
# keeps cargo's own default, which is the one value besides a number that the variable accepts.
env:
CARGO_BUILD_JOBS: ${{ matrix.os == 'ubuntu-24.04-arm' && '3' || 'default' }}
CARGO_INCREMENTAL: "0"
CARGO_PROFILE_DEV_DEBUG: line-tables-only
ET_LINK_WITH_MOLD: ${{ startsWith(matrix.os, 'ubuntu') }}
# Override the workflow-level `shell: bash` default for Windows runs.
# This uses the busybox-w32 ash that mise installs in `_setup_all` (the same shell `MISE_BASH_PATH` already
# points at for `shell = "bash"` tasks on the Windows Docker images). Avoids Git Bash's MSYS fork-emulation
Expand Down Expand Up @@ -118,9 +129,18 @@ jobs:
# macos-26-intel raises its own ceiling through the matrix, because it is the only lane that source-builds
# vector and rustfs -- upstream ships no macos/x64 prebuilt for either. Those two overran the flat 60 even
# while still failing early; completing them needs more. Every other lane falls back to 60 via the `||`.
#
# Linking through mold is off for this one step, because mold is among the tools it installs. The `cargo:` tools
# with no prebuilt for a lane are source-built here, before mold is on PATH, and asking GCC for it then fails each
# of those links with
# collect2: fatal error: cannot find 'ld'
# on commit https://github.com/edge-toolkit/core/commit/5d7dfaa10c0d10e980aa7a4a785476be059699fb at
# https://github.com/edge-toolkit/core/actions/runs/36812561314/job/110210608554.
- name: Install mise + tools
uses: ./.github/actions/install-mise-tools
timeout-minutes: ${{ matrix.install_timeout || 60 }}
env:
ET_LINK_WITH_MOLD: "false"

# GITHUB_TOKEN raises the rate-limit ceiling on mise's fetch of the rp-v<N> rustpython_wasm tarball.
# (The fetch is [tools."http:rp-wasm"], via mise's http backend against github.com release assets.)
Expand Down
19 changes: 17 additions & 2 deletions .mise/config.linux.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"conda:clangxx" = "latest"
# gpg for mise's gpg_verify signature checks; _setup_all installs it up front.
"conda:gnupg" = "latest"
# mold, the linker a Linux lane that sets ET_LINK_WITH_MOLD links Rust with.
"aqua:rui314/mold" = "latest"

# System packages `mise bootstrap packages status` verifies and `mise bootstrap packages apply` installs.
# The same prerequisite set the Dockerfile's COMMON_PACKAGES + APT_PACKAGES / DNF_PACKAGES ARGs install; the
Expand Down Expand Up @@ -56,6 +58,19 @@ a_conda_arch = "{% if arch() == 'arm64' %}aarch64{% else %}x86_64{% endif %}"
a_conda_clangxx = "{{ env.HOME }}/.local/share/mise/installs/conda-clangxx/latest"
b_clang_resource = "{{ vars.a_conda_clangxx }}/lib/clang/22"
b_clang_sysroot = "{{ vars.a_conda_clangxx }}/{{ vars.a_conda_arch }}-conda-linux-gnu/sysroot"
# Link through mold rather than the system linker, for a lane that sets ET_LINK_WITH_MOLD=true.
# On aarch64 the system linker is GNU ld -- rustc only defaults to its bundled lld on x86_64 -- and linking the
# deno/V8 test binaries with it while the rest of the workspace still compiles exhausts the runner's memory. The
# arm lane of test.yaml died that way at the same compile step on 7 of 40 runs, the hosted runner killed rather
# than any build error:
# ##[error]The runner has received a shutdown signal. This can happen when the runner service is stopped, or a
# manually started runner is canceled.
# [cargo-test] ERROR sh exited with non-zero status: killed by SIGTERM
# on commit https://github.com/edge-toolkit/core/commit/674ca2bbc30ecb34db9cbf749e5ae3e3d609a01b at
# https://github.com/edge-toolkit/core/actions/runs/36792810690/job/110199819803.
# Opt-in rather than the default because `-fuse-ld=mold` needs GCC 12.1, and the opensuse, amazonlinux and
# ubuntu:22.04 image bases ship an older one.
mold_flag = '{% if env?.ET_LINK_WITH_MOLD == "true" %}-Clink-arg=-fuse-ld=mold{% endif %}'
# bindgen loads libclang directly rather than driving the clang binary.
# So it can't auto-find its resource dir (builtins like stddef.h) or conda's bundled sysroot. Pass `-resource-dir`
# + `--sysroot` so header resolution is identical on every machine (a bare `-isystem` leaves builtin type
Expand All @@ -75,8 +90,8 @@ BINDGEN_EXTRA_CLANG_ARGS = "{{ vars.c_bindgen_args }}"
# OPENSSL_DIR points openssl-sys at conda's OpenSSL, so anything linking it records conda's libssl soname;
# without an rpath the loader only finds it when conda's soname matches the system one (it broke when conda
# bumped to libssl.so.4). pylib_flag does the same for the CPython lib dir.
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS = "{{ vars.rpath_flag }} {{ vars.pylib_flag }}"
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS = "{{ vars.rpath_flag }} {{ vars.pylib_flag }}"
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS = "{{ vars.rpath_flag }} {{ vars.pylib_flag }} {{ vars.mold_flag }}"
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS = "{{ vars.rpath_flag }} {{ vars.pylib_flag }} {{ vars.mold_flag }}"
LIBCLANG_PATH = "{{ vars.a_conda_clangxx }}/lib"

[tasks.preinstall]
Expand Down
13 changes: 7 additions & 6 deletions .mise/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1468,11 +1468,12 @@ if [ -z "${GITHUB_TOKEN:-}" ]; then
exit 1
fi

# Storage is redirected so the run is self-contained.
# Unset, the hub resolves its default against the repository root it finds by walking up, so two runs and any
# stale bucket from ordinary development share one directory and the poll below can read a model this run never
# produced.
storage=$(coreutils mktemp -d)
# Storage is where the deployment itself keeps it, beside its `mise.toml`, and is emptied first.
# The deployment's own task env names that directory, which outranks anything exported into this process, so it is
# read from there rather than redirected. Emptying it keeps a stale model from an earlier run from satisfying the
# poll below; the directory is gitignored beside the deployment.
storage="$out/storage"
coreutils rm -rf "$storage"
scenario_pid=""
cleanup() {
status=$?
Expand Down Expand Up @@ -1504,7 +1505,7 @@ coreutils rm -f "$out/mise.lock"
# fetched https://registry.npmjs.org/@edge-toolkit%2Fet-ws-math1 and installed nothing.
npmrc="$PWD/$out/npmrc"
(cd "$out" && NPM_CONFIG_USERCONFIG="$npmrc" mise install)
(cd "$out" && STORAGE_URL="file://$storage" mise run generated-scenario) &
(cd "$out" && mise run generated-scenario) &
scenario_pid=$!

# The model is what says the exchange ran, rather than the processes being up.
Expand Down
14 changes: 14 additions & 0 deletions .mise/mise.linux.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,10 @@ only correlate: every sighting was a long job.
So the remedy is `gh run rerun --job <id>` once the parent run completes, and there is nothing to fix. Do not
spend a diagnosis on it; check for the empty log first, and if the siblings passed, re-run and move on.

The `ubuntu-24.04-arm` lane of test.yaml is the exception, and it disproves the rotation argument for that lane:
its sightings kept their logs, and all of them stop at the same compile step. That is memory running out, and
the lane is now built to stay under it. A shutdown signal there again is a regression to diagnose, not a rerun.

### Fixed: vector_otlp_relay store-and-forward timing

Root-caused and fixed on 2026-09-11 by capping the retry interval; kept here because the panic line is what a
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ deno_resolver = "0.85"
# instead of panicking when no SnapshotOptions struct is in OpState -- without
# baking our own startup snapshot we'd otherwise hit the panic on first run.
deno_runtime = { version = "0.262", features = ["transpile", "hmr"] }
edge-toolkit = { path = "libs/edge-toolkit", version = "0.3.0" }
edge-toolkit = { path = "libs/edge-toolkit", version = "0.3.1" }
et-modules-service = { path = "services/modules", version = "0.2.0" }
et-org = { path = "libs/org", version = "0.1.0" }
et-otlp = { path = "libs/et-otlp", version = "0.2.0" }
Expand All @@ -100,8 +100,8 @@ et-wasi-guest = { path = "libs/wasi-guest", version = "0.1.0" }
et-web = { path = "libs/web", version = "0.2.0" }
et-websockify-service = { path = "services/websockify", version = "0.1.0" }
et-ws-runner-common = { path = "libs/ws-runner-common", version = "0.2.0" }
et-ws-server = { path = "services/ws-server", version = "0.2.0" }
et-ws-service = { path = "services/ws", version = "0.1.0" }
et-ws-server = { path = "services/ws-server", version = "0.2.1" }
et-ws-service = { path = "services/ws", version = "0.1.1" }
et-ws-test-server = { path = "services/ws-test-server", version = "0.1.0" }
et-ws-wasm-agent = { path = "services/ws-wasm-agent", version = "0.2.0" }
fake = "5"
Expand Down
2 changes: 1 addition & 1 deletion config/jscpd-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
"608f556637a1f4db": 1,
"61012257ce19e116": 1,
"61b28209f41edecf": 1,
"6214037b4acff9b5": 1,
"62257586054b0689": 1,
"635fb32c899e4df6": 1,
"644491f2c34618c6": 1,
Expand Down Expand Up @@ -172,6 +171,7 @@
"8beb95ee363cd6e3": 1,
"8c912ef640675113": 1,
"8cfbef0da485b326": 1,
"8dd8aa0822526cc2": 1,
"8fa398e0937479af": 1,
"928c39b341599636": 1,
"92ed119fbc8ed830": 1,
Expand Down
2 changes: 1 addition & 1 deletion libs/edge-toolkit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "edge-toolkit"
publish = true
description = "A collection of utilities and common code for Edge Toolkit services"
version = "0.3.0"
version = "0.3.1"
edition.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
Loading
Loading