diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..11230fc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,67 @@ +name: 问题反馈 +description: File a bug report +title: "[错误报告]: 请在此处简单描述你的问题" +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + 请确认以下信息: + 1. 请按此模板提交 issues,不按模板提交的问题将直接关闭。 + 2. 如果你的问题可以直接在以往 issue 或者 Telegram频道 中找到,那么你的 issue 将会被直接关闭。 + 3. **$\color{red}{提交问题务必描述清楚、附上日志}$**,描述不清导致无法理解和分析的问题会被直接关闭。 + 4. 此仓库为**官方插件仓库**,如果是**主程序问题**请在 [MoviePilot 主仓库](https://github.com/jxxghp/MoviePilot/issues) 提 issue,如果是**前端 WebUI 问题**请在 [前端仓库](https://github.com/jxxghp/MoviePilot-Frontend) 提 issue。 + 5. **$\color{red}{不要通过 issues 来寻求解决你的环境问题、配置安装类问题、咨询类问题}$**,否则直接关闭并加入用户 $\color{red}{黑名单}$ !实在没有精力陪一波又一波的伸手党玩。 + - type: checkboxes + id: ensure + attributes: + label: 确认 + description: 在提交 issue 之前,请确认你已经阅读并确认以下内容 + options: + - label: 我的版本是最新版本,我的版本号与 [version](https://github.com/jxxghp/MoviePilot/releases/latest) 相同。 + required: true + - label: 我已经 [issue](https://github.com/jxxghp/MoviePilot-Plugins/issues) 中搜索过,确认我的问题没有被提出过。 + required: true + - label: 我已经 [Telegram频道](https://t.me/moviepilot_channel) 中搜索过,确认我的问题没有被提出过。 + required: true + - label: 我已经修改标题,将标题中的 描述 替换为我遇到的问题。 + required: true + - type: input + id: version + attributes: + label: 当前程序版本 + description: 遇到问题时 MoviePilot 主程序所在的版本号 + validations: + required: true + - type: input + id: plugin + attributes: + label: 涉及插件名称及版本 + description: 如果是插件问题,请填写插件名称及版本号(如不清楚可留空) + placeholder: "例如:ChatGPT v3.0.4" + validations: + required: false + - type: dropdown + id: environment + attributes: + label: 运行环境 + description: 当前程序运行环境 + options: + - Docker + - Windows + validations: + required: true + - type: textarea + id: what-happened + attributes: + label: 问题描述 + description: 请详细描述你碰到的问题 + placeholder: "问题描述" + validations: + required: true + - type: textarea + id: logs + attributes: + label: 发生问题时系统日志和配置文件 + description: 问题出现时,程序运行日志请复制到这里。 + render: bash diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e927abc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: 项目讨论 + url: https://github.com/jxxghp/MoviePilot/discussions/new/choose + about: discussion + - name: Telegram 频道 + url: https://t.me/moviepilot_channel + about: 更新日志 + - name: Telegram 交流群 + url: https://t.me/moviepilot_official + about: 交流互助 diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..3599332 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,40 @@ +name: 功能改进 +description: Feature Request +title: "[Feature Request]: " +labels: ["feature request"] +body: + - type: markdown + attributes: + value: | + 请说明你希望添加的功能。 + - type: input + id: version + attributes: + label: 当前程序版本 + description: 目前使用的 MoviePilot 程序版本 + validations: + required: true + - type: dropdown + id: environment + attributes: + label: 运行环境 + description: 当前程序运行环境 + options: + - Docker + - Windows + validations: + required: true + - type: textarea + id: feature-request + attributes: + label: 功能改进 + description: 请详细描述需要改进或者添加的功能。 + placeholder: "功能改进" + validations: + required: true + - type: textarea + id: references + attributes: + label: 参考资料 + description: 可以列举一些参考资料,但是不要引用同类但商业化软件的任何内容。 + placeholder: "参考资料" diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml new file mode 100644 index 0000000..11672b2 --- /dev/null +++ b/.github/workflows/issues.yml @@ -0,0 +1,144 @@ +name: Close inactive issues +on: + workflow_dispatch: + + issues: + types: [opened, edited] + + schedule: + - cron: "0 18 * * *" + +jobs: + label-opened-issue: + if: github.event_name == 'issues' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/github-script@v7 + with: + script: | + const issue = context.payload.issue; + const title = issue.title || ''; + const body = issue.body || ''; + const currentLabels = (issue.labels || []).map((label) => label.name); + + // 网页 Issue Form 已经会自动带模板 labels;这里只兜底处理 + // API 创建或异常路径产生的无 label issue,避免重复补标。 + if (currentLabels.length > 0) { + core.info(`Issue #${issue.number} already has labels: ${currentLabels.join(', ')}`); + return; + } + + const hasAllMarkers = (markers) => markers.every((marker) => body.includes(marker)); + const labelRules = [ + { + label: 'bug', + titlePrefix: '[错误报告]:', + markers: ['### 当前程序版本', '### 运行环境', '### 问题描述'], + }, + { + label: 'feature request', + titlePrefix: '[Feature Request]:', + markers: ['### 当前程序版本', '### 运行环境', '### 功能改进'], + }, + ]; + + const matched = labelRules.find((rule) => ( + title.startsWith(rule.titlePrefix) || hasAllMarkers(rule.markers) + )); + + if (!matched) { + core.info(`Issue #${issue.number} does not match known issue templates.`); + return; + } + + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: [matched.label], + }); + core.info(`Added label "${matched.label}" to issue #${issue.number}.`); + + label-unlabeled-issues: + if: github.event_name != 'issues' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/github-script@v7 + with: + script: | + const labelRules = [ + { + label: 'bug', + titlePrefix: '[错误报告]:', + markers: ['### 当前程序版本', '### 运行环境', '### 问题描述'], + }, + { + label: 'feature request', + titlePrefix: '[Feature Request]:', + markers: ['### 当前程序版本', '### 运行环境', '### 功能改进'], + }, + ]; + + const hasAllMarkers = (body, markers) => markers.every((marker) => body.includes(marker)); + const getMatchedRule = (issue) => { + const title = issue.title || ''; + const body = issue.body || ''; + return labelRules.find((rule) => ( + title.startsWith(rule.titlePrefix) || hasAllMarkers(body, rule.markers) + )); + }; + + // Search API 支持 no:label 查询;issues.listForRepo 的 labels=none + // 会被当作名为 none 的标签,不能用于扫描无 label issue。 + const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open no:label`; + for await (const response of github.paginate.iterator(github.rest.search.issuesAndPullRequests, { + q: query, + per_page: 100, + })) { + for (const issue of response.data) { + if (issue.pull_request) { + continue; + } + + const matched = getMatchedRule(issue); + if (!matched) { + continue; + } + + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: [matched.label], + }); + core.info(`Added label "${matched.label}" to issue #${issue.number}.`); + } + } + + close-issues: + if: github.event_name != 'issues' + needs: label-unlabeled-issues + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v5 + with: + # 标记 stale 标签时间 + days-before-issue-stale: 30 + # 关闭 issues 标签时间 + days-before-issue-close: 14 + # 自定义标签名 + stale-issue-label: "stale" + stale-issue-message: "此问题已过时,因为它已打开 30 天且没有任何活动。" + close-issue-message: "此问题已关闭,因为它在标记为 stale 后,已处于无更新状态 14 天。" + # 忽略所有的 Pull Request,只处理 Issue + days-before-pr-stale: -1 + days-before-pr-close: -1 + operations-per-run: 500 + repo-token: ${{ secrets.GITHUB_TOKEN }}