mirror of
https://github.com/supabase/supabase.git
synced 2026-05-08 01:40:13 -04:00
dda0b526ac
wip <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit # Release Notes * **New Features** * Added a new Learn application offering foundational Supabase courses with interactive documentation * Courses include Architecture, Authentication, Data Fundamentals, Security, Storage, Realtime, and Edge Functions * Chapter tracking and progress indicators for course completions * Responsive sidebar navigation with search/command menu * Theme switching support (light, dark, classic dark modes) * Mobile-friendly course interface <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alan Daniel <stylesshjs@gmail.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import { config } from 'dotenv'
|
|
import { existsSync, rmSync, mkdirSync, renameSync } from 'node:fs'
|
|
import { execSync } from 'node:child_process'
|
|
import path from 'node:path'
|
|
|
|
const envLocalPath = path.resolve(process.cwd(), '.env.local')
|
|
if (existsSync(envLocalPath)) {
|
|
config({ path: envLocalPath })
|
|
}
|
|
|
|
const repo = process.env.INTERNAL_CONTENT_REPO
|
|
const token = process.env.INTERNAL_CONTENT_GITHUB_TOKEN
|
|
const branch = process.env.INTERNAL_CONTENT_BRANCH || 'main'
|
|
|
|
const targetDir = path.resolve(process.cwd(), 'content/internal')
|
|
const tmpDir = path.resolve(process.cwd(), '.tmp-internal-content')
|
|
|
|
if (!token) {
|
|
console.log('INTERNAL_CONTENT_GITHUB_TOKEN not set; skipping internal content sync.')
|
|
process.exit(0)
|
|
}
|
|
|
|
if (!repo) {
|
|
console.error('INTERNAL_CONTENT_REPO not set; cannot sync internal content.')
|
|
process.exit(1)
|
|
}
|
|
|
|
const repoUrl = `https://${token}@github.com/${repo}.git`
|
|
const safeRepo = `https://github.com/${repo}.git`
|
|
|
|
// Run command with output captured to prevent token leakage
|
|
const run = (cmd: string) => {
|
|
try {
|
|
const output = execSync(cmd, { stdio: 'pipe', encoding: 'utf-8' })
|
|
return output
|
|
} catch (error: any) {
|
|
// Sanitize error messages by replacing token with [REDACTED]
|
|
const sanitizedMessage = error.message?.replace(new RegExp(token, 'g'), '[REDACTED]') ?? 'Unknown error'
|
|
const sanitizedStderr = error.stderr?.toString().replace(new RegExp(token, 'g'), '[REDACTED]') ?? ''
|
|
const sanitizedStdout = error.stdout?.toString().replace(new RegExp(token, 'g'), '[REDACTED]') ?? ''
|
|
|
|
const sanitizedError = new Error(sanitizedMessage)
|
|
;(sanitizedError as any).stderr = sanitizedStderr
|
|
;(sanitizedError as any).stdout = sanitizedStdout
|
|
;(sanitizedError as any).status = error.status
|
|
throw sanitizedError
|
|
}
|
|
}
|
|
|
|
try {
|
|
// Clean up any existing content
|
|
rmSync(targetDir, { recursive: true, force: true })
|
|
rmSync(tmpDir, { recursive: true, force: true })
|
|
|
|
// Clone to temp directory (using token URL but errors will be sanitized)
|
|
console.log(`Cloning ${safeRepo} branch ${branch}...`)
|
|
run(`git clone --depth 1 --branch ${branch} ${repoUrl} ${tmpDir}`)
|
|
|
|
// Remove git folder so targetDir is not a git repo
|
|
rmSync(path.join(tmpDir, '.git'), { recursive: true, force: true })
|
|
|
|
// Ensure parent directory exists
|
|
mkdirSync(path.dirname(targetDir), { recursive: true })
|
|
|
|
// Move temp folder into place (Node, not shell)
|
|
renameSync(tmpDir, targetDir)
|
|
|
|
console.log('Internal content synced successfully')
|
|
} catch (e: any) {
|
|
// Sanitize error message to prevent token leakage
|
|
const sanitizedMessage = (e?.message ?? String(e)).replace(new RegExp(token, 'g'), '[REDACTED]')
|
|
console.error('Failed to sync internal content:', sanitizedMessage)
|
|
if (e?.stderr) {
|
|
console.error('Error details:', e.stderr)
|
|
}
|
|
rmSync(tmpDir, { recursive: true, force: true })
|
|
process.exit(1)
|
|
}
|