github->gitea mirror

Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2026-08-27 11:34:20 +02:00
parent 922258b4b6
commit 0f152bde71
+87 -1
View File
@@ -1,5 +1,6 @@
{ {
config, config,
pkgs,
pkgs-unstable, pkgs-unstable,
lib, lib,
... ...
@@ -11,6 +12,60 @@
sha256 = "sha256-rZHLORwLUfIFcB6K9yhrzr+UwdPNQVSadsw6rg8Q7gs="; sha256 = "sha256-rZHLORwLUfIFcB6K9yhrzr+UwdPNQVSadsw6rg8Q7gs=";
stripRoot = false; stripRoot = false;
}; };
giteaUrl = "http://10.233.11.2:3002";
githubUsername = "anotherhadi";
giteaGithubMirror = pkgs.writeShellApplication {
name = "gitea-github-mirror";
runtimeInputs = [pkgs.curl pkgs.jq];
text = ''
github_token="$(cat "$GITHUB_TOKEN_FILE")"
gitea_token="$(cat "$GITEA_TOKEN_FILE")"
tmp_github="$(mktemp)"
tmp_gitea="$(mktemp)"
trap 'rm -f "$tmp_github" "$tmp_gitea"' EXIT
page=1
while :; do
resp="$(curl -sf -H "Authorization: Bearer $github_token" \
"https://api.github.com/user/repos?affiliation=owner&per_page=100&page=$page")"
echo "$resp" >> "$tmp_github"
count="$(echo "$resp" | jq 'length')"
[ "$count" -lt 100 ] && break
page=$((page + 1))
done
page=1
while :; do
resp="$(curl -sf -H "Authorization: token $gitea_token" \
"$GITEA_URL/api/v1/users/$GITEA_OWNER/repos?limit=50&page=$page")"
echo "$resp" >> "$tmp_gitea"
count="$(echo "$resp" | jq 'length')"
[ "$count" -lt 50 ] && break
page=$((page + 1))
done
existing="$(jq -s '[.[][].name]' "$tmp_gitea")"
github_repos="$(jq -s 'add | map(select(.archived | not)) | map({name, private, clone_url, description: (.description // "")})' "$tmp_github")"
echo "$github_repos" | jq -c '.[]' | while IFS= read -r repo; do
name="$(echo "$repo" | jq -r '.name')"
if echo "$existing" | jq -e --arg n "$name" 'index($n)' > /dev/null; then
continue
fi
echo "Mirroring new repo: $name"
body="$(echo "$repo" | jq \
--arg owner "$GITEA_OWNER" \
--arg token "$github_token" \
'{clone_addr: .clone_url, service: "github", repo_name: .name, repo_owner: $owner, mirror: true, private: .private, auth_token: $token, description: .description, mirror_interval: "8h0m0s"}')"
curl -sf -X POST -H "Authorization: token $gitea_token" -H "Content-Type: application/json" \
"$GITEA_URL/api/v1/repos/migrate" -d "$body" > /dev/null \
|| echo "Failed to mirror $name" >&2
done
'';
};
in { in {
imports = [ imports = [
(mkContainer { (mkContainer {
@@ -80,5 +135,36 @@ in {
}) })
]; ];
services.cloudflared.tunnels."${config.var.tunnelId}".ingress."git.${domain}" = "http://10.233.11.2:3002"; services.cloudflared.tunnels."${config.var.tunnelId}".ingress."git.${domain}" = giteaUrl;
sops.secrets = {
github-mirror-token = {};
gitea-mirror-token = {};
};
systemd.services.gitea-github-mirror = {
description = "Mirror all GitHub repos of ${githubUsername} into Gitea";
after = ["network-online.target" "container@gitea.service"];
wants = ["network-online.target"];
environment = {
GITHUB_TOKEN_FILE = config.sops.secrets.github-mirror-token.path;
GITEA_TOKEN_FILE = config.sops.secrets.gitea-mirror-token.path;
GITEA_URL = giteaUrl;
GITEA_OWNER = githubUsername;
};
serviceConfig = {
Type = "oneshot";
ExecStart = "${giteaGithubMirror}/bin/gitea-github-mirror";
};
};
systemd.timers.gitea-github-mirror = {
description = "Periodically mirror all GitHub repos into Gitea";
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m";
OnUnitActiveSec = "30m";
Persistent = true;
};
};
} }