From 4d7ee2164a40b4d3f9c3829acaffade722077551 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:27:22 +0000 Subject: [PATCH] chore: restore sync-upstream workflow after sync --- .github/workflows/sync-upstream.yml | 125 ++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml index 069af43..2925833 100644 --- a/.github/workflows/sync-upstream.yml +++ b/.github/workflows/sync-upstream.yml @@ -4,6 +4,11 @@ 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 @@ -11,9 +16,8 @@ permissions: jobs: sync: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -22,13 +26,118 @@ jobs: git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Sync main from upstream + - name: Add upstream run: | git remote add upstream https://github.com/shuaiplus/NodeWarden.git || true - git fetch upstream - git checkout main - git merge upstream/main + git fetch upstream --tags - - name: Push synced main + - name: Resolve target commit + id: resolve run: | - git push origin main + 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