diff --git a/.github/workflows/preview-cli-package.yml b/.github/workflows/preview-cli-package.yml index 343834f..fb9e611 100644 --- a/.github/workflows/preview-cli-package.yml +++ b/.github/workflows/preview-cli-package.yml @@ -20,29 +20,18 @@ jobs: pull-requests: write steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 with: - node-version: 24 + cache: true - - name: Enable pnpm - run: | - corepack enable - PNPM_VERSION="$(node -p 'const pm = require("./package.json").packageManager; const match = pm && pm.match(/^pnpm@(.+)$/); if (!match) throw new Error("packageManager must be pnpm@"); match[1]')" - corepack prepare "pnpm@${PNPM_VERSION}" --activate - echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV" - - - name: Cache pnpm store - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - path: ${{ env.PNPM_STORE_PATH }} - key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - pnpm-store-${{ runner.os }}- + node-version-file: .node-version - name: Install dependencies run: pnpm install --frozen-lockfile @@ -50,7 +39,8 @@ jobs: - name: Resolve preview version id: cli_version run: | - node scripts/resolve-cli-version.mjs pr \ + node scripts/resolve-package-version.mjs pr \ + --package-dir packages/cli \ --sha '${{ github.event.pull_request.head.sha }}' \ --pr-number '${{ github.event.pull_request.number }}' >> "$GITHUB_OUTPUT" @@ -70,14 +60,15 @@ jobs: id: compute_build run: pnpm --filter @prisma/compute build - - name: Prepare staged preview package - id: prepare_preview - run: node scripts/prepare-cli-publish.mjs .publish/cli --version '${{ steps.cli_version.outputs.version }}' + - name: Set preview package version + id: set_preview_version + working-directory: packages/cli + run: pnpm version '${{ steps.cli_version.outputs.version }}' --no-git-tag-version - name: Publish installable PR preview id: publish_preview continue-on-error: ${{ vars.CLI_PR_PREVIEW_REQUIRED != 'true' }} - run: pnpm exec pkg-pr-new publish --bin --comment=update .publish/cli + run: pnpm exec pkg-pr-new publish --bin --comment=update packages/cli - name: Summarize PR preview publish if: ${{ always() }} @@ -90,7 +81,7 @@ jobs: echo "- Compute tests: \`${{ steps.compute_tests.outcome || 'skipped' }}\`" echo "- Build: \`${{ steps.cli_build.outcome || 'skipped' }}\`" echo "- Compute build: \`${{ steps.compute_build.outcome || 'skipped' }}\`" - echo "- Package staging: \`${{ steps.prepare_preview.outcome || 'skipped' }}\`" + echo "- Version injection: \`${{ steps.set_preview_version.outcome || 'skipped' }}\`" echo "- pkg.pr.new publish: \`${{ steps.publish_preview.outcome || 'skipped' }}\`" PUBLISH_OUTCOME="${{ steps.publish_preview.outcome || 'skipped' }}" if [ "${PUBLISH_OUTCOME}" != "success" ]; then diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml index 9f630fa..14c45d4 100644 --- a/.github/workflows/publish-cli.yml +++ b/.github/workflows/publish-cli.yml @@ -18,6 +18,7 @@ concurrency: jobs: publish-dev: + name: Publish dev package if: ${{ github.event_name == 'push' }} runs-on: ubuntu-latest permissions: @@ -25,29 +26,17 @@ jobs: id-token: write steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 with: - node-version: 24 - registry-url: https://registry.npmjs.org + cache: true - - name: Enable pnpm - run: | - corepack enable - PNPM_VERSION="$(node -p 'const pm = require("./package.json").packageManager; const match = pm && pm.match(/^pnpm@(.+)$/); if (!match) throw new Error("packageManager must be pnpm@"); match[1]')" - corepack prepare "pnpm@${PNPM_VERSION}" --activate - echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV" - - - name: Cache pnpm store - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - path: ${{ env.PNPM_STORE_PATH }} - key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - pnpm-store-${{ runner.os }}- + node-version-file: .node-version - name: Install dependencies run: pnpm install --frozen-lockfile @@ -55,75 +44,18 @@ jobs: - name: Resolve dev version id: cli_version run: | - node scripts/resolve-cli-version.mjs dev \ + node scripts/resolve-package-version.mjs dev \ + --package-dir packages/cli \ --run-number "${GITHUB_RUN_NUMBER}" \ --run-attempt "${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_OUTPUT" - - name: Fail if version already exists on npm - run: | - PACKAGE='@prisma/cli' - VERSION='${{ steps.cli_version.outputs.version }}' - if npm view "${PACKAGE}@${VERSION}" version >/dev/null 2>&1; then - echo "${PACKAGE}@${VERSION} already exists on npm." - exit 1 - fi - - - name: Run focused CLI tests - run: pnpm --filter @prisma/cli test - - - name: Build CLI package - run: pnpm --filter @prisma/cli build - - - name: Prepare staged publish package - run: node scripts/prepare-cli-publish.mjs .publish/cli --version '${{ steps.cli_version.outputs.version }}' - - - name: Audit staged package contents - working-directory: .publish/cli - run: | - PACK_JSON="$(npm pack --dry-run --json)" - PACK_JSON="${PACK_JSON}" node -e " - const pack = JSON.parse(process.env.PACK_JSON)[0] - const files = pack.files.map((file) => file.path).sort() - const forbidden = files.filter((file) => - file.startsWith('src/') || - file.startsWith('tests/') || - file.startsWith('fixtures/') || - file.startsWith('docs/') || - file.startsWith('.prisma/') || - file.startsWith('.publish/') - ) - if (forbidden.length) { - console.error('Forbidden files in npm package:', forbidden.join(', ')) - process.exit(1) - } - for (const required of ['dist/cli.js', 'README.md', 'LICENSE', 'package.json']) { - if (!files.includes(required)) { - console.error('Missing required package file:', required) - process.exit(1) - } - } - " - - - name: Smoke test staged tarball install - run: | - TARBALL="$(cd .publish/cli && npm pack --silent)" - TMPDIR="$(mktemp -d)" - cat > "${TMPDIR}/package.json" <<'EOF' - { - "name": "cli-publish-smoke", - "private": true - } - EOF - pnpm add -D "${PWD}/.publish/cli/${TARBALL}" --dir "${TMPDIR}" - ( - cd "${TMPDIR}" - pnpm prisma-cli --help - pnpm prisma-cli auth whoami --json - ) + - name: Set package version + working-directory: packages/cli + run: pnpm version '${{ steps.cli_version.outputs.version }}' --no-git-tag-version - name: Publish dev package to npm - working-directory: .publish/cli - run: npm publish --access public --tag dev --provenance + working-directory: packages/cli + run: pnpm publish --access public --tag dev --provenance --no-git-checks - name: Summarize dev publish run: | @@ -136,6 +68,7 @@ jobs: } >> "$GITHUB_STEP_SUMMARY" publish-official: + name: Publish official release if: ${{ github.event_name == 'workflow_dispatch' }} runs-on: ubuntu-latest permissions: @@ -150,30 +83,17 @@ jobs: exit 1 fi - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: - fetch-depth: 0 persist-credentials: false - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 with: - node-version: 24 - registry-url: https://registry.npmjs.org + cache: true - - name: Enable pnpm - run: | - corepack enable - PNPM_VERSION="$(node -p 'const pm = require("./package.json").packageManager; const match = pm && pm.match(/^pnpm@(.+)$/); if (!match) throw new Error("packageManager must be pnpm@"); match[1]')" - corepack prepare "pnpm@${PNPM_VERSION}" --activate - echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV" - - - name: Cache pnpm store - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - path: ${{ env.PNPM_STORE_PATH }} - key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - pnpm-store-${{ runner.os }}- + node-version-file: .node-version - name: Install dependencies run: pnpm install --frozen-lockfile @@ -182,17 +102,11 @@ jobs: id: cli_version run: | PACKAGE='@prisma/cli' - LATEST="$(npm view "${PACKAGE}" dist-tags.latest --silent 2>/dev/null || true)" - node scripts/resolve-cli-version.mjs next-beta --latest "${LATEST}" >> "$GITHUB_OUTPUT" - - - name: Fail if version already exists on npm - run: | - PACKAGE='@prisma/cli' - VERSION='${{ steps.cli_version.outputs.version }}' - if npm view "${PACKAGE}@${VERSION}" version >/dev/null 2>&1; then - echo "${PACKAGE}@${VERSION} already exists on npm." - exit 1 - fi + LATEST="$(pnpm view "${PACKAGE}" dist-tags.latest --silent 2>/dev/null || true)" + echo "latest=${LATEST}" >> "$GITHUB_OUTPUT" + node scripts/resolve-package-version.mjs next-beta \ + --package-dir packages/cli \ + --latest "${LATEST}" >> "$GITHUB_OUTPUT" - name: Fail if release tag already exists run: | @@ -203,58 +117,13 @@ jobs: exit 1 fi - - name: Run focused CLI tests - run: pnpm --filter @prisma/cli test - - - name: Build CLI package - run: pnpm --filter @prisma/cli build + - name: Set package version + working-directory: packages/cli + run: pnpm version '${{ steps.cli_version.outputs.version }}' --no-git-tag-version - - name: Prepare staged publish package - run: node scripts/prepare-cli-publish.mjs .publish/cli --version '${{ steps.cli_version.outputs.version }}' - - - name: Audit staged package contents - working-directory: .publish/cli - run: | - PACK_JSON="$(npm pack --dry-run --json)" - PACK_JSON="${PACK_JSON}" node -e " - const pack = JSON.parse(process.env.PACK_JSON)[0] - const files = pack.files.map((file) => file.path).sort() - const forbidden = files.filter((file) => - file.startsWith('src/') || - file.startsWith('tests/') || - file.startsWith('fixtures/') || - file.startsWith('docs/') || - file.startsWith('.prisma/') || - file.startsWith('.publish/') - ) - if (forbidden.length) { - console.error('Forbidden files in npm package:', forbidden.join(', ')) - process.exit(1) - } - for (const required of ['dist/cli.js', 'README.md', 'LICENSE', 'package.json']) { - if (!files.includes(required)) { - console.error('Missing required package file:', required) - process.exit(1) - } - } - " - - - name: Smoke test staged tarball install - run: | - TARBALL="$(cd .publish/cli && npm pack --silent)" - TMPDIR="$(mktemp -d)" - cat > "${TMPDIR}/package.json" <<'EOF' - { - "name": "cli-publish-smoke", - "private": true - } - EOF - pnpm add -D "${PWD}/.publish/cli/${TARBALL}" --dir "${TMPDIR}" - ( - cd "${TMPDIR}" - pnpm prisma-cli --help - pnpm prisma-cli auth whoami --json - ) + - name: Validate package artifact + working-directory: packages/cli + run: pnpm pack --dry-run - name: Ensure release still targets the latest main if: ${{ !inputs.dry_run }} @@ -267,8 +136,8 @@ jobs: - name: Publish official package to npm if: ${{ !inputs.dry_run }} - working-directory: .publish/cli - run: npm publish --access public --tag latest --provenance + working-directory: packages/cli + run: pnpm publish --access public --tag latest --provenance --no-git-checks - name: Create release tag if: ${{ !inputs.dry_run }} diff --git a/.github/workflows/publish-compute.yml b/.github/workflows/publish-compute.yml new file mode 100644 index 0000000..7275ec7 --- /dev/null +++ b/.github/workflows/publish-compute.yml @@ -0,0 +1,174 @@ +name: Publish Compute + +on: + push: + branches: + - main + workflow_dispatch: + inputs: + dry_run: + description: Validate the next official beta release without publishing or tagging + required: false + type: boolean + default: false + +concurrency: + group: publish-compute-${{ github.event_name }} + cancel-in-progress: false + +jobs: + publish-dev: + name: Publish dev package + if: ${{ github.event_name == 'push' }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + with: + cache: true + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: .node-version + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Resolve dev version + id: compute_version + run: | + node scripts/resolve-package-version.mjs dev \ + --package-dir packages/compute \ + --run-number "${GITHUB_RUN_NUMBER}" \ + --run-attempt "${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_OUTPUT" + + - name: Set package version + working-directory: packages/compute + run: pnpm version '${{ steps.compute_version.outputs.version }}' --no-git-tag-version + + - name: Publish dev package to npm + working-directory: packages/compute + run: pnpm publish --access public --tag dev --provenance --no-git-checks + + - name: Summarize dev publish + run: | + VERSION='${{ steps.compute_version.outputs.version }}' + { + echo "## Publish Compute Dev" + echo + echo "- npm package: \`@prisma/compute@${VERSION}\`" + echo "- npm dist-tag: \`dev\`" + } >> "$GITHUB_STEP_SUMMARY" + + publish-official: + name: Publish official release + if: ${{ github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + + steps: + - name: Ensure workflow runs from main + run: | + if [ "${GITHUB_REF}" != "refs/heads/main" ]; then + echo "This workflow only publishes official releases from main." + exit 1 + fi + + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 + with: + cache: true + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: .node-version + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Resolve next beta version + id: compute_version + run: | + PACKAGE='@prisma/compute' + LATEST="$(pnpm view "${PACKAGE}" dist-tags.latest --silent 2>/dev/null || true)" + echo "latest=${LATEST}" >> "$GITHUB_OUTPUT" + node scripts/resolve-package-version.mjs next-beta \ + --package-dir packages/compute \ + --latest "${LATEST}" >> "$GITHUB_OUTPUT" + + - name: Fail if release tag already exists + run: | + VERSION='${{ steps.compute_version.outputs.version }}' + TAG="compute-v${VERSION}" + if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then + echo "Release tag ${TAG} already exists." + exit 1 + fi + + - name: Set package version + working-directory: packages/compute + run: pnpm version '${{ steps.compute_version.outputs.version }}' --no-git-tag-version + + - name: Validate package artifact + working-directory: packages/compute + run: pnpm pack --dry-run + + - name: Ensure release still targets the latest main + if: ${{ !inputs.dry_run }} + run: | + git fetch origin main + if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then + echo "main moved while the release was running. Rerun the workflow from the latest main." + exit 1 + fi + + - name: Publish official package to npm + if: ${{ !inputs.dry_run }} + working-directory: packages/compute + run: pnpm publish --access public --tag latest --provenance --no-git-checks + + - name: Create release tag + if: ${{ !inputs.dry_run }} + env: + GH_TOKEN: ${{ github.token }} + run: | + VERSION='${{ steps.compute_version.outputs.version }}' + TAG="compute-v${VERSION}" + SHA="$(git rev-parse HEAD)" + gh api \ + --method POST \ + "repos/${GITHUB_REPOSITORY}/git/refs" \ + -f ref="refs/tags/${TAG}" \ + -f sha="${SHA}" + + - name: Summarize release + run: | + VERSION='${{ steps.compute_version.outputs.version }}' + LATEST='${{ steps.compute_version.outputs.latest }}' + { + echo "## Publish Compute Official" + echo + echo "- Previous npm latest: \`${LATEST:-none}\`" + echo "- Version: \`${VERSION}\`" + echo "- Dry run: \`${{ inputs.dry_run }}\`" + if [ '${{ inputs.dry_run }}' = 'true' ]; then + echo "- Publish: skipped" + echo "- Tag creation: skipped" + else + echo "- npm package: \`@prisma/compute@${VERSION}\`" + echo "- npm dist-tag: \`latest\`" + echo "- git tag: \`compute-v${VERSION}\`" + fi + } >> "$GITHUB_STEP_SUMMARY" diff --git a/AGENTS.md b/AGENTS.md index f305150..d3183fd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,109 +2,25 @@ ## Purpose -This repo uses document-driven development for the new Prisma CLI. +Use this file for repo-wide instructions. Use package-local `AGENTS.md` files for package-specific rules. -The docs in `docs/product` are the source of truth. Do not invent product behavior in code that is not already grounded in those docs. If behavior is unclear or missing, update docs first. +## Development Setup -## What This CLI Is +1. Run `pnpm install`. +2. Use `pnpm --filter