mirror of
https://github.com/amalgamated-tools/mirror-to-gitea.git
synced 2025-12-23 22:18:05 -05:00
add support for USE_SPECIFIC_USER feature to fetch starred repositories and organizations for a specified GitHub user
This commit is contained in:
@@ -53,6 +53,7 @@ All configuration is performed through environment variables. Flags are consider
|
||||
| MIRROR_ISSUES | no | bool | FALSE | If set to `true` the issues of your GitHub repositories will be mirrored to Gitea. Requires `GITHUB_TOKEN`. |
|
||||
| MIRROR_STARRED | no | bool | FALSE | If set to `true` repositories you've starred on GitHub will be mirrored to Gitea. Requires `GITHUB_TOKEN`. |
|
||||
| MIRROR_ORGANIZATIONS | no | bool | FALSE | If set to `true` repositories from organizations you belong to will be mirrored to Gitea. Requires `GITHUB_TOKEN`. |
|
||||
| USE_SPECIFIC_USER | no | bool | FALSE | If set to `true`, the tool will use public API endpoints to fetch starred repositories and organizations for the specified `GITHUB_USERNAME` instead of the authenticated user. |
|
||||
| INCLUDE_ORGS | no | string | "" | Comma-separated list of GitHub organization names to include when mirroring organizations. If not specified, all organizations will be included. |
|
||||
| EXCLUDE_ORGS | no | string | "" | Comma-separated list of GitHub organization names to exclude when mirroring organizations. Takes precedence over `INCLUDE_ORGS`. |
|
||||
| PRESERVE_ORG_STRUCTURE | no | bool | FALSE | If set to `true`, each GitHub organization will be mirrored to a Gitea organization with the same name. If the organization doesn't exist, it will be created. |
|
||||
|
||||
77
debug.sh
77
debug.sh
@@ -31,7 +31,7 @@ else
|
||||
fi
|
||||
|
||||
echo -e "\nTesting GitHub organization access:"
|
||||
echo "Method 1 - Using /user/orgs endpoint:"
|
||||
echo "Method 1 - Using /user/orgs endpoint (authenticated user):"
|
||||
ORG_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user/orgs")
|
||||
ORG_COUNT=$(echo "$ORG_RESPONSE" | jq '. | length')
|
||||
if [ "$ORG_COUNT" -eq 0 ]; then
|
||||
@@ -41,7 +41,17 @@ else
|
||||
echo "$ORG_RESPONSE" | jq '.[].login'
|
||||
fi
|
||||
|
||||
echo "Method 2 - Looking for specific organizations:"
|
||||
echo -e "\nMethod 2 - Using /users/{username}/orgs endpoint (specific user):"
|
||||
PUBLIC_USER_ORGS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" "https://api.github.com/users/$GITHUB_USERNAME/orgs")
|
||||
PUBLIC_ORG_COUNT=$(echo "$PUBLIC_USER_ORGS" | jq '. | length')
|
||||
if [ "$PUBLIC_ORG_COUNT" -eq 0 ]; then
|
||||
echo "No public organizations found for $GITHUB_USERNAME via /users/{username}/orgs endpoint."
|
||||
else
|
||||
echo "Public organizations found for $GITHUB_USERNAME:"
|
||||
echo "$PUBLIC_USER_ORGS" | jq '.[].login'
|
||||
fi
|
||||
|
||||
echo "Method 3 - Looking for specific organizations:"
|
||||
for org in "Gameplex-labs" "Neucruit" "uiastra"; do
|
||||
ORG_DETAILS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/orgs/$org")
|
||||
if [[ $(echo "$ORG_DETAILS" | jq 'has("login")') == "true" ]]; then
|
||||
@@ -62,6 +72,7 @@ for org in "Gameplex-labs" "Neucruit" "uiastra"; do
|
||||
done
|
||||
|
||||
echo -e "\nTesting GitHub starred repos access:"
|
||||
echo "Method 1 - Using /user/starred endpoint (authenticated user):"
|
||||
STARRED_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user/starred?per_page=1")
|
||||
STARRED_COUNT=$(echo "$STARRED_RESPONSE" | jq '. | length')
|
||||
if [ "$STARRED_COUNT" -eq 0 ]; then
|
||||
@@ -71,6 +82,60 @@ else
|
||||
echo "Total starred repositories accessible: $(curl -s -H "Authorization: token $GITHUB_TOKEN" -I "https://api.github.com/user/starred" | grep -i "^link:" | grep -o "page=[0-9]*" | sort -r | head -1 | cut -d= -f2 || echo "Unknown")"
|
||||
fi
|
||||
|
||||
echo -e "\nMethod 2 - Using /users/{username}/starred endpoint (specific user):"
|
||||
PUBLIC_STARRED_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" "https://api.github.com/users/$GITHUB_USERNAME/starred?per_page=1")
|
||||
PUBLIC_STARRED_COUNT=$(echo "$PUBLIC_STARRED_RESPONSE" | jq '. | length')
|
||||
if [ "$PUBLIC_STARRED_COUNT" -eq 0 ]; then
|
||||
echo "No public starred repositories found for $GITHUB_USERNAME."
|
||||
else
|
||||
echo "First public starred repo for $GITHUB_USERNAME: $(echo "$PUBLIC_STARRED_RESPONSE" | jq '.[0].full_name')"
|
||||
echo "Total public starred repositories for $GITHUB_USERNAME: $(curl -s -H "Authorization: token $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" -I "https://api.github.com/users/$GITHUB_USERNAME/starred" | grep -i "^link:" | grep -o "page=[0-9]*" | sort -r | head -1 | cut -d= -f2 || echo "Unknown")"
|
||||
fi
|
||||
|
||||
echo -e "\nTesting GitHub issues access:"
|
||||
echo "Checking for issues in your repositories..."
|
||||
|
||||
# Get a list of repositories to check for issues
|
||||
USER_REPOS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user/repos?per_page=5&sort=updated")
|
||||
REPO_COUNT=$(echo "$USER_REPOS" | jq '. | length')
|
||||
|
||||
echo "Found $REPO_COUNT recently updated repositories to check for issues"
|
||||
|
||||
# Check each repository for issues
|
||||
for i in $(seq 0 $(($REPO_COUNT - 1))); do
|
||||
REPO=$(echo "$USER_REPOS" | jq -r ".[$i].full_name")
|
||||
REPO_HAS_ISSUES=$(echo "$USER_REPOS" | jq -r ".[$i].has_issues")
|
||||
|
||||
if [ "$REPO_HAS_ISSUES" = "true" ]; then
|
||||
ISSUES_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$REPO/issues?state=all&per_page=1")
|
||||
ISSUES_COUNT=$(curl -s -H "Authorization: token $GITHUB_TOKEN" -I "https://api.github.com/repos/$REPO/issues?state=all" | grep -i "^link:" | grep -o "page=[0-9]*" | sort -r | head -1 | cut -d= -f2 || echo "0")
|
||||
|
||||
if [ -z "$ISSUES_COUNT" ]; then
|
||||
# If we couldn't get the count from Link header, count the array length
|
||||
ISSUES_COUNT=$(echo "$ISSUES_RESPONSE" | jq '. | length')
|
||||
fi
|
||||
|
||||
if [ "$ISSUES_COUNT" -gt 0 ]; then
|
||||
echo "Repository $REPO has approximately $ISSUES_COUNT issues"
|
||||
echo "Latest issue: $(echo "$ISSUES_RESPONSE" | jq -r '.[0].title // "No title"')"
|
||||
else
|
||||
echo "Repository $REPO has issues enabled but no issues were found"
|
||||
fi
|
||||
else
|
||||
echo "Repository $REPO has issues disabled"
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "\nVerifying GitHub token scopes for issues access:"
|
||||
SCOPES=$(curl -s -I -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" | grep -i "^x-oauth-scopes:" | cut -d ":" -f 2- | tr -d '\r' || echo "None found")
|
||||
|
||||
if [[ "$SCOPES" == *"repo"* ]]; then
|
||||
echo "Your token has the 'repo' scope, which is required for issues access"
|
||||
else
|
||||
echo "WARNING: Your token may not have the 'repo' scope, which is required for full issues access"
|
||||
echo "Testing issues access directly: $(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_USERNAME/$(echo "$USER_REPOS" | jq -r '.[0].name')/issues")"
|
||||
fi
|
||||
|
||||
echo -e "\nVerifying GitHub token scopes:"
|
||||
SCOPES=$(curl -s -I -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" | grep -i "^x-oauth-scopes:" | cut -d ":" -f 2- | tr -d '\r' || echo "None found")
|
||||
if [ -z "$SCOPES" ] || [ "$SCOPES" = "None found" ]; then
|
||||
@@ -89,5 +154,13 @@ echo "- repo (for repositories and issues)"
|
||||
echo "- read:org (for organization access)"
|
||||
echo "- user (for starred repositories)"
|
||||
|
||||
echo -e "\nSpecific user mode tests (USE_SPECIFIC_USER=true):"
|
||||
echo "This mode uses the following endpoints:"
|
||||
echo "- GET /users/{username}/orgs"
|
||||
echo "- GET /users/{username}/starred"
|
||||
echo "These endpoints are working: $([ "$PUBLIC_ORG_COUNT" -ge 0 ] && [ "$PUBLIC_STARRED_COUNT" -ge 0 ] && echo "YES" || echo "NO")"
|
||||
|
||||
echo -e "\nYour environment should now be ready for testing."
|
||||
echo "To test with the new USE_SPECIFIC_USER feature:"
|
||||
echo "export USE_SPECIFIC_USER=true"
|
||||
echo "Run ./run-local.sh to start the mirroring process."
|
||||
@@ -22,6 +22,7 @@ docker container run \
|
||||
-e MIRROR_ISSUES="true" \
|
||||
-e MIRROR_STARRED="true" \
|
||||
-e MIRROR_ORGANIZATIONS="true" \
|
||||
-e USE_SPECIFIC_USER="$USE_SPECIFIC_USER" \
|
||||
-e INCLUDE_ORGS="$INCLUDE_ORGS" \
|
||||
-e EXCLUDE_ORGS="$EXCLUDE_ORGS" \
|
||||
-e PRESERVE_ORG_STRUCTURE="$PRESERVE_ORG_STRUCTURE" \
|
||||
|
||||
@@ -38,6 +38,7 @@ export function configuration() {
|
||||
mirrorIssues: readBoolean("MIRROR_ISSUES"),
|
||||
mirrorStarred: readBoolean("MIRROR_STARRED"),
|
||||
mirrorOrganizations: readBoolean("MIRROR_ORGANIZATIONS"),
|
||||
useSpecificUser: readBoolean("USE_SPECIFIC_USER"),
|
||||
singleRepo: readEnv("SINGLE_REPO"),
|
||||
includeOrgs: (readEnv("INCLUDE_ORGS") || "")
|
||||
.split(",")
|
||||
|
||||
@@ -19,7 +19,9 @@ async function getRepositories(octokit, mirrorOptions) {
|
||||
|
||||
// Fetch starred repos if the option is enabled
|
||||
const starredRepos = mirrorOptions.mirrorStarred
|
||||
? await fetchStarredRepositories(octokit)
|
||||
? await fetchStarredRepositories(octokit, {
|
||||
username: mirrorOptions.useSpecificUser ? mirrorOptions.username : undefined
|
||||
})
|
||||
: [];
|
||||
|
||||
// Fetch organization repos if the option is enabled
|
||||
@@ -28,7 +30,8 @@ async function getRepositories(octokit, mirrorOptions) {
|
||||
octokit,
|
||||
mirrorOptions.includeOrgs,
|
||||
mirrorOptions.excludeOrgs,
|
||||
mirrorOptions.preserveOrgStructure
|
||||
mirrorOptions.preserveOrgStructure,
|
||||
{ username: mirrorOptions.useSpecificUser ? mirrorOptions.username : undefined }
|
||||
)
|
||||
: [];
|
||||
|
||||
@@ -98,16 +101,42 @@ async function fetchPrivateRepositories(octokit) {
|
||||
.then(toRepositoryList);
|
||||
}
|
||||
|
||||
async function fetchStarredRepositories(octokit) {
|
||||
async function fetchStarredRepositories(octokit, options = {}) {
|
||||
// If a specific username is provided, use the user-specific endpoint
|
||||
if (options.username) {
|
||||
return octokit
|
||||
.paginate("GET /users/{username}/starred", {
|
||||
username: options.username,
|
||||
headers: {
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
})
|
||||
.then(toRepositoryList);
|
||||
}
|
||||
|
||||
// Default: Get starred repos for the authenticated user (what was previously used)
|
||||
return octokit
|
||||
.paginate("GET /user/starred")
|
||||
.then(toRepositoryList);
|
||||
}
|
||||
|
||||
async function fetchOrganizationRepositories(octokit, includeOrgs = [], excludeOrgs = [], preserveOrgStructure = false) {
|
||||
async function fetchOrganizationRepositories(octokit, includeOrgs = [], excludeOrgs = [], preserveOrgStructure = false, options = {}) {
|
||||
try {
|
||||
// First get all organizations the user belongs to
|
||||
const allOrgs = await octokit.paginate("GET /user/orgs");
|
||||
// Get all organizations the user belongs to
|
||||
let allOrgs;
|
||||
|
||||
// If a specific username is provided, use the user-specific endpoint
|
||||
if (options.username) {
|
||||
allOrgs = await octokit.paginate("GET /users/{username}/orgs", {
|
||||
username: options.username,
|
||||
headers: {
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Default: Get organizations for the authenticated user (what was previously used)
|
||||
allOrgs = await octokit.paginate("GET /user/orgs");
|
||||
}
|
||||
|
||||
// Filter organizations based on include/exclude lists
|
||||
let orgsToProcess = allOrgs;
|
||||
|
||||
Reference in New Issue
Block a user