runs-on picks a runner by label. GitHub-hosted labels name images that actions/runner-images (https://github.com/actions/runner-images 13,390 ) rebuilds about weekly; each job log names the version, such as ubuntu24/20260920.314.1. For public repositories, ubuntu-24.04, ubuntu-26.04 and their -arm variants have 4 CPUs and 16 GB, ubuntu-slim 1 CPU and 5 GB, macos-15 and macos-26 3 M1 cores and 7 GB.
The -latest labels move: ubuntu-latest, Ubuntu 24.04 225 today, switches to 26.04 (generally available since 17 September 2026) in stages between 19 October and 19 November 2026. The output of 3.9.6 shows the effect: the 26.04 image ships Node.js v24.21.0 2,131 , the 24.04 image v22.23.2, so a job using the preinstalled node would change major version without a commit. So BookNest pins the image with runs-on: ubuntu-24.04 and installs Node.js itself (Matrices and Caching, from .nvmrc); runs-on: [self-hosted, linux] would instead pick one of your own runners (Self-Hosted and Pricing).
To try a new image, dispatch the context job with -f runner=ubuntu-26.04, compare, then change the label in a pull request. Prefer Linux, the fastest and cheapest (Scheduling and Billing); Windows and macOS are for platform-specific code, which BookNest lacks.