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
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ services/ws-server/static/models/
**/.pytest_cache/
**/.python-version
**/node_modules/
**/pnpm-lock.yaml
**/.venv/
# .NET build output.
# `obj/` is safe globally (nothing tracked is named obj/), but `bin/` is scoped to the module so it never
Expand Down
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ max_line_length = unset

[config/upstream-cache/data.toml]
max_line_length = 200

# pnpm writes each package's `resolution: {integrity: sha512-...}` on one line, which exceeds the line length.
[**/pnpm-lock.yaml]
max_line_length = unset
70 changes: 69 additions & 1 deletion .github/actions/free-disk-space-windows/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ description: >-
jlumbroso/free-disk-space on Linux, which doesn't have a Windows path.
Logs disk-free before + after so the reclaimed space is visible.

Enabling all makes approximately 10Gb free.
The default-on removals free roughly 17 GB. The two opt-in ones
(visual-studio, windows-kits) add up to another ~23 GB, but only a
caller that builds entirely inside a container may enable them.

Caller is responsible for the `if: runner.os == 'Windows'` guard --
every step here uses Git Bash with `C:\` mounted at `/c`; running this
Expand Down Expand Up @@ -42,6 +44,36 @@ inputs:
Strawberry Perl) -- ~1 GB combined.
required: false
default: "true"
hostedtoolcache-unused-runtimes:
description: >-
Remove the `hostedtoolcache` Ruby, Go and CodeQL trees (~4 GB
combined). Nothing here uses Ruby; Go comes from mise's own `go`
pin rather than setup-go's copy; CodeQL runs only in codeql.yaml,
which does not call this action.
required: false
default: "true"
cloud-clis:
description: >-
Remove the preinstalled Azure, AWS and Google Cloud SDK trees
(~3 GB combined). No lane in this repo talks to a cloud provider.
required: false
default: "true"
visual-studio:
description: >-
Remove the preinstalled Visual Studio tree (~10-20 GB, the single
largest reclaim available). OFF by default because it is only safe
when the caller builds entirely inside a container: test.yaml's
`override (msvc)` lane needs MSVC's link.exe on the runner itself.
docker-windows.yaml opts in.
required: false
default: "false"
windows-kits:
description: >-
Remove the preinstalled Windows SDKs under `Windows Kits` (~3 GB).
OFF by default for the same reason as visual-studio -- a native
msvc link needs these headers and import libraries.
required: false
default: "false"
keep-image:
description: >-
Docker image (repo:tag) to preserve during the docker prune.
Expand Down Expand Up @@ -104,6 +136,42 @@ runs:
[ -e "$p" ] && { echo "removing $p"; rm -rf -- "$p"; } || true
done

- name: Remove hostedtoolcache unused runtimes
if: inputs.hostedtoolcache-unused-runtimes == 'true'
shell: bash --noprofile --norc -euo pipefail {0}
run: |
for p in /c/hostedtoolcache/{Ruby,go,CodeQL}; do
[ -e "$p" ] && { echo "removing $p"; rm -rf -- "$p"; } || true
done

- name: Remove cloud CLIs
if: inputs.cloud-clis == 'true'
shell: bash --noprofile --norc -euo pipefail {0}
run: |
pf="/c/Program Files"
pf86="/c/Program Files (x86)"
paths=("$pf/Microsoft SDKs/Azure" "$pf86/Microsoft SDKs/Azure")
paths+=("$pf/Amazon" "$pf86/AWSCLIV2" "$pf86/Google/Cloud SDK")
for p in "${paths[@]}"; do
[ -e "$p" ] && { echo "removing $p"; rm -rf -- "$p"; } || true
done

- name: Remove Visual Studio
if: inputs.visual-studio == 'true'
shell: bash --noprofile --norc -euo pipefail {0}
run: |
for p in "/c/Program Files/Microsoft Visual Studio" "/c/Program Files (x86)/Microsoft Visual Studio"; do
[ -e "$p" ] && { echo "removing $p"; rm -rf -- "$p"; } || true
done

- name: Remove Windows Kits
if: inputs.windows-kits == 'true'
shell: bash --noprofile --norc -euo pipefail {0}
run: |
for p in "/c/Program Files (x86)/Windows Kits" "/c/Program Files/Windows Kits"; do
[ -e "$p" ] && { echo "removing $p"; rm -rf -- "$p"; } || true
done

- name: Prune docker images and builder cache
shell: bash --noprofile --norc -euo pipefail {0}
env:
Expand Down
17 changes: 0 additions & 17 deletions .github/actions/install-mise-tools/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ inputs:
description: >-
Comma-separated tools to co-install via taiki-e/install-action in the
same step as mise. Forwarded to install-mise's `extra-tools` input.
NOT used for `aube` -- install-action's manifest expects an `aubr`
binary that recent aube releases don't ship, so the install resolves
to a cargo source-build that flakes on crates.io SSL. The aube path
below uses the original `mise run setup-aube` (npm-backed, allowed
to fail) which has been the reliable install method.
required: false
default: ""

Expand All @@ -38,18 +33,6 @@ runs:
with:
install-action-tools: ${{ inputs.install-action-tools }}

# Optional npm backend, installed before the main `mise install`.
# Only useful when js env is loaded (it's the backend for npm:* tools, all of which live in config.js.toml); skip
# otherwise to avoid the install cost on workflows that don't need any npm: install. See [tasks.setup-aube] in
# .mise/config.toml for the full rationale.
- name: Install aube (optional npm backend, allowed to fail)
if: contains(env.MISE_ENV, 'js')
continue-on-error: true
shell: bash --noprofile --norc -euo pipefail {0}
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
run: mise run setup-aube

- name: Install mise tools
id: install-mise-tools
continue-on-error: true
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/install-mise/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ runs:
- name: Install mise
uses: taiki-e/install-action@v2
with:
tool: cargo-binstall,mise@2026.7.1
tool: cargo-binstall,mise@2026.8.0

- name: Install extra tools via install-action
if: inputs.install-action-tools != ''
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ name: dependencies
- "**/Cargo.toml"
- config/deny.toml
- config/osv-scanner.toml
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
- services/ws-server/static/package.json
- .github/workflows/dependencies.yaml
- .github/actions/install-mise/**
workflow_dispatch:
Expand Down Expand Up @@ -46,7 +50,7 @@ jobs:
- name: Install mise + dependency-scan tools
uses: ./.github/actions/install-mise
with:
install-action-tools: cargo-deny,cargo-unmaintained,coreutils,osv-scanner,ripgrep
install-action-tools: cargo-deny,cargo-unmaintained,coreutils,jaq,osv-scanner,ripgrep

- name: Generate config/osv-scanner.toml from config/deny.toml
run: mise run gen:osv-scanner
Expand All @@ -55,7 +59,12 @@ jobs:
run: mise run cargo-deny-check

- name: osv-scanner
run: mise run osv-scanner
run: mise run osv-scanner-check

# Scans the npm-backend tool install trees, which no committed lockfile covers.
# The task installs any missing npm: tool itself, so this job needs no full `mise install`.
- name: osv-scanner npm tools
run: mise run osv-scanner-npm

# Restore cached `cargo unmaintained` lookups to keep reruns fast.
# `cargo unmaintained` persists per-repository archival/last-commit lookups under
Expand Down
29 changes: 27 additions & 2 deletions .github/workflows/docker-linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ env:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 120
# Raised from 120 for the opensuse lane's CARGO_BUILD_JOBS=2 cap (see the cargo-test step).
# Capping concurrent jobs trades wall-clock for peak memory, and opensuse was already the slowest lane at
# 47m51s when green, so the old ceiling left too little margin. The other lanes finish in 39-44m and are
# unaffected; this only stops a slower-but-succeeding build from being cut off.
timeout-minutes: 150
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -146,8 +150,29 @@ jobs:
docker run --rm et-test sh -c "find / -xdev -type f -size +50M -exec du -h {} + | sort -h | tail -50"
echo "::endgroup::"

# Every cargo knob here is passed INTO the container, not set on the job.
# The compile happens inside `docker run`, so a job-level env would never reach cargo.
#
# CARGO_INCREMENTAL=0: incremental caches buy nothing on a single-shot CI compile and cost disk.
#
# CARGO_PROFILE_DEV_DEBUG=0: debug info is the bulk of what the linker reads and writes, so dropping it
# cuts peak linker memory and disk while making the build faster -- unlike a parallelism cap, it costs no
# wall-clock. The trade is shallower backtraces if a test panics on these lanes. Applied to every lane
# because two of them have already died mid-`cargo-test`: amazonlinux once, and opensuse on all three
# attempts of run 30872860977, each time with the log never published and the step frozen `in_progress`
# at ~1h13m against a 120m limit -- the shape of the runner being killed rather than a build error.
#
# CARGO_BUILD_JOBS=2 on opensuse only: it is the slowest lane even when green (47m51s vs 39-44m) and the
# only one still failing, so it links under the most memory pressure. Capping concurrent codegen/link jobs
# is the direct lever, kept off the other lanes because it does cost wall-clock -- which is why
# timeout-minutes went to 150 alongside it.
- name: Run cargo-test
run: docker run --rm et-test mise run cargo-test
env:
LANE_ARGS: ${{ matrix.base == 'opensuse/leap:15.6' && '-e CARGO_BUILD_JOBS=2' || '' }}
run: |
# $LANE_ARGS is a word-split flag list by design; do not quote it.
# shellcheck disable=SC2086
docker run --rm -e CARGO_INCREMENTAL=0 -e CARGO_PROFILE_DEV_DEBUG=0 $LANE_ARGS et-test mise run cargo-test

- name: Run mise check
run: docker run --rm et-check
30 changes: 15 additions & 15 deletions .github/workflows/docker-windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
# The classic Windows builder on windows-2022 can't substitute build-args into the Dockerfile's RUN, and
# mise's prebuilt "latest" zip is stale (2026.3.0, too old for the config). 2026.7.1 is required: the config
# templates use Tera v2 syntax, which mise switched to in 2026.7.1 (older mise fails to parse them).
MISE_VERSION: "2026.7.1"
MISE_VERSION: "2026.8.0"
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -70,10 +70,16 @@ jobs:
sc query docker | grep -q RUNNING || net start docker
docker version

# Opt into the aggressive reclaims: this lane builds entirely inside the container.
# Visual Studio and the Windows Kits are only touched by a NATIVE msvc link, which this workflow never
# does -- it only runs `docker build` and `docker run`. check.yaml and test.yaml share this action and
# leave both off, because test.yaml's `override (msvc)` lane does link natively against them.
- name: Free disk space on Windows runner
uses: ./.github/actions/free-disk-space-windows
with:
keep-image: mcr.microsoft.com/windows/${{ matrix.base }}:${{ matrix.windows_version }}
visual-studio: "true"
windows-kits: "true"

- name: Prepare mise and Github token for the build context
run: |
Expand Down Expand Up @@ -132,31 +138,25 @@ jobs:
docker run --rm "$IMAGE_TAG" cmd /c "mise exec -- rustpython -c \"print('et-rp ok')\""
echo "::endgroup::"

# The build target depends on the base image.
# nanoserver stops at `precompile` (no python/dotnet/test-runtime; the test stage doesn't exist there),
# servercore goes all the way through `test` so the next two steps can `docker run` the suite. Both targets
# compose with the precompile-stage layer cache from the build-minimal step above.
- name: Build stage precompile (nanoserver) / test (servercore)
- name: Build stage test
env:
DOCKERFILE: ${{ steps.dockerfile.outputs.dockerfile }}
run: |
if [ "${{ matrix.base }}" = "servercore" ]; then
target="test"
tag="-t et-windows-test"
else
target="precompile"
tag=""
fi
args="-f $DOCKERFILE --build-arg MISE_ENV"
if [ "${{ matrix.runner }}" != "windows-2022" ]; then
args="$args --build-arg WINDOWS_VERSION=${{ matrix.windows_version }}"
fi
args="$args --target $target $tag"
args="$args --target test -t et-windows-test"
# $args is a word-split flag list by design; do not quote it.
# shellcheck disable=SC2086
docker build $args .

# Run the Rust tests, excluding et-ws-web-runner on the gnullvm target.
# CARGO_INCREMENTAL=0 has to be passed into the container, not just set on the job: this compiles from
# scratch inside `docker run` (Dockerfile.windows's precompile stage deletes `target` after building the
# modules), so the incremental caches land on the runner's C: drive. They are pure waste on a
# single-shot CI compile and this lane has no disk to spare -- servercore ran out mid-link with
# `There is not enough space on the disk. (os error 112)` even after the disk-free step left 43 GB.
- name: Run cargo-test
if: matrix.base == 'servercore'
run: docker run --rm et-windows-test mise run cargo-test
run: docker run --rm -e CARGO_INCREMENTAL=0 et-windows-test mise run cargo-test
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ __pycache__/
.pytest_cache/
.python-version
node_modules/
pnpm-lock.yaml
.venv/
# .NET build output.
# `obj/` is safe globally (nothing tracked is named obj/), but `bin/` is scoped to the module so it never
Expand Down
Loading
Loading