GitLab Sync #51
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: GitLab Sync | |
on: | |
push: | |
branches: ["*"] | |
delete: | |
branches: ["*"] | |
pull_request: | |
types: [opened, closed, reopened, edited, labeled, unlabeled] | |
schedule: | |
- cron: "0 */6 * * *" | |
workflow_dispatch: | |
workflow_call: | |
jobs: | |
sync: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Install GitLab CLI (glab) | |
run: | | |
# Add WakeMeOps repository | |
curl -sSL "https://raw.githubusercontent.com/upciti/wakemeops/main/assets/install_repository" | sudo bash | |
# Install glab | |
sudo apt install glab | |
# Verify installation | |
if ! glab --version; then | |
echo "Installation failed" | |
exit 1 | |
fi | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
fetch-tags: false | |
- name: Set environment variables | |
run: | | |
echo "REPO_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV | |
echo "GITLAB_PROJECT_PATH=vikshan/${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV | |
- name: Determine Default Branch | |
id: default-branch | |
run: | | |
DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5) | |
echo "default_branch=$DEFAULT_BRANCH" >> $GITHUB_OUTPUT | |
echo "Current default branch: $DEFAULT_BRANCH" | |
- name: Update GitLab Default Branch | |
env: | |
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} | |
DEFAULT_BRANCH: ${{ steps.default-branch.outputs.default_branch }} | |
run: | | |
# Get GitLab project ID | |
PROJECT_ID=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ | |
"https://gitlab.com/api/v4/projects/vikshan%2F${REPO_NAME}" | jq -r '.id') | |
# Update default branch | |
curl -X PUT -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \ | |
"https://gitlab.com/api/v4/projects/${PROJECT_ID}" \ | |
-d "default_branch=${DEFAULT_BRANCH}" | |
- name: Configure Git for Original Authors | |
run: | | |
# Configure git to preserve original author information | |
git config --global user.name "$(git config user.name)" | |
git config --global user.email "$(git config user.email)" | |
- name: Sync with GitLab | |
env: | |
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} | |
DEFAULT_BRANCH: ${{ steps.default-branch.outputs.default_branch }} | |
run: | | |
# Setup GitLab remote | |
git remote add gitlab "https://oauth2:${GITLAB_TOKEN}@gitlab.com/${GITLAB_PROJECT_PATH}.git" | |
# Fetch from origin (your fork) | |
git fetch origin --no-tags || exit 1 | |
# Fetch from GitLab | |
git fetch gitlab --no-tags || { | |
echo "Failed to fetch from GitLab" | |
exit 1 | |
} | |
# Get clean branch lists (remove HEAD and empty lines) | |
GITHUB_BRANCHES=$(git branch -r | grep 'origin/' | sed 's#origin/##' | grep -v 'HEAD' | tr -d ' ' | sort) | |
GITLAB_BRANCHES=$(git branch -r | grep 'gitlab/' | sed 's#gitlab/##' | tr -d ' ' | sort) | |
# Debug output | |
echo "GitHub branches:" | |
echo "$GITHUB_BRANCHES" | |
echo "GitLab branches:" | |
echo "$GITLAB_BRANCHES" | |
# Sync branches to GitLab | |
echo "$GITHUB_BRANCHES" | while read branch; do | |
if [ -n "$branch" ]; then | |
echo "Syncing branch: $branch" | |
git checkout -B "${branch}" "origin/${branch}" | |
git push -f gitlab "${branch}:${branch}" -o ci.skip || { | |
echo "Failed to push branch ${branch}" | |
exit 1 | |
} | |
fi | |
done | |
# Clean up deleted branches with careful comparison | |
echo "$GITLAB_BRANCHES" | while read gitlab_branch; do | |
if [ -n "$gitlab_branch" ] && [ "$gitlab_branch" != "$DEFAULT_BRANCH" ]; then | |
# Check if branch exists in GitHub branches using exact match | |
if ! echo "$GITHUB_BRANCHES" | grep -Fx "$gitlab_branch" > /dev/null; then | |
echo "Branch '$gitlab_branch' exists in GitLab but not in GitHub - verifying deletion" | |
# Double check branch doesn't exist in origin | |
if ! git show-ref --verify --quiet "refs/remotes/origin/$gitlab_branch"; then | |
echo "Confirmed: Branch '$gitlab_branch' should be deleted from GitLab" | |
git push gitlab --delete "${gitlab_branch}" || { | |
echo "Warning: Failed to delete branch ${gitlab_branch}" | |
} | |
else | |
echo "Safety check: Branch '$gitlab_branch' still exists in origin - skipping deletion" | |
fi | |
fi | |
fi | |
done | |
- name: Configure GitLab Auth | |
env: | |
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} | |
run: | | |
# Configure glab authentication | |
glab auth login --token "$GITLAB_TOKEN" | |
- name: Sync Pull Requests | |
if: github.event_name == 'push' || github.event_name == 'pull_request' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} | |
run: | | |
# Create and checkout temp branch | |
TEMP_BRANCH="temp-sync-$(date +%s)" | |
git checkout -b "$TEMP_BRANCH" | |
# Debug: Check glab version and auth status | |
glab auth status | |
# Fetch open PRs from GitHub | |
OPEN_PRS=$(gh pr list --state open --json number,title,body,headRefName,baseRefName,headRepositoryOwner) | |
# Process each PR | |
echo "$OPEN_PRS" | jq -c '.[]' | while read -r pr; do | |
PR_TITLE=$(echo "$pr" | jq -r '.title') | |
PR_DESC=$(echo "$pr" | jq -r '.body') | |
SOURCE_BRANCH=$(echo "$pr" | jq -r '.headRefName') | |
TARGET_BRANCH=$(echo "$pr" | jq -r '.baseRefName') | |
HEAD_REPO_OWNER=$(echo "$pr" | jq -r '.headRepositoryOwner.login') | |
# Only process PRs from current user's fork | |
if [ true ]; then | |
echo "Processing PR: $PR_TITLE (${SOURCE_BRANCH} -> ${TARGET_BRANCH})" | |
# Create new MR | |
glab mr create \ | |
--source-branch "${SOURCE_BRANCH}" \ | |
--target-branch "${TARGET_BRANCH}" \ | |
--title "${PR_TITLE}" \ | |
--description "${PR_DESC}" \ | |
--remove-source-branch || echo "Warning: Failed to create MR" | |
else | |
echo "Skipping PR from $HEAD_REPO_OWNER: $PR_TITLE" | |
fi | |
done | |
# Cleanup: Switch back to original branch and delete temp branch | |
git checkout - | |
git branch -D "$TEMP_BRANCH" |