From 8eca5bc695d950545271f2c436551a720a3db143 Mon Sep 17 00:00:00 2001 From: enyst Date: Mon, 1 Jun 2026 15:21:08 +0000 Subject: [PATCH 1/4] Add issue duplicate checker workflow Co-authored-by: openhands --- .github/workflows/issue-duplicate-checker.yml | 93 +++++++++++++++++++ .../remove-duplicate-candidate-label.yml | 31 +++++++ 2 files changed, 124 insertions(+) create mode 100644 .github/workflows/issue-duplicate-checker.yml create mode 100644 .github/workflows/remove-duplicate-candidate-label.yml diff --git a/.github/workflows/issue-duplicate-checker.yml b/.github/workflows/issue-duplicate-checker.yml new file mode 100644 index 00000000..0c1e8d75 --- /dev/null +++ b/.github/workflows/issue-duplicate-checker.yml @@ -0,0 +1,93 @@ +--- +name: Issue Duplicate Check via OpenHands Cloud + +on: + issues: + types: [opened] + schedule: + - cron: 0 9 * * * + workflow_dispatch: + inputs: + mode: + description: Which workflow path to run + required: true + type: choice + options: + - smoke-clone + - issue-check + - auto-close + default: smoke-clone + issue_number: + description: Existing issue number to analyze when mode is issue-check + required: false + type: number + close_after_days: + description: Days to wait before auto-closing duplicate candidates in auto-close mode + required: false + type: number + default: 3 + +permissions: + contents: read + issues: write + +jobs: + smoke-clone: + if: github.event_name == 'workflow_dispatch' && inputs.mode == 'smoke-clone' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Clone repository + env: + REPOSITORY: ${{ github.repository }} + run: | + git clone --depth 1 "https://github.com/${REPOSITORY}.git" /tmp/repo-clone + echo "Repository HEAD: $(git -C /tmp/repo-clone rev-parse --short HEAD)" + + - name: Summarize smoke test + run: | + { + echo "## Smoke clone completed" + echo + echo "- Repository cloned to /tmp/repo-clone" + } >> "$GITHUB_STEP_SUMMARY" + + issue-duplicate-check: + if: | + github.event_name == 'issues' || + (github.event_name == 'workflow_dispatch' && inputs.mode == 'issue-check' && inputs.issue_number != null) + runs-on: ubuntu-latest + timeout-minutes: 35 + concurrency: + group: issue-duplicate-check-${{ github.repository }}-${{ github.event.issue.number || inputs.issue_number }} + cancel-in-progress: false + steps: + - name: Run issue duplicate check + uses: OpenHands/extensions/plugins/issue-duplicate-checker@main + with: + mode: issue-check + repository: ${{ github.repository }} + issue-number: ${{ github.event.issue.number || inputs.issue_number }} + close-after-days: ${{ inputs.close_after_days || '3' }} + openhands-api-key: ${{ secrets.OPENHANDS_API_KEY }} + github-token: ${{ secrets.OPENHANDS_BOT_GITHUB_PAT_PUBLIC || github.token }} + + auto-close-duplicates: + if: | + github.event_name == 'schedule' || + (github.event_name == 'workflow_dispatch' && inputs.mode == 'auto-close') + runs-on: ubuntu-latest + timeout-minutes: 20 + concurrency: + group: auto-close-duplicates-${{ github.repository }} + cancel-in-progress: false + steps: + - name: Auto-close aged duplicate candidates + uses: OpenHands/extensions/plugins/issue-duplicate-checker@main + with: + mode: auto-close + repository: ${{ github.repository }} + close-after-days: ${{ inputs.close_after_days || '3' }} + github-token: ${{ secrets.OPENHANDS_BOT_GITHUB_PAT_PUBLIC || github.token }} diff --git a/.github/workflows/remove-duplicate-candidate-label.yml b/.github/workflows/remove-duplicate-candidate-label.yml new file mode 100644 index 00000000..528db898 --- /dev/null +++ b/.github/workflows/remove-duplicate-candidate-label.yml @@ -0,0 +1,31 @@ +--- +name: Remove duplicate candidate label on activity + +on: + issue_comment: + types: [created] + +permissions: + issues: write + +concurrency: + group: remove-duplicate-${{ github.repository }}-${{ github.event.issue.number }} + cancel-in-progress: false + +jobs: + remove-duplicate-candidate: + if: | + github.event.issue.state == 'open' && + github.event.issue.pull_request == null && + contains(github.event.issue.labels.*.name, 'duplicate-candidate') && + github.event.comment.user.type != 'Bot' && + !startsWith(github.event.comment.body || '', '