mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-07 20:16:46 +03:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fb5f9e190 | ||
|
|
dacec93f55 |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [3.2.6] - 2025-08-09
|
||||
|
||||
### Fixed
|
||||
- Added missing release asset mirroring functionality (APK, ZIP, Binary files)
|
||||
- Release assets (attachments) are now properly downloaded from GitHub and uploaded to Gitea
|
||||
- Fixed missing metadata component configuration checks
|
||||
|
||||
### Added
|
||||
- Full support for mirroring release assets/attachments
|
||||
- Debug logging for metadata component configuration to help troubleshoot mirroring issues
|
||||
- Download and upload progress logging for release assets
|
||||
|
||||
### Improved
|
||||
- Enhanced release mirroring to include all associated binary files and attachments
|
||||
- Better visibility into which metadata components are enabled/disabled
|
||||
- More detailed logging during the release asset transfer process
|
||||
|
||||
### Notes
|
||||
This patch adds the missing functionality to mirror release assets (APK, ZIP, Binary files, etc.) that was reported in Issue #68. Previously only release metadata was being mirrored, now all attachments are properly transferred to Gitea.
|
||||
|
||||
## [3.2.5] - 2025-08-09
|
||||
|
||||
### Fixed
|
||||
- Fixed critical authentication issue in releases mirroring that was still using encrypted tokens
|
||||
- Added missing repository existence check for releases mirroring function
|
||||
- Fixed "user does not exist [uid: 0]" error specifically affecting GitHub releases synchronization
|
||||
|
||||
### Improved
|
||||
- Enhanced releases mirroring with duplicate detection to avoid errors on re-runs
|
||||
- Better error handling and logging for release operations with [Releases] prefix
|
||||
- Added individual release error handling to continue mirroring even if some releases fail
|
||||
|
||||
### Notes
|
||||
This patch completes the authentication fixes started in v3.2.4, specifically addressing the releases mirroring function that was accidentally missed in the previous update.
|
||||
|
||||
## [3.2.4] - 2025-08-09
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "gitea-mirror",
|
||||
"type": "module",
|
||||
"version": "3.2.4",
|
||||
"version": "3.2.6",
|
||||
"engines": {
|
||||
"bun": ">=1.2.9"
|
||||
},
|
||||
|
||||
139
src/lib/gitea.ts
139
src/lib/gitea.ts
@@ -429,6 +429,7 @@ export const mirrorGithubRepoToGitea = async ({
|
||||
);
|
||||
|
||||
//mirror releases
|
||||
console.log(`[Metadata] Release mirroring check: mirrorReleases=${config.giteaConfig?.mirrorReleases}`);
|
||||
if (config.giteaConfig?.mirrorReleases) {
|
||||
await mirrorGitHubReleasesToGitea({
|
||||
config,
|
||||
@@ -442,6 +443,8 @@ export const mirrorGithubRepoToGitea = async ({
|
||||
const shouldMirrorIssues = config.giteaConfig?.mirrorIssues &&
|
||||
!(repository.isStarred && config.githubConfig?.skipStarredIssues);
|
||||
|
||||
console.log(`[Metadata] Issue mirroring check: mirrorIssues=${config.giteaConfig?.mirrorIssues}, isStarred=${repository.isStarred}, skipStarredIssues=${config.githubConfig?.skipStarredIssues}, shouldMirrorIssues=${shouldMirrorIssues}`);
|
||||
|
||||
if (shouldMirrorIssues) {
|
||||
await mirrorGitRepoIssuesToGitea({
|
||||
config,
|
||||
@@ -452,6 +455,7 @@ export const mirrorGithubRepoToGitea = async ({
|
||||
}
|
||||
|
||||
// Mirror pull requests if enabled
|
||||
console.log(`[Metadata] Pull request mirroring check: mirrorPullRequests=${config.giteaConfig?.mirrorPullRequests}`);
|
||||
if (config.giteaConfig?.mirrorPullRequests) {
|
||||
await mirrorGitRepoPullRequestsToGitea({
|
||||
config,
|
||||
@@ -462,6 +466,7 @@ export const mirrorGithubRepoToGitea = async ({
|
||||
}
|
||||
|
||||
// Mirror labels if enabled (and not already done via issues)
|
||||
console.log(`[Metadata] Label mirroring check: mirrorLabels=${config.giteaConfig?.mirrorLabels}, shouldMirrorIssues=${shouldMirrorIssues}`);
|
||||
if (config.giteaConfig?.mirrorLabels && !shouldMirrorIssues) {
|
||||
await mirrorGitRepoLabelsToGitea({
|
||||
config,
|
||||
@@ -472,6 +477,7 @@ export const mirrorGithubRepoToGitea = async ({
|
||||
}
|
||||
|
||||
// Mirror milestones if enabled
|
||||
console.log(`[Metadata] Milestone mirroring check: mirrorMilestones=${config.giteaConfig?.mirrorMilestones}`);
|
||||
if (config.giteaConfig?.mirrorMilestones) {
|
||||
await mirrorGitRepoMilestonesToGitea({
|
||||
config,
|
||||
@@ -683,6 +689,7 @@ export async function mirrorGitHubRepoToGiteaOrg({
|
||||
);
|
||||
|
||||
//mirror releases
|
||||
console.log(`[Metadata] Release mirroring check: mirrorReleases=${config.giteaConfig?.mirrorReleases}`);
|
||||
if (config.giteaConfig?.mirrorReleases) {
|
||||
await mirrorGitHubReleasesToGitea({
|
||||
config,
|
||||
@@ -706,6 +713,7 @@ export async function mirrorGitHubRepoToGiteaOrg({
|
||||
}
|
||||
|
||||
// Mirror pull requests if enabled
|
||||
console.log(`[Metadata] Pull request mirroring check: mirrorPullRequests=${config.giteaConfig?.mirrorPullRequests}`);
|
||||
if (config.giteaConfig?.mirrorPullRequests) {
|
||||
await mirrorGitRepoPullRequestsToGitea({
|
||||
config,
|
||||
@@ -716,6 +724,7 @@ export async function mirrorGitHubRepoToGiteaOrg({
|
||||
}
|
||||
|
||||
// Mirror labels if enabled (and not already done via issues)
|
||||
console.log(`[Metadata] Label mirroring check: mirrorLabels=${config.giteaConfig?.mirrorLabels}, shouldMirrorIssues=${shouldMirrorIssues}`);
|
||||
if (config.giteaConfig?.mirrorLabels && !shouldMirrorIssues) {
|
||||
await mirrorGitRepoLabelsToGitea({
|
||||
config,
|
||||
@@ -726,6 +735,7 @@ export async function mirrorGitHubRepoToGiteaOrg({
|
||||
}
|
||||
|
||||
// Mirror milestones if enabled
|
||||
console.log(`[Metadata] Milestone mirroring check: mirrorMilestones=${config.giteaConfig?.mirrorMilestones}`);
|
||||
if (config.giteaConfig?.mirrorMilestones) {
|
||||
await mirrorGitRepoMilestonesToGitea({
|
||||
config,
|
||||
@@ -1298,36 +1308,131 @@ export async function mirrorGitHubReleasesToGitea({
|
||||
throw new Error("Gitea config is incomplete for mirroring releases.");
|
||||
}
|
||||
|
||||
// Decrypt config tokens for API usage
|
||||
const decryptedConfig = decryptConfigTokens(config as Config);
|
||||
|
||||
const repoOwner = await getGiteaRepoOwnerAsync({
|
||||
config,
|
||||
repository,
|
||||
});
|
||||
|
||||
const { url, token } = config.giteaConfig;
|
||||
// Verify the repository exists in Gitea before attempting to mirror releases
|
||||
console.log(`[Releases] Verifying repository ${repository.name} exists at ${repoOwner}`);
|
||||
const repoExists = await isRepoPresentInGitea({
|
||||
config,
|
||||
owner: repoOwner,
|
||||
repoName: repository.name,
|
||||
});
|
||||
|
||||
if (!repoExists) {
|
||||
console.error(`[Releases] Repository ${repository.name} not found at ${repoOwner}. Cannot mirror releases.`);
|
||||
throw new Error(`Repository ${repository.name} does not exist in Gitea at ${repoOwner}. Please ensure the repository is mirrored first.`);
|
||||
}
|
||||
|
||||
const releases = await octokit.rest.repos.listReleases({
|
||||
owner: repository.owner,
|
||||
repo: repository.name,
|
||||
});
|
||||
|
||||
for (const release of releases.data) {
|
||||
await httpPost(
|
||||
`${url}/api/v1/repos/${repoOwner}/${repository.name}/releases`,
|
||||
{
|
||||
tag_name: release.tag_name,
|
||||
target: release.target_commitish,
|
||||
title: release.name || release.tag_name,
|
||||
note: release.body || "",
|
||||
draft: release.draft,
|
||||
prerelease: release.prerelease,
|
||||
},
|
||||
{
|
||||
Authorization: `token ${token}`,
|
||||
}
|
||||
);
|
||||
console.log(`[Releases] Found ${releases.data.length} releases to mirror for ${repository.fullName}`);
|
||||
|
||||
if (releases.data.length === 0) {
|
||||
console.log(`[Releases] No releases to mirror for ${repository.fullName}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`✅ Mirrored ${releases.data.length} GitHub releases to Gitea`);
|
||||
let mirroredCount = 0;
|
||||
let skippedCount = 0;
|
||||
|
||||
for (const release of releases.data) {
|
||||
try {
|
||||
// Check if release already exists
|
||||
const existingReleasesResponse = await httpGet(
|
||||
`${config.giteaConfig.url}/api/v1/repos/${repoOwner}/${repository.name}/releases/tags/${release.tag_name}`,
|
||||
{
|
||||
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
||||
}
|
||||
).catch(() => null);
|
||||
|
||||
if (existingReleasesResponse) {
|
||||
console.log(`[Releases] Release ${release.tag_name} already exists, skipping`);
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create the release
|
||||
const createReleaseResponse = await httpPost(
|
||||
`${config.giteaConfig.url}/api/v1/repos/${repoOwner}/${repository.name}/releases`,
|
||||
{
|
||||
tag_name: release.tag_name,
|
||||
target: release.target_commitish,
|
||||
title: release.name || release.tag_name,
|
||||
note: release.body || "",
|
||||
draft: release.draft,
|
||||
prerelease: release.prerelease,
|
||||
},
|
||||
{
|
||||
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
||||
}
|
||||
);
|
||||
|
||||
// Mirror release assets if they exist
|
||||
if (release.assets && release.assets.length > 0) {
|
||||
console.log(`[Releases] Mirroring ${release.assets.length} assets for release ${release.tag_name}`);
|
||||
|
||||
for (const asset of release.assets) {
|
||||
try {
|
||||
// Download the asset from GitHub
|
||||
console.log(`[Releases] Downloading asset: ${asset.name} (${asset.size} bytes)`);
|
||||
const assetResponse = await fetch(asset.browser_download_url, {
|
||||
headers: {
|
||||
'Accept': 'application/octet-stream',
|
||||
'Authorization': `token ${decryptedConfig.githubConfig.token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!assetResponse.ok) {
|
||||
console.error(`[Releases] Failed to download asset ${asset.name}: ${assetResponse.statusText}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const assetData = await assetResponse.arrayBuffer();
|
||||
|
||||
// Upload the asset to Gitea release
|
||||
const formData = new FormData();
|
||||
formData.append('attachment', new Blob([assetData]), asset.name);
|
||||
|
||||
const uploadResponse = await fetch(
|
||||
`${config.giteaConfig.url}/api/v1/repos/${repoOwner}/${repository.name}/releases/${createReleaseResponse.data.id}/assets?name=${encodeURIComponent(asset.name)}`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `token ${decryptedConfig.giteaConfig.token}`,
|
||||
},
|
||||
body: formData,
|
||||
}
|
||||
);
|
||||
|
||||
if (uploadResponse.ok) {
|
||||
console.log(`[Releases] Successfully uploaded asset: ${asset.name}`);
|
||||
} else {
|
||||
const errorText = await uploadResponse.text();
|
||||
console.error(`[Releases] Failed to upload asset ${asset.name}: ${errorText}`);
|
||||
}
|
||||
} catch (assetError) {
|
||||
console.error(`[Releases] Error processing asset ${asset.name}: ${assetError instanceof Error ? assetError.message : String(assetError)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mirroredCount++;
|
||||
console.log(`[Releases] Successfully mirrored release: ${release.tag_name}`);
|
||||
} catch (error) {
|
||||
console.error(`[Releases] Failed to mirror release ${release.tag_name}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ Mirrored ${mirroredCount} new releases to Gitea (${skippedCount} already existed)`);
|
||||
}
|
||||
|
||||
export async function mirrorGitRepoPullRequestsToGitea({
|
||||
|
||||
Reference in New Issue
Block a user