Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
201 lines
8.0 KiB
YAML
201 lines
8.0 KiB
YAML
name: Environments
|
|
|
|
# Execution environments on every OS: Durable's NodeExecutionEnv and pi-env's daemon and RemoteExecutionEnv, which
|
|
# must give the same results. The main CI runs on Linux only. The release builds of the daemon are tested as shipped,
|
|
# and so is the npm package's file list.
|
|
on:
|
|
push:
|
|
branches: [main, "durable-env-*"]
|
|
paths: ["packages/durable/src/env/**", "packages/durable/src/tools/**", "packages/durable/test/env-*", "packages/env/**", ".github/workflows/env.yml", ".github/workflows/env-daemons.yml"]
|
|
pull_request:
|
|
branches: [main]
|
|
paths: ["packages/durable/src/env/**", "packages/durable/src/tools/**", "packages/durable/test/env-*", "packages/env/**", ".github/workflows/env.yml", ".github/workflows/env-daemons.yml"]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: env-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
daemons:
|
|
uses: ./.github/workflows/env-daemons.yml
|
|
permissions:
|
|
contents: read
|
|
|
|
check:
|
|
needs: daemons
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep
|
|
sudo ln -s $(which fdfind) /usr/local/bin/fd
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
|
|
- name: Check
|
|
run: npm run check
|
|
|
|
- name: Download the pi-env daemons
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
pattern: pi-env-*
|
|
path: packages/env/bin
|
|
|
|
- name: Check the pi-env package contents
|
|
working-directory: packages/env
|
|
run: |
|
|
npm pack --dry-run --json > "$RUNNER_TEMP/pack.json"
|
|
node -e '
|
|
const files = new Set(JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8"))[0].files.map((file) => file.path));
|
|
const expected = ["dist/index.js", "dist/index.d.ts", "dist/ssh.js", "README.md", "CHANGELOG.md", "docs/protocol.md"];
|
|
for (const name of ["linux-x64", "linux-arm64", "android-arm64", "android-x64", "darwin-arm64", "darwin-x64"]) expected.push(`bin/pi-env-${name}/pi-env`);
|
|
for (const name of ["windows-x64", "windows-arm64"]) expected.push(`bin/pi-env-${name}/pi-env.exe`);
|
|
const missing = expected.filter((file) => !files.has(file));
|
|
const unexpected = [...files].filter((file) => file.startsWith("src/") || file.startsWith("daemon/") || file.startsWith("test/"));
|
|
if (missing.length || unexpected.length) { console.error({ missing, unexpected }); process.exit(1); }
|
|
console.log(`${files.size} files`);
|
|
' "$RUNNER_TEMP/pack.json"
|
|
|
|
# The pi-env tests against each release build of the daemon, as the npm package ships it.
|
|
release-daemons:
|
|
needs: daemons
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- { os: ubuntu-latest, name: linux-x64 }
|
|
- { os: ubuntu-24.04-arm, name: linux-arm64 }
|
|
- { os: macos-latest, name: darwin-arm64 }
|
|
# Under Rosetta on the Apple silicon runner.
|
|
- { os: macos-latest, name: darwin-x64 }
|
|
- { os: windows-latest, name: windows-x64 }
|
|
- { os: windows-11-arm, name: windows-arm64 }
|
|
runs-on: ${{ matrix.os }}
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Install an SSH server for the bootstrap tests
|
|
if: runner.os == 'Linux'
|
|
run: command -v sshd || test -x /usr/sbin/sshd || (sudo apt-get update && sudo apt-get install -y openssh-server)
|
|
|
|
- name: Install Rosetta
|
|
if: matrix.name == 'darwin-x64'
|
|
run: softwareupdate --install-rosetta --agree-to-license
|
|
|
|
- name: Download the daemon
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: pi-env-${{ matrix.name }}
|
|
path: ${{ runner.temp }}/daemon
|
|
|
|
- name: pi-env tests
|
|
working-directory: packages/env
|
|
run: |
|
|
daemon="$RUNNER_TEMP/daemon/pi-env"
|
|
case "${{ matrix.name }}" in windows-*) daemon="$daemon.exe" ;; esac
|
|
chmod +x "$daemon"
|
|
file "$daemon" || true
|
|
PI_ENV_DAEMON="$daemon" npx vitest --run
|
|
|
|
tests:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest, windows-11-arm]
|
|
runs-on: ${{ matrix.os }}
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Install an SSH server for the bootstrap tests
|
|
if: runner.os == 'Linux'
|
|
run: command -v sshd || test -x /usr/sbin/sshd || (sudo apt-get update && sudo apt-get install -y openssh-server)
|
|
|
|
- name: Daemon format, lint and unit tests
|
|
working-directory: packages/env/daemon
|
|
run: |
|
|
cargo fmt --check
|
|
cargo clippy --locked --all-targets -- -D warnings
|
|
cargo test --locked
|
|
|
|
- name: Build the daemon
|
|
working-directory: packages/env
|
|
run: npm run build:daemon
|
|
|
|
- name: Durable env tests
|
|
working-directory: packages/durable
|
|
run: npx vitest --run test/env-node.test.ts test/env-node-spill.test.ts test/env-node-conformance.test.ts test/env-line-scan.test.ts test/tools.test.ts test/tools-read-differential.test.ts
|
|
|
|
- name: pi-env tests
|
|
working-directory: packages/env
|
|
run: npx vitest --run
|
|
|
|
- name: Start Windows' OpenSSH server
|
|
if: matrix.os == 'windows-latest'
|
|
shell: pwsh
|
|
run: |
|
|
if (-not (Get-Service sshd -ErrorAction SilentlyContinue)) {
|
|
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 | Out-Null
|
|
}
|
|
Start-Service sshd
|
|
$key = Join-Path $env:RUNNER_TEMP 'ssh_client_key'
|
|
& "$env:WINDIR\System32\OpenSSH\ssh-keygen.exe" -q -t ed25519 -N '' -f $key
|
|
icacls $key /inheritance:r /grant "${env:USERNAME}:F" | Out-Null
|
|
# The runner's user is an administrator; sshd reads administrators' keys from ProgramData.
|
|
$authorized = "$env:ProgramData\ssh\administrators_authorized_keys"
|
|
Get-Content "$key.pub" | Set-Content -Path $authorized -Encoding ascii
|
|
icacls $authorized /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" | Out-Null
|
|
|
|
- name: pi-env tests over Windows' OpenSSH, with cmd.exe and then PowerShell as its default shell
|
|
if: matrix.os == 'windows-latest'
|
|
working-directory: packages/env
|
|
env:
|
|
PI_ENV_SSH_HOST: 127.0.0.1
|
|
PI_ENV_SSH_KEY: ${{ runner.temp }}\ssh_client_key
|
|
run: |
|
|
export PI_ENV_SSH_USER="$USERNAME"
|
|
export PI_ENV_SSH_PROGRAM="$WINDIR\System32\OpenSSH\ssh.exe"
|
|
npx vitest --run test/ssh-external.test.ts
|
|
powershell -NoProfile -Command "New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShell -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -PropertyType String -Force | Out-Null"
|
|
PI_ENV_SSH_SHELL=powershell npx vitest --run test/ssh-external.test.ts
|