Skip to content

Merging branches into dev by @b3nw #10

Merging branches into dev by @b3nw

Merging branches into dev by @b3nw #10

Workflow file for this run

name: AI Multi-Branch Merge
run-name: Merging branches into dev by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
reset_dev:
description: 'Reset dev to main before merging (destroys existing dev)'
type: boolean
default: false
sync_upstream:
description: 'Sync with upstream before merging (pulls latest from Mirrowel/LLM-API-Key-Proxy)'
type: boolean
default: false
upstream_branch:
description: 'Upstream branch to sync from'
type: string
default: 'dev'
branch_feature_chutes_quota_system:
description: 'feature/chutes-quota-system'
type: boolean
default: false
branch_feature_firmware_quota_tracking:
description: 'feature/firmware-quota-tracking'
type: boolean
default: false
branch_feature_google_search:
description: 'feature/google_search'
type: boolean
default: false
branch_feature_nanogpt_quota_system:
description: 'feature/nanogpt-quota-system'
type: boolean
default: false
custom_branches:
description: 'Additional branches (comma-separated, optional)'
type: string
required: false
concurrency:
group: ai-merge-dev
cancel-in-progress: false
jobs:
merge-branches:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GH_PAT }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Install Opencode
run: curl -fsSL https://opencode.ai/install | bash
- name: Configure Opencode for LLM Proxy
env:
LLM_PROXY_URL: ${{ secrets.LLM_PROXY_URL }}
LLM_PROXY_API_KEY: ${{ secrets.LLM_PROXY_API_KEY }}
LLM_PROXY_MODEL: ${{ secrets.LLM_PROXY_MODEL }}
run: |
mkdir -p ~/.config/opencode
DOLLAR='$'
MODEL="${LLM_PROXY_MODEL:-nano_gpt/zai-org/glm-4.7}"
cat > ~/.config/opencode/opencode.json <<EOFCFG
{
"${DOLLAR}schema": "https://opencode.ai/config.json",
"provider": {
"llm-proxy": {
"api": "openai",
"models": { "$MODEL": {} },
"options": { "apiKey": "$LLM_PROXY_API_KEY", "baseURL": "$LLM_PROXY_URL" }
}
},
"model": "llm-proxy/$MODEL"
}
EOFCFG
- name: Collect selected branches
id: collect
env:
INPUTS_JSON: ${{ toJSON(github.event.inputs) }}
SYNC_UPSTREAM: ${{ github.event.inputs.sync_upstream }}
run: |
echo "Processing inputs..."
branches=""
selected=$(echo "$INPUTS_JSON" | jq -r 'to_entries | .[] | select(.key | startswith("branch_")) | select(.value == "true") | .key')
for input_name in $selected; do
branch_name=$(grep -A1 "^ $input_name:" .github/workflows/ai-merge-dev.yml | grep "description:" | sed "s/.*description: '\\(.*\\)'/\\1/")
if [ -n "$branch_name" ]; then branches="${branches:+$branches, }$branch_name"; fi
done
custom="${{ github.event.inputs.custom_branches }}"
if [ -n "$custom" ]; then branches="${branches:+$branches, }$custom"; fi
echo "Selected branches: $branches"
echo "branches=$branches" >> $GITHUB_OUTPUT
echo "has_branches=$( [ -n "$branches" ] && echo true || echo false )" >> $GITHUB_OUTPUT
if [ -z "$branches" ] && [ "$SYNC_UPSTREAM" != "true" ]; then
echo "::error::No branches selected and upstream sync not enabled"
exit 1
fi
- name: Prepare Dev Branch
env:
RESET_DEV: ${{ github.event.inputs.reset_dev }}
run: |
echo "## AI Multi-Branch Merge" >> $GITHUB_STEP_SUMMARY
git fetch origin main:main
if git ls-remote --heads origin dev | grep -q dev; then
git checkout dev
git pull origin dev
if [ "$RESET_DEV" = "true" ]; then
git reset --hard origin/main
echo ":warning: Reset 'dev' to 'main'." >> $GITHUB_STEP_SUMMARY
else
echo "Continuing from existing 'dev' branch." >> $GITHUB_STEP_SUMMARY
fi
else
git checkout -b dev origin/main
echo "Created 'dev' from 'main'." >> $GITHUB_STEP_SUMMARY
fi
- name: Sync with Upstream
if: github.event.inputs.sync_upstream == 'true'
env:
UPSTREAM_BRANCH: ${{ github.event.inputs.upstream_branch }}
run: |
echo "### Upstream Sync" >> $GITHUB_STEP_SUMMARY
git remote add upstream https://github.com/Mirrowel/LLM-API-Key-Proxy.git 2>/dev/null || true
git fetch upstream "$UPSTREAM_BRANCH"
echo "Merging upstream/$UPSTREAM_BRANCH..."
if git merge "upstream/$UPSTREAM_BRANCH" --no-commit --no-ff; then
if git diff --cached --quiet; then
echo "Already up to date with upstream/$UPSTREAM_BRANCH." >> $GITHUB_STEP_SUMMARY
else
git commit -m "chore(dev): sync with upstream/$UPSTREAM_BRANCH"
echo ":arrows_counterclockwise: Synced with upstream/$UPSTREAM_BRANCH (clean merge)." >> $GITHUB_STEP_SUMMARY
fi
else
echo "Conflicts with upstream - invoking Opencode..."
for file in $(git diff --name-only --diff-filter=U); do
echo "Resolving $file..."
printf "Resolve merge conflict in %s. Read the file, analyze conflict markers, resolve logically, and save. Ensure no markers remain." "$file" > /tmp/prompt.txt
opencode run --share - < /tmp/prompt.txt || { git merge --abort; echo ":x: Failed to sync with upstream (AI error)." >> $GITHUB_STEP_SUMMARY; exit 1; }
grep -qE '^(<<<<<<<|=======|>>>>>>>)' "$file" && { git merge --abort; echo ":x: Failed to sync with upstream (markers remain)." >> $GITHUB_STEP_SUMMARY; exit 1; }
git add "$file"
done
git commit -m "chore(dev): sync with upstream/$UPSTREAM_BRANCH (AI resolved)"
echo ":robot: Synced with upstream/$UPSTREAM_BRANCH (AI resolved conflicts)." >> $GITHUB_STEP_SUMMARY
fi
- name: Merge Branches
if: steps.collect.outputs.has_branches == 'true'
env:
BRANCHES_INPUT: ${{ steps.collect.outputs.branches }}
run: |
echo "### Merge Results" >> $GITHUB_STEP_SUMMARY
echo "| Branch | Status | Notes |" >> $GITHUB_STEP_SUMMARY
echo "|--------|--------|-------|" >> $GITHUB_STEP_SUMMARY
IFS=',' read -ra BRANCHES <<< "$BRANCHES_INPUT"
for branch in "${BRANCHES[@]}"; do
branch=$(echo "$branch" | xargs)
echo "::group::Merging $branch"
git fetch origin "$branch" 2>/dev/null || { echo "| $branch | :x: Not Found | - |" >> $GITHUB_STEP_SUMMARY; echo "::endgroup::"; continue; }
if git merge "origin/$branch" --no-commit --no-ff; then
if git diff --cached --quiet; then
echo "| $branch | :white_check_mark: Already merged | - |" >> $GITHUB_STEP_SUMMARY
else
git commit -m "chore(dev): merge branch '$branch'"
echo "| $branch | :white_check_mark: Clean | - |" >> $GITHUB_STEP_SUMMARY
fi
else
echo "Conflicts in $branch - invoking Opencode..."
for file in $(git diff --name-only --diff-filter=U); do
echo "Resolving $file..."
printf "Resolve merge conflict in %s. Read the file, analyze conflict markers, resolve logically, and save. Ensure no markers remain." "$file" > /tmp/prompt.txt
opencode run --share - < /tmp/prompt.txt || { git merge --abort; echo "| $branch | :x: Failed | Opencode error |" >> $GITHUB_STEP_SUMMARY; echo "::endgroup::"; continue 2; }
grep -qE '^(<<<<<<<|=======|>>>>>>>)' "$file" && { git merge --abort; echo "| $branch | :x: Failed | Markers remain |" >> $GITHUB_STEP_SUMMARY; echo "::endgroup::"; continue 2; }
git add "$file"
done
git commit -m "chore(dev): merge '$branch' with AI resolution"
echo "| $branch | :robot: AI Resolved | - |" >> $GITHUB_STEP_SUMMARY
fi
echo "::endgroup::"
done
- name: Push Dev Branch
run: |
git push origin dev --force
echo ":rocket: Pushed 'dev' branch." >> $GITHUB_STEP_SUMMARY