Skip to content

Commit 474d34e

Browse files
authored
chore(ci): publish jsr script (#1878)
1 parent b5ea928 commit 474d34e

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

scripts/publish-to-jsr.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { execSync } from 'child_process'
2+
import { readFileSync, writeFileSync, existsSync } from 'fs'
3+
import { join } from 'path'
4+
5+
// Only publishing packages with explicit return types to JSR
6+
const packages = ['functions-js', 'supabase-js']
7+
8+
function getArg(name: string): string | undefined {
9+
const idx = process.argv.findIndex((a) => a === `--${name}` || a.startsWith(`--${name}=`))
10+
if (idx === -1) return undefined
11+
const token = process.argv[idx]
12+
if (token.includes('=')) return token.split('=')[1]
13+
return process.argv[idx + 1]
14+
}
15+
16+
const tag = getArg('tag') || 'latest'
17+
const dryRun = process.argv.includes('--dry-run')
18+
19+
function safeExec(cmd: string, opts = {}) {
20+
try {
21+
return execSync(cmd, { stdio: 'inherit', ...opts })
22+
} catch (err) {
23+
console.error(`❌ Command failed: ${cmd}`)
24+
throw err
25+
}
26+
}
27+
28+
async function publishToJsr() {
29+
console.log(`\n📦 Publishing packages to JSR (tag: ${tag})...\n`)
30+
31+
// GitHub Actions uses OIDC authentication automatically via id-token: write permission
32+
// No manual token setup required when running in CI with proper permissions
33+
if (!process.env.GITHUB_ACTIONS && !dryRun) {
34+
console.warn('⚠️ Not running in GitHub Actions.')
35+
console.warn(' Local publishing will use interactive browser authentication.')
36+
console.warn(' For CI/CD, ensure your workflow has "id-token: write" permission.')
37+
}
38+
39+
let hasErrors = false
40+
const results: { package: string; success: boolean; error?: string }[] = []
41+
42+
for (const pkg of packages) {
43+
const packagePath = join(process.cwd(), 'packages', 'core', pkg)
44+
const jsrPath = join(packagePath, 'jsr.json')
45+
46+
// Check if jsr.json exists
47+
if (!existsSync(jsrPath)) {
48+
console.log(`⚠️ Skipping ${pkg}: no jsr.json file found`)
49+
continue
50+
}
51+
52+
// Read the package.json to get the current version
53+
const packageJsonPath = join(packagePath, 'package.json')
54+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
55+
const version = packageJson.version
56+
57+
// Read and backup the original jsr.json
58+
const originalJsrContent = readFileSync(jsrPath, 'utf-8')
59+
const jsrConfig = JSON.parse(originalJsrContent)
60+
61+
// Update jsr.json with the current version
62+
jsrConfig.version = version
63+
writeFileSync(jsrPath, JSON.stringify(jsrConfig, null, 2) + '\n')
64+
65+
console.log(`\n📤 Publishing @supabase/${pkg}@${version} to JSR...`)
66+
67+
try {
68+
// Change to package directory and publish
69+
// Note: In GitHub Actions, authentication happens automatically via OIDC
70+
// Provenance is automatically enabled when using OIDC (no flag needed)
71+
// Local publishing will prompt for interactive browser authentication
72+
const publishCmd = dryRun
73+
? `cd "${packagePath}" && npx jsr publish --dry-run --allow-dirty`
74+
: `cd "${packagePath}" && npx jsr publish --allow-dirty`
75+
76+
safeExec(publishCmd)
77+
78+
console.log(`✅ Successfully published @supabase/${pkg}@${version} to JSR`)
79+
results.push({ package: pkg, success: true })
80+
} catch (error) {
81+
const errorMsg = error instanceof Error ? error.message : String(error)
82+
console.error(`❌ Failed to publish ${pkg} to JSR: ${errorMsg}`)
83+
results.push({ package: pkg, success: false, error: errorMsg })
84+
hasErrors = true
85+
} finally {
86+
// Restore original jsr.json to keep working directory clean
87+
writeFileSync(jsrPath, originalJsrContent)
88+
}
89+
}
90+
91+
// Summary
92+
console.log('\n' + '='.repeat(50))
93+
console.log('JSR Publishing Summary:')
94+
console.log('='.repeat(50))
95+
96+
for (const result of results) {
97+
const icon = result.success ? '✅' : '❌'
98+
const status = result.success ? 'SUCCESS' : 'FAILED'
99+
console.log(`${icon} ${result.package}: ${status}`)
100+
if (result.error) {
101+
console.log(` Error: ${result.error}`)
102+
}
103+
}
104+
105+
if (hasErrors && !dryRun) {
106+
console.log('\n⚠️ Some packages failed to publish to JSR.')
107+
console.log('This does not affect the npm release which has already succeeded.')
108+
// Don't exit with error to avoid failing the entire release
109+
}
110+
}
111+
112+
// Run the script
113+
publishToJsr().catch((error) => {
114+
console.error('Unexpected error:', error)
115+
process.exit(1)
116+
})

0 commit comments

Comments
 (0)