diff --git a/.github/workflows/install-e2e-macos-run.yml b/.github/workflows/install-e2e-macos-run.yml index e23dcab79e..450cf42bc0 100644 --- a/.github/workflows/install-e2e-macos-run.yml +++ b/.github/workflows/install-e2e-macos-run.yml @@ -39,7 +39,7 @@ jobs: # Static name on purpose: the caller's job name already carries the # method pair, and GitHub renders name expressions UNEXPANDED (literal # "${{ inputs... }}") on natively skipped jobs. - name: run + name: e2e # No macOS driver exists yet: every pair is a declared TODO, so this is # constant-false until the first method lands. Written as an impossible # input comparison rather than `if: false` because actionlint rejects diff --git a/.github/workflows/install-e2e-run.yml b/.github/workflows/install-e2e-run.yml index 1d73af329e..c7077870ca 100644 --- a/.github/workflows/install-e2e-run.yml +++ b/.github/workflows/install-e2e-run.yml @@ -60,11 +60,11 @@ jobs: e2e: # Static name on purpose: the caller's job name already carries the # method pair, and GitHub renders name expressions UNEXPANDED (literal - # "${{ inputs... }}") on natively skipped jobs. - name: run - # The pairs the sandbox driver can run today. Anything else is a - # declared TODO: native skip, so the coverage gap is a grey check on - # every run. + # "${{ inputs... }}") on natively skipped jobs. Short because it is + # only a rendered tail (" -> HEAD / e2e"). + name: e2e + # The pairs the sandbox driver can run today; anything else is a + # declared TODO and natively skips. if: inputs.install-method == 'curl-bash' && contains(fromJSON('["hermes-update", "curl-bash"]'), inputs.update-method) runs-on: ${{ inputs.runner }} timeout-minutes: ${{ inputs.timeout-minutes }} diff --git a/.github/workflows/install-e2e-windows-run.yml b/.github/workflows/install-e2e-windows-run.yml index c1e9a63ffd..fdac6d6ce0 100644 --- a/.github/workflows/install-e2e-windows-run.yml +++ b/.github/workflows/install-e2e-windows-run.yml @@ -57,6 +57,11 @@ on: required: false type: string default: auto + tag-has-desktop: + description: 'Whether install-ref ships the desktop app (apps/desktop). The caller annotates this from the tag''s own tree; desktop-method legs from pre-desktop releases natively skip.' + required: false + type: boolean + default: true setup-exe-url: description: 'Bootstrap installer to install OLD with. Default: the latest published one — what a user downloads today.' required: false @@ -72,52 +77,17 @@ permissions: contents: read jobs: - # Can this starting version run this flow at all? The desktop app - # (apps/desktop) only exists in releases from v2026.5.31 on (#20059): - # older tags have no window to launch and no Update button to click, so - # desktop-method legs from them natively skip below. Data-driven from the - # tag's own tree -- no hardcoded version list to rot. - probe: - name: probe tag - if: inputs.install-method == 'desktop-installer@latest' && inputs.update-method == 'desktop-app' - runs-on: ubuntu-latest - timeout-minutes: 5 - outputs: - has-desktop: ${{ steps.probe.outputs.has-desktop }} - steps: - # Tree listings only: no blobs, full history + tags so any ref - # resolves. - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - filter: blob:none - - id: probe - run: | - set -euo pipefail - ref='${{ inputs.install-ref }}' - if [ "$ref" = "auto" ]; then - # Same choice the driver's stage phase makes: newest release tag. - ref="$(git tag --list 'v[0-9]*' --sort=-creatordate | head -1)" - fi - if git ls-tree -d "$ref" apps/desktop | grep -q .; then - has=true - else - has=false - fi - echo "ref $ref: has-desktop=$has" - echo "has-desktop=$has" >> "$GITHUB_OUTPUT" - e2e: # Static name on purpose: the caller's job name already carries the # method pair, and GitHub renders name expressions UNEXPANDED (literal # "${{ inputs... }}") on natively skipped jobs. - name: run - needs: probe + name: e2e # The one pair the driver can run today, and only from a starting - # version that ships the desktop app. Anything else is a native skip: - # a declared-TODO method pair, or a tag from before the app existed. - # (When probe itself skipped, its output is empty and this is false.) - if: inputs.install-method == 'desktop-installer@latest' && inputs.update-method == 'desktop-app' && needs.probe.outputs.has-desktop == 'true' + # version that ships the desktop app (the caller annotates + # tag-has-desktop from the tag's own tree; releases before #20059 have + # no window to launch and no Update button to click). Anything else is + # a native skip: a declared-TODO method pair, or a pre-desktop tag. + if: inputs.install-method == 'desktop-installer@latest' && inputs.update-method == 'desktop-app' && inputs.tag-has-desktop runs-on: windows-latest timeout-minutes: ${{ inputs.timeout-minutes }} diff --git a/.github/workflows/install-e2e.yml b/.github/workflows/install-e2e.yml index c571186805..2a92db7578 100644 --- a/.github/workflows/install-e2e.yml +++ b/.github/workflows/install-e2e.yml @@ -95,12 +95,22 @@ jobs: 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" + # 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" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "both", "update"]'), inputs.route) needs: pick-releases strategy: @@ -108,32 +118,32 @@ jobs: # failed, so let every leg report. fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} linux-curl-bash-to-curl-bash: - name: "linux: curl-bash -> curl-bash" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + 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" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || contains(fromJSON('["all", "windows-desktop"]'), inputs.route) needs: pick-releases strategy: @@ -142,195 +152,203 @@ jobs: # enough for a 5-tag axis without hogging the Windows pool. max-parallel: 2 matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-desktop-installer-to-installer-rerun: - name: "windows: desktop-installer@latest -> desktop-installer-rerun@latest" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-desktop-installer-to-hermes-update: - name: "windows: desktop-installer@latest -> hermes-update" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-desktop-installer-to-irm-iex: - name: "windows: desktop-installer@latest -> irm-iex" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} # ---- windows: install via irm | iex -------------------------------------- windows-irm-iex-to-desktop-app: - name: "windows: irm-iex -> desktop-app" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-irm-iex-to-installer-rerun: - name: "windows: irm-iex -> desktop-installer-rerun@latest" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-irm-iex-to-hermes-update: - name: "windows: irm-iex -> hermes-update" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} windows-irm-iex-to-irm-iex: - name: "windows: irm-iex -> irm-iex" + name: "${{ 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: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + 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" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} macos-curl-bash-to-hermes-update: - name: "macos: curl-bash -> hermes-update" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} macos-curl-bash-to-app-update: - name: "macos: curl-bash -> app-update" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} macos-packaged-app-to-curl-bash: - name: "macos: packaged-app -> curl-bash" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} macos-packaged-app-to-hermes-update: - name: "macos: packaged-app -> hermes-update" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }} macos-packaged-app-to-app-update: - name: "macos: packaged-app -> app-update" + name: "${{ matrix.tag.ref }} -> HEAD" if: github.event_name != 'workflow_dispatch' || inputs.route == 'all' needs: pick-releases strategy: fail-fast: false matrix: - install-ref: ${{ fromJSON(needs.pick-releases.outputs.tags) }} + 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.install-ref }} + install-ref: ${{ matrix.tag.ref }}