A workflow still pinned to macos-14 can lose its runner image before the next release is ready.
GitHub announced retirement for November 2, 2026. Start a parallel migration now, test a supported replacement against the real project, and switch only after build, test, signing, and release checks pass. If the project needs a persistent, tightly controlled Mac host, assess remote Mac CI separately.
Who this is for: Developers whose iOS or macOS workflows still specify a macOS 14 runner label and need to check toolchain compatibility before changing production.
CI engineers can use the steps below to compare dependencies, caches, test results, and deliverables without confusing an environment change with a code regression.
Platform owners can use the decision conditions to determine whether hosted runners still meet their operational needs.
Last updated October 7, 2026. Retirement details were checked against GitHub’s announcement; confirm its current status before publishing or scheduling a production cutover.
Stage the response around the retirement notice
GitHub’s announcement says the macOS 14 hosted runner image is scheduled to retire on November 2, 2026. The affected labels are macos-14, macos-14-large, and macos-14-xlarge. The announcement also describes brownout arrangements and recommended replacement labels; check its current text for those schedules and labels rather than relying on a copied calendar entry.
A runner label is a workflow selector, not a full environment lock. A label points to an available hosted image, whose installed software and system details need their own verification. Xcode and SDK availability can differ from the project’s deployment target, and none of those facts alone tells you whether the workflow’s scripts or dependencies will work.
Start with repository search, not a broad replacement:
- [ ] Search workflow files for all three affected labels, including reusable workflows and matrix values.
- [ ] Identify the branches and events that can run each matching workflow: pull requests, pushes, scheduled jobs, manual dispatches, or release triggers.
- [ ] Record which jobs build, test, sign, archive, publish, or perform maintenance. Note any downstream job that consumes their artifacts.
- [ ] Check for labels assembled from variables or workflow inputs; a simple text search may not reveal those selectors.
- [ ] Compare the list with the retirement notice’s current brownout schedule and recommended labels.
The GitHub Actions workflow syntax reference explains how runs-on can be specified. Review the evaluated workflow configuration as well as the YAML source, especially if a reusable workflow or expression determines the runner.
This scope review prevents a common gap: migrating the main build job while leaving a release or scheduled workflow pinned to the retiring image.
Capture a baseline before changing the environment
A useful comparison starts with an unchanged project revision and a record of the environment it currently uses. Without that baseline, a failure after changing the runner could come from code, dependency resolution, a cache hit, or a toolchain difference.
Record the following from a known-good run:
- The commit, branch, and workflow revision.
- The runner label and the macOS, architecture, Xcode, and SDK details shown in the job logs.
- The dependency installation and resolution method, including lockfiles and any scripts that download tools.
- Build configuration, destination, scheme, signing settings, and relevant environment variables. Do not copy secrets into a general-purpose log.
- The test targets and the way the workflow reports failures.
- The archive, package, or other release artifact checks used by the project.
- Cache keys, restore behavior, and the steps that run after a cache miss.
Use the official Runner Images repository to locate the current image documentation. Check the relevant macOS 15 image manifest or macOS 26 image manifest for the candidate image’s published system and software inventory. These manifests are the right place to verify installed tools; don’t infer an Xcode version from the runner label.
Save representative logs and test output with the baseline. Then compare candidate runs at the same commit. Treat any performance comparison as project-specific evidence: do not assume the newer image is faster or slower without measuring your own workload.
Isolate the candidate runner for a controlled trial
Do not replace the production label as the first test. Add a candidate job on a migration branch, or run a parallel job with the same checkout, inputs, and build commands. Keep the existing production job available until the candidate has met its acceptance criteria.
Choose candidate labels from GitHub’s current retirement announcement. The label names may suggest a macOS generation, but the label itself does not pin every installed tool. Check the corresponding image manifest for the actual system, architecture, and software inventory. GitHub’s hosted runner documentation is also relevant when reviewing the available runner types and their operating model.
Make the candidate job comparable:
- Use the same commit and workflow inputs as the baseline.
- Keep build settings and test destinations unchanged at first.
- Emit the environment details into the job log, so later runs can be compared.
- Give the trial its own cache key if an existing cache could conceal dependency or build-state differences.
- Do not combine the runner migration with unrelated Xcode, dependency, or project configuration upgrades.
If the project needs to compare more than one announced replacement, test each candidate as a separate condition. That makes failures easier to attribute and prevents a changed runner, Xcode selection, and cache state from becoming one ambiguous change.
Diagnose differences one cause at a time
A red candidate job is evidence to investigate, not a reason to pin the project to an old environment or clear every cache. First identify the failing step and compare its inputs with the baseline.
Use the failure location to choose the next check:
- System tool or SDK mismatch: Compare the installed tools against the official image manifest, then confirm which tool the workflow actually selects. A machine can have a tool installed without the project using it.
- Dependency resolution: Check lockfiles, package sources, and install scripts. Confirm that the candidate run resolved the expected dependency versions before changing constraints.
- Cache behavior: Run a controlled cache-miss trial if logs point to stale or incomplete state. GitHub’s dependency caching documentation describes cache keys and restore behavior; use that guidance to make the test deliberate rather than deleting all caches reflexively.
- Architecture-sensitive steps: Inspect shell scripts, downloaded binaries, and conditional logic that assumes a particular architecture. Confirm the candidate image’s architecture from its manifest before modifying those assumptions.
- Historical macOS 14 checks: Search for explicit version comparisons, filesystem paths, or tool-selection logic. Keep a macOS 14 condition only if a real project requirement depends on it.
Repair one confirmed cause at a time and rerun the same candidate job. If several variables must change, capture each change in the commit or job output. That preserves a useful trail and makes rollback more precise.
Validate the project’s full delivery path
A successful compile does not establish that a release workflow is ready. The migration is complete only when the project’s required build, tests, archive, signing, and delivery checks have passed on the candidate runner.
Use a project-specific acceptance list:
- [ ] The required scheme and configuration build from a clean checkout.
- [ ] The tests that gate the project’s release pass, and failures remain visible to the workflow.
- [ ] Archive or package generation completes using the same intended release settings.
- [ ] Signing steps use the expected identities, profiles, and secret-handling process.
- [ ] The resulting artifact passes the project’s own inspection or downstream validation.
- [ ] Any publishing or handoff job receives the expected artifact and records its outcome.
- [ ] A responsible maintainer has reviewed the logs and approved the candidate for production.
Record build success separately from release-path success. For example, a build may pass while archive export, signing, or artifact delivery fails. Keeping those results distinct prevents a green compile from being mistaken for a complete migration.
A hosted runner may not meet a project’s hardware or session requirements. If a test needs a physical device, a persistent graphical session, or another resource not provided by the hosted job, document that boundary and plan a separate test path. Do not assume that changing the runner label supplies hardware or interactive access.
Cut over only with an explicit rollback condition
When the candidate meets the acceptance list and its owner approves the evidence, change the production workflow to the selected supported label. Keep the patch small: avoid combining the cutover with unrelated dependency changes, Xcode upgrades, or workflow refactoring. Remove obsolete macOS 14 selectors only after confirming that no active workflow still relies on them.
Before the change, define what triggers a pause or rollback. Examples include a required test failing only on the candidate, a signing or archive step producing an invalid deliverable, or a downstream release job receiving the wrong artifact. Set the response according to the project’s release controls: disable the affected rollout, restore the previous workflow configuration where still available, or hold the release while the cause is investigated. Do not assume the retiring image will remain available as a dependable rollback target.
Use these decision conditions to choose the operating model after migration:
- If the project runs reliably on GitHub’s currently supported hosted images and does not need persistent machine state or host-level control, keep the hosted runner and maintain the image checks in the workflow review process.
- If the project needs a specific environment detail that is available in a different supported hosted image, test that label in isolation and document the dependency before switching.
- If the workflow needs a long-lived Mac host, continuous access, or more direct control over the machine, evaluate remote Mac CI and include host maintenance, access control, and recovery ownership in that evaluation.
- If the project has neither a persistent-host requirement nor a demonstrated hosted-runner limitation, do not move to a remote Mac solely because macOS 14 is retiring.
A remote Mac is not automatically a better replacement. Hosted runners avoid having the team operate a persistent machine, while a remote Mac can be useful when the project genuinely needs a controlled, continuously available host. If that is the case, review RUVCLOUD’s Mac rental options as part of a broader environment comparison, not as a substitute for testing the workflow.
Migration FAQ
When does the macOS 14 runner retire?
GitHub’s published notice schedules retirement for November 2, 2026, and lists macos-14, macos-14-large, and macos-14-xlarge as affected labels. The notice also contains the transition’s brownout details and recommended labels. Recheck that source before the production cutover because the published schedule or available-image information may change.
How can a workflow migration be tested before retirement?
Run a candidate label in a separate branch or parallel job while leaving the existing production workflow unchanged. Use the same project revision and compare toolchain details, dependency resolution, tests, archive and signing steps, and artifact checks. Switch only after the required release path passes and its maintainer accepts the evidence.
What changes should be checked when moving to macOS 15 or macOS 26?
Check the runner label and image manifest separately from the selected Xcode and SDK, project deployment target, and workflow configuration. Then test dependencies, caches, scripts with architecture assumptions, tests, signing, archives, and delivery. A label alone does not prove that every tool or project requirement matches the previous environment.
When is a remote Mac more appropriate than a hosted runner?
A remote Mac is worth evaluating when the workflow needs a persistent environment, ongoing host access, or machine-level control that the team cannot get from its hosted runner setup. If the project works on supported hosted images and does not require those capabilities, migration to another hosted label is usually the simpler operational path.
The safe migration decision is based on project evidence, not the runner name: preserve a comparable baseline, prove the delivery path on a supported image, and retain a rollback condition until the production change is accepted.
If hosted images cannot provide the persistent environment or control the project actually needs, compare the team’s current CI approach—which may depend on image changes, limited host access, or non-persistent state—with a remote Mac before committing to a new operating model. RUVCLOUD provides remote access to a hosted Mac; review the available rental plans and assess fit against the project’s actual build, test, and maintenance requirements.