83d009ae82
Two structural changes to the combination fanout:
1. Tags become the OUTER axis, as a sub-graph per starting version:
install-e2e.yml fans a plain matrix over the picked tags into a new
per-tag reusable workflow (install-e2e-tag.yml), which runs the
combination generator for that one tag and fans out one job per
{os, install-method, update-method}. The Actions graph now reads
'from vX -> windows: install -> update' per leg. Nothing is
hardcoded in the workflows: the tag workflow calls the generator
itself.
2. Native skips move to the point that owns the capability knowledge:
macOS combos (no driving workflow exists) grey out in the tag
workflow via install-e2e-skip.yml, untouched by the tag axis; ALL
windows combos dispatch to install-e2e-windows-run.yml, which takes
install-method/update-method inputs and natively skips the pairs
its driver cannot run yet - so implementing a windows method is a
change in the run workflow + driver only. The driver's -Route ids
now match the generator's method ids verbatim.
Generator output shape, route filters, and all error paths re-verified
locally; all four workflows pass actionlint; driver re-parses clean
pure-ASCII.
124 lines
5.3 KiB
YAML
124 lines
5.3 KiB
YAML
name: Install & Update E2E
|
|
|
|
# Can a user on a released version get to this commit?
|
|
#
|
|
# The support matrix -- every {os, install-method, update-method} combination
|
|
# a user could be on -- lives in scripts/sandbox/generate-e2e-matrix.mjs.
|
|
# The job graph nests one sub-graph per starting release tag:
|
|
#
|
|
# from <tag> (install-e2e-tag.yml)
|
|
# -> linux: <install> -> <update> one job per combination, a real
|
|
# curl|bash install in bubblewrap
|
|
# (install-e2e-run.yml)
|
|
# -> windows: <install> -> <update> one job per combination, the real
|
|
# desktop user flow: website exe
|
|
# clicked by AutoHotkey, update via
|
|
# the app, Playwright clicking
|
|
# "Update now"
|
|
# (install-e2e-windows-run.yml)
|
|
# -> macos: <install> -> <update> natively skipped until a macos
|
|
# workflow exists
|
|
# (install-e2e-skip.yml)
|
|
#
|
|
# Every combination is dispatched; unimplemented ones natively skip (grey)
|
|
# at the point that owns the knowledge -- macOS combos in the tag workflow
|
|
# (no driver exists), windows method pairs inside the windows run workflow
|
|
# (next to the driver that will implement them).
|
|
#
|
|
# The starting versions are chosen at runtime from the repo's release tags
|
|
# (scripts/sandbox/pick-release-tags.sh): newest, oldest, and a spread
|
|
# between. A hardcoded list would stop covering the newest release the day
|
|
# after it ships, and would pin an "oldest" that nobody still runs. The tag
|
|
# axis is applied to EVERY os: linux legs install the tag in the sandbox;
|
|
# windows legs stage serve.git's `main` at it, which is what the published
|
|
# installer (no commit pin) then installs.
|
|
#
|
|
# Triggers:
|
|
# * every 12 hours, so upstream drift (a new uv, a Node bump, a PyPI change)
|
|
# surfaces on a schedule rather than in someone's review cycle;
|
|
# * when a release tag is created -- the moment the set of versions users can
|
|
# update FROM changes, and the moment a broken updater would strand them;
|
|
# * manually, where you can pick the route and how many releases to sample.
|
|
#
|
|
# Deliberately NOT on pull_request: a leg takes ~11 minutes of real toolchain
|
|
# installation, and the matrix multiplies that. Updating is release-shaped work,
|
|
# so it is gated on releases and the clock instead.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
route:
|
|
description: 'Which update route to exercise. all/both include the Windows desktop leg.'
|
|
required: false
|
|
type: choice
|
|
default: all
|
|
options: [all, both, update, installer, windows-desktop]
|
|
tag-count:
|
|
description: 'How many release tags to sample (newest, oldest, and a spread between).'
|
|
required: false
|
|
type: string
|
|
default: '5'
|
|
schedule:
|
|
# Every 12 hours, off the hour to avoid the top-of-hour runner crunch.
|
|
- cron: '20 7,19 * * *'
|
|
push:
|
|
tags:
|
|
# Release tags only: the repo also carries backup/* and one-off tags.
|
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
|
- 'v[0-9]+.[0-9]+.[0-9]+.[0-9]+'
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: install-e2e-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# Which released versions do we test updating FROM? Resolved once; the
|
|
# generator applies the tag axis to every OS's legs.
|
|
pick-releases:
|
|
name: Pick release tags
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
tags: ${{ steps.pick.outputs.tags }}
|
|
steps:
|
|
# This job only reads tag names and runs one script, so take the cheap
|
|
# checkout: no blobs (filter), no other files (sparse), but DO fetch tags
|
|
# -- they are the whole input, and the default shallow checkout has none.
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
filter: blob:none
|
|
fetch-tags: true
|
|
sparse-checkout: scripts/sandbox/pick-release-tags.sh
|
|
sparse-checkout-cone-mode: false
|
|
- id: pick
|
|
run: |
|
|
set -euo pipefail
|
|
tags="$(scripts/sandbox/pick-release-tags.sh --count '${{ inputs.tag-count || 5 }}')"
|
|
echo "Testing updates from: $tags"
|
|
echo "tags=$tags" >> "$GITHUB_OUTPUT"
|
|
|
|
# One sub-graph per starting tag: install-e2e-tag.yml expands the
|
|
# {os, install-method, update-method} support matrix for that tag and
|
|
# fans out one job per combination, so the graph reads
|
|
# "from vX -> windows: install -> update" per leg. Skips happen where
|
|
# the knowledge lives: macOS combos natively skip inside the tag
|
|
# workflow (no workflow exists for them at all); unimplemented windows
|
|
# method pairs natively skip inside install-e2e-windows-run.yml, next
|
|
# to the driver that will implement them.
|
|
from-tag:
|
|
name: "from ${{ matrix.install-ref }}"
|
|
needs: pick-releases
|
|
strategy:
|
|
# One tag breaking is worth knowing about even if another already
|
|
# failed, so let every sub-graph report.
|
|
fail-fast: false
|
|
matrix:
|
|
install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-tag.yml
|
|
with:
|
|
install-ref: ${{ matrix.install-ref }}
|
|
route: ${{ inputs.route || 'all' }}
|