mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-08 12:36:44 +03:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8965a9fd4 | ||
|
|
598e81ff45 | ||
|
|
fef6cbb60d | ||
|
|
c793be5863 | ||
|
|
d097ded6ee |
@@ -26,7 +26,7 @@ BETTER_AUTH_URL=http://localhost:4321
|
||||
|
||||
# Docker Registry Configuration
|
||||
DOCKER_REGISTRY=ghcr.io
|
||||
DOCKER_IMAGE=arunavo4/gitea-mirror
|
||||
DOCKER_IMAGE=raylabshq/gitea-mirror:
|
||||
DOCKER_TAG=latest
|
||||
|
||||
# ===========================================
|
||||
|
||||
14
bun.lock
14
bun.lock
@@ -31,7 +31,7 @@
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@types/react": "^19.1.12",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"astro": "^5.13.4",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"better-auth": "^1.3.7",
|
||||
@@ -55,7 +55,7 @@
|
||||
"typescript": "^5.9.2",
|
||||
"uuid": "^11.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^4.1.4",
|
||||
"zod": "^4.1.5",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
@@ -64,7 +64,7 @@
|
||||
"@types/bun": "^1.2.21",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vitejs/plugin-react": "^5.0.1",
|
||||
"@vitejs/plugin-react": "^5.0.2",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"jsdom": "^26.1.0",
|
||||
"tsx": "^4.20.5",
|
||||
@@ -439,7 +439,7 @@
|
||||
|
||||
"@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
|
||||
|
||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.32", "", {}, "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g=="],
|
||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.34", "", {}, "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA=="],
|
||||
|
||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
||||
|
||||
@@ -587,7 +587,7 @@
|
||||
|
||||
"@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.1.8", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-xG7xaBMJCpcK0RpN8jDbAACQo54ycO6h4dSSmgv8+fu6ZIAdANkx/WsawASUjVXYfy+J9AbUpRMNNEsXCDfDBQ=="],
|
||||
"@types/react-dom": ["@types/react-dom@19.1.9", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ=="],
|
||||
|
||||
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
|
||||
|
||||
@@ -595,7 +595,7 @@
|
||||
|
||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||
|
||||
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.0.1", "", { "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.32", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-DE4UNaBXwtVoDJ0ccBdLVjFTWL70NRuWNCxEieTI3lrq9ORB9aOCQEKstwDXBl87NvFdbqh/p7eINGyj0BthJA=="],
|
||||
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.0.2", "", { "dependencies": { "@babel/core": "^7.28.3", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.34", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw=="],
|
||||
|
||||
"@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
|
||||
|
||||
@@ -1753,7 +1753,7 @@
|
||||
|
||||
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
||||
|
||||
"zod": ["zod@4.1.4", "", {}, "sha512-2YqJuWkU6IIK9qcE4k1lLLhyZ6zFw7XVRdQGpV97jEIZwTrscUw+DY31Xczd8nwaoksyJUIxCojZXwckJovWxA=="],
|
||||
"zod": ["zod@4.1.5", "", {}, "sha512-rcUUZqlLJgBC33IT3PNMgsCq6TzLQEG/Ei/KTCU0PedSWRMAXoOUN+4t/0H+Q8bdnLPdqUYnvboJT0bn/229qg=="],
|
||||
|
||||
"zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="],
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ Settings specific to Docker deployments.
|
||||
| Variable | Description | Default | Options |
|
||||
|----------|-------------|---------|---------|
|
||||
| `DOCKER_REGISTRY` | Docker registry URL | `ghcr.io` | Registry URL |
|
||||
| `DOCKER_IMAGE` | Docker image name | `arunavo4/gitea-mirror` | Image name |
|
||||
| `DOCKER_IMAGE` | Docker image name | `raylabshq/gitea-mirror:` | Image name |
|
||||
| `DOCKER_TAG` | Docker image tag | `latest` | Tag name |
|
||||
|
||||
## Example Docker Compose Configuration
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "gitea-mirror",
|
||||
"type": "module",
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.0",
|
||||
"engines": {
|
||||
"bun": ">=1.2.9"
|
||||
},
|
||||
@@ -69,7 +69,7 @@
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@types/react": "^19.1.12",
|
||||
"@types/react-dom": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"astro": "^5.13.4",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"better-auth": "^1.3.7",
|
||||
@@ -93,7 +93,7 @@
|
||||
"typescript": "^5.9.2",
|
||||
"uuid": "^11.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^4.1.4"
|
||||
"zod": "^4.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
@@ -102,7 +102,7 @@
|
||||
"@types/bun": "^1.2.21",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vitejs/plugin-react": "^5.0.1",
|
||||
"@vitejs/plugin-react": "^5.0.2",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"jsdom": "^26.1.0",
|
||||
"tsx": "^4.20.5",
|
||||
|
||||
@@ -57,7 +57,7 @@ http://<container-ip>:4321
|
||||
|
||||
```bash
|
||||
git clone https://github.com/RayLabsHQ/gitea-mirror.git # if not already
|
||||
curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-local.sh -o gitea-mirror-lxc-local.sh
|
||||
curl -fsSL https://raw.githubusercontent.com/raylabshq/gitea-mirror:/main/scripts/gitea-mirror-lxc-local.sh -o gitea-mirror-lxc-local.sh
|
||||
chmod +x gitea-mirror-lxc-local.sh
|
||||
|
||||
sudo LOCAL_REPO_DIR=~/Development/gitea-mirror \
|
||||
|
||||
@@ -183,7 +183,9 @@ export default function Repository() {
|
||||
);
|
||||
|
||||
if (response.success) {
|
||||
toast.success(`Mirroring started for repository ID: ${repoId}`);
|
||||
const repo = repositories.find(r => r.id === repoId);
|
||||
const repoName = repo?.fullName || `repository ${repoId}`;
|
||||
toast.success(`Mirroring started for ${repoName}`);
|
||||
setRepositories((prevRepos) =>
|
||||
prevRepos.map((repo) => {
|
||||
const updated = response.repositories.find((r) => r.id === repo.id);
|
||||
@@ -496,7 +498,9 @@ export default function Repository() {
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
toast.success(`Syncing started for repository ID: ${repoId}`);
|
||||
const repo = repositories.find(r => r.id === repoId);
|
||||
const repoName = repo?.fullName || `repository ${repoId}`;
|
||||
toast.success(`Syncing started for ${repoName}`);
|
||||
setRepositories((prevRepos) =>
|
||||
prevRepos.map((repo) => {
|
||||
const updated = response.repositories.find((r) => r.id === repo.id);
|
||||
@@ -588,7 +592,9 @@ export default function Repository() {
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
toast.success(`Retrying job for repository ID: ${repoId}`);
|
||||
const repo = repositories.find(r => r.id === repoId);
|
||||
const repoName = repo?.fullName || `repository ${repoId}`;
|
||||
toast.success(`Retrying job for ${repoName}`);
|
||||
setRepositories((prevRepos) =>
|
||||
prevRepos.map((repo) => {
|
||||
const updated = response.repositories.find((r) => r.id === repo.id);
|
||||
|
||||
@@ -1583,9 +1583,26 @@ export async function mirrorGitRepoPullRequestsToGitea({
|
||||
// Pull requests are typically created through Git operations
|
||||
// For now, we'll create them as issues with a special label
|
||||
|
||||
// Get or create a PR label
|
||||
// Get existing labels from Gitea and ensure "pull-request" label exists
|
||||
const giteaLabelsRes = await httpGet(
|
||||
`${config.giteaConfig.url}/api/v1/repos/${giteaOwner}/${repository.name}/labels`,
|
||||
{
|
||||
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
||||
}
|
||||
);
|
||||
|
||||
const giteaLabels = giteaLabelsRes.data;
|
||||
const labelMap = new Map<string, number>(
|
||||
giteaLabels.map((label: any) => [label.name, label.id])
|
||||
);
|
||||
|
||||
// Ensure "pull-request" label exists
|
||||
let pullRequestLabelId: number | null = null;
|
||||
if (labelMap.has("pull-request")) {
|
||||
pullRequestLabelId = labelMap.get("pull-request")!;
|
||||
} else {
|
||||
try {
|
||||
await httpPost(
|
||||
const created = await httpPost(
|
||||
`${config.giteaConfig.url}/api/v1/repos/${giteaOwner}/${repository.name}/labels`,
|
||||
{
|
||||
name: "pull-request",
|
||||
@@ -1596,8 +1613,11 @@ export async function mirrorGitRepoPullRequestsToGitea({
|
||||
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
||||
}
|
||||
);
|
||||
pullRequestLabelId = created.data.id;
|
||||
} catch (error) {
|
||||
// Label might already exist, continue
|
||||
console.error(`Failed to create "pull-request" label in Gitea: ${error}`);
|
||||
// Continue without labels if creation fails
|
||||
}
|
||||
}
|
||||
|
||||
const { processWithRetry } = await import("@/lib/utils/concurrency");
|
||||
@@ -1681,8 +1701,8 @@ export async function mirrorGitRepoPullRequestsToGitea({
|
||||
const issueData = {
|
||||
title: issueTitle,
|
||||
body: richBody,
|
||||
labels: [{ name: "pull-request" }],
|
||||
state: pr.state === "closed" ? "closed" : "open",
|
||||
labels: pullRequestLabelId ? [pullRequestLabelId] : [],
|
||||
closed: pr.state === "closed" || pr.merged_at !== null,
|
||||
};
|
||||
|
||||
console.log(`[Pull Requests] Creating enriched issue for PR #${pr.number}: ${pr.title}`);
|
||||
@@ -1701,8 +1721,8 @@ export async function mirrorGitRepoPullRequestsToGitea({
|
||||
const basicIssueData = {
|
||||
title: `[PR #${pr.number}] ${pr.title}`,
|
||||
body: `**Original Pull Request:** ${pr.html_url}\n\n**State:** ${pr.state}\n**Merged:** ${pr.merged_at ? 'Yes' : 'No'}\n\n---\n\n${pr.body || 'No description provided'}`,
|
||||
labels: [{ name: "pull-request" }],
|
||||
state: pr.state === "closed" ? "closed" : "open",
|
||||
labels: pullRequestLabelId ? [pullRequestLabelId] : [],
|
||||
closed: pr.state === "closed" || pr.merged_at !== null,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user