#!/usr/bin/env ruby require 'net/http' require 'json' require 'uri' # Configuration GITEA_URL = "https://git.staging.jamkazam.com/api/v1" GITEA_TOKEN = "6798c2d2b1beed9a8c33c738f7a521548e40bcc5" GITEA_OWNER = "seth" REPOS = [ { name: "jam-cloud", url: "https://bitbucket.org/jamkazam/jam-cloud.git" }, { name: "video-iac", url: "https://bitbucket.org/jamkazam/video-iac.git" } ] if ARGV.length < 2 puts "Usage: ruby setup-gitea-mirror.rb " puts "NOTE: Use your Bitbucket USERNAME (slug), not your email address." exit 1 end bb_user = ARGV[0] bb_pass = ARGV[1] def gitea_request(method, path, payload = nil) uri = URI.parse("#{GITEA_URL}#{path}") header = { 'Content-Type' => 'application/json', 'Authorization' => "token #{GITEA_TOKEN}" } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true # Increase timeouts for large repository migrations http.open_timeout = 300 # 5 minutes http.read_timeout = 300 # 5 minutes case method when :get request = Net::HTTP::Get.new(uri.request_uri, header) when :post request = Net::HTTP::Post.new(uri.request_uri, header) request.body = payload.to_json if payload when :delete request = Net::HTTP::Delete.new(uri.request_uri, header) end http.request(request) end puts "šŸš€ Synchronizing Gitea mirrors via HTTPS..." REPOS.each do |repo| puts "\n--- Repository: #{repo[:name]} ---" # 1. Check if repo already exists check_resp = gitea_request(:get, "/repos/#{GITEA_OWNER}/#{repo[:name]}") if check_resp.code == "200" repo_data = JSON.parse(check_resp.body) # Check if it's actually mirrored and has data if repo_data["empty"] puts "āš ļø Repository exists but is EMPTY (likely a failed migration)." puts "šŸ—‘ļø Deleting broken repo to retry..." gitea_request(:delete, "/repos/#{GITEA_OWNER}/#{repo[:name]}") else puts "āœ… Repository already exists and has data. Skipping." next end end puts "šŸ” Migrating from Bitbucket via HTTPS..." payload = { "clone_addr" => repo[:url], "auth_username" => bb_user, "auth_password" => bb_pass, "repo_name" => repo[:name], "mirror" => true, "mirror_interval" => "10m", # Gitea minimum is 10m "service" => "bitbucket", "repo_owner" => GITEA_OWNER, "lfs" => true, "releases" => true } begin migrate_resp = gitea_request(:post, "/repos/migrate", payload) if migrate_resp.code == "201" puts "āœ… Mirror created successfully!" puts "šŸ’” Webhook for 'Instant Updates':" puts " URL: https://git.staging.jamkazam.com/api/v1/repos/#{GITEA_OWNER}/#{repo[:name]}/mirror-sync?token=#{GITEA_TOKEN}" else puts "āŒ Failed to create mirror: #{migrate_resp.code}" puts migrate_resp.body end rescue Net::ReadTimeout, Net::OpenTimeout puts "āš ļø Request timed out, but Gitea might still be processing the migration in the background." puts " Check Gitea UI: https://git.staging.jamkazam.com/#{GITEA_OWNER}/#{repo[:name]}" end end puts "\n✨ All mirrors synchronized."