DEV Community

daniel jeong
daniel jeong

Posted on • Originally published at manoit.co.kr

GitHub Actions May 2026 Triple Migration: Arm64 Self-Managed, windows-latest VS2026, macos-latest macOS 26, and the ghs_ Stateless JWT Token Format

GitHub Actions May 2026 Triple Migration Deep Dive — Arm64 GitHub Self-Managed, windows-latest VS2026, macos-latest macOS 26, and the ghs_ Stateless Token Format Redefining the 2026 CI/CD Standard

On May 14 and 15, 2026, the GitHub Actions team published two changelogs in the same week that simultaneously redefine hosted runner infrastructure and the token issuance system. The first is the triple image migration — (1) Ubuntu Arm64 and Windows 11 Arm images transition from Arm Limited to GitHub-managed pipelines, (2) windows-latest and windows-2025 labels are force-migrated to Visual Studio 2026 between June 8–15, and (3) macos-latest moves to macOS 26 over 30 days starting June 15. The second is the conversion of ghs_-prefixed GitHub App installation tokens from a 40-character opaque string into a ~520-character JWT (ghs_APPID_JWT) stateless format, with the new X-GitHub-Stateless-S2S-Token header providing per-request opt-in/opt-out for validation.

The two changes arriving in the same week are not a coincidence — they are the inflection point of GitHub's Q1 roadmap for "in-house Actions infrastructure ownership + S2S token performance and reliability." The operational cost lands on both our workflow YAML and our GitHub App code at the same time. This article weaves together the two May changelogs, the April 24 advance notice (stateless tokens), the April 27 – mid-May initial rollout, and the May 13 Enterprise Installation API public preview to break down what we must verify before the June 8 D-day, dissected at the PR, YAML, and HTTP header levels — accompanied by ManoIT's internal 18-workflow + 4-GitHub-App migration checklist and regression matrix across 8 axes.

1. Why May 14–15, 2026 Is the Inflection Point for GitHub Actions

Since the GA in 2019, GitHub Actions has partially outsourced hosted runner image operations to external partners. Linux x64, Windows, and macOS x64 were built, signed, and distributed by GitHub directly, but Arm64 family images were built and verified by Arm Limited, LLC, with GitHub handling only labeling and operations. This split structure made sense early in Arm64 adoption, but accumulated reports from late 2025 — CVE patch timing gaps, tool version drift, issue tracking split between actions/partner-runner-images and actions/runner-images — accelerated GitHub's pivot to self-management. The May 14 announcement is that inflection point.

Date Event Operational Meaning
2024.06 Linux Arm64 hosted runner public preview Arm Limited partnership, separate label (ubuntu-22.04-arm)
2025.01 Linux Arm64 GA, actions/partner-runner-images published External image build recipes visible
2025.10 Windows 11 Arm hosted runner windows-11-arm label, native .NET/MSBuild builds
2026.03.26 Custom images for GitHub-hosted runners GA Organization-wide base image standardization
2026.04.02 GitHub Actions Early April 2026 updates Service Container Overrides, OIDC Repository claim
2026.04.20 SHA-1 sunsetting in HTTPS Legacy client compatibility end
2026.04.24 ghs_ stateless token format advance notice 40 → ~520 chars, staged rollout starting April 27
2026.04.27 Stateless token first rollout begins GITHUB_TOKEN + first-party integrations (Dependabot, Slack, Teams)
2026.05.13 Enterprise Installation API public preview New endpoints for enterprise-level App install/lookup
2026.05.14 Triple image migration announcement — Arm64 self-managed, Windows VS2026, macOS 26 Runner image operations structure and label semantics both change
2026.05.15 X-GitHub-Stateless-S2S-Token header introduced Per-request forced opt-in/opt-out for pre-validation
2026.06.08 windows-latest VS2026 rollout begins Gradual over 1 week, completing June 15
2026.06.15 macos-latest macOS 26 rollout begins Gradual over 30 days
Late 2026 Stateless token broad enablement + brownout X-GitHub-Stateless-S2S-Token header deprecation expected

From an operational standpoint, three lines matter most: (1) windows-latest auto-converts to VS2026 starting June 8, (2) macos-latest converts to macOS 26 starting June 15, (3) GitHub App installation tokens arrive as ~520-character JWTs starting mid-May. The first two mean your build environment changes even with unchanged workflow YAML, and the third means your code breaks if it validates tokens by regex or if your DB column length is too short. This is not a gentle progressive upgrade — it is a forced schedule where unvalidated workflows can break starting June 8.

2. Arm64 Runner Image Self-Management Transition — What Changes and What Doesn't

The first item in the May 14 announcement is the transfer of operational ownership for Arm64 images. GitHub says no user action is required ("No action is required from users as part of this transition"), but knowing the structural change keeps future CVE responses and image change tracking smooth.

2.1 What Changes vs. What Doesn't

Axis Before (Arm Limited) After (GitHub Self-Managed)
Windows 11 Arm External build → GitHub labeling GitHub-managed builds + pipelines (complete)
Ubuntu 24.04 Arm actions/partner-runner-images GitHub internal pipelines (in progress)
Ubuntu 22.04 Arm Same Same
Issue tracking partner-runner-images + runner-images (two repos) Consolidated into actions/runner-images
partner-runner-images repo Active Archived after transition completes
Image functionality/compatibility No change
Package add/remove No change
Breaking changes None
Updates during transition Regular updates Ubuntu Arm images paused, no release notes published

The most noteworthy line is the last row — during the transition, Ubuntu Arm64 images won't receive new releases, and no new release notes will appear in actions/runner-images. Teams that pipe release notes to a CI watch channel should document "silence is normal" in their operations manual to avoid false alarms. However, GitHub explicitly says CVEs or vulnerabilities discovered during the transition should be reported as issues in actions/runner-images as a workaround.

2.2 ManoIT's Arm64 Footprint and Regression Checks

ManoIT uses ubuntu-24.04-arm or windows-11-arm in 4 of our 18 workflows. (1) Multi-arch Rust backend builds, (2) iOS simulator compatibility pre-ABI verification, (3) Bun 1.3 back-office ARM Linux container builds, (4) .NET MAUI side-channel verification. The transition itself is zero-downtime, but we made one operational change — migrated release notes RSS subscriptions from partner-runner-images to runner-images and auto-closed partner-side issues in our tracking system. Even trusting GitHub's "the image is the same" guarantee, diverting heavy Arm64 jobs to a fallback queue (self-hosted Graviton) during the first transition week is the safe play.

3. Auto-Migration of windows-latest to Visual Studio 2026

The second migration has the broadest impact. windows-latest and windows-2025 gradually convert to Visual Studio 2026 as default between June 8–15 over one week. Only workflows that explicitly use windows-2022 are unaffected. A temporary validation label windows-2025-vs2026 is provided, and after migration completes, it will point to the same image as windows-2025.

3.1 Label Semantics Matrix

runs-on Label Current (2026.05) June 8–15 Rollout After June 15
windows-latest Windows Server 2025 + VS 2022 Gradually transitions to VS 2026 Windows Server 2025 + VS 2026
windows-2025 Windows Server 2025 + VS 2022 Gradually transitions to VS 2026 Windows Server 2025 + VS 2026
windows-2025-vs2026 Windows Server 2025 + VS 2026 (test) No change Points to windows-2025 image (i.e., VS 2026)
windows-2022 Windows Server 2022 + VS 2022 No change Windows Server 2022 + VS 2022 (preserved)

3.2 Pre-Validation YAML — Opt In with windows-2025-vs2026

# .github/workflows/windows-vs2026-precheck.yml
# Pre-validate VS 2026 compatibility before the June 8 D-day
name: Windows VS2026 Precheck

on:
  workflow_dispatch:
  schedule:
    - cron: '0 18 * * 1-5'  # Weekday KST 03:00 regression run

jobs:
  build-vs2026:
    runs-on: windows-2025-vs2026  # ← test-only label
    steps:
      - uses: actions/checkout@v5
      - name: Inspect VS toolchain
        shell: pwsh
        run: |
          $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
          & $vswhere -latest -property installationVersion
          & $vswhere -latest -property productLineVersion
      - name: MSBuild detection
        shell: pwsh
        run: |
          $msbuild = (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
            -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe) | Select-Object -First 1
          & $msbuild -version
      - name: Build (VS2026 MSBuild)
        shell: pwsh
        run: msbuild .\src\App.sln /p:Configuration=Release /m
      - name: Unit tests
        shell: pwsh
        run: dotnet test --no-build --logger "trx;LogFileName=test.trx"

  build-vs2022-baseline:
    # Regression comparison — windows-2022 remains after June 15
    runs-on: windows-2022
    steps:
      - uses: actions/checkout@v5
      - name: Build (VS2022 MSBuild)
        shell: pwsh
        run: msbuild .\src\App.sln /p:Configuration=Release /m
Enter fullscreen mode Exit fullscreen mode

The operational value of this YAML is twofold. (1) You can compare actual build/test results in a VS 2026 environment before June 8, and (2) running it alongside a windows-2022 job catches subtle build differences as MSBuild 16 transitions to MSBuild 18 (C++/CLI handling, .NET 9 → 10 default, /std:c++latest semantics shift). When differences appear, you can temporarily pin to windows-2022 and defer the full migration to July.

3.3 Patterns That Commonly Break — 7 Things to Check in the VS2022 → VS2026 Transition

Area VS 2022 Assumption Change in VS 2026 Mitigation
MSBuild path Fixed MSBuild\Current\Bin\amd64 Path partially changed, use vswhere vswhere -find MSBuild\**\Bin\MSBuild.exe
MSVC toolset v143 (VS2022) v144 (VS2026) default Pin with PlatformToolset=v143
.NET SDK 9.x default 10.x default Pin SDK version in global.json
C++ /std /std:c++20 default /std:c++latest means c++23 Revisit warning-suppression policy, audit deprecation flags
UWP / WinUI Some UWP templates exist Further UWP deprecation, WinUI 3 recommended Plan WinUI 3 migration
Workload names --add Microsoft.VisualStudio.Workload.NativeDesktop Some component IDs renamed Re-verify workload install scripts
VC++ Redistributable 14.40.x 14.50.x Refresh installer bundles

Of the seven above, ManoIT's most painful hits in production were (3) the .NET SDK major version jump and (4) the promotion of /std:c++latest to c++23. The former caused nullable warnings to explode in legacy solutions that lacked an explicit global.json SDK pin; the latter failed builds on STL APIs deprecated under c++23 (e.g., std::wstring_convert). Both fix with a single build option line.

4. Migration of macos-latest to macOS 26

The third migration is macos-latest gradually moving from macOS 15 (Sequoia) to macOS 26 over 30 days starting June 15. iOS/macOS build workflows are heavily impacted. Only workflows that explicitly use macos-15 are unaffected.

4.1 Label Semantics Matrix

runs-on Label Current (2026.05) June 15 – July 15 Rollout After Transition
macos-latest macOS 15 (Sequoia) Gradually transitions to macOS 26 macOS 26
macos-15 macOS 15 No change macOS 15 (preserved)
macos-26 macOS 26 No change macOS 26
macos-14 macOS 14 (Sonoma) No change EOL schedule announced separately

4.2 Things to Check in iOS/macOS Builds

Area macOS 15 Environment Change in macOS 26 Mitigation
Default Xcode Xcode 16.x Xcode 26.x default Pin via sudo xcode-select -s /Applications/Xcode_16.app
Swift version Swift 6.0/6.1 Swift 6.2 default Check SwiftPM swift-tools-version
iOS Simulator iOS 18.x default iOS 26.x default, iOS 17 sim may not be pre-installed Install explicitly via xcrun simctl runtime add
SwiftPM cache ~/Library/Caches/org.swift.swiftpm Path same, build artifacts invalid Include ${{ runner.os }}-${{ env.IMAGE_VERSION }} in cache key
Homebrew prefix /opt/homebrew No change (Apple Silicon)
Ruby/CocoaPods Ruby 3.x + CocoaPods 1.16 Ruby 3.x + CocoaPods 1.17 Verify Gemfile.lock
Fastlane plugins Apple Notarization API may change Regression-test fastlane match/gym

4.3 macOS Migration Regression YAML

# .github/workflows/macos-26-precheck.yml
# Catch regressions with a matrix across macos-latest and macos-15
name: macOS 26 Precheck

on:
  workflow_dispatch:
  pull_request:
    paths:
      - 'ios/**'
      - 'Package.swift'
      - 'Package.resolved'

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        runner: [macos-15, macos-26]
    runs-on: ${{ matrix.runner }}
    steps:
      - uses: actions/checkout@v5
      - name: Select Xcode
        run: |
          xcodebuild -version
          sudo xcode-select -p
      - name: SwiftPM resolve
        run: swift package resolve
      - name: Build iOS app
        run: |
          set -euo pipefail
          xcodebuild \
            -workspace ios/App.xcworkspace \
            -scheme App \
            -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' \
            -configuration Debug \
            build
      - name: Run unit tests
        run: |
          xcodebuild \
            -workspace ios/App.xcworkspace \
            -scheme AppTests \
            -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' \
            test
Enter fullscreen mode Exit fullscreen mode

5. ghs_ Installation Token Migration to Stateless JWT Format

The second major change arriving in the same week as the image migrations is the format change for GitHub App installation tokens. The sequence was: April 24 advance notice, April 27 first rollout, May 15 introduction of the validation header. All installation tokens are expected to be issued in the new format by late June at the latest.

5.1 Format Comparison — What Changes and How

Axis Old (stateful, classic) New (stateless)
Prefix ghs_ ghs_ (preserved)
Overall structure ghs_ + 36 alphanumeric = ~40-char opaque string ghs_APPID_JWT = ~520-char JWT (with two dots)
Dots (.) None Two (JWT header.payload.signature structure)
Validation method Stateful GitHub server lookup Signed JWT from GitHub-internal issuer, client treats as opaque
Performance DB roundtrip on issuance Improved issuance under load, better API reliability
Scope GitHub Enterprise Cloud, Data Residency. GitHub Enterprise Server unaffected
Existing tokens Valid until expiry (new format from re-issuance)
Applies to S2S (server-to-server) tokens + Actions GITHUB_TOKEN. user-to-server announced separately

5.2 Pre-Validation with X-GitHub-Stateless-S2S-Token Header

The temporary header introduced on May 15 overrides the server-side rollout decision for a single POST /app/installations/:installation_id/access_tokens request. Values and behavior:

Header Value Effect
enabled Forces issuance of stateless (JWT) token regardless of rollout state
disabled Forces issuance of stateful (opaque) token even when rollout has reached you
(header absent) Standard rollout policy applies
Other values (true, 1, false, 0, etc.) Silently ignored, standard rollout policy

Operational uses are twofold — (1) Use enabled to pre-validate the new format before rollout reaches your app, (2) Use disabled to temporarily fall back if rollout reaches you before you're ready. But remember the header is temporary and GitHub plans to deprecate it via a separate announcement.

5.3 Pre-Validation cURL — Force-Issue Both Formats for the Same GitHub App

#!/usr/bin/env bash
# scripts/precheck-stateless-token.sh
# Issue stateful and stateless tokens for the same installation and compare length / dot count

set -euo pipefail

APP_ID="${APP_ID:?GitHub App ID required}"
INSTALLATION_ID="${INSTALLATION_ID:?Installation ID required}"
PRIVATE_KEY_PATH="${PRIVATE_KEY_PATH:?PEM path required}"

# 1) Create App JWT (10-minute validity)
JWT=$(python3 - <<PY
import jwt, time
payload = {"iat": int(time.time())-60, "exp": int(time.time())+600, "iss": "${APP_ID}"}
with open("${PRIVATE_KEY_PATH}") as f: key = f.read()
print(jwt.encode(payload, key, algorithm="RS256"))
PY
)

issue_token() {
  local mode="$1"  # enabled | disabled | none
  local headers=(-H "Authorization: Bearer ${JWT}" -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28")
  if [[ "${mode}" != "none" ]]; then
    headers+=(-H "X-GitHub-Stateless-S2S-Token: ${mode}")
  fi
  curl -sS -X POST "${headers[@]}" \
    "https://api.github.com/app/installations/${INSTALLATION_ID}/access_tokens" \
    | python3 -c 'import sys,json; print(json.load(sys.stdin)["token"])'
}

STATEFUL=$(issue_token disabled)
STATELESS=$(issue_token enabled)

format_check() {
  local label="$1" token="$2"
  local len=${#token}
  local dots=$(printf '%s' "$token" | tr -cd '.' | wc -c | tr -d ' ')
  printf 'mode=%-9s len=%-4d dots=%-1d prefix=%s\n' "$label" "$len" "$dots" "${token:0:8}"
}

format_check stateful  "$STATEFUL"
format_check stateless "$STATELESS"

# Expected:
# mode=stateful  len=40   dots=0 prefix=ghs_XXXX
# mode=stateless len=~520 dots=2 prefix=ghs_XXXX
Enter fullscreen mode Exit fullscreen mode

5.4 Code Compatibility Checks — Regex, Length Assumptions, DB Schema

GitHub recommends checking four items: regex, length assumptions, DB column size, and token introspection.

Check Area Old Assumption New Recommendation
Regex ghs_[A-Za-z0-9]{36} ghs_[A-Za-z0-9\._]{36,} (dots, underscores, variable length)
Length assumption Fixed 40 Variable (≥520 chars allowed)
DB column VARCHAR(40) or VARCHAR(64) At least 520 charsVARCHAR(1024) recommended
Token introspection Check prefix, call GitHub API Same, treat as opaque, never trust JWT contents
HTTP header limits Some proxies hit 8KB header limit — audit
Logging filters Tokens in logs grow payload — re-check masking policy

The last two rows actually bit us in ManoIT's regression tests. (1) An internal reverse proxy had large_client_header_buffers configured at 4KB × 4, causing sidecars that pass the JWT in a header to return 400 Bad Request; (2) A Loki indexing pipeline that masked tokens via regex had a 36-char length assumption baked in, so the tail of the ~520-char token leaked into the index. Both are infrastructure-side fixes — meaning you must audit the entire network path the token traverses, not just your GitHub App.

6. Integrated Calendar — What to Do Before the June 8 D-day

Bundling the two changelogs with the April notice yields a 4-stage calendar at D-30, D-14, D-7, and D-0. This is the standard schedule ManoIT distributed internally.

Date Action Deliverable
D-30 (May 19) Identify windows-latest, windows-2025, macos-latest usage in workflow inventory List of affected workflows
D-30 Grep ghs_[A-Za-z0-9]{36} regex, length-40 assumption, DB column size in GitHub App codebase List of affected code lines
D-21 (May 26) Add regression build matrix with windows-2025-vs2026 label VS 2026 build success rate report
D-21 Pre-validation cron with X-GitHub-Stateless-S2S-Token: enabled Stateless-token compatibility report
D-14 (June 1) Pin only workflows with regressions to windows-2022 temporarily Isolate roll-back-safe workflows
D-14 DB migration to expand token columns to VARCHAR(1024) Schema-change PR
D-7 (June 8) windows-latest VS 2026 rollout begins — monitor build success rate live Dashboard (Actions API → Prometheus)
D-7 If issues appear, immediately downgrade affected workflows to windows-2022 Hotfix PR template
D+7 (June 15) windows-latest transition done + macos-latest macOS 26 rollout begins iOS build matrix regression
D+30 (July 8) macos-latest transition done + stateless tokens broadly applied Remove X-GitHub-Stateless-S2S-Token headers PR
D+60 Gradually retire legacy label usage (windows-2022, macos-15) Standard-label unification PR

6.1 Inventory Grep — Five Minutes to See the Blast Radius

# 1) Workflow inventory
find .github/workflows -name '*.yml' -o -name '*.yaml' \
  | xargs grep -nE 'runs-on:.*(windows-latest|windows-2025|macos-latest)' \
  | tee inventory-impacted-workflows.txt

# 2) GitHub App regex / length assumptions
rg -n --type-add 'all:*.{ts,js,py,rb,go,java,cs,php,rs}' \
  -e 'ghs_\[A-Za-z0-9\]\{36\}' \
  -e '\.length\s*===?\s*40' \
  -e 'VARCHAR\s*\(\s*(40|64|128)\s*\)' \
  -e '/ghs_[A-Za-z0-9_]{36}/' \
  -tall

# 3) Header size limits (NGINX example)
rg -n 'large_client_header_buffers|client_header_buffer_size' /etc/nginx/

# 4) Logging masking patterns (Loki example)
rg -n 'ghs_\[A-Za-z0-9\]\{36\}' deploy/loki/
Enter fullscreen mode Exit fullscreen mode

7. Regression Matrix — What to Validate and How

The calendar is meaningless without an explicit regression matrix. ManoIT's matrix has three dimensions: build environment (image) × workload × token format.

Workload Current Label Regression Labels Token Format Validation Channel
.NET back-office build windows-latest windows-2025-vs2026 + windows-2022 GITHUB_TOKEN (auto stateless) Actions build success rate + unit test pass rate
C++ native module windows-latest windows-2025-vs2026 MSBuild v144 warning count, /std:c++latest build result
iOS Swift Package macos-latest macos-26 + macos-15 Xcode 26 build, iOS 26 simulator unit tests
Multi-arch Rust ubuntu-24.04-arm No change (zero-downtime) Move release-notes RSS from partner-runner-images to runner-images
Custom GitHub App (back-office sync) enabled force-issue cron + regex fix Token length metric, issuance failure rate
Custom GitHub App (deploy bot) Same NGINX header limit audit, Loki masking rule refresh
Dependabot Auto-converted as first-party (since April 27) Inspect May dependency-PR failure logs
Slack/Teams integration Same Confirm webhook payload token masking

8. ManoIT Internal Checklist — 18 Workflows + 4 GitHub Apps

Operational rollout of the calendar and matrix above. Every line must be processed before the June 8 D-day.

# Item Owner Done Criterion
1 Identify windows-latest, windows-2025, macos-latest usage across all workflows Platform Inventory PR merged
2 Add regression jobs — windows-2025-vs2026, macos-26, macos-15 matrix Platform First green build in comparison matrix
3 Branch PRs by regression result — VS 2026 compatible vs. VS 2022 pinned Each service owner All branched PRs green
4 Grep + fix custom GitHub App regex Back-office Unified to ghs_[A-Za-z0-9\._]{36,}
5 Migrate token DB column to length 1024 DBA Alembic / Prisma migration applied
6 Raise NGINX proxy large_client_header_buffers to 32KB Infra Reload complete on each cluster
7 Refresh Loki masking patterns — include variable-length ghs_ tokens Observability Verify masking on sample logs
8 Run stateless-force-issuance cron every 30 minutes Platform 100% issuance success, length ≥ 500 metric
9 June 8 D-day monitoring dashboard — Actions API → Prometheus → Grafana Observability Real-time build success panel live
10 Hotfix PR template to downgrade affected workflows to windows-2022 on incidents Platform PR template merged
11 Cancel partner-runner-images RSS, migrate to runner-images Observability Alert channels cleaned up
12 Scale self-hosted Graviton queue capacity +30% in the first week of June Infra Karpenter NodePool adjusted
13 iOS builds — explicitly install iOS 17 simulator via xcrun simctl runtime add Mobile iOS 17 baseline regression job green
14 .NET global.json audit — pin SDK version where missing Each service owner Pinned PRs green
15 C++ /std explicit — decide between keeping /std:c++20 or moving to /std:c++23 Each service owner Decision doc + build option PR
16 Fastlane match/gym regression — macOS 26 unit tests Mobile Matrix builds green
17 Remove X-GitHub-Stateless-S2S-Token headers after transition Back-office Zero header grep hits
18 Legacy label cleanup campaign — usage of windows-2022, macos-15 Platform Standard-label unification PR merged

9. Conclusion — A "Label Line" Is No Longer Just a Label Line

The message from the two May 2026 changelogs is clear. "The operational ownership of hosted runners and the structure of token issuance change in the same week" means that the abstraction boundaries we operate against — runs-on labels, the ghs_ prefix string — are no longer simple identifiers but live infrastructure undergoing staged rollouts. We used to trust that windows-latest and macos-latest "would just point to the latest, courtesy of GitHub," and assumed ghs_ tokens were "40-character opaque strings." After May 14–15, both assumptions partially collapse.

Three operational reminders to close on: (1) Lock down the affected inventory and regression matrix before June 8 — the cost of pre-building with the windows-2025-vs2026 label is one week of infra time; the cost of skipping it is a broken production build at 3 AM on June 8. (2) Stateless tokens are not a one-line code change but a token-path problem — you must audit regex, DB columns, proxy header limits, and logging masking at all four chokepoints. (3) GitHub Enterprise Server is excluded from this token change, but don't relax — if your organization mixes GHEC and GHES, your code path must handle both token shapes. Mark June 8 and 15 in your calendar and process the §8 checklist one PR at a time over the next 30 days.


This article is a technical report authored by ManoIT's automated blogging pipeline (Claude Opus 4.6 + Cowork Agent) using the two GitHub Changelogs published on May 14–15, 2026 as the primary source. Schedules, rollout phases, and label semantics in this article reflect the official changelog state at the time of writing (2026-05-19) and may change in subsequent GitHub announcements. Please verify the current state at actions/runner-images and the GitHub Blog Changelog before applying anything operationally. Internal cases cited are adapted from ManoIT's platform-team internal RFCs.


Originally published at ManoIT Tech Blog.

Top comments (0)