ci: every system on x64 and arm64, on the newest runner images (#258)

* ci: every system on x64 and arm64, on the newest runner images

The desktop app is packaged, and the known-answer workloads checked, on
Ubuntu 26.04, Windows 2025 and Windows 11, and macOS 26, each on x64 and
on arm64. Jobs name their image rather than -latest, download-artifact
moves to v8, and Dependabot keeps actions, Go modules and the desktop's
packages current.

* fix: verify unpacked packages on arm64

---------

Co-authored-by: excho0 <realexcho@gmail.com>
This commit was merged in pull request #258.
This commit is contained in:
rvnminers-A-and-Nandexcho0 authored and GitHub committed 2026-10-14 18:45:24 -04:00
1 parent 75998a128c
commit 8507cbea1c
8 files changed
+77 -21

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
# Keeps the actions, Go modules and the desktop app's packages current.
# Updates come weekly, grouped so that each ecosystem is one pull request,
# and pass the same checks as any other change before they merge.
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns: ["*"]
labels: [infra, dependencies]
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
groups:
go:
patterns: ["*"]
labels: [area:daemon, dependencies]
- package-ecosystem: npm
directory: /apps/sisyphus
schedule:
interval: weekly
groups:
desktop:
patterns: ["*"]
update-types: [minor, patch]
labels: [area:client, dependencies]
+12 -6
View File
@@ -12,7 +12,7 @@ jobs:
test: test:
# Keep untrusted fork pull requests on GitHub-hosted infrastructure. PRs # Keep untrusted fork pull requests on GitHub-hosted infrastructure. PRs
# from this repository and pushes to dev use the project's Linux runner. # from this repository and pushes to dev use the project's Linux runner.
runs-on: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'ubuntu-latest' || 'sisyphus-ci' }} runs-on: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'ubuntu-26.04' || 'sisyphus-ci' }}
env: env:
# All three self-hosted runners share the same host loopback and ephemeral-port space. # All three self-hosted runners share the same host loopback and ephemeral-port space.
SISYPHUS_CI_LOCAL_NETWORK_LOCK: /tmp/sisyphus-ci-local-network.lock SISYPHUS_CI_LOCAL_NETWORK_LOCK: /tmp/sisyphus-ci-local-network.lock
@@ -95,18 +95,24 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- runner: ubuntu-24.04 - runner: ubuntu-26.04
goos: linux goos: linux
goarch: amd64 goarch: amd64
- runner: ubuntu-24.04-arm - runner: ubuntu-26.04-arm
goos: linux goos: linux
goarch: arm64 goarch: arm64
- runner: windows-2025 - runner: windows-2025
goos: windows goos: windows
goarch: amd64 goarch: amd64
- runner: macos-15 - runner: windows-11-arm
goos: windows
goarch: arm64
- runner: macos-26
goos: darwin goos: darwin
goarch: arm64 goarch: arm64
- runner: macos-26-intel
goos: darwin
goarch: amd64
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
@@ -127,7 +133,7 @@ jobs:
# container with its own address and disk. It is what finds faults that # container with its own address and disk. It is what finds faults that
# tests on one machine cannot, since those all run over loopback. # tests on one machine cannot, since those all run over loopback.
rehearsal: rehearsal:
runs-on: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'ubuntu-latest' || 'sisyphus-ci' }} runs-on: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'ubuntu-26.04' || 'sisyphus-ci' }}
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
- uses: actions/setup-go@v7 - uses: actions/setup-go@v7
@@ -141,7 +147,7 @@ jobs:
# Electron E2E must never attach to the maintainer's interactive desktop. # Electron E2E must never attach to the maintainer's interactive desktop.
# Keep desktop checks on an isolated hosted runner; Go integration jobs may # Keep desktop checks on an isolated hosted runner; Go integration jobs may
# still use the self-hosted runner above. # still use the self-hosted runner above.
runs-on: ubuntu-latest runs-on: ubuntu-26.04
defaults: defaults:
run: run:
working-directory: apps/sisyphus working-directory: apps/sisyphus
+3 -1
View File
@@ -13,7 +13,9 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest] # Every system and processor the app ships for, each built on its
# own: Linux, Windows and macOS, on x64 and on arm64.
os: [ubuntu-26.04, ubuntu-26.04-arm, windows-2025, windows-11-arm, macos-26, macos-26-intel]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
defaults: defaults:
run: run:
+6 -4
View File
@@ -17,7 +17,7 @@ permissions:
jobs: jobs:
daemon: daemon:
runs-on: ubuntu-latest runs-on: ubuntu-26.04
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
- uses: actions/setup-go@v7 - uses: actions/setup-go@v7
@@ -38,7 +38,9 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest] # Every system and processor the app ships for, each built on its
# own: Linux, Windows and macOS, on x64 and on arm64.
os: [ubuntu-26.04, ubuntu-26.04-arm, windows-2025, windows-11-arm, macos-26, macos-26-intel]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
defaults: defaults:
run: run:
@@ -72,11 +74,11 @@ jobs:
publish: publish:
if: github.ref_type == 'tag' if: github.ref_type == 'tag'
needs: [daemon, desktop] needs: [daemon, desktop]
runs-on: ubuntu-latest runs-on: ubuntu-26.04
permissions: permissions:
contents: write contents: write
steps: steps:
- uses: actions/download-artifact@v7 - uses: actions/download-artifact@v8
with: with:
path: dist path: dist
merge-multiple: true merge-multiple: true
+9
View File
@@ -0,0 +1,9 @@
export function packageResourcesDirectory(platform, architecture) {
const suffix = architecture === 'arm64' ? '-arm64' : ''
if (platform === 'linux') return `linux${suffix}-unpacked/resources`
if (platform === 'win32') return `win${suffix}-unpacked/resources`
if (platform === 'darwin') {
return `${architecture === 'arm64' ? 'mac-arm64' : 'mac'}/Sisyphus.app/Contents/Resources`
}
throw new Error(`Unsupported package platform: ${platform}`)
}
+12
View File
@@ -3,6 +3,8 @@ import assert from 'node:assert/strict'
import { createRequire } from 'node:module' import { createRequire } from 'node:module'
import { existsSync } from 'node:fs' import { existsSync } from 'node:fs'
import { resolve } from 'node:path' import { resolve } from 'node:path'
import { packageResourcesDirectory } from './package-layout.mjs'
const require = createRequire(import.meta.url) const require = createRequire(import.meta.url)
const config = require('../electron-builder.config.cjs') const config = require('../electron-builder.config.cjs')
@@ -27,3 +29,13 @@ test('every package carries an icon drawn from the logo', () => {
test('cross-platform builds fail rather than package a mismatched daemon', async () => { test('cross-platform builds fail rather than package a mismatched daemon', async () => {
await assert.rejects(config.beforePack({ electronPlatformName: process.platform === 'linux' ? 'win32' : 'linux', arch: 1 }), /matching operating system/) await assert.rejects(config.beforePack({ electronPlatformName: process.platform === 'linux' ? 'win32' : 'linux', arch: 1 }), /matching operating system/)
}) })
test('package verification locates the unpacked app for every shipped architecture', () => {
assert.equal(packageResourcesDirectory('linux', 'x64'), 'linux-unpacked/resources')
assert.equal(packageResourcesDirectory('linux', 'arm64'), 'linux-arm64-unpacked/resources')
assert.equal(packageResourcesDirectory('win32', 'x64'), 'win-unpacked/resources')
assert.equal(packageResourcesDirectory('win32', 'arm64'), 'win-arm64-unpacked/resources')
assert.equal(packageResourcesDirectory('darwin', 'x64'), 'mac/Sisyphus.app/Contents/Resources')
assert.equal(packageResourcesDirectory('darwin', 'arm64'), 'mac-arm64/Sisyphus.app/Contents/Resources')
assert.throws(() => packageResourcesDirectory('freebsd', 'x64'), /Unsupported package platform/)
})
+2 -7
View File
@@ -4,15 +4,10 @@ import { access } from 'node:fs/promises'
import { join, resolve } from 'node:path' import { join, resolve } from 'node:path'
import { listPackage } from '@electron/asar' import { listPackage } from '@electron/asar'
import { createRequire } from 'node:module' import { createRequire } from 'node:module'
import { packageResourcesDirectory } from './package-layout.mjs'
const { version } = createRequire(import.meta.url)('../package.json') const { version } = createRequire(import.meta.url)('../package.json')
const resources = resolve('dist', packageResourcesDirectory(process.platform, process.arch))
const platforms = {
linux: 'linux-unpacked/resources',
win32: 'win-unpacked/resources',
darwin: `${process.arch === 'arm64' ? 'mac-arm64' : 'mac'}/Sisyphus.app/Contents/Resources`,
}
const resources = resolve('dist', platforms[process.platform])
const daemon = join(resources, 'bin', process.platform === 'win32' ? 'sisyphusd.exe' : 'sisyphusd') const daemon = join(resources, 'bin', process.platform === 'win32' ? 'sisyphusd.exe' : 'sisyphusd')
await access(daemon) await access(daemon)
assert.equal(execFileSync(daemon, ['version'], { encoding: 'utf8', timeout: 10000 }).trim(), `sisyphusd ${version}`) assert.equal(execFileSync(daemon, ['version'], { encoding: 'utf8', timeout: 10000 }).trim(), `sisyphusd ${version}`)
+3 -3
View File
@@ -33,9 +33,9 @@ Without building anything, take a package of the app with the node inside. A rel
| System | File | What to do with it | | System | File | What to do with it |
|---|---|---| |---|---|---|
| Windows | `Sisyphus-<version>-win-x64-setup.exe` | Run it. It installs for you alone, asks where, and puts Sisyphus in the Start menu and on the desktop. | | Windows | `Sisyphus-<version>-win-x64-setup.exe`, or `-win-arm64-setup.exe` on an Arm laptop | Run it. It installs for you alone, asks where, and puts Sisyphus in the Start menu and on the desktop. |
| macOS | `Sisyphus-<version>-mac-arm64.dmg` | Open it and drag Sisyphus onto Applications. | | macOS | `Sisyphus-<version>-mac-arm64.dmg` on Apple silicon, `-mac-x64.dmg` on an Intel Mac | Open it and drag Sisyphus onto Applications. |
| Linux | `Sisyphus-<version>-linux-x86_64.AppImage` | `chmod +x` it and run it. | | Linux | `Sisyphus-<version>-linux-x86_64.AppImage`, or `-linux-arm64.AppImage` on an Arm machine | `chmod +x` it and run it. |
Each also comes as a plain `.zip` or `.tar.gz` to unpack and run in place. Each also comes as a plain `.zip` or `.tar.gz` to unpack and run in place.