Load and save schema files #610
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |