mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 11:56:01 +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);
 | 
						|
});
 |