UNPKG

functionalscript

Version:

FunctionalScript is a purely functional subset of JavaScript

170 lines (169 loc) 6.09 kB
const os = ['ubuntu', 'macos', 'windows']; const architecture = ['intel', 'arm']; // https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories const images = { ubuntu: { intel: 'ubuntu-latest', arm: 'ubuntu-24.04-arm' }, macos: { intel: 'macos-15-intel', arm: 'macos-latest' }, windows: { intel: 'windows-latest', arm: 'windows-11-arm', } }; const install = (step) => ({ type: 'install', step }); const test = (step) => ({ type: 'test', step }); const installOnWindowsArm = ({ def, name, path }) => (v) => (a) => install(v === 'windows' && a === 'arm' ? { run: `irm ${path}/install.ps1 | iex; "$env:USERPROFILE\\.${name}\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append` } : def); const installBun = installOnWindowsArm({ def: { uses: 'oven-sh/setup-bun@v1' }, name: 'bun', path: 'bun.sh' }); const installDeno = installOnWindowsArm({ def: { uses: 'denoland/setup-deno@v2', with: { 'deno-version': '2' } }, name: 'deno', path: 'deno.land' }); const cargoTest = (target, config) => { const to = target ? ` --target ${target}` : ''; const co = config ? ` --config ${config}` : ''; const main = `cargo test${to}${co}`; return [ test({ run: main }), test({ run: `${main} --release` }) ]; }; const customTarget = (target) => [ { type: 'rust', target }, ...cargoTest(target) ]; const wasmTarget = (target) => [ ...customTarget(target), ...cargoTest(target, '.cargo/config.wasmer.toml') ]; const clean = (steps) => [ ...steps, test({ run: 'git reset --hard HEAD && git clean -fdx' }) ]; const installNode = (version) => ({ uses: 'actions/setup-node@v6', with: { 'node-version': version } }); const basicNode = (version) => (extra) => clean([ install(installNode(version)), test({ run: 'npm ci' }), ...extra, ]); const node = (version) => (extra) => basicNode(version)([ test({ run: 'npm test' }), test({ run: 'npm run fst' }), ...extra, ]); const findTgz = (v) => v === 'windows' ? '(Get-ChildItem *.tgz).FullName' : './*.tgz'; const toSteps = (m) => { const filter = (st) => m.flatMap((mt) => mt.type === st ? [mt.step] : []); const aptGet = m.flatMap(v => v.type === 'apt-get' ? [v.package] : []).join(' '); const rust = m.find(v => v.type === 'rust') !== undefined; const targets = m.flatMap(v => v.type === 'rust' && v.target !== undefined ? [v.target] : []).join(','); return [ ...(aptGet !== '' ? [{ run: `sudo apt-get update && sudo apt-get install -y ${aptGet}` }] : []), ...(rust ? [{ // wasm32-wasip1-threads doesn't work on Rust 1.91 in the release mode. // See https://github.com/sergey-shandar/wasmtime-crash uses: 'dtolnay/rust-toolchain@1.90.0', with: { components: 'rustfmt,clippy', targets } }] : []), ...filter('install'), { uses: 'actions/checkout@v5' }, ...filter('test'), ]; }; const nodes = ['20', '22', '25']; const nodeTest = (v) => v === '20' ? 'run test20' : 'test'; const nodeSteps = (v) => [ install(installNode(v)), test({ run: 'npm ci' }), test({ run: `npm ${nodeTest(v)}` }), ]; const ubuntu = (ms) => ({ 'runs-on': 'ubuntu-latest', steps: toSteps(ms) }); const nodeVersions = Object.fromEntries(nodes.map(v => [`node${v}`, ubuntu(nodeSteps(v))])); const steps = (v) => (a) => { const result = [ // Rust test({ run: 'cargo fmt -- --check' }), test({ run: 'cargo clippy -- -D warnings' }), ...cargoTest(), install({ uses: 'bytecodealliance/actions/wasmtime/setup@v1' }), install({ uses: 'wasmerio/setup-wasmer@v1' }), ...wasmTarget('wasm32-wasip1'), ...wasmTarget('wasm32-wasip2'), ...wasmTarget('wasm32-unknown-unknown'), ...wasmTarget('wasm32-wasip1-threads'), ...(a !== 'intel' ? [] : v === 'windows' ? customTarget('i686-pc-windows-msvc') : v === 'ubuntu' ? [ { type: 'apt-get', package: 'libc6-dev-i386' }, ...customTarget('i686-unknown-linux-gnu'), ] : []), // Node.js ...node('24')([ // TypeScript Preview install({ run: 'npm install -g @typescript/native-preview' }), test({ run: 'tsgo' }), // Playwright install({ run: 'npm install -g playwright' }), install({ run: 'playwright install --with-deps' }), ...['chromium', 'firefox', 'webkit'].map(browser => (test({ run: `npx playwright test --browser=${browser}` }))), // publishing test({ run: 'npm pack' }), test({ run: `npm install -g ${findTgz(v)}` }), test({ run: 'fsc issues/demo/data/tree.json _tree.f.js' }), test({ run: 'fst' }), test({ run: 'npm uninstall functionalscript -g' }), ]), // Deno ...clean([ installDeno(v)(a), test({ run: 'deno install' }), test({ run: 'deno task test' }), test({ run: 'deno task fst' }), test({ run: 'deno publish --dry-run' }), ]), // Bun ...clean([ installBun(v)(a), test({ run: 'bun test --timeout 20000' }), test({ run: 'bun ./dev/tf/module.ts' }), ]), ]; return toSteps(result); }; const jobs = { ...Object.fromEntries([ ...os.flatMap(v => architecture.map(a => [`${v}-${a}`, { 'runs-on': images[v][a], steps: steps(v)(a), }])) ]), ...nodeVersions, }; const gha = { name: 'CI', on: { pull_request: {} }, jobs, }; export default async (io) => { io.fs.writeFileSync('.github/workflows/ci.yml', JSON.stringify(gha, null, ' ')); return 0; };