From 8405076e7c70707699e00cca73c80794e21c0b2e Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 13:24:45 +0200 Subject: [PATCH 1/6] ci(release): set up jsr releasing --- .github/workflows/publish.yml | 2 + docs/JSR_PUBLISHING.md | 61 +++++++++++++ package-lock.json | 1 + package.json | 1 + packages/core/auth-js/jsr.json | 6 ++ packages/core/postgrest-js/jsr.json | 6 ++ packages/core/realtime-js/jsr.json | 6 ++ packages/core/storage-js/jsr.json | 6 ++ scripts/publish-to-jsr.ts | 129 ++++++++++++++++++++++++++++ scripts/release-canary.ts | 10 +++ scripts/release-stable.ts | 10 +++ 11 files changed, 238 insertions(+) create mode 100644 docs/JSR_PUBLISHING.md create mode 100644 packages/core/auth-js/jsr.json create mode 100644 packages/core/postgrest-js/jsr.json create mode 100644 packages/core/realtime-js/jsr.json create mode 100644 packages/core/storage-js/jsr.json create mode 100644 scripts/publish-to-jsr.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8a63aadc9..81724cff2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -111,6 +111,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} GH_TOKEN: ${{ steps.app-token.outputs.token }} + JSR_TOKEN: ${{ secrets.JSR_TOKEN }} shell: bash run: npm run release-stable -- --versionSpecifier "${{ github.event.inputs.version_specifier }}" @@ -276,6 +277,7 @@ jobs: NPM_CONFIG_PROVENANCE: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + JSR_TOKEN: ${{ secrets.JSR_TOKEN }} notify-stable-failure: name: Notify Slack for Stable failure diff --git a/docs/JSR_PUBLISHING.md b/docs/JSR_PUBLISHING.md new file mode 100644 index 000000000..4e9819f2d --- /dev/null +++ b/docs/JSR_PUBLISHING.md @@ -0,0 +1,61 @@ +# JSR Publishing Setup + +This document explains how JSR (JavaScript Registry) publishing is configured in this monorepo. + +## Overview + +All Supabase JavaScript packages are published to both npm and JSR. JSR publishing happens automatically after npm publishing in both stable and canary releases. + +## Current Status + +โœ… **JSR publishing is configured but requires authentication setup** + +The following packages are configured for JSR publishing: + +- @supabase/auth-js +- @supabase/functions-js +- @supabase/postgrest-js +- @supabase/realtime-js +- @supabase/storage-js +- @supabase/supabase-js + +## Setup Requirements + +### 1. Create JSR Access Token + +1. Go to https://jsr.io/account/tokens +2. Create a new access token with publish permissions +3. Copy the token (it won't be shown again) + +### 2. Add GitHub Secret + +Add the token as a GitHub secret named `JSR_TOKEN` in your repository settings. + +## How It Works + +1. **Version Synchronization**: The `jsr.json` files use `"0.0.0-automated"` as a placeholder. The publish script updates this to match the package.json version before publishing. + +2. **Type Checking**: Some packages have missing explicit return types. These use the `--allow-slow-types` flag temporarily. Future improvements should add explicit return types to improve performance. + +3. **Provenance**: When running in GitHub Actions with proper authentication, the `--provenance` flag is added for trusted publishing. + +4. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. + +## Files Involved + +- `scripts/publish-to-jsr.ts` - Main JSR publishing script +- `scripts/release-stable.ts` - Calls JSR publish after stable npm release +- `scripts/release-canary.ts` - Calls JSR publish after canary npm release +- `packages/core/*/jsr.json` - JSR configuration for each package + +## Testing + +To test JSR publishing locally: + +```bash +# Dry run (no authentication needed) +npx tsx scripts/publish-to-jsr.ts --dry-run + +# Actual publish (requires authentication) +JSR_TOKEN=your-token-here npx tsx scripts/publish-to-jsr.ts +``` diff --git a/package-lock.json b/package-lock.json index 68e36d0ba..cbd579a63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ "jiti": "2.4.2", "jsonc-eslint-parser": "^2.1.0", "jsonwebtoken": "^9.0.0", + "jsr": "^0.13.5", "nx": "21.6.2", "prettier": "^3.6.2", "ts-jest": "^29.4.2", diff --git a/package.json b/package.json index 837d37040..a6a850dd3 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "jiti": "2.4.2", "jsonc-eslint-parser": "^2.1.0", "jsonwebtoken": "^9.0.0", + "jsr": "^0.13.5", "nx": "21.6.2", "prettier": "^3.6.2", "ts-jest": "^29.4.2", diff --git a/packages/core/auth-js/jsr.json b/packages/core/auth-js/jsr.json new file mode 100644 index 000000000..fdbea5296 --- /dev/null +++ b/packages/core/auth-js/jsr.json @@ -0,0 +1,6 @@ +{ + "name": "@supabase/auth-js", + "version": "0.0.0", + "exports": "./src/index.ts", + "exclude": ["example", "test", "infra"] +} diff --git a/packages/core/postgrest-js/jsr.json b/packages/core/postgrest-js/jsr.json new file mode 100644 index 000000000..8bcaee21c --- /dev/null +++ b/packages/core/postgrest-js/jsr.json @@ -0,0 +1,6 @@ +{ + "name": "@supabase/postgrest-js", + "version": "0.0.0-automated", + "exports": "./src/index.ts", + "exclude": ["test", "infra"] +} diff --git a/packages/core/realtime-js/jsr.json b/packages/core/realtime-js/jsr.json new file mode 100644 index 000000000..cae46ec97 --- /dev/null +++ b/packages/core/realtime-js/jsr.json @@ -0,0 +1,6 @@ +{ + "name": "@supabase/realtime-js", + "version": "0.0.0-automated", + "exports": "./src/index.ts", + "exclude": ["example", "test"] +} diff --git a/packages/core/storage-js/jsr.json b/packages/core/storage-js/jsr.json new file mode 100644 index 000000000..9b0e3602b --- /dev/null +++ b/packages/core/storage-js/jsr.json @@ -0,0 +1,6 @@ +{ + "name": "@supabase/storage-js", + "version": "0.0.0", + "exports": "./src/index.ts", + "exclude": ["test", "infra"] +} diff --git a/scripts/publish-to-jsr.ts b/scripts/publish-to-jsr.ts new file mode 100644 index 000000000..127dc1267 --- /dev/null +++ b/scripts/publish-to-jsr.ts @@ -0,0 +1,129 @@ +import { execSync } from 'child_process' +import { readFileSync, writeFileSync, existsSync } from 'fs' +import { join } from 'path' + +const packages = [ + 'auth-js', + 'functions-js', + 'postgrest-js', + 'realtime-js', + 'storage-js', + 'supabase-js', +] + +function getArg(name: string): string | undefined { + const idx = process.argv.findIndex((a) => a === `--${name}` || a.startsWith(`--${name}=`)) + if (idx === -1) return undefined + const token = process.argv[idx] + if (token.includes('=')) return token.split('=')[1] + return process.argv[idx + 1] +} + +const tag = getArg('tag') || 'latest' +const dryRun = process.argv.includes('--dry-run') + +// Packages that need --allow-slow-types due to missing explicit return types +// These should be fixed in the future but for now we'll allow slow types +const packagesWithSlowTypes = ['auth-js', 'postgrest-js', 'storage-js', 'realtime-js'] + +function safeExec(cmd: string, opts = {}) { + try { + return execSync(cmd, { stdio: 'inherit', ...opts }) + } catch (err) { + console.error(`โŒ Command failed: ${cmd}`) + throw err + } +} + +async function publishToJsr() { + console.log(`\n๐Ÿ“ฆ Publishing packages to JSR (tag: ${tag})...\n`) + + // Check if we have JSR token for authentication + const jsrToken = process.env.JSR_TOKEN + if (!jsrToken && !dryRun) { + console.warn('โš ๏ธ JSR_TOKEN environment variable not set.') + console.warn(' Publishing will require interactive authentication or will fail in CI.') + console.warn(' To set up JSR publishing:') + console.warn(' 1. Create a JSR access token at https://jsr.io/account/tokens') + console.warn(' 2. Add JSR_TOKEN as a GitHub secret') + console.warn(' 3. Pass it to the release script in the workflow') + } + + let hasErrors = false + const results: { package: string; success: boolean; error?: string }[] = [] + + for (const pkg of packages) { + const packagePath = join(process.cwd(), 'packages', 'core', pkg) + const jsrPath = join(packagePath, 'jsr.json') + + // Check if jsr.json exists + if (!existsSync(jsrPath)) { + console.log(`โš ๏ธ Skipping ${pkg}: no jsr.json file found`) + continue + } + + // Read the package.json to get the current version + const packageJsonPath = join(packagePath, 'package.json') + const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) + const version = packageJson.version + + // Update jsr.json with the current version + const jsrConfig = JSON.parse(readFileSync(jsrPath, 'utf-8')) + jsrConfig.version = version + writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n') + + console.log(`\n๐Ÿ“ค Publishing @supabase/${pkg}@${version} to JSR...`) + + try { + // Determine if we need to allow slow types for this package + const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' + + // Add authentication token if available + const tokenFlag = jsrToken && !dryRun ? ` --token ${jsrToken}` : '' + + // Add provenance flag if we're in GitHub Actions CI + const provenanceFlag = process.env.GITHUB_ACTIONS && !dryRun ? ' --provenance' : '' + + // Change to package directory and publish + const publishCmd = dryRun + ? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty${allowSlowTypes}` + : `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${tokenFlag}${provenanceFlag}` + + safeExec(publishCmd) + + console.log(`โœ… Successfully published @supabase/${pkg}@${version} to JSR`) + results.push({ package: pkg, success: true }) + } catch (error) { + const errorMsg = error instanceof Error ? error.message : String(error) + console.error(`โŒ Failed to publish ${pkg} to JSR: ${errorMsg}`) + results.push({ package: pkg, success: false, error: errorMsg }) + hasErrors = true + } + } + + // Summary + console.log('\n' + '='.repeat(50)) + console.log('JSR Publishing Summary:') + console.log('='.repeat(50)) + + for (const result of results) { + const icon = result.success ? 'โœ…' : 'โŒ' + const status = result.success ? 'SUCCESS' : 'FAILED' + console.log(`${icon} ${result.package}: ${status}`) + if (result.error) { + console.log(` Error: ${result.error}`) + } + } + + if (hasErrors && !dryRun) { + console.log('\nโš ๏ธ Some packages failed to publish to JSR.') + console.log('This does not affect the npm release which has already succeeded.') + // Don't exit with error to avoid failing the entire release + } +} + +// Run the script +publishToJsr().catch((error) => { + console.error('Unexpected error:', error) + process.exit(1) +}) diff --git a/scripts/release-canary.ts b/scripts/release-canary.ts index 7fe18a8c8..786596474 100644 --- a/scripts/release-canary.ts +++ b/scripts/release-canary.ts @@ -78,5 +78,15 @@ import { execSync } from 'child_process' console.log('โš ๏ธ Continuing with release despite gotrue-js publish failure') } + // Publish all packages to JSR + console.log('\n๐Ÿ“ฆ Publishing packages to JSR (canary)...') + try { + execSync('npx tsx scripts/publish-to-jsr.ts --tag=canary', { stdio: 'inherit' }) + } catch (error) { + console.error('โŒ Failed to publish to JSR:', error) + // Don't fail the entire release if JSR publishing fails + console.log('โš ๏ธ Continuing with release despite JSR publish failure') + } + process.exit(Object.values(publishResult).every((result) => result.code === 0) ? 0 : 1) })() diff --git a/scripts/release-stable.ts b/scripts/release-stable.ts index a1f58d2d6..b7ff67f4d 100644 --- a/scripts/release-stable.ts +++ b/scripts/release-stable.ts @@ -142,6 +142,16 @@ function safeExec(cmd: string, opts = {}) { console.log('โš ๏ธ Continuing with release despite gotrue-js publish failure') } + // Publish all packages to JSR + console.log('\n๐Ÿ“ฆ Publishing packages to JSR...') + try { + safeExec('npx tsx scripts/publish-to-jsr.ts --tag=latest') + } catch (error) { + console.error('โŒ Failed to publish to JSR:', error) + // Don't fail the entire release if JSR publishing fails + console.log('โš ๏ธ Continuing with release despite JSR publish failure') + } + // ---- CREATE RELEASE BRANCH + PR ---- process.env.GITHUB_TOKEN = process.env.RELEASE_GITHUB_TOKEN From c6a0ee07f71a6252ae05172e3ef23fcdb7e51a73 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 15:59:55 +0200 Subject: [PATCH 2/6] chore(ci): a couple of fixes --- .github/workflows/publish.yml | 2 - docs/JSR_PUBLISHING.md | 75 ++++++++++++++++++++++++++++------- scripts/publish-to-jsr.ts | 43 +++++++++++++------- 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 81724cff2..8a63aadc9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -111,7 +111,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} GH_TOKEN: ${{ steps.app-token.outputs.token }} - JSR_TOKEN: ${{ secrets.JSR_TOKEN }} shell: bash run: npm run release-stable -- --versionSpecifier "${{ github.event.inputs.version_specifier }}" @@ -277,7 +276,6 @@ jobs: NPM_CONFIG_PROVENANCE: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - JSR_TOKEN: ${{ secrets.JSR_TOKEN }} notify-stable-failure: name: Notify Slack for Stable failure diff --git a/docs/JSR_PUBLISHING.md b/docs/JSR_PUBLISHING.md index 4e9819f2d..b91cf9812 100644 --- a/docs/JSR_PUBLISHING.md +++ b/docs/JSR_PUBLISHING.md @@ -8,7 +8,7 @@ All Supabase JavaScript packages are published to both npm and JSR. JSR publishi ## Current Status -โœ… **JSR publishing is configured but requires authentication setup** +โœ… **JSR publishing is fully configured and ready to use** The following packages are configured for JSR publishing: @@ -19,27 +19,46 @@ The following packages are configured for JSR publishing: - @supabase/storage-js - @supabase/supabase-js -## Setup Requirements +## Authentication -### 1. Create JSR Access Token +JSR publishing uses **OpenID Connect (OIDC)** authentication from GitHub Actions, which is the recommended approach by JSR. This means: -1. Go to https://jsr.io/account/tokens -2. Create a new access token with publish permissions -3. Copy the token (it won't be shown again) +- โœ… No secrets to manage or rotate +- โœ… Automatic authentication via GitHub +- โœ… Short-lived tokens for enhanced security +- โœ… Works automatically when `id-token: write` permission is set -### 2. Add GitHub Secret +The workflow already has the required permissions configured: -Add the token as a GitHub secret named `JSR_TOKEN` in your repository settings. +```yaml +permissions: + contents: read + id-token: write # Required for JSR OIDC authentication +``` + +**No additional setup is required** - JSR publishing works automatically in GitHub Actions. ## How It Works -1. **Version Synchronization**: The `jsr.json` files use `"0.0.0-automated"` as a placeholder. The publish script updates this to match the package.json version before publishing. +1. **Version Synchronization**: The `jsr.json` files use placeholder versions (e.g., `"0.0.0"` or `"0.0.0-automated"`). The publish script updates these to match the package.json version before publishing, then restores the original placeholder to keep the working directory clean. + +2. **OIDC Authentication**: When running in GitHub Actions with `id-token: write` permission, JSR automatically authenticates using GitHub's OIDC tokens. No manual token management is required. + +3. **Type Checking**: Some packages have missing explicit return types and use the `--allow-slow-types` flag temporarily. Future improvements should add explicit return types to improve performance. -2. **Type Checking**: Some packages have missing explicit return types. These use the `--allow-slow-types` flag temporarily. Future improvements should add explicit return types to improve performance. + Packages requiring `--allow-slow-types`: + - `auth-js` - Missing return types in auth client methods + - `postgrest-js` - Missing return types in query builder methods + - `storage-js` - Missing return types in storage methods + - `realtime-js` - Missing return types in channel and presence methods -3. **Provenance**: When running in GitHub Actions with proper authentication, the `--provenance` flag is added for trusted publishing. + Packages with explicit return types (no flag needed): + - `functions-js` - Has explicit return types + - `supabase-js` - Has explicit return types (aggregates other packages) -4. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. +4. **Provenance**: When running in GitHub Actions, the `--provenance` flag is added for trusted publishing, linking packages to their source repository. + +5. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. ## Files Involved @@ -47,8 +66,9 @@ Add the token as a GitHub secret named `JSR_TOKEN` in your repository settings. - `scripts/release-stable.ts` - Calls JSR publish after stable npm release - `scripts/release-canary.ts` - Calls JSR publish after canary npm release - `packages/core/*/jsr.json` - JSR configuration for each package +- `.github/workflows/publish.yml` - GitHub Actions workflow with OIDC permissions -## Testing +## Testing Locally To test JSR publishing locally: @@ -56,6 +76,31 @@ To test JSR publishing locally: # Dry run (no authentication needed) npx tsx scripts/publish-to-jsr.ts --dry-run -# Actual publish (requires authentication) -JSR_TOKEN=your-token-here npx tsx scripts/publish-to-jsr.ts +# Actual publish (uses interactive browser authentication) +npx tsx scripts/publish-to-jsr.ts +``` + +When running locally, JSR will open your browser for interactive authentication. You don't need to set up any tokens manually. + +## Troubleshooting + +### Publishing fails with authentication error in GitHub Actions + +Ensure your workflow has the `id-token: write` permission: + +```yaml +permissions: + contents: read + id-token: write ``` + +### Publishing fails with "slow types" error + +This means a package is missing explicit return types. Either: + +1. Add explicit return types to the code (recommended) +2. Temporarily use `--allow-slow-types` flag (already configured for affected packages) + +### Working directory is dirty after publish + +The publish script automatically restores the original `jsr.json` files after publishing. If you see uncommitted changes, this indicates a bug in the cleanup logic. diff --git a/scripts/publish-to-jsr.ts b/scripts/publish-to-jsr.ts index 127dc1267..c3b47eb29 100644 --- a/scripts/publish-to-jsr.ts +++ b/scripts/publish-to-jsr.ts @@ -23,7 +23,17 @@ const tag = getArg('tag') || 'latest' const dryRun = process.argv.includes('--dry-run') // Packages that need --allow-slow-types due to missing explicit return types -// These should be fixed in the future but for now we'll allow slow types +// TODO: Remove --allow-slow-types once explicit return types are added to improve JSR performance +// +// Packages requiring --allow-slow-types: +// - auth-js: Missing return types in auth client methods +// - postgrest-js: Missing return types in query builder methods +// - storage-js: Missing return types in storage methods +// - realtime-js: Missing return types in channel and presence methods +// +// Packages NOT requiring --allow-slow-types: +// - functions-js: Has explicit return types +// - supabase-js: Has explicit return types (aggregates other packages) const packagesWithSlowTypes = ['auth-js', 'postgrest-js', 'storage-js', 'realtime-js'] function safeExec(cmd: string, opts = {}) { @@ -38,15 +48,12 @@ function safeExec(cmd: string, opts = {}) { async function publishToJsr() { console.log(`\n๐Ÿ“ฆ Publishing packages to JSR (tag: ${tag})...\n`) - // Check if we have JSR token for authentication - const jsrToken = process.env.JSR_TOKEN - if (!jsrToken && !dryRun) { - console.warn('โš ๏ธ JSR_TOKEN environment variable not set.') - console.warn(' Publishing will require interactive authentication or will fail in CI.') - console.warn(' To set up JSR publishing:') - console.warn(' 1. Create a JSR access token at https://jsr.io/account/tokens') - console.warn(' 2. Add JSR_TOKEN as a GitHub secret') - console.warn(' 3. Pass it to the release script in the workflow') + // GitHub Actions uses OIDC authentication automatically via id-token: write permission + // No manual token setup required when running in CI with proper permissions + if (!process.env.GITHUB_ACTIONS && !dryRun) { + console.warn('โš ๏ธ Not running in GitHub Actions.') + console.warn(' Local publishing will use interactive browser authentication.') + console.warn(' For CI/CD, ensure your workflow has "id-token: write" permission.') } let hasErrors = false @@ -67,8 +74,11 @@ async function publishToJsr() { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) const version = packageJson.version + // Read and backup the original jsr.json + const originalJsrContent = readFileSync(jsrPath, 'utf-8') + const jsrConfig = JSON.parse(originalJsrContent) + // Update jsr.json with the current version - const jsrConfig = JSON.parse(readFileSync(jsrPath, 'utf-8')) jsrConfig.version = version writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n') @@ -78,16 +88,16 @@ async function publishToJsr() { // Determine if we need to allow slow types for this package const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' - // Add authentication token if available - const tokenFlag = jsrToken && !dryRun ? ` --token ${jsrToken}` : '' - // Add provenance flag if we're in GitHub Actions CI + // GitHub Actions OIDC automatically handles authentication via id-token: write const provenanceFlag = process.env.GITHUB_ACTIONS && !dryRun ? ' --provenance' : '' // Change to package directory and publish + // Note: In GitHub Actions, authentication happens automatically via OIDC + // Local publishing will prompt for interactive browser authentication const publishCmd = dryRun ? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty${allowSlowTypes}` - : `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${tokenFlag}${provenanceFlag}` + : `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${provenanceFlag}` safeExec(publishCmd) @@ -98,6 +108,9 @@ async function publishToJsr() { console.error(`โŒ Failed to publish ${pkg} to JSR: ${errorMsg}`) results.push({ package: pkg, success: false, error: errorMsg }) hasErrors = true + } finally { + // Restore original jsr.json to keep working directory clean + writeFileSync(jsrPath, originalJsrContent) } } From 9f98c047ad3edea0298ec3e0f2bab179d558d48c Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 16:16:54 +0200 Subject: [PATCH 3/6] chore(ci): test jsr publich --- .github/workflows/test-jsr-publish.yml | 48 +++++++++++ JSR_TEST_README.md | 98 +++++++++++++++++++++ scripts/test-jsr-publish.ts | 113 +++++++++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 .github/workflows/test-jsr-publish.yml create mode 100644 JSR_TEST_README.md create mode 100644 scripts/test-jsr-publish.ts diff --git a/.github/workflows/test-jsr-publish.yml b/.github/workflows/test-jsr-publish.yml new file mode 100644 index 000000000..d6f69d1c7 --- /dev/null +++ b/.github/workflows/test-jsr-publish.yml @@ -0,0 +1,48 @@ +# TEMPORARY TEST WORKFLOW - DO NOT MERGE +# This workflow tests JSR publishing without affecting npm +name: Test JSR Publishing + +on: + push: + branches: [chore/release-jsr] + pull_request: + branches: [chore/release-jsr] + types: [synchronize] + workflow_dispatch: # Manual trigger only + +env: + NODE_VERSION: '20' + +jobs: + test-jsr: + name: Test JSR Publish + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # Required for JSR OIDC authentication + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Test JSR Publishing + run: npx tsx scripts/test-jsr-publish.ts + + - name: Summary + run: | + echo "## ๐Ÿงช JSR Test Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "โœ… JSR test publishing completed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Check the logs above for details." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "View at: https://jsr.io/@supabase/functions-js/versions" >> $GITHUB_STEP_SUMMARY diff --git a/JSR_TEST_README.md b/JSR_TEST_README.md new file mode 100644 index 000000000..81684ff83 --- /dev/null +++ b/JSR_TEST_README.md @@ -0,0 +1,98 @@ +# Testing JSR Publishing (TEMPORARY) + +This document explains how to test JSR publishing in CI without affecting npm. + +## Test Files (DO NOT MERGE) + +These files are temporary for testing only: + +- `.github/workflows/test-jsr-publish.yml` - Test workflow +- `scripts/test-jsr-publish.ts` - Test script with hardcoded version +- `JSR_TEST_README.md` - This file + +## How to Test + +### 1. Commit the test files + +```bash +git add .github/workflows/test-jsr-publish.yml scripts/test-jsr-publish.ts JSR_TEST_README.md +git commit -m "test: add temporary JSR publishing test" +git push +``` + +### 2. Run the test workflow + +1. Go to: https://github.com/supabase/supabase-js/actions/workflows/test-jsr-publish.yml +2. Click "Run workflow" +3. Select your branch (`chore/release-jsr`) +4. Click "Run workflow" + +### 3. Check results + +The workflow will: + +- โœ… Only publish to JSR (no npm) +- โœ… Use hardcoded test version `0.0.0-jsr-test.1` +- โœ… Only test with `functions-js` (simplest package) +- โœ… Use OIDC authentication automatically +- โœ… Restore original `jsr.json` files after publish + +View published package at: https://jsr.io/@supabase/functions-js/versions + +### 4. Test all packages (optional) + +Edit `scripts/test-jsr-publish.ts` to include all packages: + +```typescript +const packages = [ + 'auth-js', + 'functions-js', + 'postgrest-js', + 'realtime-js', + 'storage-js', + 'supabase-js', +] +``` + +Change the version if needed: + +```typescript +const TEST_VERSION = '0.0.0-jsr-test.2' +``` + +### 5. Clean up after testing + +Once testing is complete, remove the test files: + +```bash +git rm .github/workflows/test-jsr-publish.yml +git rm scripts/test-jsr-publish.ts +git rm JSR_TEST_README.md +git commit -m "test: remove temporary JSR test files" +git push +``` + +## Local Testing + +You can also test locally (will prompt for browser authentication): + +```bash +npx tsx scripts/test-jsr-publish.ts +``` + +## Troubleshooting + +### Error: "Package already published" + +JSR doesn't allow re-publishing the same version. Either: + +1. Change `TEST_VERSION` in the script +2. Delete the test version from JSR (if you have access) + +### Error: "Authentication failed" + +Ensure the workflow has `id-token: write` permission (already configured). + +### Error: "Slow types" + +If testing packages with slow types, they're already configured with `--allow-slow-types`. diff --git a/scripts/test-jsr-publish.ts b/scripts/test-jsr-publish.ts new file mode 100644 index 000000000..d686b198f --- /dev/null +++ b/scripts/test-jsr-publish.ts @@ -0,0 +1,113 @@ +// TEMPORARY TEST SCRIPT - DO NOT MERGE +// This script is for testing JSR publishing in CI without affecting npm +import { execSync } from 'child_process' +import { readFileSync, writeFileSync, existsSync } from 'fs' +import { join } from 'path' + +// Hardcoded test version - change this to test different versions +const TEST_VERSION = '0.0.0-jsr-test.1' + +// Test with just one package to start +const packages = [ + 'functions-js', // Start with simplest package (no slow types) +] + +// Packages that need --allow-slow-types +const packagesWithSlowTypes = ['auth-js', 'postgrest-js', 'storage-js', 'realtime-js'] + +function safeExec(cmd: string, opts = {}) { + try { + return execSync(cmd, { stdio: 'inherit', ...opts }) + } catch (err) { + console.error(`โŒ Command failed: ${cmd}`) + throw err + } +} + +async function testJsrPublish() { + console.log(`\n๐Ÿงช TESTING JSR Publishing with version: ${TEST_VERSION}\n`) + console.log('โš ๏ธ This is a TEST - using hardcoded version\n') + + // GitHub Actions uses OIDC authentication automatically via id-token: write permission + if (!process.env.GITHUB_ACTIONS) { + console.warn('โš ๏ธ Not running in GitHub Actions.') + console.warn(' Local publishing will use interactive browser authentication.') + } + + let hasErrors = false + const results: { package: string; success: boolean; error?: string }[] = [] + + for (const pkg of packages) { + const packagePath = join(process.cwd(), 'packages', 'core', pkg) + const jsrPath = join(packagePath, 'jsr.json') + + // Check if jsr.json exists + if (!existsSync(jsrPath)) { + console.log(`โš ๏ธ Skipping ${pkg}: no jsr.json file found`) + continue + } + + // Read and backup the original jsr.json + const originalJsrContent = readFileSync(jsrPath, 'utf-8') + const jsrConfig = JSON.parse(originalJsrContent) + + // Update jsr.json with the TEST version + jsrConfig.version = TEST_VERSION + writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n') + + console.log(`\n๐Ÿ“ค [TEST] Publishing @supabase/${pkg}@${TEST_VERSION} to JSR...`) + + try { + // Determine if we need to allow slow types for this package + const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' + + // Add provenance flag if we're in GitHub Actions CI + const provenanceFlag = process.env.GITHUB_ACTIONS ? ' --provenance' : '' + + // Change to package directory and publish + const publishCmd = `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${provenanceFlag}` + + console.log(`Running: ${publishCmd}`) + safeExec(publishCmd) + + console.log(`โœ… Successfully published @supabase/${pkg}@${TEST_VERSION} to JSR`) + results.push({ package: pkg, success: true }) + } catch (error) { + const errorMsg = error instanceof Error ? error.message : String(error) + console.error(`โŒ Failed to publish ${pkg} to JSR: ${errorMsg}`) + results.push({ package: pkg, success: false, error: errorMsg }) + hasErrors = true + } finally { + // Restore original jsr.json + writeFileSync(jsrPath, originalJsrContent) + } + } + + // Summary + console.log('\n' + '='.repeat(50)) + console.log('๐Ÿงช JSR Test Publishing Summary:') + console.log('='.repeat(50)) + + for (const result of results) { + const icon = result.success ? 'โœ…' : 'โŒ' + const status = result.success ? 'SUCCESS' : 'FAILED' + console.log(`${icon} ${result.package}: ${status}`) + if (result.error) { + console.log(` Error: ${result.error}`) + } + } + + if (hasErrors) { + console.log('\nโš ๏ธ Some packages failed to publish to JSR.') + process.exit(1) + } + + console.log('\nโœ… Test completed successfully!') + console.log(`\nView published package at: https://jsr.io/@supabase/${packages[0]}/versions`) +} + +// Run the test +testJsrPublish().catch((error) => { + console.error('Unexpected error:', error) + process.exit(1) +}) From f308d95991f167eb2df47f85142687da8a7bdbd6 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 19:41:04 +0200 Subject: [PATCH 4/6] fix(ci): remove invalid --provenance flag from JSR publish --- docs/JSR_PUBLISHING.md | 50 +++++++++++++++++++++---------------- scripts/publish-to-jsr.ts | 39 ++++++----------------------- scripts/test-jsr-publish.ts | 6 ++--- 3 files changed, 38 insertions(+), 57 deletions(-) diff --git a/docs/JSR_PUBLISHING.md b/docs/JSR_PUBLISHING.md index b91cf9812..0b87a1525 100644 --- a/docs/JSR_PUBLISHING.md +++ b/docs/JSR_PUBLISHING.md @@ -4,20 +4,25 @@ This document explains how JSR (JavaScript Registry) publishing is configured in ## Overview -All Supabase JavaScript packages are published to both npm and JSR. JSR publishing happens automatically after npm publishing in both stable and canary releases. +Supabase JavaScript packages are published to npm, and select packages with explicit return types are also published to JSR. JSR publishing happens automatically after npm publishing in both stable and canary releases. + +Currently, only packages with complete TypeScript typing (explicit return types) are published to JSR to maintain high quality standards and optimal type-checking performance. ## Current Status -โœ… **JSR publishing is fully configured and ready to use** +โœ… **JSR publishing is configured for packages with explicit return types** + +The following packages are currently published to JSR: + +- @supabase/functions-js โœ… (has explicit return types) +- @supabase/supabase-js โœ… (has explicit return types) -The following packages are configured for JSR publishing: +The following packages are **not yet published to JSR** (pending explicit return types): -- @supabase/auth-js -- @supabase/functions-js -- @supabase/postgrest-js -- @supabase/realtime-js -- @supabase/storage-js -- @supabase/supabase-js +- @supabase/auth-js โณ (needs explicit return types) +- @supabase/postgrest-js โณ (needs explicit return types) +- @supabase/realtime-js โณ (needs explicit return types) +- @supabase/storage-js โณ (needs explicit return types) ## Authentication @@ -44,21 +49,19 @@ permissions: 2. **OIDC Authentication**: When running in GitHub Actions with `id-token: write` permission, JSR automatically authenticates using GitHub's OIDC tokens. No manual token management is required. -3. **Type Checking**: Some packages have missing explicit return types and use the `--allow-slow-types` flag temporarily. Future improvements should add explicit return types to improve performance. +3. **Type Checking**: Only packages with explicit return types are published to JSR. This ensures optimal performance and aligns with JSR's quality standards. - Packages requiring `--allow-slow-types`: - - `auth-js` - Missing return types in auth client methods - - `postgrest-js` - Missing return types in query builder methods - - `storage-js` - Missing return types in storage methods - - `realtime-js` - Missing return types in channel and presence methods - - Packages with explicit return types (no flag needed): + Currently published packages (with explicit return types): - `functions-js` - Has explicit return types - `supabase-js` - Has explicit return types (aggregates other packages) -4. **Provenance**: When running in GitHub Actions, the `--provenance` flag is added for trusted publishing, linking packages to their source repository. + Not yet published (pending explicit return types): + - `auth-js` - Needs explicit return types in auth client methods + - `postgrest-js` - Needs explicit return types in query builder methods + - `storage-js` - Needs explicit return types in storage methods + - `realtime-js` - Needs explicit return types in channel and presence methods -5. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. +4. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. ## Files Involved @@ -96,10 +99,13 @@ permissions: ### Publishing fails with "slow types" error -This means a package is missing explicit return types. Either: +This means a package is missing explicit return types. To publish to JSR: + +1. Add explicit return types to all public APIs +2. Update the `packages` array in `scripts/publish-to-jsr.ts` to include the package +3. Update this documentation to reflect the change -1. Add explicit return types to the code (recommended) -2. Temporarily use `--allow-slow-types` flag (already configured for affected packages) +We intentionally avoid using the `--allow-slow-types` flag to maintain JSR quality standards. ### Working directory is dirty after publish diff --git a/scripts/publish-to-jsr.ts b/scripts/publish-to-jsr.ts index c3b47eb29..72d1b9c33 100644 --- a/scripts/publish-to-jsr.ts +++ b/scripts/publish-to-jsr.ts @@ -2,14 +2,11 @@ import { execSync } from 'child_process' import { readFileSync, writeFileSync, existsSync } from 'fs' import { join } from 'path' -const packages = [ - 'auth-js', - 'functions-js', - 'postgrest-js', - 'realtime-js', - 'storage-js', - 'supabase-js', -] +// Only publishing packages with explicit return types to JSR +// Other packages (auth-js, postgrest-js, storage-js, realtime-js) require +// explicit return types to be added before they can be published to JSR +// without the --allow-slow-types flag +const packages = ['functions-js', 'supabase-js'] function getArg(name: string): string | undefined { const idx = process.argv.findIndex((a) => a === `--${name}` || a.startsWith(`--${name}=`)) @@ -22,20 +19,6 @@ function getArg(name: string): string | undefined { const tag = getArg('tag') || 'latest' const dryRun = process.argv.includes('--dry-run') -// Packages that need --allow-slow-types due to missing explicit return types -// TODO: Remove --allow-slow-types once explicit return types are added to improve JSR performance -// -// Packages requiring --allow-slow-types: -// - auth-js: Missing return types in auth client methods -// - postgrest-js: Missing return types in query builder methods -// - storage-js: Missing return types in storage methods -// - realtime-js: Missing return types in channel and presence methods -// -// Packages NOT requiring --allow-slow-types: -// - functions-js: Has explicit return types -// - supabase-js: Has explicit return types (aggregates other packages) -const packagesWithSlowTypes = ['auth-js', 'postgrest-js', 'storage-js', 'realtime-js'] - function safeExec(cmd: string, opts = {}) { try { return execSync(cmd, { stdio: 'inherit', ...opts }) @@ -85,19 +68,13 @@ async function publishToJsr() { console.log(`\n๐Ÿ“ค Publishing @supabase/${pkg}@${version} to JSR...`) try { - // Determine if we need to allow slow types for this package - const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' - - // Add provenance flag if we're in GitHub Actions CI - // GitHub Actions OIDC automatically handles authentication via id-token: write - const provenanceFlag = process.env.GITHUB_ACTIONS && !dryRun ? ' --provenance' : '' - // Change to package directory and publish // Note: In GitHub Actions, authentication happens automatically via OIDC + // Provenance is automatically enabled when using OIDC (no flag needed) // Local publishing will prompt for interactive browser authentication const publishCmd = dryRun - ? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty${allowSlowTypes}` - : `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${provenanceFlag}` + ? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty` + : `cd "${packagePath}" && npx jsr publish --allow-dirty` safeExec(publishCmd) diff --git a/scripts/test-jsr-publish.ts b/scripts/test-jsr-publish.ts index d686b198f..3a7bf03d5 100644 --- a/scripts/test-jsr-publish.ts +++ b/scripts/test-jsr-publish.ts @@ -61,11 +61,9 @@ async function testJsrPublish() { // Determine if we need to allow slow types for this package const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' - // Add provenance flag if we're in GitHub Actions CI - const provenanceFlag = process.env.GITHUB_ACTIONS ? ' --provenance' : '' - // Change to package directory and publish - const publishCmd = `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}${provenanceFlag}` + // Note: Provenance is automatically enabled in GitHub Actions via OIDC (no flag needed) + const publishCmd = `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}` console.log(`Running: ${publishCmd}`) safeExec(publishCmd) From 3ab4a83a2d4e197792ab35b3698a8ba39da71358 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 19:42:03 +0200 Subject: [PATCH 5/6] fix(repo): remove tests --- .github/workflows/test-jsr-publish.yml | 48 ----------- JSR_TEST_README.md | 98 ---------------------- scripts/test-jsr-publish.ts | 111 ------------------------- 3 files changed, 257 deletions(-) delete mode 100644 .github/workflows/test-jsr-publish.yml delete mode 100644 JSR_TEST_README.md delete mode 100644 scripts/test-jsr-publish.ts diff --git a/.github/workflows/test-jsr-publish.yml b/.github/workflows/test-jsr-publish.yml deleted file mode 100644 index d6f69d1c7..000000000 --- a/.github/workflows/test-jsr-publish.yml +++ /dev/null @@ -1,48 +0,0 @@ -# TEMPORARY TEST WORKFLOW - DO NOT MERGE -# This workflow tests JSR publishing without affecting npm -name: Test JSR Publishing - -on: - push: - branches: [chore/release-jsr] - pull_request: - branches: [chore/release-jsr] - types: [synchronize] - workflow_dispatch: # Manual trigger only - -env: - NODE_VERSION: '20' - -jobs: - test-jsr: - name: Test JSR Publish - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write # Required for JSR OIDC authentication - - steps: - - name: Checkout code - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - - - name: Install dependencies - run: npm ci --legacy-peer-deps - - - name: Test JSR Publishing - run: npx tsx scripts/test-jsr-publish.ts - - - name: Summary - run: | - echo "## ๐Ÿงช JSR Test Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "โœ… JSR test publishing completed" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Check the logs above for details." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "View at: https://jsr.io/@supabase/functions-js/versions" >> $GITHUB_STEP_SUMMARY diff --git a/JSR_TEST_README.md b/JSR_TEST_README.md deleted file mode 100644 index 81684ff83..000000000 --- a/JSR_TEST_README.md +++ /dev/null @@ -1,98 +0,0 @@ -# Testing JSR Publishing (TEMPORARY) - -This document explains how to test JSR publishing in CI without affecting npm. - -## Test Files (DO NOT MERGE) - -These files are temporary for testing only: - -- `.github/workflows/test-jsr-publish.yml` - Test workflow -- `scripts/test-jsr-publish.ts` - Test script with hardcoded version -- `JSR_TEST_README.md` - This file - -## How to Test - -### 1. Commit the test files - -```bash -git add .github/workflows/test-jsr-publish.yml scripts/test-jsr-publish.ts JSR_TEST_README.md -git commit -m "test: add temporary JSR publishing test" -git push -``` - -### 2. Run the test workflow - -1. Go to: https://github.com/supabase/supabase-js/actions/workflows/test-jsr-publish.yml -2. Click "Run workflow" -3. Select your branch (`chore/release-jsr`) -4. Click "Run workflow" - -### 3. Check results - -The workflow will: - -- โœ… Only publish to JSR (no npm) -- โœ… Use hardcoded test version `0.0.0-jsr-test.1` -- โœ… Only test with `functions-js` (simplest package) -- โœ… Use OIDC authentication automatically -- โœ… Restore original `jsr.json` files after publish - -View published package at: https://jsr.io/@supabase/functions-js/versions - -### 4. Test all packages (optional) - -Edit `scripts/test-jsr-publish.ts` to include all packages: - -```typescript -const packages = [ - 'auth-js', - 'functions-js', - 'postgrest-js', - 'realtime-js', - 'storage-js', - 'supabase-js', -] -``` - -Change the version if needed: - -```typescript -const TEST_VERSION = '0.0.0-jsr-test.2' -``` - -### 5. Clean up after testing - -Once testing is complete, remove the test files: - -```bash -git rm .github/workflows/test-jsr-publish.yml -git rm scripts/test-jsr-publish.ts -git rm JSR_TEST_README.md -git commit -m "test: remove temporary JSR test files" -git push -``` - -## Local Testing - -You can also test locally (will prompt for browser authentication): - -```bash -npx tsx scripts/test-jsr-publish.ts -``` - -## Troubleshooting - -### Error: "Package already published" - -JSR doesn't allow re-publishing the same version. Either: - -1. Change `TEST_VERSION` in the script -2. Delete the test version from JSR (if you have access) - -### Error: "Authentication failed" - -Ensure the workflow has `id-token: write` permission (already configured). - -### Error: "Slow types" - -If testing packages with slow types, they're already configured with `--allow-slow-types`. diff --git a/scripts/test-jsr-publish.ts b/scripts/test-jsr-publish.ts deleted file mode 100644 index 3a7bf03d5..000000000 --- a/scripts/test-jsr-publish.ts +++ /dev/null @@ -1,111 +0,0 @@ -// TEMPORARY TEST SCRIPT - DO NOT MERGE -// This script is for testing JSR publishing in CI without affecting npm -import { execSync } from 'child_process' -import { readFileSync, writeFileSync, existsSync } from 'fs' -import { join } from 'path' - -// Hardcoded test version - change this to test different versions -const TEST_VERSION = '0.0.0-jsr-test.1' - -// Test with just one package to start -const packages = [ - 'functions-js', // Start with simplest package (no slow types) -] - -// Packages that need --allow-slow-types -const packagesWithSlowTypes = ['auth-js', 'postgrest-js', 'storage-js', 'realtime-js'] - -function safeExec(cmd: string, opts = {}) { - try { - return execSync(cmd, { stdio: 'inherit', ...opts }) - } catch (err) { - console.error(`โŒ Command failed: ${cmd}`) - throw err - } -} - -async function testJsrPublish() { - console.log(`\n๐Ÿงช TESTING JSR Publishing with version: ${TEST_VERSION}\n`) - console.log('โš ๏ธ This is a TEST - using hardcoded version\n') - - // GitHub Actions uses OIDC authentication automatically via id-token: write permission - if (!process.env.GITHUB_ACTIONS) { - console.warn('โš ๏ธ Not running in GitHub Actions.') - console.warn(' Local publishing will use interactive browser authentication.') - } - - let hasErrors = false - const results: { package: string; success: boolean; error?: string }[] = [] - - for (const pkg of packages) { - const packagePath = join(process.cwd(), 'packages', 'core', pkg) - const jsrPath = join(packagePath, 'jsr.json') - - // Check if jsr.json exists - if (!existsSync(jsrPath)) { - console.log(`โš ๏ธ Skipping ${pkg}: no jsr.json file found`) - continue - } - - // Read and backup the original jsr.json - const originalJsrContent = readFileSync(jsrPath, 'utf-8') - const jsrConfig = JSON.parse(originalJsrContent) - - // Update jsr.json with the TEST version - jsrConfig.version = TEST_VERSION - writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n') - - console.log(`\n๐Ÿ“ค [TEST] Publishing @supabase/${pkg}@${TEST_VERSION} to JSR...`) - - try { - // Determine if we need to allow slow types for this package - const allowSlowTypes = packagesWithSlowTypes.includes(pkg) ? ' --allow-slow-types' : '' - - // Change to package directory and publish - // Note: Provenance is automatically enabled in GitHub Actions via OIDC (no flag needed) - const publishCmd = `cd "${packagePath}" && npx jsr publish --allow-dirty${allowSlowTypes}` - - console.log(`Running: ${publishCmd}`) - safeExec(publishCmd) - - console.log(`โœ… Successfully published @supabase/${pkg}@${TEST_VERSION} to JSR`) - results.push({ package: pkg, success: true }) - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error) - console.error(`โŒ Failed to publish ${pkg} to JSR: ${errorMsg}`) - results.push({ package: pkg, success: false, error: errorMsg }) - hasErrors = true - } finally { - // Restore original jsr.json - writeFileSync(jsrPath, originalJsrContent) - } - } - - // Summary - console.log('\n' + '='.repeat(50)) - console.log('๐Ÿงช JSR Test Publishing Summary:') - console.log('='.repeat(50)) - - for (const result of results) { - const icon = result.success ? 'โœ…' : 'โŒ' - const status = result.success ? 'SUCCESS' : 'FAILED' - console.log(`${icon} ${result.package}: ${status}`) - if (result.error) { - console.log(` Error: ${result.error}`) - } - } - - if (hasErrors) { - console.log('\nโš ๏ธ Some packages failed to publish to JSR.') - process.exit(1) - } - - console.log('\nโœ… Test completed successfully!') - console.log(`\nView published package at: https://jsr.io/@supabase/${packages[0]}/versions`) -} - -// Run the test -testJsrPublish().catch((error) => { - console.error('Unexpected error:', error) - process.exit(1) -}) From ec9556bacc6c8d37f7e4bdecbc5799c7edf607de Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 19 Nov 2025 19:45:33 +0200 Subject: [PATCH 6/6] fix(repo): remove jsr json from rest of packages --- docs/JSR_PUBLISHING.md | 72 +++-------------- packages/core/auth-js/jsr.json | 6 -- packages/core/postgrest-js/jsr.json | 6 -- packages/core/realtime-js/jsr.json | 6 -- packages/core/storage-js/jsr.json | 6 -- scripts/publish-to-jsr.ts | 119 ---------------------------- 6 files changed, 10 insertions(+), 205 deletions(-) delete mode 100644 packages/core/auth-js/jsr.json delete mode 100644 packages/core/postgrest-js/jsr.json delete mode 100644 packages/core/realtime-js/jsr.json delete mode 100644 packages/core/storage-js/jsr.json delete mode 100644 scripts/publish-to-jsr.ts diff --git a/docs/JSR_PUBLISHING.md b/docs/JSR_PUBLISHING.md index 0b87a1525..aa87f2560 100644 --- a/docs/JSR_PUBLISHING.md +++ b/docs/JSR_PUBLISHING.md @@ -10,28 +10,21 @@ Currently, only packages with complete TypeScript typing (explicit return types) ## Current Status -โœ… **JSR publishing is configured for packages with explicit return types** +**JSR publishing is configured for packages with explicit return types** The following packages are currently published to JSR: -- @supabase/functions-js โœ… (has explicit return types) -- @supabase/supabase-js โœ… (has explicit return types) - -The following packages are **not yet published to JSR** (pending explicit return types): - -- @supabase/auth-js โณ (needs explicit return types) -- @supabase/postgrest-js โณ (needs explicit return types) -- @supabase/realtime-js โณ (needs explicit return types) -- @supabase/storage-js โณ (needs explicit return types) +- @supabase/functions-js (has explicit return types) +- @supabase/supabase-js (has explicit return types) ## Authentication JSR publishing uses **OpenID Connect (OIDC)** authentication from GitHub Actions, which is the recommended approach by JSR. This means: -- โœ… No secrets to manage or rotate -- โœ… Automatic authentication via GitHub -- โœ… Short-lived tokens for enhanced security -- โœ… Works automatically when `id-token: write` permission is set +- No secrets to manage or rotate +- Automatic authentication via GitHub +- Short-lived tokens for enhanced security +- Works automatically when `id-token: write` permission is set The workflow already has the required permissions configured: @@ -51,15 +44,10 @@ permissions: 3. **Type Checking**: Only packages with explicit return types are published to JSR. This ensures optimal performance and aligns with JSR's quality standards. - Currently published packages (with explicit return types): - - `functions-js` - Has explicit return types - - `supabase-js` - Has explicit return types (aggregates other packages) +Published packages (with explicit return types): - Not yet published (pending explicit return types): - - `auth-js` - Needs explicit return types in auth client methods - - `postgrest-js` - Needs explicit return types in query builder methods - - `storage-js` - Needs explicit return types in storage methods - - `realtime-js` - Needs explicit return types in channel and presence methods +- `functions-js` - Has explicit return types +- `supabase-js` - Has explicit return types (aggregates other packages) 4. **Failure Handling**: JSR publishing failures don't fail the entire release - npm releases will still succeed. @@ -70,43 +58,3 @@ permissions: - `scripts/release-canary.ts` - Calls JSR publish after canary npm release - `packages/core/*/jsr.json` - JSR configuration for each package - `.github/workflows/publish.yml` - GitHub Actions workflow with OIDC permissions - -## Testing Locally - -To test JSR publishing locally: - -```bash -# Dry run (no authentication needed) -npx tsx scripts/publish-to-jsr.ts --dry-run - -# Actual publish (uses interactive browser authentication) -npx tsx scripts/publish-to-jsr.ts -``` - -When running locally, JSR will open your browser for interactive authentication. You don't need to set up any tokens manually. - -## Troubleshooting - -### Publishing fails with authentication error in GitHub Actions - -Ensure your workflow has the `id-token: write` permission: - -```yaml -permissions: - contents: read - id-token: write -``` - -### Publishing fails with "slow types" error - -This means a package is missing explicit return types. To publish to JSR: - -1. Add explicit return types to all public APIs -2. Update the `packages` array in `scripts/publish-to-jsr.ts` to include the package -3. Update this documentation to reflect the change - -We intentionally avoid using the `--allow-slow-types` flag to maintain JSR quality standards. - -### Working directory is dirty after publish - -The publish script automatically restores the original `jsr.json` files after publishing. If you see uncommitted changes, this indicates a bug in the cleanup logic. diff --git a/packages/core/auth-js/jsr.json b/packages/core/auth-js/jsr.json deleted file mode 100644 index fdbea5296..000000000 --- a/packages/core/auth-js/jsr.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@supabase/auth-js", - "version": "0.0.0", - "exports": "./src/index.ts", - "exclude": ["example", "test", "infra"] -} diff --git a/packages/core/postgrest-js/jsr.json b/packages/core/postgrest-js/jsr.json deleted file mode 100644 index 8bcaee21c..000000000 --- a/packages/core/postgrest-js/jsr.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@supabase/postgrest-js", - "version": "0.0.0-automated", - "exports": "./src/index.ts", - "exclude": ["test", "infra"] -} diff --git a/packages/core/realtime-js/jsr.json b/packages/core/realtime-js/jsr.json deleted file mode 100644 index cae46ec97..000000000 --- a/packages/core/realtime-js/jsr.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@supabase/realtime-js", - "version": "0.0.0-automated", - "exports": "./src/index.ts", - "exclude": ["example", "test"] -} diff --git a/packages/core/storage-js/jsr.json b/packages/core/storage-js/jsr.json deleted file mode 100644 index 9b0e3602b..000000000 --- a/packages/core/storage-js/jsr.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@supabase/storage-js", - "version": "0.0.0", - "exports": "./src/index.ts", - "exclude": ["test", "infra"] -} diff --git a/scripts/publish-to-jsr.ts b/scripts/publish-to-jsr.ts deleted file mode 100644 index 72d1b9c33..000000000 --- a/scripts/publish-to-jsr.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { execSync } from 'child_process' -import { readFileSync, writeFileSync, existsSync } from 'fs' -import { join } from 'path' - -// Only publishing packages with explicit return types to JSR -// Other packages (auth-js, postgrest-js, storage-js, realtime-js) require -// explicit return types to be added before they can be published to JSR -// without the --allow-slow-types flag -const packages = ['functions-js', 'supabase-js'] - -function getArg(name: string): string | undefined { - const idx = process.argv.findIndex((a) => a === `--${name}` || a.startsWith(`--${name}=`)) - if (idx === -1) return undefined - const token = process.argv[idx] - if (token.includes('=')) return token.split('=')[1] - return process.argv[idx + 1] -} - -const tag = getArg('tag') || 'latest' -const dryRun = process.argv.includes('--dry-run') - -function safeExec(cmd: string, opts = {}) { - try { - return execSync(cmd, { stdio: 'inherit', ...opts }) - } catch (err) { - console.error(`โŒ Command failed: ${cmd}`) - throw err - } -} - -async function publishToJsr() { - console.log(`\n๐Ÿ“ฆ Publishing packages to JSR (tag: ${tag})...\n`) - - // GitHub Actions uses OIDC authentication automatically via id-token: write permission - // No manual token setup required when running in CI with proper permissions - if (!process.env.GITHUB_ACTIONS && !dryRun) { - console.warn('โš ๏ธ Not running in GitHub Actions.') - console.warn(' Local publishing will use interactive browser authentication.') - console.warn(' For CI/CD, ensure your workflow has "id-token: write" permission.') - } - - let hasErrors = false - const results: { package: string; success: boolean; error?: string }[] = [] - - for (const pkg of packages) { - const packagePath = join(process.cwd(), 'packages', 'core', pkg) - const jsrPath = join(packagePath, 'jsr.json') - - // Check if jsr.json exists - if (!existsSync(jsrPath)) { - console.log(`โš ๏ธ Skipping ${pkg}: no jsr.json file found`) - continue - } - - // Read the package.json to get the current version - const packageJsonPath = join(packagePath, 'package.json') - const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) - const version = packageJson.version - - // Read and backup the original jsr.json - const originalJsrContent = readFileSync(jsrPath, 'utf-8') - const jsrConfig = JSON.parse(originalJsrContent) - - // Update jsr.json with the current version - jsrConfig.version = version - writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n') - - console.log(`\n๐Ÿ“ค Publishing @supabase/${pkg}@${version} to JSR...`) - - try { - // Change to package directory and publish - // Note: In GitHub Actions, authentication happens automatically via OIDC - // Provenance is automatically enabled when using OIDC (no flag needed) - // Local publishing will prompt for interactive browser authentication - const publishCmd = dryRun - ? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty` - : `cd "${packagePath}" && npx jsr publish --allow-dirty` - - safeExec(publishCmd) - - console.log(`โœ… Successfully published @supabase/${pkg}@${version} to JSR`) - results.push({ package: pkg, success: true }) - } catch (error) { - const errorMsg = error instanceof Error ? error.message : String(error) - console.error(`โŒ Failed to publish ${pkg} to JSR: ${errorMsg}`) - results.push({ package: pkg, success: false, error: errorMsg }) - hasErrors = true - } finally { - // Restore original jsr.json to keep working directory clean - writeFileSync(jsrPath, originalJsrContent) - } - } - - // Summary - console.log('\n' + '='.repeat(50)) - console.log('JSR Publishing Summary:') - console.log('='.repeat(50)) - - for (const result of results) { - const icon = result.success ? 'โœ…' : 'โŒ' - const status = result.success ? 'SUCCESS' : 'FAILED' - console.log(`${icon} ${result.package}: ${status}`) - if (result.error) { - console.log(` Error: ${result.error}`) - } - } - - if (hasErrors && !dryRun) { - console.log('\nโš ๏ธ Some packages failed to publish to JSR.') - console.log('This does not affect the npm release which has already succeeded.') - // Don't exit with error to avoid failing the entire release - } -} - -// Run the script -publishToJsr().catch((error) => { - console.error('Unexpected error:', error) - process.exit(1) -})