Skip to content

Merge pull request #5012 from drizzle-team/ae-api-studio #5833

Merge pull request #5012 from drizzle-team/ae-api-studio

Merge pull request #5012 from drizzle-team/ae-api-studio #5833

name: Release (feature branch)
on:
push:
branches-ignore:
- main
pull_request: {}
concurrency:
group: feature-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
prepare:
runs-on: ubuntu-24.04
timeout-minutes: 25
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: 'team_KbvYUtAn1Tqytsj8HbNcYDqV'
steps:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with: { run_install: false }
- uses: actions/setup-node@v6
with: { node-version: '24', registry-url: 'https://registry.npmjs.org', cache: 'pnpm', cache-dependency-path: pnpm-lock.yaml }
- run: pnpm install --frozen-lockfile --prefer-offline
- name: Compute version suffix
id: meta
shell: bash
run: echo "suffix=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
- name: Build Prisma client
working-directory: drizzle-orm
run: pnpm prisma generate --schema src/prisma/schema.prisma
- name: Build all
run: pnpm build:artifact
- name: Upload build-dist
uses: actions/upload-artifact@v4
with:
name: build-dist
path: |
**/dist
**/*.tsbuildinfo
- name: Pack
run: pnpm pack:artifact
- uses: actions/upload-artifact@v4
with:
name: packages
path: |
drizzle-orm/package.tgz
drizzle-kit/package.tgz
drizzle-zod/package.tgz
drizzle-seed/package.tgz
drizzle-typebox/package.tgz
drizzle-valibot/package.tgz
drizzle-arktype/package.tgz
eslint-plugin-drizzle/package.tgz
# Tiny marker so other jobs can wait without failing
- name: Upload build-ready marker
run: mkdir -p .gh && echo "ok" > .gh/build-ready
- uses: actions/upload-artifact@v4
with:
name: build-ready
path: .gh/build-ready
- name: test:types & lint
run: pnpm test:types-lint
test:
# NOTE: no 'needs: [prepare]' on purpose — start early, warm DBs, then wait for artifacts
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- shard: int:gel
dbs: [gel]
- shard: int:singlestore
dbs: [singlestore]
- shard: int:singlestore-core
dbs: [singlestore-many]
- shard: int:singlestore-proxy
dbs: [singlestore-many]
- shard: int:mysql
dbs: [mysql]
- shard: int:postgres
dbs: [postgres]
- shard: int:sqlite
dbs: []
- shard: int:other
dbs: [mysql, mssql, cockroach, singlestore, postgres, postgres-postgis, postgres-vector]
- shard: int:planetscale
dbs: []
- shard: int:cockroach
dbs: [cockroach]
# TODO:
# - shard: int:bun
# dbs: [postgres, mysql]
- shard: int:mssql
dbs: [mssql]
- shard: orm
dbs: []
- shard: kit:other
dbs: [mysql]
- shard: kit:postgres
dbs: [postgres, postgres-postgis]
- shard: kit:cockroach
dbs: [cockroach]
- shard: kit:mssql
dbs: [mssql]
- shard: seed
dbs: [cockroach, mysql, mssql, postgres-postgis, singlestore]
- shard: validators
dbs: []
name: ${{ matrix.shard }}
steps:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with: { run_install: false }
- uses: actions/setup-node@v6
with: { node-version: '24', registry-url: 'https://registry.npmjs.org', cache: 'pnpm', cache-dependency-path: pnpm-lock.yaml }
- run: pnpm install --frozen-lockfile --prefer-offline
- name: Start DBs needed by shard (pre-warm)
if: ${{ matrix.dbs && join(matrix.dbs, ',') != '' }}
shell: bash
run: |
set -euxo pipefail
compose_files=()
for db in ${{ join(matrix.dbs, ' ') }}; do
case "$db" in
postgres) compose_files+=("-f" "compose/postgres.yml") ;;
postgres-postgis) compose_files+=("-f" "compose/postgres-postgis.yml") ;;
postgres-vector) compose_files+=("-f" "compose/postgres-vector.yml") ;;
mysql) compose_files+=("-f" "compose/mysql.yml") ;;
singlestore) compose_files+=("-f" "compose/singlestore.yml") ;;
singlestore-many) compose_files+=("-f" "compose/singlestore-many.yml") ;;
mssql) compose_files+=("-f" "compose/mssql.yml") ;;
cockroach) compose_files+=("-f" "compose/cockroach.yml") ;;
gel) compose_files+=("-f" "compose/gel.yml") ;;
*) echo "Unknown db '$db'"; exit 1 ;;
esac
done
docker compose "${compose_files[@]}" up -d
chmod +x compose/wait.sh
compose/wait.sh ${{ join(matrix.dbs, ' ') }}
- name: Wait for 'prepare' to finish (poll artifact)
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
run_id="${{ github.run_id }}"
repo="${{ github.repository }}"
echo "Waiting for 'build-ready' artifact from prepare job in run $run_id..."
for i in $(seq 1 120); do
artifacts_json="$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${repo}/actions/runs/${run_id}/artifacts")"
echo "$artifacts_json" | jq -e '.artifacts[] | select(.name=="build-ready")' >/dev/null 2>&1 && { echo "build-ready found"; break; }
echo "…still waiting ($i/120)"
sleep 5
done
- name: Download build-dist (compiled JS)
uses: actions/download-artifact@v4
with:
name: build-dist
path: .
# Prisma client was generated in prepare -> build outputs already contain it
# No `pnpm build` here — we reuse dist to save time
- uses: oven-sh/setup-bun@v2
- name: Run tests
env:
PG_CONNECTION_STRING: postgres://postgres:postgres@localhost:55433/drizzle
PG_VECTOR_CONNECTION_STRING: postgres://postgres:postgres@localhost:54321/drizzle
PG_POSTGIS_CONNECTION_STRING: postgres://postgres:postgres@localhost:54322/drizzle
POSTGIS_URL: postgres://postgres:postgres@localhost:54322/drizzle
MYSQL_CONNECTION_STRING: mysql://root:mysql@localhost:3306/drizzle
PLANETSCALE_CONNECTION_STRING: ${{ secrets.PLANETSCALE_CONNECTION_STRING }}
NEON_CONNECTION_STRING: ${{ secrets.NEON_CONNECTION_STRING }}
TIDB_CONNECTION_STRING: ${{ secrets.TIDB_CONNECTION_STRING }}
XATA_API_KEY: ${{ secrets.XATA_API_KEY }}
XATA_BRANCH: ${{ secrets.XATA_BRANCH }}
LIBSQL_URL: file:local.db
LIBSQL_REMOTE_URL: ${{ secrets.LIBSQL_REMOTE_URL }}
LIBSQL_REMOTE_TOKEN: ${{ secrets.LIBSQL_REMOTE_TOKEN }}
GEL_CONNECTION_STRING: gel://admin:password@localhost:56565/main
SINGLESTORE_CONNECTION_STRING: singlestore://root:singlestore@localhost:33307/
COCKROACH_CONNECTION_STRING: postgresql://root@127.0.0.1:26257/defaultdb?sslmode=disable
MSSQL_CONNECTION_STRING: mssql://SA:drizzle123PASSWORD!@localhost:1433?encrypt=true&trustServerCertificate=true
TEST_CONFIG_PATH_PREFIX: ./tests/cli/
working-directory: integration-tests
shell: bash
run: |
set -euxo pipefail
if [[ ${{ github.event_name }} != "push" && "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]]; then
export SKIP_EXTERNAL_DB_TESTS=1
fi
case ${{ matrix.shard }} in
int:gel)
if [[ -z "${SKIP_EXTERNAL_DB_TESTS:-}" ]]; then
pnpm --stream vitest --reporter=verbose --silent=false run tests/gel
fi
;;
int:singlestore) pnpm --stream vitest --reporter=verbose --silent=false run ./singlestore/singlestore-prefixed.test.ts ./singlestore/singlestore-custom.test.ts ;;
int:singlestore-core) pnpm --stream vitest --reporter=verbose --silent=false run ./singlestore/singlestore.test.ts ;;
int:singlestore-proxy) pnpm --stream vitest --reporter=verbose --silent=false run ./singlestore/singlestore-proxy.test.ts ;;
int:postgres)
if [[ -z "${SKIP_EXTERNAL_DB_TESTS:-}" ]]; then
pnpm --stream vitest --reporter=verbose --silent=false run tests/pg/
fi
;;
int:mysql)
pnpm --stream test:mysql
;;
int:tidb)
if [[ -z "${SKIP_EXTERNAL_DB_TESTS:-}" ]]; then
pnpm --stream vitest --reporter=verbose --silent=false tests/mysql/tidb
fi
;;
int:planetscale)
if [[ -z "${SKIP_EXTERNAL_DB_TESTS:-}" ]]; then
pnpm --stream test:planetscale
fi
;;
int:cockroach) pnpm --stream vitest --reporter=verbose --silent=false run tests/cockroach ;;
int:mssql) pnpm --stream vitest --reporter=verbose --silent=false run tests/mssql ;;
int:sqlite) pnpm --stream vitest --reporter=verbose --silent=false run tests/sqlite ;;
kit:other) cd ../drizzle-kit && pnpm --stream run test:other ;;
kit:postgres) cd ../drizzle-kit && pnpm --stream run test:postgres ;;
kit:cockroach) cd ../drizzle-kit && pnpm --stream run test:cockroach ;;
kit:mssql) cd ../drizzle-kit && pnpm --stream run test:mssql ;;
validators)
(cd ../drizzle-zod && pnpm --stream test --reporter=verbose --silent=false)
(cd ../drizzle-valibot && pnpm --stream test --reporter=verbose --silent=false)
(cd ../drizzle-arktype && pnpm --stream test --reporter=verbose --silent=false)
(cd ../drizzle-typebox && pnpm --stream test --reporter=verbose --silent=false)
;;
orm|seed)
(cd ../drizzle-${{ matrix.shard }} && pnpm --stream test --reporter=verbose --silent=false)
;;
int:bun) bun test ./tests/bun/ ;;
int:other)
pnpm --stream vitest --reporter=verbose --silent=false run tests \
--exclude ./tests/gel/ \
--exclude ./tests/mysql/ \
--exclude ./tests/cockroach/ \
--exclude ./tests/singlestore/ \
--exclude ./tests/mssql/ \
--exclude ./tests/pg/ \
--exclude ./tests/sqlite/ \
--exclude ./tests/bun/
;;
*) echo "Unknown shard: ${{matrix.shard}}"; exit 1 ;;
esac
attw:
needs: [prepare]
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { run_install: false }
- uses: actions/setup-node@v6
with: { node-version: '24', registry-url: 'https://registry.npmjs.org', cache: 'pnpm', cache-dependency-path: pnpm-lock.yaml }
- run: pnpm install --frozen-lockfile --prefer-offline
- uses: oven-sh/setup-bun@v2
- name: Download package tarball
uses: actions/download-artifact@v4
with:
name: packages
path: ./artifacts
- name: Run @arethetypeswrong/cli
run: |
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-kit/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-zod/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-seed/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-typebox/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-valibot/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/drizzle-arktype/package.tgz
bun --bun run ./attw-fork/src/run.ts ./artifacts/eslint-plugin-drizzle/package.tgz
attw-orm:
needs: [prepare]
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
matrix:
package: [node10, node16-cjs, node16-esm, bundler]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { run_install: false }
- uses: actions/setup-node@v6
with: { node-version: '24', registry-url: 'https://registry.npmjs.org', cache: 'pnpm', cache-dependency-path: pnpm-lock.yaml }
- run: pnpm fetch && pnpm install --frozen-lockfile --prefer-offline
- uses: oven-sh/setup-bun@v2
- name: Download drizzle-orm tarball
uses: actions/download-artifact@v4
with:
name: packages
path: ./artifacts
- name: Run @arethetypeswrong/cli
working-directory: drizzle-orm
run: bun --bun run ../attw-fork/src/run.ts ../artifacts/drizzle-orm/package.tgz ${{ matrix.package }}
release:
needs: [test, prepare, attw, attw-orm]
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions: { contents: read, id-token: write }
# force empty so npm can use OIDC
env:
NODE_AUTH_TOKEN: ""
NPM_TOKEN: ""
strategy:
matrix:
package: [drizzle-orm, drizzle-kit, drizzle-zod, drizzle-seed, drizzle-typebox, drizzle-valibot, drizzle-arktype, eslint-plugin-drizzle]
steps:
- uses: actions/checkout@v4
# don't specify registry url, so there's no .npmrc config file
- uses: actions/setup-node@v6
with: { node-version: '24' }
# nuke, so npm can use OIDC
- name: Remove temp npmrc
run: rm -f "$NPM_CONFIG_USERCONFIG"
# >= 11.5.1 for trusted publishing
- name: Update NPM
run: npm install -g npm@latest
- name: Download package tarball
uses: actions/download-artifact@v4
with:
name: packages
path: ./artifacts
- name: Check preconditions (from tarball)
id: checks
shell: bash
run: |
set -euxo pipefail
_version="$(tar -xOf ./artifacts/${{ matrix.package }}/package.tgz package/package.json | jq -r .version)"
tag="${{ github.ref_name }}"
suffix=$(git rev-parse --short HEAD)
version="$_version-$suffix"
tmpdir="$(mktemp -d)"
tar -xzf ./artifacts/${{ matrix.package }}/package.tgz -C "$tmpdir"
jq --arg v "$version" '.version = $v' \
"$tmpdir/package/package.json" > "$tmpdir/package/package.json.tmp"
mv "$tmpdir/package/package.json.tmp" "$tmpdir/package/package.json"
tar -czf ./artifacts/${{ matrix.package }}/package.tgz -C "$tmpdir" package
rm -rf "$tmpdir"
is_published="$(npm view ${{ matrix.package }} versions --json | jq -r '.[] | select(. == "'$version'") | . == "'$version'"')"
if [[ "$is_published" == "true" ]]; then
echo "\`${{ matrix.package }}@$version\` already published, tagging \`$tag\`" >> $GITHUB_STEP_SUMMARY
else
{ echo "version=$version"; echo "tag=$tag"; echo "has_new_release=true"; } >> $GITHUB_OUTPUT
fi
- name: Publish (from tarball)
if: steps.checks.outputs.has_new_release == 'true'
shell: bash
run: |
set -euxo pipefail
npm publish ./artifacts/${{ matrix.package }}/package.tgz --tag "${{ steps.checks.outputs.tag }}"
echo "npm: \`${{ matrix.package }}@${{ steps.checks.outputs.tag }} | ${{ steps.checks.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY