mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
144 lines
5.3 KiB
YAML
144 lines
5.3 KiB
YAML
name: Sync upstream
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "0 3 * * *"
|
|
workflow_dispatch:
|
|
inputs:
|
|
target_commit:
|
|
description: 'Commit hash (leave blank to use latest commit)'
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
sync:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Configure git
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
|
|
- name: Add upstream
|
|
run: |
|
|
git remote add upstream https://github.com/shuaiplus/NodeWarden.git || true
|
|
git fetch upstream --tags
|
|
|
|
- name: Resolve target commit
|
|
id: resolve
|
|
run: |
|
|
TRIGGER="${{ github.event_name }}"
|
|
MANUAL_INPUT="${{ github.event.inputs.target_commit }}"
|
|
|
|
if [ "$TRIGGER" = "schedule" ]; then
|
|
# Auto mode: resolve latest upstream release tag
|
|
LATEST_TAG=$(curl -s https://api.github.com/repos/shuaiplus/NodeWarden/releases/latest | jq -r .tag_name)
|
|
if [ "$LATEST_TAG" = "null" ] || [ -z "$LATEST_TAG" ]; then
|
|
echo "No release found in upstream."
|
|
exit 1
|
|
fi
|
|
TARGET_SHA=$(git rev-list -n 1 "$LATEST_TAG" 2>/dev/null)
|
|
if [ -z "$TARGET_SHA" ]; then
|
|
echo "Tag '$LATEST_TAG' not found after fetch."
|
|
exit 1
|
|
fi
|
|
echo "mode=auto" >> $GITHUB_OUTPUT
|
|
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
|
|
echo "target_sha=$TARGET_SHA" >> $GITHUB_OUTPUT
|
|
echo "Auto mode — latest release: $LATEST_TAG ($TARGET_SHA)"
|
|
|
|
elif [ -n "$MANUAL_INPUT" ]; then
|
|
# Manual mode: use provided commit hash or tag
|
|
TARGET_SHA=$(git rev-parse "$MANUAL_INPUT" 2>/dev/null)
|
|
if [ -z "$TARGET_SHA" ]; then
|
|
echo "Cannot resolve '$MANUAL_INPUT' to a commit."
|
|
exit 1
|
|
fi
|
|
echo "mode=manual" >> $GITHUB_OUTPUT
|
|
echo "target_sha=$TARGET_SHA" >> $GITHUB_OUTPUT
|
|
echo "Manual mode — target: $MANUAL_INPUT ($TARGET_SHA)"
|
|
|
|
else
|
|
# Manual mode, blank input: use latest commit on upstream/main
|
|
TARGET_SHA=$(git rev-parse upstream/main)
|
|
echo "mode=manual" >> $GITHUB_OUTPUT
|
|
echo "target_sha=$TARGET_SHA" >> $GITHUB_OUTPUT
|
|
echo "Manual mode — latest commit: $TARGET_SHA"
|
|
fi
|
|
|
|
- name: Check if update is needed
|
|
id: check
|
|
run: |
|
|
TARGET_SHA="${{ steps.resolve.outputs.target_sha }}"
|
|
MODE="${{ steps.resolve.outputs.mode }}"
|
|
|
|
if [ "$MODE" = "manual" ]; then
|
|
# Manual: skip only if HEAD is exactly this commit
|
|
CURRENT_SHA=$(git rev-parse HEAD)
|
|
if [ "$CURRENT_SHA" = "$TARGET_SHA" ]; then
|
|
echo "Already at $TARGET_SHA — skipping."
|
|
echo "needs_update=false" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "Switching to $TARGET_SHA"
|
|
echo "needs_update=true" >> $GITHUB_OUTPUT
|
|
fi
|
|
else
|
|
# Auto: skip if target is already in ancestry
|
|
if git merge-base --is-ancestor "$TARGET_SHA" HEAD 2>/dev/null; then
|
|
echo "Already up to date with $TARGET_SHA — skipping."
|
|
echo "needs_update=false" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "Update needed — target: $TARGET_SHA"
|
|
echo "needs_update=true" >> $GITHUB_OUTPUT
|
|
fi
|
|
fi
|
|
|
|
- name: Apply update
|
|
if: steps.check.outputs.needs_update == 'true'
|
|
run: |
|
|
TARGET_SHA="${{ steps.resolve.outputs.target_sha }}"
|
|
MODE="${{ steps.resolve.outputs.mode }}"
|
|
git checkout main
|
|
if [ "$MODE" = "manual" ]; then
|
|
# Hard reset allows both upgrade and rollback
|
|
git reset --hard "$TARGET_SHA"
|
|
else
|
|
git merge "$TARGET_SHA" --no-edit
|
|
fi
|
|
|
|
- name: Restore workflow file
|
|
if: steps.check.outputs.needs_update == 'true'
|
|
run: |
|
|
# Always keep our own workflow file, never let upstream overwrite it
|
|
git checkout HEAD@{1} -- .github/workflows/sync-upstream.yml 2>/dev/null || true
|
|
if ! git diff --cached --quiet; then
|
|
git commit -m "chore: restore sync-upstream workflow after sync"
|
|
fi
|
|
|
|
- name: Push
|
|
if: steps.check.outputs.needs_update == 'true'
|
|
run: |
|
|
if [ "${{ steps.resolve.outputs.mode }}" = "manual" ]; then
|
|
git push origin main --force
|
|
else
|
|
git push origin main
|
|
fi
|
|
|
|
- name: Summary
|
|
run: |
|
|
if [ "${{ steps.check.outputs.needs_update }}" = "true" ]; then
|
|
echo "### Synced successfully" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Mode:** ${{ steps.resolve.outputs.mode }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Tag:** ${{ steps.resolve.outputs.latest_tag || 'N/A (manual)' }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Commit:** \`${{ steps.resolve.outputs.target_sha }}\`" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "### Nothing to update" >> $GITHUB_STEP_SUMMARY
|
|
fi
|