mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-02 19:36:12 +01:00 
			
		
		
		
	
		
			
	
	
		
			126 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			126 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								// 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);
							 | 
						||
| 
								 | 
							
								});
							 |