Skip to content

Load and save schema files #610

Load and save schema files

Load and save schema files #610

Workflow file for this run

name: Node.js CI
on:
push:
branches: ['master']
pull_request:
branches: ['master']
permissions:
contents: read
jobs:
checks:
name: Checks
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install hadolint
shell: bash
run: |
set -euo pipefail
HADOLINT_VERSION=v2.14.0
sudo wget -q -O /usr/local/bin/hadolint "https://github.com/hadolint/hadolint/releases/download/${HADOLINT_VERSION}/hadolint-Linux-x86_64"
sudo chmod +x /usr/local/bin/hadolint
hadolint --version
- name: Run checks
run: |
pnpm run lint
pnpm run format:check
pnpm run lint:docker
unit-tests:
name: Unit and Workspace Tests
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Verify test toolchain dependencies
shell: bash
run: |
set -euo pipefail
node -e "require.resolve('jest')"
node -e "require.resolve('jest-environment-jsdom')"
- name: Run root and workspace tests
run: |
pnpm test
pnpm run test:workspaces
coverage:
name: Coverage
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Verify test toolchain dependencies
shell: bash
run: |
set -euo pipefail
node -e "require.resolve('jest')"
node -e "require.resolve('jest-environment-jsdom')"
- name: Run coverage
run: pnpm run testcoverage
- name: Upload coverage artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-report-node-24.16.0
path: coverage/
- name: Upload HTML coverage report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-html-report-node-24.16.0
path: coverage/lcov-report/
storybook:
name: Storybook
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Ensure Linux rolldown native binding
if: runner.os == 'Linux'
shell: bash
run: |
set -euo pipefail
if node -e "require.resolve('@rolldown/binding-linux-x64-gnu')" >/dev/null 2>&1; then
echo "rolldown Linux binding already present"
else
echo "rolldown Linux binding missing; forcing reinstall with minimumReleaseAge disabled"
pnpm install --force --frozen-lockfile --config.minimumReleaseAge=0
node -e "require.resolve('@rolldown/binding-linux-x64-gnu')"
fi
- name: Install Playwright browser
run: pnpm exec playwright install --with-deps chromium
- name: Run Storybook gates
run: |
pnpm run test:storybook
pnpm run build-storybook
browser:
name: Browser
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Playwright browser
run: pnpm exec playwright install --with-deps chromium
- name: Run browser tests
run: pnpm run test:browser
api-tests:
name: API Tests
runs-on: ubuntu-latest
env:
NODE_ENV: development
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js 24.16.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.16.0
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run API tests
run: pnpm run test:api
verify-ci:
name: Verify CI
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs:
- checks
- unit-tests
- storybook
- browser
- api-tests
steps:
- name: PR gates passed
run: echo "All PR CI gates passed"
verify-ci-main:
name: Verify CI (main)
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
needs:
- checks
- unit-tests
- coverage
- storybook
- browser
- api-tests
steps:
- name: Main gates passed
run: echo "All main-branch CI gates passed"
cross-language-toolchain:
name: Cross-Language Toolchain
runs-on: ubuntu-latest
env:
NODE_ENV: development
strategy:
matrix:
node-version: [24.16.0]
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
with:
version: 11.1.1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node-version }}
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
- name: Set up Ruby
uses: ruby/setup-ruby@12fd324f1d0b43274fdc8130f6980590a667c455 # v1
with:
ruby-version: '3.3'
- name: Set up PHP
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
with:
php-version: '8.3'
- name: Set up Java
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: '21'
- name: Set up .NET
uses: actions/setup-dotnet@9a946fdbd5fb07b82b2f5a4466058b876ab72bb2 # v5.3.0
with:
dotnet-version: '8.0.x'
- name: Install Perl and Kotlin compiler
run: |
sudo apt-get update
sudo apt-get install -y perl unzip
KOTLIN_VERSION=2.1.21
wget -q "https://github.com/JetBrains/kotlin/releases/download/v${KOTLIN_VERSION}/kotlin-compiler-${KOTLIN_VERSION}.zip"
unzip -q "kotlin-compiler-${KOTLIN_VERSION}.zip"
sudo mv kotlinc /opt/kotlinc
echo "/opt/kotlinc/bin" >> "$GITHUB_PATH"
- name: Verify language toolchains
run: |
node --version
python --version
ruby --version
php --version
perl --version
javac -version
dotnet --version
kotlinc -version
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: CLI pack smoke test
shell: bash
run: |
set -euo pipefail
rm -rf .tmp-pack
mkdir -p .tmp-pack
CORE_TARBALL="$(pnpm --filter @anywaydata/core pack --pack-destination ./.tmp-pack | tail -n 1)"
CLI_TARBALL="$(pnpm --filter @anywaydata/cli pack --pack-destination ./.tmp-pack | tail -n 1)"
CORE_TARBALL_ABS="$(realpath "${CORE_TARBALL}")"
CLI_TARBALL_ABS="$(realpath "${CLI_TARBALL}")"
echo "Core tarball: ${CORE_TARBALL_ABS}"
echo "CLI tarball: ${CLI_TARBALL_ABS}"
test -f "${CORE_TARBALL_ABS}"
test -f "${CLI_TARBALL_ABS}"
SMOKE_DIR="$(mktemp -d)"
export SMOKE_DIR
mkdir -p "${SMOKE_DIR}/core" "${SMOKE_DIR}/cli"
tar -xzf "${CORE_TARBALL_ABS}" -C "${SMOKE_DIR}/core"
tar -xzf "${CLI_TARBALL_ABS}" -C "${SMOKE_DIR}/cli"
node - <<NODE
const fs = require('node:fs');
const path = require('node:path');
const cliPkgPath = path.join(process.env.SMOKE_DIR, 'cli', 'package', 'package.json');
const cliPkg = JSON.parse(fs.readFileSync(cliPkgPath, 'utf8'));
cliPkg.dependencies = cliPkg.dependencies || {};
cliPkg.dependencies['@anywaydata/core'] = 'file:../../core/package';
fs.writeFileSync(cliPkgPath, JSON.stringify(cliPkg, null, 2));
NODE
cat "${SMOKE_DIR}/cli/package/package.json"
pnpm --dir "${SMOKE_DIR}/cli/package" install --frozen-lockfile=false
pnpm --dir "${SMOKE_DIR}/cli/package" list --depth 0
node "${SMOKE_DIR}/cli/package/src/node-entry.js" --help
echo "CLI pack smoke test passed with local core+cli tarballs: ${CORE_TARBALL}, ${CLI_TARBALL}"
- name: Build
run: pnpm run build:workspaces
- name: Set up Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.2.10
- name: Bun CLI entry smoke test
run: bun run apps/cli/src/bun-entry.js --help
docker-smoke:
name: Docker Smoke Tests
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Docker smoke test (API)
run: |
set -euo pipefail
cleanup() {
docker rm -f api-ci >/dev/null 2>&1 || true
}
trap cleanup EXIT
api_curl() {
if ! curl -fsS "$@"; then
echo "API smoke request failed: curl $*"
docker logs api-ci || true
exit 1
fi
}
docker build -f apps/api/Dockerfile -t anywaydata-api-ci .
docker run -d --name api-ci -p 18082:3000 anywaydata-api-ci
ready=0
for i in {1..40}; do
if ! docker ps --format '{{.Names}}' | grep -q '^api-ci$'; then
echo "API container exited before readiness check completed"
docker ps -a --filter "name=api-ci" || true
docker logs api-ci || true
exit 1
fi
if curl -fsS http://127.0.0.1:18082/v1/health >/dev/null; then
ready=1
break
fi
sleep 1
done
if [ "$ready" -ne 1 ]; then
docker logs api-ci || true
echo "API container did not become ready within timeout"
exit 1
fi
api_curl http://127.0.0.1:18082/v1/health | grep -qi "ok"
api_curl -X POST "http://127.0.0.1:18082/v1/generate" \
-H "content-type: application/json" \
-d '{"textSpec":"Name\nBob","rowCount":2,"outputFormat":"json"}' | grep -q '"format":"json"'
echo "API docker smoke test passed"
- name: Docker smoke test (Web)
run: |
set -euo pipefail
cleanup() {
docker rm -f web-ci >/dev/null 2>&1 || true
}
trap cleanup EXIT
web_curl() {
for attempt in {1..5}; do
if curl -fsS "$@"; then
return 0
fi
sleep 1
done
echo "Web smoke request failed after retries: curl $*"
docker ps -a --filter "name=web-ci" || true
docker logs web-ci || true
exit 1
}
docker build -f apps/web/Dockerfile -t anywaydata-web-ci .
docker run -d --rm --name web-ci -p 18080:80 anywaydata-web-ci
ready=0
for i in {1..20}; do
if ! docker ps --format '{{.Names}}' | grep -q '^web-ci$'; then
echo "Web container exited before readiness check completed"
docker ps -a --filter "name=web-ci" || true
docker logs web-ci || true
exit 1
fi
if curl -fsS http://127.0.0.1:18080/app.html >/dev/null; then
ready=1
break
fi
sleep 1
done
if [ "$ready" -ne 1 ]; then
docker logs web-ci || true
echo "Web container did not become ready within timeout"
exit 1
fi
web_curl http://127.0.0.1:18080/app.html | grep -q "AnyWayData"
web_curl http://127.0.0.1:18080/generator.html | grep -q "AnyWayData"
echo "Web docker smoke test passed"
- name: Docker smoke test (AnyWayData full site)
run: |
set -euo pipefail
cleanup() {
docker rm -f site-ci >/dev/null 2>&1 || true
}
trap cleanup EXIT
site_curl() {
for attempt in {1..5}; do
if curl -fsS "$@"; then
return 0
fi
sleep 1
done
echo "AnyWayData full-site smoke request failed after retries: curl $*"
docker ps -a --filter "name=site-ci" || true
docker logs site-ci || true
exit 1
}
docker build -f apps/anywaydata/Dockerfile -t anywaydata-site-ci .
docker run -d --rm --name site-ci -p 18081:8080 anywaydata-site-ci
ready=0
for i in {1..20}; do
if ! docker ps --format '{{.Names}}' | grep -q '^site-ci$'; then
echo "AnyWayData full-site container exited before readiness check completed"
docker ps -a --filter "name=site-ci" || true
docker logs site-ci || true
exit 1
fi
if curl -fsS http://127.0.0.1:18081/ >/dev/null; then
ready=1
break
fi
sleep 1
done
if [ "$ready" -ne 1 ]; then
docker logs site-ci || true
echo "AnyWayData full-site container did not become ready within timeout"
exit 1
fi
site_curl http://127.0.0.1:18081/ | grep -q "AnyWayData"
site_curl http://127.0.0.1:18081/app.html | grep -q "AnyWayData"
echo "AnyWayData full-site docker smoke test passed"