mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-27 00:06:30 +01:00 
			
		
		
		
	feat(scripts): add script used to migrate releases
This commit is contained in:
		
							
								
								
									
										125
									
								
								scripts/migrate-releases.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								scripts/migrate-releases.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| // migrate-releases.js | ||||
| const fetch = require('node-fetch').default; | ||||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
|  | ||||
| const TOKEN = process.env.GITHUB_TOKEN; | ||||
| const SOURCE_REPO = 'TriliumNext/Notes'; | ||||
| const DEST_REPO = 'TriliumNext/trilium'; | ||||
|  | ||||
| if (!TOKEN) { | ||||
|   console.error('Error: Please set your GITHUB_TOKEN environment variable'); | ||||
|   process.exit(1); | ||||
| } | ||||
|  | ||||
| const headers = { | ||||
|   Authorization: `token ${TOKEN}`, | ||||
|   Accept: 'application/vnd.github.v3+json', | ||||
| }; | ||||
|  | ||||
| async function getReleases(repo) { | ||||
|   let releases = []; | ||||
|   let page = 1; | ||||
|  | ||||
|   while (true) { | ||||
|     console.log("Got fetch", fetch); | ||||
|     const res = await fetch( | ||||
|       `https://api.github.com/repos/${repo}/releases?per_page=100&page=${page}`, | ||||
|       { headers } | ||||
|     ); | ||||
|     if (!res.ok) throw new Error(`Failed to get releases: ${res.status} ${res.statusText}`); | ||||
|  | ||||
|     const data = await res.json(); | ||||
|     if (data.length === 0) break; | ||||
|  | ||||
|     releases = releases.concat(data); | ||||
|     page++; | ||||
|   } | ||||
|   return releases; | ||||
| } | ||||
|  | ||||
| async function createRelease(repo, release) { | ||||
|   // Strip id, url etc. fields to prepare payload | ||||
|   const payload = { | ||||
|     tag_name: release.tag_name, | ||||
|     target_commitish: "main", | ||||
|     name: release.name, | ||||
|     body: release.body, | ||||
|     draft: release.draft, | ||||
|     prerelease: release.prerelease, | ||||
|   }; | ||||
|  | ||||
|   const res = await fetch(`https://api.github.com/repos/${repo}/releases`, { | ||||
|     method: 'POST', | ||||
|     headers: { ...headers, 'Content-Type': 'application/json' }, | ||||
|     body: JSON.stringify(payload), | ||||
|   }); | ||||
|  | ||||
|   console.log(`POST to https://api.github.com/repos/${repo}/releases with payload:`, payload); | ||||
|  | ||||
|   if (!res.ok) { | ||||
|     const text = await res.text(); | ||||
|     throw new Error(`Failed to create release: ${res.status} ${res.statusText} - ${text}`); | ||||
|   } | ||||
|  | ||||
|   return await res.json(); | ||||
| } | ||||
|  | ||||
| async function downloadAsset(assetUrl, filename) { | ||||
|   const res = await fetch(assetUrl, { headers: { ...headers, Accept: 'application/octet-stream' } }); | ||||
|   if (!res.ok) throw new Error(`Failed to download asset: ${res.status} ${res.statusText}`); | ||||
|   const buffer = await res.buffer(); | ||||
|   fs.writeFileSync(filename, buffer); | ||||
| } | ||||
|  | ||||
| async function uploadAsset(uploadUrl, filepath) { | ||||
|   const filename = path.basename(filepath); | ||||
|   const stats = fs.statSync(filepath); | ||||
|   const res = await fetch(`${uploadUrl}?name=${encodeURIComponent(filename)}`, { | ||||
|     method: 'POST', | ||||
|     headers: { | ||||
|       Authorization: `token ${TOKEN}`, | ||||
|       'Content-Type': 'application/octet-stream', | ||||
|       'Content-Length': stats.size, | ||||
|     }, | ||||
|     body: fs.createReadStream(filepath), | ||||
|   }); | ||||
|  | ||||
|   if (!res.ok) { | ||||
|     const text = await res.text(); | ||||
|     throw new Error(`Failed to upload asset: ${res.status} ${res.statusText} - ${text}`); | ||||
|   } | ||||
|  | ||||
|   return await res.json(); | ||||
| } | ||||
|  | ||||
| async function migrate() { | ||||
|   console.log(`Fetching releases from ${SOURCE_REPO}...`); | ||||
|   const releases = await getReleases(SOURCE_REPO); | ||||
|   console.log(`Found ${releases.length} releases.`); | ||||
|  | ||||
|   releases.sort((a, b) => new Date(a.created_at) - new Date(b.created_at)); | ||||
|  | ||||
|   for (const release of releases) { | ||||
|     console.log(`Migrating release: ${release.name} (${release.tag_name})`); | ||||
|     const newRelease = await createRelease(DEST_REPO, release); | ||||
|  | ||||
|     // Download and upload assets if any | ||||
|     for (const asset of release.assets) { | ||||
|       const tempFile = path.join(__dirname, asset.name); | ||||
|       console.log(`Downloading asset ${asset.name}...`); | ||||
|       await downloadAsset(asset.url, tempFile); | ||||
|  | ||||
|       console.log(`Uploading asset ${asset.name}...`); | ||||
|       await uploadAsset(newRelease.upload_url.replace('{?name,label}', ''), tempFile); | ||||
|  | ||||
|       fs.unlinkSync(tempFile); // Clean up temp file | ||||
|     } | ||||
|   } | ||||
|   console.log('Migration complete!'); | ||||
| } | ||||
|  | ||||
| migrate().catch((err) => { | ||||
|   console.error('Migration failed:', err); | ||||
|   process.exit(1); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user