355 lines
14 KiB
YAML
355 lines
14 KiB
YAML
name: Install & Update E2E
|
|
|
|
# Can a user on a released version get to this commit?
|
|
#
|
|
# One matrix job per {os, install-method -> update-method} combination a
|
|
# user could be on, hardcoded HERE so the workflow is the support matrix
|
|
# and the Actions graph draws one box per combination. Each box fans out
|
|
# over the release tags picked at runtime, so every leg reads
|
|
# "<tag> -> HEAD": install that tag the combo's way, update to this commit
|
|
# the combo's way.
|
|
#
|
|
# Matrix: linux-* a real curl|bash install in the bubblewrap sandbox
|
|
# (install-e2e-run.yml)
|
|
# Matrix: windows-* the real desktop user flow: website Hermes-Setup.exe
|
|
# clicked by AutoHotkey, update via the app,
|
|
# Playwright clicking "Update now"
|
|
# (install-e2e-windows-run.yml)
|
|
# Matrix: macos-* no driver yet (install-e2e-macos-run.yml)
|
|
#
|
|
# Every combination is dispatched to its OS's run workflow; the run
|
|
# workflow natively skips (grey) what its driver cannot run yet -- an
|
|
# unimplemented method pair, or a starting tag that predates the surface
|
|
# under test (e.g. windows desktop legs from releases before the desktop
|
|
# app existed). Capability knowledge lives next to each driver, never
|
|
# here: adding a method = adding one job below; implementing one = flipping
|
|
# the run workflow's gate.
|
|
#
|
|
# 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.
|
|
#
|
|
# 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 combinations to run. all = every OS; both/update/installer = the linux legs; windows-desktop = the windows legs.'
|
|
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 and
|
|
# shared by every combination's matrix, so all combos cover the same set.
|
|
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"
|
|
# Annotate each tag with what its own tree supports, so legs can
|
|
# natively skip surfaces the starting version does not have.
|
|
# Today: does the release ship the desktop app (apps/desktop,
|
|
# #20059)? Cheaper and simpler here -- the tags are already
|
|
# checked out -- than a probe job per windows leg.
|
|
enriched="$(for t in $(echo "$tags" | jq -r '.[]'); do
|
|
if git ls-tree -d "$t" apps/desktop | grep -q .; then d=true; else d=false; fi
|
|
echo "{\"ref\":\"$t\",\"desktop\":$d}"
|
|
done | jq -sc .)"
|
|
echo "Annotated: $enriched"
|
|
echo "tags=$enriched" >> "$GITHUB_OUTPUT"
|
|
|
|
# ---- linux: install via curl-bash ---------------------------------------
|
|
|
|
linux-curl-bash-to-hermes-update:
|
|
name: "linux: curl-bash -> hermes-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "both", "update"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
# One leg breaking is worth knowing about even if another already
|
|
# failed, so let every leg report.
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-run.yml
|
|
with:
|
|
install-method: curl-bash
|
|
update-method: hermes-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
linux-curl-bash-to-curl-bash:
|
|
name: "linux: curl-bash -> curl-bash (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "both", "installer"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
max-parallel: 3
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-run.yml
|
|
with:
|
|
install-method: curl-bash
|
|
update-method: curl-bash
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
# ---- windows: install via the website's Hermes-Setup.exe ----------------
|
|
|
|
windows-desktop-installer-to-desktop-app:
|
|
name: "windows: desktop-installer@latest -> desktop-app (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
# 2x-cost runners at ~14 min a leg: two at a time is throughput
|
|
# enough for a 5-tag axis without hogging the Windows pool.
|
|
max-parallel: 2
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: desktop-installer@latest
|
|
update-method: desktop-app
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-desktop-installer-to-installer-rerun:
|
|
name: "windows: desktop-installer@latest -> desktop-installer-rerun@latest (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: desktop-installer@latest
|
|
update-method: desktop-installer-rerun@latest
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-desktop-installer-to-hermes-update:
|
|
name: "windows: desktop-installer@latest -> hermes-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: desktop-installer@latest
|
|
update-method: hermes-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-desktop-installer-to-irm-iex:
|
|
name: "windows: desktop-installer@latest -> irm-iex (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: desktop-installer@latest
|
|
update-method: irm-iex
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
# ---- windows: install via irm | iex --------------------------------------
|
|
|
|
windows-irm-iex-to-desktop-app:
|
|
name: "windows: irm-iex -> desktop-app (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: irm-iex
|
|
update-method: desktop-app
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-irm-iex-to-installer-rerun:
|
|
name: "windows: irm-iex -> desktop-installer-rerun@latest (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: irm-iex
|
|
update-method: desktop-installer-rerun@latest
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-irm-iex-to-hermes-update:
|
|
name: "windows: irm-iex -> hermes-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: irm-iex
|
|
update-method: hermes-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
windows-irm-iex-to-irm-iex:
|
|
name: "windows: irm-iex -> irm-iex (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route)
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-windows-run.yml
|
|
with:
|
|
tag-has-desktop: ${{ matrix.tag.desktop }}
|
|
install-method: irm-iex
|
|
update-method: irm-iex
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
# ---- macos: no driver yet (every leg natively skips in the run workflow) -
|
|
|
|
macos-curl-bash-to-curl-bash:
|
|
name: "macos: curl-bash -> curl-bash (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: curl-bash
|
|
update-method: curl-bash
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
macos-curl-bash-to-hermes-update:
|
|
name: "macos: curl-bash -> hermes-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: curl-bash
|
|
update-method: hermes-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
macos-curl-bash-to-app-update:
|
|
name: "macos: curl-bash -> app-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: curl-bash
|
|
update-method: app-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
macos-packaged-app-to-curl-bash:
|
|
name: "macos: packaged-app -> curl-bash (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: packaged-app
|
|
update-method: curl-bash
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
macos-packaged-app-to-hermes-update:
|
|
name: "macos: packaged-app -> hermes-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: packaged-app
|
|
update-method: hermes-update
|
|
install-ref: ${{ matrix.tag.ref }}
|
|
|
|
macos-packaged-app-to-app-update:
|
|
name: "macos: packaged-app -> app-update (${{ matrix.tag.ref }} -> HEAD)"
|
|
if: github.event_name != 'workflow_dispatch' || inputs.route == 'all'
|
|
needs: pick-releases
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
tag: ${{ fromJSON(needs.pick-releases.outputs.tags) }}
|
|
uses: ./.github/workflows/install-e2e-macos-run.yml
|
|
with:
|
|
install-method: packaged-app
|
|
update-method: app-update
|
|
install-ref: ${{ matrix.tag.ref }}
|