mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
Fedora, RHEL and openSUSE cannot install the .deb. electron-builder now also builds an .rpm, signed and mirrored with the same minisign flow, and studio-manifest lists it under native_packages[linux-<arch>-rpm] beside the unchanged .deb key. fpm spells the architecture of an .rpm name x86_64; the packaging hook renames it to the release architecture and fails on any spelling it does not know. The package job reads the rpm back for its name, the helper's owner and mode, and the rpm's post-uninstall leaves the command link alone on upgrade.
523 lines
23 KiB
YAML
523 lines
23 KiB
YAML
name: Studio
|
|
|
|
# Studio's own surface — desktop/frontend-next (the SPA) and the Electron shell
|
|
# that serves it — exists only on the studio branch, so it cannot live in ci.yml
|
|
# without failing on main-v2 where neither directory is present. ci.yml covers
|
|
# the kernel; this file covers the frontend build, the desktop module's Go side,
|
|
# and the packaging contract on real artifacts.
|
|
on:
|
|
push:
|
|
branches: [studio]
|
|
pull_request:
|
|
branches: [studio]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: studio-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
frontend:
|
|
name: frontend-next
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: desktop/frontend-next
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 10
|
|
run_install: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: "24"
|
|
cache: pnpm
|
|
cache-dependency-path: desktop/frontend-next/pnpm-lock.yaml
|
|
|
|
- name: Install
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: typecheck
|
|
run: pnpm typecheck
|
|
|
|
# The reducer and the event port carry the two pieces of logic a type
|
|
# error cannot reach: what a card means when a turn is interrupted, and
|
|
# what the client does about a frame that never arrived.
|
|
- name: test
|
|
run: pnpm test
|
|
|
|
# What the UI census holds. The gate reads structure — which inputs reach
|
|
# a mutating endpoint, and which of those the product names an action for
|
|
# — so UNDECLARED_MUTATION == 0 is a fact about the tree, not a lint over
|
|
# how anything is spelled.
|
|
- name: census invariants
|
|
run: pnpm census > /dev/null
|
|
|
|
# And that the analyzer still judges the way it did. _fx is a corpus
|
|
# written to exercise the rules, so its reports move only when a judgement
|
|
# moves; the product's name every root by file and line and are stale the
|
|
# moment a button moves, which is why they are not frozen.
|
|
- name: census fixture reports have not drifted
|
|
run: pnpm census:verify
|
|
|
|
# `build` runs tsc -b before vite, so this also proves the project
|
|
# references resolve — typecheck alone uses --noEmit and does not.
|
|
- name: build
|
|
run: pnpm build
|
|
|
|
# The published bundle must not carry MockPort's scripted fixtures: a
|
|
# release that cannot reach the kernel has to say so, not act out a fake
|
|
# session. main.tsx guards the import behind import.meta.env.DEV, and this
|
|
# is what proves the guard still holds.
|
|
- name: no fixtures in the bundle
|
|
run: |
|
|
if grep -rl 网关瞬时态 dist/ 2>/dev/null; then
|
|
echo "::error::MockPort fixtures reached the production bundle - check the import.meta.env.DEV guard in main.tsx"
|
|
exit 1
|
|
fi
|
|
|
|
# Real-Chromium guards that run without a kernel. Only the ones that passed
|
|
# three consecutive local runs are wired; the rest stay manual (see
|
|
# desktop/frontend-next/perf/README.md). Skipped unless the SPA changed.
|
|
browser-guards:
|
|
name: browser guards
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
defaults:
|
|
run:
|
|
working-directory: desktop/frontend-next
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: SPA changed?
|
|
id: spa
|
|
working-directory: .
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "pull_request" ] &&
|
|
git diff --quiet "origin/${{ github.base_ref }}...HEAD" -- desktop/frontend-next; then
|
|
echo "run=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "run=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- if: steps.spa.outputs.run == 'true'
|
|
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 10
|
|
run_install: false
|
|
|
|
- if: steps.spa.outputs.run == 'true'
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: "24"
|
|
cache: pnpm
|
|
cache-dependency-path: desktop/frontend-next/pnpm-lock.yaml
|
|
|
|
- if: steps.spa.outputs.run == 'true'
|
|
name: Install
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- if: steps.spa.outputs.run == 'true'
|
|
name: Build the perf harness and install Chromium
|
|
run: |
|
|
pnpm exec vite build --config vite.perf.config.ts
|
|
pnpm exec playwright install --with-deps chromium
|
|
|
|
- if: steps.spa.outputs.run == 'true'
|
|
name: Guards
|
|
run: |
|
|
python3 -m http.server 4399 --directory dist-perf >/dev/null 2>&1 &
|
|
for _ in $(seq 30); do curl -sf http://localhost:4399/perf.html >/dev/null && break; sleep 1; done
|
|
node perf/intrinsic.mjs
|
|
node perf/contrast.mjs
|
|
node perf/wheel.mjs
|
|
node perf/branch-tooltip.mjs
|
|
node perf/selfcheck.mjs branch-tooltip
|
|
|
|
desktop:
|
|
name: desktop (${{ matrix.os }})
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-22.04, windows-latest, macos-latest]
|
|
defaults:
|
|
run:
|
|
working-directory: desktop
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
|
with:
|
|
go-version-file: desktop/go.mod
|
|
cache: true
|
|
cache-dependency-path: desktop/go.sum
|
|
|
|
# The desktop module's Go tests: the elevated update helper, the
|
|
# release-side tools and the Windows uninstall planner. The code this
|
|
# gate covers is what replaces a running application on a user's disk.
|
|
# The module is CGO-free since the Wails shell retired, so no platform
|
|
# carries build dependencies of its own.
|
|
# Same command as `make studio-test`; this job is already in desktop/.
|
|
- name: go test
|
|
run: go test ./...
|
|
|
|
# The host sits in the main module and nothing else builds it, so its
|
|
# dependency closure is checked here: it must stay CGO-free and
|
|
# platform-neutral or the Electron bundle cannot ship it. Cross-compiling
|
|
# is host-independent, so once is enough.
|
|
- name: host stays pure Go and platform-neutral
|
|
if: runner.os == 'Linux'
|
|
working-directory: .
|
|
run: |
|
|
for os in windows linux darwin; do
|
|
CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -o /dev/null ./cmd/reasonix-studio-host
|
|
done
|
|
|
|
# The ARM64 leg queues on a scarcer runner pool, so a pull request runs it
|
|
# only when it touches what the leg verifies; a push to studio always does.
|
|
scope:
|
|
name: package matrix
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
matrix: ${{ steps.pick.outputs.matrix }}
|
|
arm64: ${{ steps.pick.outputs.arm64 }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- id: pick
|
|
env:
|
|
EVENT: ${{ github.event_name }}
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
arm64=true
|
|
if [ "$EVENT" = pull_request ]; then
|
|
arm64=false
|
|
if git diff --name-only "$BASE_SHA" HEAD |
|
|
grep -qE '^(desktop/electron/|desktop/cmd/studio-manifest/|desktop/go\.(mod|sum)$|cmd/reasonix-studio-host/|internal/platform/(update|appupdate)/|go\.(mod|sum)$|scripts/(windows-signing-lib|verify-windows-package|verify-windows-authenticode|install-smoke)\.ps1$|\.github/workflows/(studio|release-studio)\.yml$)'; then
|
|
arm64=true
|
|
fi
|
|
fi
|
|
legs='[
|
|
{"os":"macos-latest","arch":"arm64","platform":"darwin"},
|
|
{"os":"ubuntu-22.04","arch":"amd64","platform":"linux"},
|
|
{"os":"windows-latest","arch":"amd64","platform":"windows","ebarch":"x64"}
|
|
]'
|
|
if [ "$arm64" = true ]; then
|
|
legs="$(jq -c '. + [{"os":"windows-11-arm","arch":"arm64","platform":"windows","ebarch":"arm64"}]' <<<"$legs")"
|
|
else
|
|
legs="$(jq -c . <<<"$legs")"
|
|
fi
|
|
echo "arm64=$arm64" >> "$GITHUB_OUTPUT"
|
|
echo "matrix={\"include\":$legs}" >> "$GITHUB_OUTPUT"
|
|
|
|
# The packaging contract, on real artifacts rather than on the config that
|
|
# describes them. Unsigned on purpose: signing and notarization are a
|
|
# distribution concern and belong to the release workflow, and treating their
|
|
# absence as "packaging unverified" is what left macOS and Linux resting on a
|
|
# cross-compile while only Windows had ever produced a package.
|
|
package:
|
|
name: package (${{ matrix.os }})
|
|
needs: scope
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 45
|
|
strategy:
|
|
fail-fast: false
|
|
matrix: ${{ fromJSON(needs.scope.outputs.matrix) }}
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
|
with:
|
|
go-version-file: desktop/go.mod
|
|
cache: true
|
|
cache-dependency-path: desktop/go.sum
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 10
|
|
run_install: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: "24"
|
|
cache: pnpm
|
|
cache-dependency-path: desktop/electron/pnpm-lock.yaml
|
|
|
|
# electron-builder shells out to dpkg-deb through fakeroot for the .deb and
|
|
# to rpmbuild for the .rpm.
|
|
- name: Install Linux packaging deps
|
|
if: runner.os == 'Linux'
|
|
run: sudo apt-get update && sudo apt-get install -y fakeroot rpm
|
|
|
|
- name: Build the SPA
|
|
working-directory: desktop/frontend-next
|
|
run: pnpm install --frozen-lockfile && pnpm build
|
|
|
|
# The Windows legs name their architecture instead of taking the
|
|
# toolchain's, so a runner whose Go or Node is the other architecture
|
|
# fails here rather than shipping a mislabelled package.
|
|
- name: Build the kernel the shell speaks to
|
|
working-directory: desktop/electron
|
|
env:
|
|
REASONIX_GOARCH: ${{ matrix.platform == 'windows' && matrix.arch || '' }}
|
|
run: pnpm install --frozen-lockfile && pnpm run build:host
|
|
|
|
# The .deb's absolute-path payload. A no-op off Linux, so it is not
|
|
# guarded here: the one place it must not be forgotten is the one place
|
|
# it does anything.
|
|
- name: Stage the Linux package payload
|
|
working-directory: desktop/electron
|
|
run: pnpm run build:linux-payload
|
|
|
|
# No identity on a runner, and none wanted here: auto-discovery would make
|
|
# this job fail for the one reason it is not testing.
|
|
- name: Package
|
|
working-directory: desktop/electron
|
|
env:
|
|
CSC_IDENTITY_AUTO_DISCOVERY: "false"
|
|
ELECTRON_BUILDER_7Z_FILTER: ${{ matrix.platform == 'windows' && matrix.arch == 'arm64' && 'BCJ' || '' }}
|
|
run: pnpm run build:dist ${{ matrix.ebarch && format('--{0}', matrix.ebarch) || '' }}
|
|
|
|
# The release vocabulary is GOARCH. electron-builder's own is not, and the
|
|
# rename that reconciles them runs here rather than in the manifest.
|
|
- name: Artifacts carry the release architecture
|
|
run: |
|
|
ls -la dist
|
|
if ls dist | grep -q -- '-x64'; then
|
|
echo "::error::an artifact still names x64; studio-manifest reads names as GOARCH"
|
|
exit 1
|
|
fi
|
|
if ! ls dist | grep -q -- "-${{ matrix.platform }}-${{ matrix.arch }}"; then
|
|
echo "::error::no artifact named for ${{ matrix.platform }}-${{ matrix.arch }}"
|
|
exit 1
|
|
fi
|
|
|
|
# An emulated x64 program runs on ARM64 Windows, so a package that merely
|
|
# starts proves nothing about its architecture: every PE image in the
|
|
# bundle has to be built for the one the package is named for.
|
|
- name: Every PE image is built for the package's architecture
|
|
if: matrix.platform == 'windows'
|
|
run: |
|
|
dir=$(find dist -maxdepth 1 -type d -name 'win*-unpacked' | head -1)
|
|
test -n "$dir"
|
|
node desktop/electron/packaging/pe.js "$dir" "${{ matrix.arch }}"
|
|
|
|
# The release packages a signed copy of the bundle and then reads both
|
|
# packages back against it. The same recipe on an unsigned copy, so the
|
|
# packaging contract (the installer's one application archive, the pinned
|
|
# elevate.exe, every PE image's architecture) is exercised on pull
|
|
# requests and not first by a release.
|
|
- name: The packages read back against the bundle they were made from
|
|
if: matrix.platform == 'windows'
|
|
shell: bash
|
|
env:
|
|
ELECTRON_BUILDER_7Z_FILTER: ${{ matrix.arch == 'arm64' && 'BCJ' || '' }}
|
|
run: |
|
|
rm -rf payload nsis-src packed zip-src
|
|
cp -r "$(find dist -maxdepth 1 -type d -name 'win*-unpacked' | head -1)" payload
|
|
rm -f payload/resources/elevate.exe
|
|
# The NSIS run writes elevate.exe into the tree it packs, so each
|
|
# packager gets a copy and payload stays what was signed.
|
|
cp -r payload zip-src
|
|
cp -r payload nsis-src
|
|
cd desktop/electron
|
|
pnpm exec electron-builder --prepackaged ../../zip-src --win zip --${{ matrix.ebarch }} \
|
|
-c.extraMetadata.version=0.0.0-ci -c.directories.output=../../packed-zip
|
|
pnpm exec electron-builder --prepackaged ../../nsis-src --win nsis --${{ matrix.ebarch }} \
|
|
-c.extraMetadata.version=0.0.0-ci -c.directories.output=../../packed
|
|
mv ../../packed-zip/ReasonixStudio-windows-${{ matrix.arch }}.zip ../../packed/
|
|
ls -la ../../packed
|
|
|
|
- name: verify-windows-package.ps1 accepts them
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = 'Stop'
|
|
. ./scripts/windows-signing-lib.ps1
|
|
$digest = Get-ManifestDigest -Manifest @(Get-TreeManifest -Root payload)
|
|
./scripts/verify-windows-package.ps1 `
|
|
-PayloadDirectory payload `
|
|
-ExpectedPayloadDigest $digest `
|
|
-InstallerPath "packed/ReasonixStudio-windows-${{ matrix.arch }}-installer.exe" `
|
|
-PortableArchivePath "packed/ReasonixStudio-windows-${{ matrix.arch }}.zip" `
|
|
-OutputPath "$env:RUNNER_TEMP/verify-output.txt" `
|
|
-Architecture ${{ matrix.arch }}
|
|
Get-Content "$env:RUNNER_TEMP/verify-output.txt"
|
|
|
|
# The release's own install smoke, against the unsigned installer: the
|
|
# package is installed where it is meant to run, its tree checked, and
|
|
# removed.
|
|
- name: The package installs, runs and uninstalls
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
./scripts/install-smoke.ps1 `
|
|
-Installer "dist/ReasonixStudio-windows-${{ matrix.arch }}-installer.exe" `
|
|
-Architecture ${{ matrix.arch }}
|
|
|
|
- name: Keep the arm64 installer for the x64 refusal check
|
|
if: matrix.platform == 'windows' && matrix.arch == 'arm64'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: studio-arm64-installer-ci
|
|
path: dist/ReasonixStudio-windows-arm64-installer.exe
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
# The update channel is the signed manifest. A second answer to which
|
|
# version is current is not a convenience. The .blockmap is the same
|
|
# channel's differential index and carries the release prefix, so it also
|
|
# inflates the count the release uses to refuse a partial publish.
|
|
- name: No electron-updater metadata
|
|
run: |
|
|
if ls dist | grep -qiE '^(latest|beta|alpha).*\.yml$'; then
|
|
echo "::error::electron-updater metadata was published beside the manifest channel"
|
|
exit 1
|
|
fi
|
|
if ls dist | grep -q '\.blockmap$'; then
|
|
echo "::error::a .blockmap ships under the release prefix; set differentialPackage: false"
|
|
exit 1
|
|
fi
|
|
|
|
# A binary inside app.asar cannot be spawned and the kernel serves the SPA
|
|
# off disk, so both have to be resources. Found rather than asserted at a
|
|
# path, because the unpacked directory is named by the builder.
|
|
- name: The kernel and the page are resources, not archive members
|
|
run: |
|
|
host=$(find dist -type f -path '*/bin/reasonix-studio-host*' ! -path '*app.asar*' | head -1)
|
|
page=$(find dist -type f -path '*/frontend-next/dist/index.html' ! -path '*app.asar*' | head -1)
|
|
echo "kernel: ${host:-<missing>}"
|
|
echo "page: ${page:-<missing>}"
|
|
test -n "$host" -a -n "$page"
|
|
|
|
# Read off the package rather than off the config that describes it. Both
|
|
# of these went wrong the same way once: electron-builder names a package
|
|
# after package.json unless told, and fpm records the owner it finds on
|
|
# disk. Either one leaves a Studio that cannot update itself on Linux and
|
|
# says nothing about it until a user asks.
|
|
- name: The .deb is Studio's own package and carries what updates it
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
deb=$(ls dist/ReasonixStudio-linux-*.deb)
|
|
name=$(dpkg-deb -f "$deb" Package)
|
|
if [ "$name" != "reasonix-studio" ]; then
|
|
echo "::error::the package is $name; dpkg holds that beside the installed reasonix-studio instead of upgrading it, and update.StudioLine asks for it by name"
|
|
exit 1
|
|
fi
|
|
dpkg-deb -c "$deb" > contents.txt
|
|
# The path is the polkit action's exec.path annotation, so it is the
|
|
# only one authorization is granted for; root because polkit will not
|
|
# run a helper the invoking user could have written. Either spelling
|
|
# of root: dpkg-deb prints the numeric ids it cannot map, and which
|
|
# one it prints is a property of the machine reading the package
|
|
# rather than of the package.
|
|
if ! grep -qE '^-rwxr-xr-x (root/root|0/0) +[0-9]+ .* \./usr/lib/reasonix-studio/reasonix-studio-update-helper$' contents.txt; then
|
|
echo "::error::no root-owned executable update helper at the path the polkit action names"
|
|
grep reasonix-studio-update-helper contents.txt || echo "(not in the package at all)"
|
|
exit 1
|
|
fi
|
|
if ! grep -q './usr/share/polkit-1/actions/io.reasonix.studio.update.policy$' contents.txt; then
|
|
echo "::error::the polkit action is not in the package, so pkexec has nothing to authorize against"
|
|
exit 1
|
|
fi
|
|
|
|
# The .rpm is read back for the same two properties as the .deb: it is the
|
|
# package update.StudioLine names, and the helper pkexec runs as root is
|
|
# owned by root and writable by no one else, or any local user could
|
|
# replace it.
|
|
- name: The .rpm is Studio's own package and carries what updates it
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
rpm=$(ls dist/ReasonixStudio-linux-*.rpm)
|
|
name=$(rpm -qp --qf '%{NAME}' "$rpm")
|
|
if [ "$name" != "reasonix-studio" ]; then
|
|
echo "::error::the package is $name; rpm holds that beside the installed reasonix-studio instead of upgrading it"
|
|
exit 1
|
|
fi
|
|
rpm -qp --qf '[%{FILEMODES:perms} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' "$rpm" > contents.txt
|
|
if ! grep -qxE -- '-rwxr-xr-x root root /usr/lib/reasonix-studio/reasonix-studio-update-helper' contents.txt; then
|
|
echo "::error::no root-owned, executable, not-writable update helper at the path the polkit action names"
|
|
grep reasonix-studio-update-helper contents.txt || echo "(not in the package at all)"
|
|
exit 1
|
|
fi
|
|
if ! grep -qE -- '^-r[w-][x-]r-[x-]r-[x-] root root /usr/share/polkit-1/actions/io.reasonix.studio.update.policy$' contents.txt; then
|
|
echo "::error::the polkit action is missing, or is not a root-owned file no one else can write"
|
|
grep polkit contents.txt || echo "(not in the package at all)"
|
|
exit 1
|
|
fi
|
|
|
|
# The Electron shell sets the package's glibc floor; a Go binary linked
|
|
# with cgo would raise it to the runner's own.
|
|
- name: The .deb's Go binaries are statically linked
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
deb=$(ls dist/ReasonixStudio-linux-*.deb)
|
|
dpkg-deb -x "$deb" "$RUNNER_TEMP/deb"
|
|
host=$(find "$RUNNER_TEMP/deb" -type f -path '*/resources/bin/reasonix-studio-host')
|
|
test -n "$host"
|
|
node desktop/electron/packaging/elf.js "$host" "$RUNNER_TEMP/deb/usr/lib/reasonix-studio/reasonix-studio-update-helper"
|
|
|
|
# Recorded, not asserted: the real bundle layout, so later work argues
|
|
# from what electron-builder produced rather than from its documentation.
|
|
- name: Record the macOS bundle layout
|
|
if: runner.os == 'macOS'
|
|
run: |
|
|
app=$(find dist -maxdepth 2 -name '*.app' | head -1)
|
|
echo "app: $app"
|
|
ls "$app/Contents"
|
|
ls "$app/Contents/Resources" | head -20
|
|
ls "$app/Contents/Frameworks" | head -20
|
|
|
|
# The end of the contract: not that the name parses, but that the manifest
|
|
# keys the artifact under the platform this runner actually is. The tool
|
|
# writes latest.json into the directory and logs to stdout, so the check
|
|
# reads the file -- captured output would match its own progress line.
|
|
- name: studio-manifest resolves the platform this runner is
|
|
working-directory: desktop
|
|
env:
|
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
run: |
|
|
go run ./cmd/studio-manifest ../dist v0.0.0-ci v0.0.0-ci
|
|
cat ../dist/latest.json
|
|
if ! grep -q '"${{ matrix.platform }}-${{ matrix.arch }}"' ../dist/latest.json; then
|
|
echo "::error::the manifest has no entry for ${{ matrix.platform }}-${{ matrix.arch }}"
|
|
exit 1
|
|
fi
|
|
|
|
# The arm64 installer carries one application and no other. Run anywhere but
|
|
# ARM64 Windows it has to say so and stop, instead of exiting 0 with nothing
|
|
# installed.
|
|
arm64-installer-refuses-x64:
|
|
name: arm64 installer refuses an x64 machine
|
|
needs: [scope, package]
|
|
if: needs.scope.outputs.arm64 == 'true'
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: studio-arm64-installer-ci
|
|
path: installer
|
|
|
|
- name: Run it silently
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$target = Join-Path $env:RUNNER_TEMP 'rx-refused'
|
|
$run = Start-Process -FilePath installer/ReasonixStudio-windows-arm64-installer.exe -ArgumentList '/S', "/D=$target" -Wait -PassThru
|
|
Write-Host "exit code $($run.ExitCode)"
|
|
if ($run.ExitCode -eq 0) { throw 'the arm64 installer exited 0 on an x64 machine' }
|
|
if (@(Get-ChildItem -Recurse -Force $target -ErrorAction SilentlyContinue).Count -ne 0) { throw 'the arm64 installer wrote into the target on an x64 machine' }
|