Bump dependencies and increase coverage #235
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: docker-linux | |
| "on": | |
| pull_request: | |
| paths: | |
| - .github/workflows/docker-linux.yaml | |
| - Dockerfile | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: "${{ github.workflow }}-${{ github.ref }}" | |
| cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} | |
| defaults: | |
| run: | |
| shell: bash --noprofile --norc -euo pipefail {0} | |
| env: | |
| MISE_ENV: dart,dotnet,java,js,kotlin,python,r,rust,zig | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| # 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: | |
| base: | |
| - amazonlinux:2023 | |
| - azurelinux v3.0 | |
| - debian:bookworm | |
| - debian:trixie | |
| - fedora:42 | |
| - opensuse/leap:15.6 | |
| - ubuntu:22.04 | |
| - ubuntu:24.04 | |
| - ubuntu:26.04 | |
| name: build (${{ matrix.base }}) | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Show MISE_ENV | |
| run: echo "MISE_ENV=$MISE_ENV" | |
| # Relocate Docker's data dir onto an LVM volume to maximize build space. | |
| # jlumbroso/free-disk-space (which test.yaml uses) only frees space on the existing root partition. This | |
| # workflow needs more: the image build writes to /var/lib/docker, so we have to relocate Docker's data dir | |
| # onto an LVM volume that concatenates the freed root space with /mnt. easimon is the only maintained action | |
| # that does that LVM remount, so we stay on it here despite its rougher edges (hard-fails on runners without | |
| # /mnt or without a Docker daemon -- not a concern for this workflow's ubuntu-latest matrix, which has both). | |
| - name: Maximize build space | |
| uses: easimon/maximize-build-space@v10 | |
| with: | |
| root-reserve-mb: 4096 | |
| swap-size-mb: 1024 | |
| remove-dotnet: "true" | |
| remove-android: "true" | |
| remove-haskell: "true" | |
| remove-codeql: "true" | |
| remove-docker-images: "true" | |
| build-mount-path: /var/lib/docker | |
| build-mount-path-ownership: "root:root" | |
| - name: Restart Docker on the maximized volume | |
| run: sudo systemctl restart docker | |
| - name: Resolve BASE_IMAGE | |
| env: | |
| MATRIX_BASE: ${{ matrix.base }} | |
| run: | | |
| if [ "$MATRIX_BASE" = "azurelinux v3.0" ]; then | |
| echo "BASE_IMAGE=mcr.microsoft.com/azurelinux/base/core:3.0" >> "$GITHUB_ENV" | |
| else | |
| echo "BASE_IMAGE=$MATRIX_BASE" >> "$GITHUB_ENV" | |
| fi | |
| - name: Build stage test | |
| env: | |
| DOCKER_BUILDKIT: "1" | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| args="--target test --build-arg BASE_IMAGE --build-arg MISE_ENV" | |
| args="$args --secret id=gh_token,env=GITHUB_TOKEN -t et-test" | |
| # $args is a word-split flag list by design; do not quote it. | |
| # shellcheck disable=SC2086 | |
| docker build $args . | |
| # The check stage needs `.git/` + every tracked Dockerfile. | |
| # The main `.dockerignore` excludes both (`**/Dockerfile*` so Dockerfiles in subdirs don't bloat the build | |
| # context), so we pre-stage them into a directory and hand it to docker as a named build context (`extras`). | |
| # The check stage does `COPY --from=extras . ./` to land them in /workspace. `cp --parents` preserves the | |
| # subdir path of each Dockerfile (e.g. services/ws-server/Dockerfile), so hadolint's | |
| # `git ls-files '*Dockerfile' '*Dockerfile.*' | xargs hadolint` finds every entry on disk -- a top-level cp | |
| # would have left subdir Dockerfiles unfindable. | |
| - name: Build stage check | |
| env: | |
| CTX: target/check-ctx | |
| DOCKER_BUILDKIT: "1" | |
| TAG: et-check | |
| gh_token: ${{ github.token }} | |
| run: | | |
| mkdir -p "$CTX" | |
| cp -r .git "$CTX/" | |
| git ls-files '*Dockerfile' '*Dockerfile.*' | xargs -I{} cp --parents {} "$CTX/" | |
| args="--target check --build-arg BASE_IMAGE --build-arg MISE_ENV" | |
| args="$args --build-context extras=$CTX --secret id=gh_token -t $TAG" | |
| # $args is a word-split flag list by design; do not quote it. | |
| # shellcheck disable=SC2086 | |
| docker build $args . | |
| # Capture image + intermediate stage sizes after the builds. | |
| # This also runs after the test/check runs leave any -rm'd container layers behind. `always()` so we still | |
| # get the breakdown when a downstream step ran the disk dry; the typical failure mode (test-ws-web-runner | |
| # compile inside `docker run`) leaves the host's image catalogue intact and this step is what surfaces | |
| # which layer ballooned. -a includes intermediate/dangling layers each stage produces; `system df -v` | |
| # totals per cache type (Images, Build Cache, Containers, Volumes). | |
| - name: Docker disk usage (debug) | |
| if: always() | |
| run: | | |
| echo "::group::docker images -a" | |
| docker images -a | |
| echo "::endgroup::" | |
| echo "::group::docker system df -v" | |
| docker system df -v | |
| echo "::endgroup::" | |
| echo "::group::df -h /var/lib/docker" | |
| df -h /var/lib/docker || true | |
| echo "::endgroup::" | |
| # Report which paths inside the et-test image are eating space. | |
| # `du --threshold=10M --max-depth=2` for a top-level subtree map (catches install dirs, tool caches, | |
| # /var stragglers); `find ... -size +50M` for the individual heavyweights. Run in a throwaway container | |
| # so the host's writable layer doesn't tilt the numbers; find/du stderr noise (unreadable /proc entries | |
| # etc.) prints to the log but doesn't affect the sort pipeline. | |
| # | |
| # Both runs are gated on the tag existing locally: this step is `always()`, and when the build died | |
| # before tagging, a bare `docker run et-test` falls through to pulling `et-test:latest` from Docker | |
| # Hub -- failing this debug step with the misleading | |
| # | |
| # docker: Error response from daemon: pull access denied for et-test, repository does not exist | |
| # or may require 'docker login': denied: requested access to the resource is denied | |
| # | |
| # on top of the real build error (observed on commit | |
| # https://github.com/edge-toolkit/core/commit/5c08a759202d166ac9fac48f5e54ec998d5fcb6e at | |
| # https://github.com/edge-toolkit/core/actions/runs/31659062139/job/94319942583), and handing | |
| # execution to whoever squats that name on Docker Hub if the pull ever resolved. `--pull=never` | |
| # keeps the registry unreachable even if the gate is edited away. | |
| if docker image inspect et-test >/dev/null 2>&1; then | |
| echo "::group::et-test: largest dirs (depth 2, >=10M)" | |
| du_cmd="du -h --threshold=10M --max-depth=2 / | sort -h | tail -50" | |
| docker run --rm --pull=never et-test sh -c "$du_cmd" | |
| echo "::endgroup::" | |
| echo "::group::et-test: individual files >50M" | |
| find_cmd="find / -xdev -type f -size +50M -exec du -h {} + | sort -h | tail -50" | |
| docker run --rm --pull=never et-test sh -c "$find_cmd" | |
| echo "::endgroup::" | |
| else | |
| echo "et-test image not present (build failed before tagging); skipping in-image size report" | |
| fi | |
| # 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 | |
| env: | |
| LANE_ARGS: ${{ matrix.base == 'opensuse/leap:15.6' && '-e CARGO_BUILD_JOBS=2' || '' }} | |
| run: | | |
| args="--rm --pull=never -e CARGO_INCREMENTAL=0 -e CARGO_PROFILE_DEV_DEBUG=0 $LANE_ARGS" | |
| # $args is a word-split flag list by design; do not quote it. | |
| # shellcheck disable=SC2086 | |
| docker run $args et-test mise run cargo-test | |
| - name: Run mise check | |
| run: docker run --rm --pull=never et-check |