This repository was archived by the owner on Apr 7, 2026. It is now read-only.
Upstream Sync #47
This file contains hidden or 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: Upstream Sync | |
| on: | |
| schedule: | |
| # Daily at 06:00 UTC | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| inputs: | |
| mode: | |
| description: "Sync mode" | |
| required: true | |
| default: "pr" | |
| type: choice | |
| options: | |
| - pr | |
| - push | |
| - dry-run | |
| - scan-only | |
| jobs: | |
| sync: | |
| runs-on: self-hosted | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Checkout (full history for rebase) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GH_PAT }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Nuke stale credential helpers on self-hosted runner (prevents "denied to TSavo") | |
| git config --local --unset-all credential.helper 2>/dev/null || true | |
| git config --global --unset-all credential.helper 2>/dev/null || true | |
| - name: Clean working tree (self-hosted runner may have leftovers) | |
| run: | | |
| git checkout master 2>/dev/null || true | |
| git rebase --abort 2>/dev/null || true | |
| git reset --hard HEAD | |
| git clean -fd | |
| - name: Add upstream remote | |
| run: | | |
| git remote get-url upstream 2>/dev/null || \ | |
| git remote add upstream https://github.com/paperclipai/paperclip.git | |
| git fetch upstream | |
| - name: Install Agent SDK | |
| run: | | |
| rm -rf "$(npm root -g)/@anthropic-ai/.claude-code-"* "$(npm root -g)/@anthropic-ai/.claude-agent-sdk-"* 2>/dev/null || true | |
| npm install -g @anthropic-ai/claude-code || npm install -g @anthropic-ai/claude-code | |
| npm install -g @anthropic-ai/claude-agent-sdk || npm install -g @anthropic-ai/claude-agent-sdk | |
| node -e "require('@anthropic-ai/claude-agent-sdk')" 2>/dev/null || echo "SDK import check: will resolve at runtime via global root" | |
| - name: Write Claude credentials | |
| run: | | |
| mkdir -p ~/.claude | |
| echo '${{ secrets.CLAUDE_CREDENTIALS_JSON }}' > ~/.claude/.credentials.json | |
| - name: Check for upstream changes | |
| id: check | |
| run: | | |
| BEHIND=$(git rev-list HEAD..upstream/master --count) | |
| echo "behind=$BEHIND" >> "$GITHUB_OUTPUT" | |
| if [ "$BEHIND" -eq 0 ]; then | |
| echo "Up to date with upstream. Skipping sync." | |
| else | |
| echo "Behind upstream by $BEHIND commits." | |
| fi | |
| - name: Run upstream sync | |
| if: steps.check.outputs.behind != '0' || contains(fromJSON('["scan-only", "dry-run"]'), github.event.inputs.mode) | |
| env: | |
| CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| run: | | |
| MODE="${{ github.event.inputs.mode || 'pr' }}" | |
| case "$MODE" in | |
| push) FLAG="--push" ;; | |
| pr) FLAG="--pr" ;; | |
| dry-run) FLAG="--dry-run" ;; | |
| scan-only) FLAG="--scan-only --dry-run" ;; | |
| esac | |
| node scripts/upstream-sync.mjs $FLAG | |
| - name: Upload agent event log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: agent-events-log | |
| path: agent-events.log | |
| if-no-files-found: ignore | |
| retention-days: 14 |