Last active
July 23, 2025 16:36
-
-
Save flavio/f13ab7ebd9b421a4602a7569a9100a50 to your computer and use it in GitHub Desktop.
Revisions
-
flavio revised this gist
Jul 23, 2025 . No changes.There are no files selected for viewing
-
flavio revised this gist
Jul 23, 2025 . 1 changed file with 50 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,50 @@ require 'octokit' # Usage: # ruby org-backup.rb save org_name # ruby org-backup.rb restore org_name # (expects token in .github_token file in current directory or HOME) def read_token paths = [ File.join(Dir.pwd, ".github_token"), File.join(Dir.home, ".github_token") ] paths.each do |path| return File.read(path).strip if File.exist?(path) end puts "GitHub token not found. Please create a .github_token file in the current directory or your home directory." exit 1 end if ARGV.length != 2 || !%w[save restore].include?(ARGV[0]) puts "Usage:" puts " ruby org-backup.rb save org_name" puts " ruby org-backup.rb restore org_name" exit 1 end mode, org = ARGV token = read_token client = Octokit::Client.new(access_token: token) client.auto_paginate = true repos = client.org_repos(org, type: 'all').map(&:full_name) total = repos.size repos.each_with_index do |repo, idx| file = "#{repo.gsub('/', '__')}.json" progress = "#{idx + 1}/#{total}" if mode == "save" puts "[#{progress}] Saving labels for #{repo}..." system("ruby repo-backup.rb save #{repo} #{file}") else if File.exist?(file) puts "[#{progress}] Restoring labels for #{repo}..." system("ruby repo-backup.rb restore #{repo} #{file}") else puts "[#{progress}] Backup file #{file} not found for #{repo}, skipping." end end end -
flavio created this gist
Jul 23, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ require 'octokit' require 'json' # Usage: # ruby repo-backup.rb save owner/repo output.json # ruby repo-backup.rb restore owner/repo input.json # (expects token in .github_token file in the current directory or HOME) def read_token paths = [ File.join(Dir.pwd, ".github_token"), File.join(Dir.home, ".github_token") ] paths.each do |path| return File.read(path).strip if File.exist?(path) end puts "GitHub token not found. Please create a .github_token file in the current directory or your home directory." exit 1 end if ARGV.length != 3 || !%w[save restore].include?(ARGV[0]) puts "Usage:" puts " ruby repo-backup.rb save owner/repo output.json" puts " ruby repo-backup.rb restore owner/repo input.json" puts " (expects token in .github_token file in current directory or HOME)" exit 1 end mode, repo, file = ARGV token = read_token client = Octokit::Client.new(access_token: token) client.auto_paginate = true def fetch_labels_for_items(client, repo, type) items = [] page = 1 loop do batch = if type == :issue client.issues(repo, state: 'all', per_page: 100, page: page) else client.pull_requests(repo, state: 'all', per_page: 100, page: page) end break if batch.empty? items.concat(batch) page += 1 end items.map do |item| { id: item.id, number: item.number, title: item.title, labels: item.labels.map { |l| l.name } } end end if mode == "save" puts "Fetching issues..." issues = fetch_labels_for_items(client, repo, :issue) puts "Fetching pull requests..." prs = fetch_labels_for_items(client, repo, :pr) result = { issues: issues, pull_requests: prs } File.write(file, JSON.pretty_generate(result)) puts "Saved associations to #{file}" elsif mode == "restore" data = JSON.parse(File.read(file)) puts "Restoring issue labels..." data["issues"].each do |issue| begin client.update_issue(repo, issue["number"], labels: issue["labels"]) puts "Restored labels for issue ##{issue["number"]}" rescue => e puts "Failed to restore labels for issue ##{issue["number"]}: #{e}" end end puts "Restoring pull request labels..." data["pull_requests"].each do |pr| begin client.update_issue(repo, pr["number"], labels: pr["labels"]) puts "Restored labels for pull request ##{pr["number"]}" rescue => e puts "Failed to restore labels for pull request ##{pr["number"]}: #{e}" end end end