From be83ac8be4df8ac62999f70993950ebc64ff76d1 Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Thu, 27 Nov 2025 14:32:29 +0800 Subject: [PATCH] chore: fix prettier config --- .github/ISSUE_TEMPLATE/bug_report_en.yml | 162 +++++------ .github/ISSUE_TEMPLATE/bug_report_zh.yml | 166 +++++------ .github/ISSUE_TEMPLATE/feature_request_en.yml | 67 +++-- .github/ISSUE_TEMPLATE/feature_request_zh.yml | 67 +++-- .github/ISSUE_TEMPLATE/rss_request_en.yml | 147 +++++----- .github/ISSUE_TEMPLATE/rss_request_zh.yml | 146 +++++----- .github/PULL_REQUEST_TEMPLATE.md | 13 +- .github/dependabot.yml | 80 ++--- .github/labeler.yml | 20 +- .github/prompts/similar_issues.prompt.yml | 80 ++--- .github/pull.yml | 12 +- .github/workflows/build-assets.yml | 200 ++++++------- .github/workflows/codeql.yml | 116 ++++---- .github/workflows/comment-on-issue.yml | 50 ++-- .github/workflows/dependabot-fork.yml | 26 +- .github/workflows/docker-release.yml | 266 ++++++++--------- .github/workflows/docker-test-cont.yml | 250 ++++++++-------- .github/workflows/docker-test.yml | 124 ++++---- .github/workflows/format.yml | 48 +-- .github/workflows/ghcr-retention.yml | 42 +-- .github/workflows/issue-command.yml | 236 +++++++-------- .github/workflows/lint.yml | 110 +++---- .github/workflows/npm-publish.yml | 70 ++--- .github/workflows/semgrep.yml | 54 ++-- .github/workflows/similar-issues.yml | 164 +++++------ .github/workflows/stale.yml | 60 ++-- .github/workflows/test-full-routes.yml | 68 ++--- .github/workflows/test.yml | 274 +++++++++--------- .prettierignore | 3 +- CODE_OF_CONDUCT.md | 26 +- README.md | 9 +- eslint.config.mjs | 9 +- package.json | 20 +- pnpm-lock.yaml | 57 +--- scripts/ansible/rsshub.yaml | 210 +++++++------- 35 files changed, 1696 insertions(+), 1756 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report_en.yml b/.github/ISSUE_TEMPLATE/bug_report_en.yml index 884c92cd2b..d58dd04ffd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_en.yml +++ b/.github/ISSUE_TEMPLATE/bug_report_en.yml @@ -3,86 +3,86 @@ description: Submit discovered bugs labels: ['RSS bug'] body: - - type: markdown - attributes: - value: | - Please ensure you have read [documentation](https://docs.rsshub.app/), and provide all the information required by this template, otherwise the issue will be closed immediately. - Due to the anti-crawling policy implemented by certain websites, some RSS routes provided by the demo will return status code 403 or fetch failed. This is not an issue caused by RSSHub and please do not report it. + - type: markdown + attributes: + value: | + Please ensure you have read [documentation](https://docs.rsshub.app/), and provide all the information required by this template, otherwise the issue will be closed immediately. + Due to the anti-crawling policy implemented by certain websites, some RSS routes provided by the demo will return status code 403 or fetch failed. This is not an issue caused by RSSHub and please do not report it. - - type: textarea - id: routes - attributes: - label: Routes - description: The involved route, without any parameters, copied directly from the docs "route" field, one link per line. Use `NOROUTE` if it is not route related. - placeholder: /someroute/:type? - render: routes - validations: - required: true - - - type: textarea - id: fullroutes - attributes: - label: Full routes - description: The involved route, with all required and optional parameters, and could be duplicate if necessary (different parameters) - placeholder: /routes/1234?some_extension=mode - render: fullroutes - validations: - required: true - - - type: input - id: docs-link - attributes: - label: Related documentation - description: Link to related documentation - placeholder: https://docs.rsshub.app/... - validations: - required: true - - - type: textarea - id: what-expected - attributes: - label: What is expected? - validations: - required: true - - - type: textarea - id: actual-happened - attributes: - label: What is actually happening? - validations: - required: true - - - type: dropdown - id: deployment - attributes: - label: Deployment information - multiple: false - options: - - Self-hosted - - RSSHub demo (https://rsshub.app) - validations: - required: true - - - type: input - id: deploy-info - attributes: - label: Deployment information (for self-hosted) - description: Please provide your OS, node version, docker version and environment variables (if applicable) - placeholder: 'OS: Linux, Node: v10.15.3, Docker: v19.03.13' - - - type: textarea - id: logs - attributes: - label: Additional info - description: logs, errors, etc. - render: shell - validations: - required: true - - - type: checkboxes - id: terms - attributes: - label: This is not a duplicated issue - options: - - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) to ensure this bug has not already been reported + - type: textarea + id: routes + attributes: + label: Routes + description: The involved route, without any parameters, copied directly from the docs "route" field, one link per line. Use `NOROUTE` if it is not route related. + placeholder: /someroute/:type? + render: routes + validations: required: true + + - type: textarea + id: fullroutes + attributes: + label: Full routes + description: The involved route, with all required and optional parameters, and could be duplicate if necessary (different parameters) + placeholder: /routes/1234?some_extension=mode + render: fullroutes + validations: + required: true + + - type: input + id: docs-link + attributes: + label: Related documentation + description: Link to related documentation + placeholder: https://docs.rsshub.app/... + validations: + required: true + + - type: textarea + id: what-expected + attributes: + label: What is expected? + validations: + required: true + + - type: textarea + id: actual-happened + attributes: + label: What is actually happening? + validations: + required: true + + - type: dropdown + id: deployment + attributes: + label: Deployment information + multiple: false + options: + - Self-hosted + - RSSHub demo (https://rsshub.app) + validations: + required: true + + - type: input + id: deploy-info + attributes: + label: Deployment information (for self-hosted) + description: Please provide your OS, node version, docker version and environment variables (if applicable) + placeholder: 'OS: Linux, Node: v10.15.3, Docker: v19.03.13' + + - type: textarea + id: logs + attributes: + label: Additional info + description: logs, errors, etc. + render: shell + validations: + required: true + + - type: checkboxes + id: terms + attributes: + label: This is not a duplicated issue + options: + - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) to ensure this bug has not already been reported + required: true diff --git a/.github/ISSUE_TEMPLATE/bug_report_zh.yml b/.github/ISSUE_TEMPLATE/bug_report_zh.yml index c0aecbd7f3..7c37ed220b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_zh.yml +++ b/.github/ISSUE_TEMPLATE/bug_report_zh.yml @@ -3,88 +3,88 @@ description: 早起的小可爱有虫抓 labels: ['RSS bug'] body: - - type: markdown - attributes: - value: | - 请确保已阅读 [文档](https://docs.rsshub.app) 内相关部分,并按照模版提供信息,否则 issue 将被立即关闭。 - 由于部分源网站反爬缘故,演示地址一些 RSS 会返回 status code 403 或 fetch failed,该问题不是 RSSHub 所致,请勿提交 issue。 + - type: markdown + attributes: + value: | + 请确保已阅读 [文档](https://docs.rsshub.app) 内相关部分,并按照模版提供信息,否则 issue 将被立即关闭。 + 由于部分源网站反爬缘故,演示地址一些 RSS 会返回 status code 403 或 fetch failed,该问题不是 RSSHub 所致,请勿提交 issue。 - - type: textarea - id: routes - attributes: - label: 路由地址 - description: 不包含参数,复制文档路由参数,一行一个,不要重复。如果和路由没有关系,请写 `NOROUTE` - placeholder: /someroute/:type? - render: routes - validations: - required: true - - - type: textarea - id: fullroutes - attributes: - label: 完整路由地址 - description: 包含所有必选与可选参数,一行一个,可以有重复路由不同参数(如果需要) - placeholder: /routes/1234?some_extension=mode - render: fullroutes - validations: - required: true - - - type: input - id: docs-link - attributes: - label: 相关文档 - description: 相关文档地址 - placeholder: https://docs.rsshub.app/... - validations: - required: true - - - type: textarea - id: what-expected - attributes: - label: 预期是什么? - validations: - required: true - - - type: textarea - id: actual-happened - attributes: - label: 实际发生了什么? - validations: - required: true - - - type: dropdown - id: deployment - attributes: - label: 部署 - multiple: false - options: - - 自建 - - RSSHub 演示 (https://rsshub.app) - validations: - required: true - - - type: input - id: deploy-info - attributes: - label: 部署相关信息 - description: | - 请提供您的操作系统、node 版本、(如果适用) docker 版本和环境变量。 - 请确保您部署的是 [主线 master 分支](https://github.com/DIYgod/RSSHub/tree/master) 最新版 RSSHub。 - placeholder: 'OS: Linux, Node: v10.15.3, Docker: v19.03.13' - - - type: textarea - id: logs - attributes: - label: 额外信息 - description: 日志、报错等 - render: shell - validations: - required: true - - - type: checkboxes - id: terms - attributes: - label: 这不是重复的 issue - options: - - label: 我已经搜索了 [现有 issue](https://github.com/DIYgod/RSSHub/issues),以确保该错误尚未被报告。 + - type: textarea + id: routes + attributes: + label: 路由地址 + description: 不包含参数,复制文档路由参数,一行一个,不要重复。如果和路由没有关系,请写 `NOROUTE` + placeholder: /someroute/:type? + render: routes + validations: required: true + + - type: textarea + id: fullroutes + attributes: + label: 完整路由地址 + description: 包含所有必选与可选参数,一行一个,可以有重复路由不同参数(如果需要) + placeholder: /routes/1234?some_extension=mode + render: fullroutes + validations: + required: true + + - type: input + id: docs-link + attributes: + label: 相关文档 + description: 相关文档地址 + placeholder: https://docs.rsshub.app/... + validations: + required: true + + - type: textarea + id: what-expected + attributes: + label: 预期是什么? + validations: + required: true + + - type: textarea + id: actual-happened + attributes: + label: 实际发生了什么? + validations: + required: true + + - type: dropdown + id: deployment + attributes: + label: 部署 + multiple: false + options: + - 自建 + - RSSHub 演示 (https://rsshub.app) + validations: + required: true + + - type: input + id: deploy-info + attributes: + label: 部署相关信息 + description: | + 请提供您的操作系统、node 版本、(如果适用) docker 版本和环境变量。 + 请确保您部署的是 [主线 master 分支](https://github.com/DIYgod/RSSHub/tree/master) 最新版 RSSHub。 + placeholder: 'OS: Linux, Node: v10.15.3, Docker: v19.03.13' + + - type: textarea + id: logs + attributes: + label: 额外信息 + description: 日志、报错等 + render: shell + validations: + required: true + + - type: checkboxes + id: terms + attributes: + label: 这不是重复的 issue + options: + - label: 我已经搜索了 [现有 issue](https://github.com/DIYgod/RSSHub/issues),以确保该错误尚未被报告。 + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request_en.yml b/.github/ISSUE_TEMPLATE/feature_request_en.yml index 7aee701cc8..6aaca941ce 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_en.yml +++ b/.github/ISSUE_TEMPLATE/feature_request_en.yml @@ -3,39 +3,38 @@ description: Submit a new feature request labels: ['RSS enhancement'] body: + - type: markdown + attributes: + value: | + Please ensure the feature requested is not listed in [documentation](https://docs.rsshub.app/) or [issue](https://github.com/DIYgod/RSSHub/issues), and is not a [new RSS proposal](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_en.yml), and provide all the information required by this template. + Otherwise the issue will be closed immediately. - - type: markdown - attributes: - value: | - Please ensure the feature requested is not listed in [documentation](https://docs.rsshub.app/) or [issue](https://github.com/DIYgod/RSSHub/issues), and is not a [new RSS proposal](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_en.yml), and provide all the information required by this template. - Otherwise the issue will be closed immediately. - - - type: textarea - id: feature - attributes: - label: What feature is it? - placeholder: Please describe the feature you want to see. - validations: - required: true - - - type: textarea - id: problem - attributes: - label: What problem does this feature solve? - placeholder: Please describe the problem this feature solves. - validations: - required: true - - - type: textarea - id: description - attributes: - label: Additional description - placeholder: Any additional description. - - - type: checkboxes - id: terms - attributes: - label: This is not a duplicated feature request or new RSS proposal - options: - - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) to ensure this feature has not already been requested and this is not a [new RSS proposal](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_en.yml). + - type: textarea + id: feature + attributes: + label: What feature is it? + placeholder: Please describe the feature you want to see. + validations: required: true + + - type: textarea + id: problem + attributes: + label: What problem does this feature solve? + placeholder: Please describe the problem this feature solves. + validations: + required: true + + - type: textarea + id: description + attributes: + label: Additional description + placeholder: Any additional description. + + - type: checkboxes + id: terms + attributes: + label: This is not a duplicated feature request or new RSS proposal + options: + - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) to ensure this feature has not already been requested and this is not a [new RSS proposal](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_en.yml). + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request_zh.yml b/.github/ISSUE_TEMPLATE/feature_request_zh.yml index 710ed55380..5ffe0b4558 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_zh.yml +++ b/.github/ISSUE_TEMPLATE/feature_request_zh.yml @@ -3,39 +3,38 @@ description: 提交新的功能需求 labels: ['RSS enhancement'] body: + - type: markdown + attributes: + value: | + 请确保 [文档](https://docs.rsshub.app) 和 [Issue](https://github.com/DIYgod/RSSHub/issues) 中没有相关内容及不是 [新的 RSS 提案](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_zh.yml),并按照模版提供信息, + 否则 issue 将被立即关闭。 - - type: markdown - attributes: - value: | - 请确保 [文档](https://docs.rsshub.app) 和 [Issue](https://github.com/DIYgod/RSSHub/issues) 中没有相关内容及不是 [新的 RSS 提案](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_zh.yml),并按照模版提供信息, - 否则 issue 将被立即关闭。 - - - type: textarea - id: feature - attributes: - label: 这是一个什么样的功能? - placeholder: 请描述你想看到的功能。 - validations: - required: true - - - type: textarea - id: problem - attributes: - label: 这个功能可以解决什么问题? - placeholder: 请描述该功能解决的问题。 - validations: - required: true - - - type: textarea - id: description - attributes: - label: 额外描述 - placeholder: 任何补充说明。 - - - type: checkboxes - id: terms - attributes: - label: 这不是重复的功能请求和 RSS 提案 - options: - - label: 我已经搜索了 [现有 issue](https://github.com/DIYgod/RSSHub/issues),以确保这项功能尚未被请求及不是 [新的 RSS 提案](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_zh.yml)。 + - type: textarea + id: feature + attributes: + label: 这是一个什么样的功能? + placeholder: 请描述你想看到的功能。 + validations: required: true + + - type: textarea + id: problem + attributes: + label: 这个功能可以解决什么问题? + placeholder: 请描述该功能解决的问题。 + validations: + required: true + + - type: textarea + id: description + attributes: + label: 额外描述 + placeholder: 任何补充说明。 + + - type: checkboxes + id: terms + attributes: + label: 这不是重复的功能请求和 RSS 提案 + options: + - label: 我已经搜索了 [现有 issue](https://github.com/DIYgod/RSSHub/issues),以确保这项功能尚未被请求及不是 [新的 RSS 提案](https://github.com/DIYgod/RSSHub/issues/new?assignees=&labels=RSS+proposal&template=rss_request_zh.yml)。 + required: true diff --git a/.github/ISSUE_TEMPLATE/rss_request_en.yml b/.github/ISSUE_TEMPLATE/rss_request_en.yml index 0f1efc64b5..da24c323d7 100644 --- a/.github/ISSUE_TEMPLATE/rss_request_en.yml +++ b/.github/ISSUE_TEMPLATE/rss_request_en.yml @@ -3,80 +3,79 @@ description: Submit a new RSS proposal labels: ['RSS proposal'] body: + - type: markdown + attributes: + value: | + Please ensure the RSS proposal is not listed in [documentation](https://docs.rsshub.app/) or [issue](https://github.com/DIYgod/RSSHub/issues), website doesn't provide this kind of RSS feed, and provide all the information required by this template. + Otherwise the issue will be closed immediately. - - type: markdown - attributes: - value: | - Please ensure the RSS proposal is not listed in [documentation](https://docs.rsshub.app/) or [issue](https://github.com/DIYgod/RSSHub/issues), website doesn't provide this kind of RSS feed, and provide all the information required by this template. - Otherwise the issue will be closed immediately. + We are flooded with feature requests and short-handed, please try to make it yourself, the [guide](https://docs.rsshub.app/joinus) is a good place to start. Submit a pull request when done! - We are flooded with feature requests and short-handed, please try to make it yourself, the [guide](https://docs.rsshub.app/joinus) is a good place to start. Submit a pull request when done! - - - type: dropdown - id: category - attributes: - label: Category - multiple: false - options: - - Social Media - - New media - - News - - BBS - - Blog - - Programming - - Design - - Live - - Multimedia - - Picture - - ACG - - Application Updates - - University - - Forecast - - Travel - - Shopping - - Gaming - - Reading - - Government - - Study - - Scientific Journal - - Finance - - Uncategorized - validations: - required: true - - - type: input - id: site-url - attributes: - label: Website URL - placeholder: https://example.com - validations: - required: true - - - type: textarea - id: description - attributes: - label: Website description - placeholder: A short description of the website - validations: - required: true - - - type: textarea - id: content - attributes: - label: What content should be included? - validations: - required: true - - - type: textarea - id: info - attributes: - label: Additional description - placeholder: Any additional information you want to share - - - type: checkboxes - id: terms - attributes: - label: This is not a duplicated rss request - options: - - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) and [pull requests](https://github.com/DIYgod/RSSHub/pulls) to ensure this rss proposal has not already been requested + - type: dropdown + id: category + attributes: + label: Category + multiple: false + options: + - Social Media + - New media + - News + - BBS + - Blog + - Programming + - Design + - Live + - Multimedia + - Picture + - ACG + - Application Updates + - University + - Forecast + - Travel + - Shopping + - Gaming + - Reading + - Government + - Study + - Scientific Journal + - Finance + - Uncategorized + validations: required: true + + - type: input + id: site-url + attributes: + label: Website URL + placeholder: https://example.com + validations: + required: true + + - type: textarea + id: description + attributes: + label: Website description + placeholder: A short description of the website + validations: + required: true + + - type: textarea + id: content + attributes: + label: What content should be included? + validations: + required: true + + - type: textarea + id: info + attributes: + label: Additional description + placeholder: Any additional information you want to share + + - type: checkboxes + id: terms + attributes: + label: This is not a duplicated rss request + options: + - label: I have searched [existing issues](https://github.com/DIYgod/RSSHub/issues) and [pull requests](https://github.com/DIYgod/RSSHub/pulls) to ensure this rss proposal has not already been requested + required: true diff --git a/.github/ISSUE_TEMPLATE/rss_request_zh.yml b/.github/ISSUE_TEMPLATE/rss_request_zh.yml index 2970aa6381..bb10bbf940 100644 --- a/.github/ISSUE_TEMPLATE/rss_request_zh.yml +++ b/.github/ISSUE_TEMPLATE/rss_request_zh.yml @@ -3,81 +3,79 @@ description: 提交新的 RSS 提案 labels: ['RSS proposal'] body: + - type: markdown + attributes: + value: | + 请确保 [文档](https://docs.rsshub.app) 和 [issue](https://github.com/DIYgod/RSSHub/issues) 中没有相关内容,且源站没有提供 RSS,并按照模版提供信息 + 否则 issue 将被立即关闭 - - type: markdown - attributes: - value: | - 请确保 [文档](https://docs.rsshub.app) 和 [issue](https://github.com/DIYgod/RSSHub/issues) 中没有相关内容,且源站没有提供 RSS,并按照模版提供信息 - 否则 issue 将被立即关闭 + 目前 RSS 提案滞销,如有能力请按照 [指南](https://docs.rsshub.app/joinus/quick-start) 自行编写并提交 PR - 目前 RSS 提案滞销,如有能力请按照 [指南](https://docs.rsshub.app/joinus/quick-start) 自行编写并提交 PR - - - type: dropdown - id: category - attributes: - label: 类型 - multiple: false - options: - - 社交媒体 - - 新媒体 - - 传统媒体 - - 论坛 - - 博客 - - 编程 - - 设计 - - 直播 - - 音视频 - - 图片 - - 二次元 - - 程序更新 - - 大学通知 - - 预报预警 - - 出行旅游 - - 购物 - - 游戏 - - 阅读 - - 政务消息 - - 学习 - - 科学期刊 - - 金融 - - 其他 - validations: - required: true - - - type: input - id: site-url - attributes: - label: 网站地址 - placeholder: https://example.com - validations: - required: true - - - type: textarea - id: description - attributes: - label: 网站描述 - placeholder: 对网站的简短描述 - validations: - required: true - - - type: textarea - id: content - attributes: - label: 需要生成什么内容? - validations: - required: true - - - type: textarea - id: info - attributes: - label: 额外描述 - placeholder: 如果提案需要额外描述,请在此处填写 - - - type: checkboxes - id: terms - attributes: - label: 这不是重复的 RSS 请求 - options: - - label: 我已经搜索了[现有 issue](https://github.com/DIYgod/RSSHub/issues) 和 [pull requests](https://github.com/DIYgod/RSSHub/pulls),以确保该 RSS 尚未被请求。 + - type: dropdown + id: category + attributes: + label: 类型 + multiple: false + options: + - 社交媒体 + - 新媒体 + - 传统媒体 + - 论坛 + - 博客 + - 编程 + - 设计 + - 直播 + - 音视频 + - 图片 + - 二次元 + - 程序更新 + - 大学通知 + - 预报预警 + - 出行旅游 + - 购物 + - 游戏 + - 阅读 + - 政务消息 + - 学习 + - 科学期刊 + - 金融 + - 其他 + validations: required: true + - type: input + id: site-url + attributes: + label: 网站地址 + placeholder: https://example.com + validations: + required: true + + - type: textarea + id: description + attributes: + label: 网站描述 + placeholder: 对网站的简短描述 + validations: + required: true + + - type: textarea + id: content + attributes: + label: 需要生成什么内容? + validations: + required: true + + - type: textarea + id: info + attributes: + label: 额外描述 + placeholder: 如果提案需要额外描述,请在此处填写 + + - type: checkboxes + id: terms + attributes: + label: 这不是重复的 RSS 请求 + options: + - label: 我已经搜索了[现有 issue](https://github.com/DIYgod/RSSHub/issues) 和 [pull requests](https://github.com/DIYgod/RSSHub/pulls),以确保该 RSS 尚未被请求。 + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e6ae2dd496..8c14e6b8f9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,4 @@ - @@ -27,17 +27,18 @@ If your changes are not related to route, please fill in `routes` section with ` --> ```routes + ``` ## New RSS Route Checklist / 新 RSS 路由检查表 - + - [ ] New Route / 新的路由 - - [ ] Follows [Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard) + - [ ] Follows [Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard) - [ ] Anti-bot or rate limit / 反爬/频率限制 - - [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施? + - [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施? - [ ] [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) / [日期和时间](https://docs.rsshub.app/zh/joinus/advanced/pub-date) - - [ ] Parsed / 可以解析 - - [ ] Correct time zone / 时区正确 + - [ ] Parsed / 可以解析 + - [ ] Correct time zone / 时区正确 - [ ] New package added / 添加了新的包 - [ ] `Puppeteer` diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 91cee7d772..37386b83ff 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,43 +1,43 @@ version: 2 updates: - - package-ecosystem: npm - directory: '/' - schedule: - interval: daily - time: '08:00' - open-pull-requests-limit: 100 - labels: - - dependencies - ignore: - # pin to version before it is sold to potential suspicious party - # https://github.com/goofychris/art-template/issues/660 the issue created from original author stating v4.13.3 - # contains suspicious code and related issues (#658, #659) were deleted - # related: - # https://github.com/fastify/point-of-view/issues/463 https://github.com/fastify/point-of-view/pull/461#issuecomment-2718888986 - # https://github.com/cnpm/bug-versions/pull/266 https://github.com/cnpm/cnpmcore/issues/777 - # https://github.com/yoimiya-kokomi/Miao-Yunzai/pull/515 https://github.com/zhangfisher/flex-tools/commit/09b565dfe6e2932bb829613ddbe09f6d0acbccd4 - - dependency-name: art-template - versions: ['>=4.13.3'] - # no longer includes KJUR.crypto.Cipher for RSA - - dependency-name: jsrsasign - versions: ['>=11.0.0'] - groups: - eslint: - patterns: - - 'eslint' - - '@eslint/*' - opentelemetry: - patterns: - - '@opentelemetry/*' - typescript-eslint: - patterns: - - '@typescript-eslint/*' + - package-ecosystem: npm + directory: '/' + schedule: + interval: daily + time: '08:00' + open-pull-requests-limit: 100 + labels: + - dependencies + ignore: + # pin to version before it is sold to potential suspicious party + # https://github.com/goofychris/art-template/issues/660 the issue created from original author stating v4.13.3 + # contains suspicious code and related issues (#658, #659) were deleted + # related: + # https://github.com/fastify/point-of-view/issues/463 https://github.com/fastify/point-of-view/pull/461#issuecomment-2718888986 + # https://github.com/cnpm/bug-versions/pull/266 https://github.com/cnpm/cnpmcore/issues/777 + # https://github.com/yoimiya-kokomi/Miao-Yunzai/pull/515 https://github.com/zhangfisher/flex-tools/commit/09b565dfe6e2932bb829613ddbe09f6d0acbccd4 + - dependency-name: art-template + versions: ['>=4.13.3'] + # no longer includes KJUR.crypto.Cipher for RSA + - dependency-name: jsrsasign + versions: ['>=11.0.0'] + groups: + eslint: + patterns: + - 'eslint' + - '@eslint/*' + opentelemetry: + patterns: + - '@opentelemetry/*' + typescript-eslint: + patterns: + - '@typescript-eslint/*' - - package-ecosystem: 'github-actions' - directory: '/' - schedule: - interval: daily - time: '08:00' - open-pull-requests-limit: 100 - labels: - - dependencies + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: daily + time: '08:00' + open-pull-requests-limit: 100 + labels: + - dependencies diff --git a/.github/labeler.yml b/.github/labeler.yml index 5223042575..1983ce1f81 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,17 +1,17 @@ 'route: deprecated': -- changed-files: - - any-glob-to-any-file: ['lib/router.js'] - - all-globs-to-any-file: ['lib/routes-deprecated/**/*.js', '!lib/routes-deprecated/index.js'] + - changed-files: + - any-glob-to-any-file: ['lib/router.js'] + - all-globs-to-any-file: ['lib/routes-deprecated/**/*.js', '!lib/routes-deprecated/index.js'] 'Route': -- changed-files: - - any-glob-to-any-file: ['lib/routes/**/*.ts'] + - changed-files: + - any-glob-to-any-file: ['lib/routes/**/*.ts'] core enhancement: -- changed-files: - - any-glob-to-any-file: ['lib/routes/index.ts'] - - all-globs-to-any-file: ['lib/**', '!lib/config.ts', '!lib/router.js', '!lib/routes/**', '!lib/routes-deprecated/**'] + - changed-files: + - any-glob-to-any-file: ['lib/routes/index.ts'] + - all-globs-to-any-file: ['lib/**', '!lib/config.ts', '!lib/router.js', '!lib/routes/**', '!lib/routes-deprecated/**'] dependencies: -- changed-files: - - any-glob-to-any-file: ['package.json', 'pnpm-lock.yaml', 'yarn.lock'] + - changed-files: + - any-glob-to-any-file: ['package.json', 'pnpm-lock.yaml', 'yarn.lock'] diff --git a/.github/prompts/similar_issues.prompt.yml b/.github/prompts/similar_issues.prompt.yml index 1c85493b2b..c1bf40ea58 100644 --- a/.github/prompts/similar_issues.prompt.yml +++ b/.github/prompts/similar_issues.prompt.yml @@ -1,46 +1,46 @@ messages: - - role: system - content: |- - You are a GitHub assistant with access to GitHub Model Context Protocol (MCP) - tools in read-only mode. Your task is to search this repository's issues to find - previously filed issues similar to the provided issue title and body. Use the - GitHub tools via MCP to perform the search and retrieve real issue data (do not - fabricate results). Consider semantic similarity across title and body. Exclude - the current issue {{issue_number}}. Return up to 3 of the most similar past issues. If none are - reasonably similar, return an empty list. Output must follow the response schema - exactly and include only data you actually retrieved from GitHub tools. - The current GitHub repository is: "{{repository}}". - - role: user - content: |- - Find similar issues for issue {{issue_number}}: - Title: {{issue_title}} - Body: - {{issue_body}} + - role: system + content: |- + You are a GitHub assistant with access to GitHub Model Context Protocol (MCP) + tools in read-only mode. Your task is to search this repository's issues to find + previously filed issues similar to the provided issue title and body. Use the + GitHub tools via MCP to perform the search and retrieve real issue data (do not + fabricate results). Consider semantic similarity across title and body. Exclude + the current issue {{issue_number}}. Return up to 3 of the most similar past issues. If none are + reasonably similar, return an empty list. Output must follow the response schema + exactly and include only data you actually retrieved from GitHub tools. + The current GitHub repository is: "{{repository}}". + - role: user + content: |- + Find similar issues for issue {{issue_number}}: + Title: {{issue_title}} + Body: + {{issue_body}} model: openai/gpt-4.1-mini responseFormat: json_schema jsonSchema: |- - { - "name": "similar_issues_result", - "strict": true, - "schema": { - "type": "object", - "properties": { - "matches": { - "type": "array", - "items": { - "type": "object", - "properties": { - "number": { "type": "integer" }, - "title": { "type": "string" }, - "url": { "type": "string" }, - "similarity_score": { "type": "number", "minimum": 0, "maximum": 1 } - }, - "required": ["number", "title", "url", "similarity_score"], - "additionalProperties": false + { + "name": "similar_issues_result", + "strict": true, + "schema": { + "type": "object", + "properties": { + "matches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "number": { "type": "integer" }, + "title": { "type": "string" }, + "url": { "type": "string" }, + "similarity_score": { "type": "number", "minimum": 0, "maximum": 1 } + }, + "required": ["number", "title", "url", "similarity_score"], + "additionalProperties": false + } } - } - }, - "required": ["matches"], - "additionalProperties": false + }, + "required": ["matches"], + "additionalProperties": false + } } - } diff --git a/.github/pull.yml b/.github/pull.yml index c9692c59dc..ea31d4616a 100644 --- a/.github/pull.yml +++ b/.github/pull.yml @@ -1,8 +1,8 @@ version: '1' rules: - - base: master - upstream: diygod:master - # default value if this file does not exist is `hardreset`, effectively overwriting any downstream changes! - # previously it was the misconfigured PR route test workflow that rescued downstream changes from being overwritten - mergeMethod: merge - mergeUnstable: true # prevent non-pass tests from preventing automatic merge + - base: master + upstream: diygod:master + # default value if this file does not exist is `hardreset`, effectively overwriting any downstream changes! + # previously it was the misconfigured PR route test workflow that rescued downstream changes from being overwritten + mergeMethod: merge + mergeUnstable: true # prevent non-pass tests from preventing automatic merge diff --git a/.github/workflows/build-assets.yml b/.github/workflows/build-assets.yml index bc51e8163f..331a18c9d6 100644 --- a/.github/workflows/build-assets.yml +++ b/.github/workflows/build-assets.yml @@ -1,108 +1,108 @@ name: Build assets on: - workflow_dispatch: - push: - branches: - - master - paths: - - 'lib/**/*.ts' + workflow_dispatch: + push: + branches: + - master + paths: + - 'lib/**/*.ts' jobs: - build: - runs-on: ubuntu-latest - name: Build assets - timeout-minutes: 5 - permissions: - contents: write - steps: - - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - name: Use Node.js Active LTS - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - - name: Install dependencies (yarn) - run: pnpm i + build: + runs-on: ubuntu-latest + name: Build assets + timeout-minutes: 5 + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - name: Install pnpm + uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - name: Use Node.js Active LTS + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + - name: Install dependencies (yarn) + run: pnpm i - # assets - - name: Build assets - run: pnpm build - - name: Deploy - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./assets - user_name: 'github-actions[bot]' - user_email: '41898282+github-actions[bot]@users.noreply.github.com' - # prevent deleting build/test-full-routes.json which will break build:docs - keep_files: true + # assets + - name: Build assets + run: pnpm build + - name: Deploy + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./assets + user_name: 'github-actions[bot]' + user_email: '41898282+github-actions[bot]@users.noreply.github.com' + # prevent deleting build/test-full-routes.json which will break build:docs + keep_files: true - # docs - - name: Build docs - run: pnpm build:docs - - id: check-docs-env - env: - DOCS_API_TOKEN: ${{ secrets.DOCS_API_TOKEN }} - if: ${{ env.DOCS_API_TOKEN != '' }} - run: echo "defined=true" >> $GITHUB_OUTPUT - - name: Checkout docs - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - if: steps.check-docs-env.outputs.defined == 'true' - with: - repository: 'RSSNext/rsshub-docs' - token: ${{ secrets.DOCS_API_TOKEN }} - path: rsshub-docs - - name: Update docs - if: steps.check-docs-env.outputs.defined == 'true' - run: | - cp -r ./assets/build/docs/en/* ./rsshub-docs/src/routes - cp -r ./assets/build/docs/zh/* ./rsshub-docs/src/zh/routes - cp ./lib/types.ts ./rsshub-docs/.vitepress/theme/types.ts - cp ./scripts/workflow/data.ts ./rsshub-docs/.vitepress/config/data.ts - - name: Commit docs - if: steps.check-docs-env.outputs.defined == 'true' - run: | - cd rsshub-docs - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git status - git diff-index --quiet HEAD || (git commit -m "chore: auto build https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.DOCS_API_TOKEN }}@github.com/RSSNext/rsshub-docs.git" HEAD:main) + # docs + - name: Build docs + run: pnpm build:docs + - id: check-docs-env + env: + DOCS_API_TOKEN: ${{ secrets.DOCS_API_TOKEN }} + if: ${{ env.DOCS_API_TOKEN != '' }} + run: echo "defined=true" >> $GITHUB_OUTPUT + - name: Checkout docs + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + if: steps.check-docs-env.outputs.defined == 'true' + with: + repository: 'RSSNext/rsshub-docs' + token: ${{ secrets.DOCS_API_TOKEN }} + path: rsshub-docs + - name: Update docs + if: steps.check-docs-env.outputs.defined == 'true' + run: | + cp -r ./assets/build/docs/en/* ./rsshub-docs/src/routes + cp -r ./assets/build/docs/zh/* ./rsshub-docs/src/zh/routes + cp ./lib/types.ts ./rsshub-docs/.vitepress/theme/types.ts + cp ./scripts/workflow/data.ts ./rsshub-docs/.vitepress/config/data.ts + - name: Commit docs + if: steps.check-docs-env.outputs.defined == 'true' + run: | + cd rsshub-docs + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git status + git diff-index --quiet HEAD || (git commit -m "chore: auto build https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.DOCS_API_TOKEN }}@github.com/RSSNext/rsshub-docs.git" HEAD:main) - # vercel - - id: check-vercel-env - env: - VERCEL_API_TOKEN: ${{ secrets.VERCEL_API_TOKEN }} - if: ${{ env.VERCEL_API_TOKEN != '' }} - run: echo "defined=true" >> $GITHUB_OUTPUT - - name: Checkout vercel - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - if: steps.check-vercel-env.outputs.defined == 'true' - with: - repository: 'RSSNext/rsshub-vercel' - token: ${{ secrets.VERCEL_API_TOKEN }} - path: rsshub-vercel - - name: Build vercel - if: steps.check-vercel-env.outputs.defined == 'true' - run: pnpm build:vercel - - name: Update vercel - if: steps.check-vercel-env.outputs.defined == 'true' - run: | - rm -rf ./rsshub-vercel/src - rm -rf ./rsshub-vercel/pnpm-lock.yaml - mkdir -p ./rsshub-vercel/src - cp -r ./dist/* ./rsshub-vercel/src - cd rsshub-vercel - pnpm i - - name: Commit vercel - if: steps.check-vercel-env.outputs.defined == 'true' - run: | - cd rsshub-vercel - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git add -A - git status - git diff-index --quiet HEAD || (git commit -m "chore: auto build https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.VERCEL_API_TOKEN }}@github.com/RSSNext/rsshub-vercel.git" HEAD:main) + # vercel + - id: check-vercel-env + env: + VERCEL_API_TOKEN: ${{ secrets.VERCEL_API_TOKEN }} + if: ${{ env.VERCEL_API_TOKEN != '' }} + run: echo "defined=true" >> $GITHUB_OUTPUT + - name: Checkout vercel + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + if: steps.check-vercel-env.outputs.defined == 'true' + with: + repository: 'RSSNext/rsshub-vercel' + token: ${{ secrets.VERCEL_API_TOKEN }} + path: rsshub-vercel + - name: Build vercel + if: steps.check-vercel-env.outputs.defined == 'true' + run: pnpm build:vercel + - name: Update vercel + if: steps.check-vercel-env.outputs.defined == 'true' + run: | + rm -rf ./rsshub-vercel/src + rm -rf ./rsshub-vercel/pnpm-lock.yaml + mkdir -p ./rsshub-vercel/src + cp -r ./dist/* ./rsshub-vercel/src + cd rsshub-vercel + pnpm i + - name: Commit vercel + if: steps.check-vercel-env.outputs.defined == 'true' + run: | + cd rsshub-vercel + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add -A + git status + git diff-index --quiet HEAD || (git commit -m "chore: auto build https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.VERCEL_API_TOKEN }}@github.com/RSSNext/rsshub-vercel.git" HEAD:main) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3d00b6b69f..e2d3e07d94 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,73 +12,73 @@ name: 'CodeQL' on: - push: - branches: ['master'] - pull_request: - branches: ['master'] - schedule: - - cron: '15 9 * * 3' + push: + branches: ['master'] + pull_request: + branches: ['master'] + schedule: + - cron: '15 9 * * 3' jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - # required for all workflows - security-events: write + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + # required for all workflows + security-events: write - # only required for workflows in private repositories - actions: read - contents: read + # only required for workflows in private repositories + actions: read + contents: read - strategy: - fail-fast: false - matrix: - language: ['javascript-typescript'] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + strategy: + fail-fast: false + matrix: + language: ['javascript-typescript'] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - steps: - - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + steps: + - name: Checkout repository + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - # Initializes the CodeQL tools for scanning. - # TODO: use hash pinning when https://github.com/dependabot/dependabot-core/pull/13007 pass - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + # TODO: use hash pinning when https://github.com/dependabot/dependabot-core/pull/13007 pass + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v4 + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v4 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: '/language:${{matrix.language}}' + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: '/language:${{matrix.language}}' diff --git a/.github/workflows/comment-on-issue.yml b/.github/workflows/comment-on-issue.yml index 9e2c6da528..984f96a93d 100644 --- a/.github/workflows/comment-on-issue.yml +++ b/.github/workflows/comment-on-issue.yml @@ -1,30 +1,30 @@ name: Comment on Issue on: - issues: - types: [opened, edited, reopened] + issues: + types: [opened, edited, reopened] jobs: - testRoute: - name: Call maintainers - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - issues: write - if: github.event.sender.login != 'issuehunt-oss[bot]' - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - - name: Install dependencies (pnpm) # import remark-parse and unified - run: pnpm i - - name: Generate feedback - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { default: callMaintainer } = await import('${{ github.workspace }}/scripts/workflow/test-issue/call-maintainer.mjs') - await callMaintainer({ github, context, core }) + testRoute: + name: Call maintainers + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + issues: write + if: github.event.sender.login != 'issuehunt-oss[bot]' + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + - name: Install dependencies (pnpm) # import remark-parse and unified + run: pnpm i + - name: Generate feedback + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { default: callMaintainer } = await import('${{ github.workspace }}/scripts/workflow/test-issue/call-maintainer.mjs') + await callMaintainer({ github, context, core }) diff --git a/.github/workflows/dependabot-fork.yml b/.github/workflows/dependabot-fork.yml index 2c73760bd2..a3d74a394c 100644 --- a/.github/workflows/dependabot-fork.yml +++ b/.github/workflows/dependabot-fork.yml @@ -3,17 +3,17 @@ name: Ignore dependabot on forks on: pull_request jobs: - dependabot-fork: - if: github.repository_owner != 'DIYgod' && github.actor == 'dependabot[bot]' - runs-on: ubuntu-latest - name: Ignore dependabot on forks - timeout-minutes: 5 - steps: - - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + dependabot-fork: + if: github.repository_owner != 'DIYgod' && github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + name: Ignore dependabot on forks + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Comment Dependabot PR - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 - with: - message: '@dependabot ignore this dependency' - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Comment Dependabot PR + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 + with: + message: '@dependabot ignore this dependency' + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 2da7c32c5d..4a09ea942e 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -1,152 +1,152 @@ name: 'Docker Release' on: - push: - branches: - - master - paths: - - '.github/workflows/docker-release.yml' - - 'lib/**' - - '!lib/**/*.test.ts' - - 'Dockerfile' - workflow_dispatch: {} + push: + branches: + - master + paths: + - '.github/workflows/docker-release.yml' + - 'lib/**' + - '!lib/**/*.test.ts' + - 'Dockerfile' + workflow_dispatch: {} jobs: - check-env: - permissions: - contents: none - runs-on: ubuntu-latest - timeout-minutes: 5 - outputs: - check-docker: ${{ steps.check-docker.outputs.defined }} - steps: - - id: check-docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - if: ${{ env.DOCKER_USERNAME != '' }} - run: echo "defined=true" >> $GITHUB_OUTPUT - release: - runs-on: ubuntu-latest - needs: check-env - if: needs.check-env.outputs.check-docker == 'true' - timeout-minutes: 120 - permissions: - packages: write - id-token: write - steps: - - name: Enable ZRAM - # Reduce memory pressure - # PERCENT=100 is safe: https://fedoraproject.org/wiki/Changes/Scale_ZRAM_to_full_memory_size - run: | - sudo apt-get update -yq - sudo apt-get install -yq "linux-modules-extra-$(uname -r)" zram-tools - echo -e 'ALGO=lz4\nPERCENT=100' | sudo tee -a /etc/default/zramswap - sudo systemctl restart zramswap - swapon + check-env: + permissions: + contents: none + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + check-docker: ${{ steps.check-docker.outputs.defined }} + steps: + - id: check-docker + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + if: ${{ env.DOCKER_USERNAME != '' }} + run: echo "defined=true" >> $GITHUB_OUTPUT + release: + runs-on: ubuntu-latest + needs: check-env + if: needs.check-env.outputs.check-docker == 'true' + timeout-minutes: 120 + permissions: + packages: write + id-token: write + steps: + - name: Enable ZRAM + # Reduce memory pressure + # PERCENT=100 is safe: https://fedoraproject.org/wiki/Changes/Scale_ZRAM_to_full_memory_size + run: | + sudo apt-get update -yq + sudo apt-get install -yq "linux-modules-extra-$(uname -r)" zram-tools + echo -e 'ALGO=lz4\nPERCENT=100' | sudo tee -a /etc/default/zramswap + sudo systemctl restart zramswap + swapon - - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Install cosign - if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 + - name: Install cosign + if: github.event_name != 'pull_request' + uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - - name: Set up QEMU - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + - name: Set up QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Log in to Docker Hub - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + - name: Log in to Docker Hub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - - name: Log in to the Container registry - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Log in to the Container registry + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract Docker metadata (ordinary version) - id: meta-ordinary - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 - with: - images: | - ${{ secrets.DOCKER_USERNAME }}/rsshub - ghcr.io/${{ github.repository }} - tags: | - type=raw,value=latest,enable=true - type=raw,value={{date 'YYYY-MM-DD'}},enable=true - type=sha,format=long,prefix=,enable=true - flavor: latest=false + - name: Extract Docker metadata (ordinary version) + id: meta-ordinary + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 + with: + images: | + ${{ secrets.DOCKER_USERNAME }}/rsshub + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=latest,enable=true + type=raw,value={{date 'YYYY-MM-DD'}},enable=true + type=sha,format=long,prefix=,enable=true + flavor: latest=false - - name: Build and push Docker image (ordinary version) - id: build-and-push - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - push: true - tags: ${{ steps.meta-ordinary.outputs.tags }} - labels: ${{ steps.meta-ordinary.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha,scope=docker-release - cache-to: type=gha,mode=max,scope=docker-release - outputs: type=image,compression=zstd,force-compression=true + - name: Build and push Docker image (ordinary version) + id: build-and-push + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + push: true + tags: ${{ steps.meta-ordinary.outputs.tags }} + labels: ${{ steps.meta-ordinary.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha,scope=docker-release + cache-to: type=gha,mode=max,scope=docker-release + outputs: type=image,compression=zstd,force-compression=true - - name: Sign the published Docker image - if: ${{ github.event_name != 'pull_request' }} - env: - COSIGN_EXPERIMENTAL: 'true' - run: echo "${{ steps.meta-ordinary.outputs.tags }}" | xargs -I {} cosign sign --yes {}@${{ steps.build-and-push.outputs.digest }} + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + COSIGN_EXPERIMENTAL: 'true' + run: echo "${{ steps.meta-ordinary.outputs.tags }}" | xargs -I {} cosign sign --yes {}@${{ steps.build-and-push.outputs.digest }} - - name: Extract Docker metadata (Chromium-bundled version) - id: meta-chromium-bundled - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 - with: - images: | - ${{ secrets.DOCKER_USERNAME }}/rsshub - ghcr.io/${{ github.repository }} - tags: | - type=raw,value=chromium-bundled,enable=true - type=raw,value=chromium-bundled-{{date 'YYYY-MM-DD'}},enable=true - type=sha,format=long,prefix=chromium-bundled-,enable=true - flavor: latest=false + - name: Extract Docker metadata (Chromium-bundled version) + id: meta-chromium-bundled + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 + with: + images: | + ${{ secrets.DOCKER_USERNAME }}/rsshub + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=chromium-bundled,enable=true + type=raw,value=chromium-bundled-{{date 'YYYY-MM-DD'}},enable=true + type=sha,format=long,prefix=chromium-bundled-,enable=true + flavor: latest=false - - name: Build and push Docker image (Chromium-bundled version) - id: build-and-push-chromium - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - build-args: PUPPETEER_SKIP_DOWNLOAD=0 - push: true - tags: ${{ steps.meta-chromium-bundled.outputs.tags }} - labels: ${{ steps.meta-chromium-bundled.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: | - type=registry,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled - cache-to: type=inline,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled # inline cache is enough - outputs: type=image,compression=zstd,force-compression=true + - name: Build and push Docker image (Chromium-bundled version) + id: build-and-push-chromium + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + build-args: PUPPETEER_SKIP_DOWNLOAD=0 + push: true + tags: ${{ steps.meta-chromium-bundled.outputs.tags }} + labels: ${{ steps.meta-chromium-bundled.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: | + type=registry,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled + cache-to: type=inline,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled # inline cache is enough + outputs: type=image,compression=zstd,force-compression=true - - name: Sign the published Docker image - if: ${{ github.event_name != 'pull_request' }} - env: - COSIGN_EXPERIMENTAL: 'true' - run: echo "${{ steps.meta-chromium-bundled.outputs.tags }}" | xargs -I {} cosign sign --yes {}@${{ steps.build-and-push-chromium.outputs.digest }} + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + COSIGN_EXPERIMENTAL: 'true' + run: echo "${{ steps.meta-chromium-bundled.outputs.tags }}" | xargs -I {} cosign sign --yes {}@${{ steps.build-and-push-chromium.outputs.digest }} - description: - runs-on: ubuntu-latest - needs: check-env - if: needs.check-env.outputs.check-docker == 'true' - timeout-minutes: 5 - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + description: + runs-on: ubuntu-latest + needs: check-env + if: needs.check-env.outputs.check-docker == 'true' + timeout-minutes: 5 + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Docker Hub Description - uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - repository: ${{ secrets.DOCKER_USERNAME }}/rsshub + - name: Docker Hub Description + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: ${{ secrets.DOCKER_USERNAME }}/rsshub diff --git a/.github/workflows/docker-test-cont.yml b/.github/workflows/docker-test-cont.yml index 9fc642c7a3..6512b83bab 100644 --- a/.github/workflows/docker-test-cont.yml +++ b/.github/workflows/docker-test-cont.yml @@ -1,143 +1,143 @@ name: PR - route test on: - workflow_run: - workflows: [PR - Docker build test] # open, reopen, synchronized, edited included - types: [completed] + workflow_run: + workflows: [PR - Docker build test] # open, reopen, synchronized, edited included + types: [completed] jobs: - testRoute: - name: Route test - runs-on: ubuntu-latest - permissions: - pull-requests: write - if: ${{ github.event.workflow_run.conclusion == 'success' }} # skip if unsuccessful - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + testRoute: + name: Route test + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: ${{ github.event.workflow_run.conclusion == 'success' }} # skip if unsuccessful + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - # https://github.com/orgs/community/discussions/25220 - - name: Search the PR that triggered this workflow - uses: potiuk/get-workflow-origin@e2dae063368361e4cd1f510e8785cd73bca9352e # v1_5 - id: source-run-info - with: - token: ${{ secrets.GITHUB_TOKEN }} - sourceRunId: ${{ github.event.workflow_run.id }} + # https://github.com/orgs/community/discussions/25220 + - name: Search the PR that triggered this workflow + uses: potiuk/get-workflow-origin@e2dae063368361e4cd1f510e8785cd73bca9352e # v1_5 + id: source-run-info + with: + token: ${{ secrets.GITHUB_TOKEN }} + sourceRunId: ${{ github.event.workflow_run.id }} - - name: Fetch PR data via GitHub API - uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0 - id: pr-data - with: - route: GET /repos/{repo}/pulls/{number} - repo: ${{ github.repository }} - number: ${{ steps.source-run-info.outputs.pullRequestNumber }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Fetch PR data via GitHub API + uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0 + id: pr-data + with: + route: GET /repos/{repo}/pulls/{number} + repo: ${{ github.repository }} + number: ${{ steps.source-run-info.outputs.pullRequestNumber }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Fetch affected routes - id: fetch-route - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - PULL_REQUEST: ${{ steps.pr-data.outputs.data }} - with: - # by default, JSON format returned - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const PR = JSON.parse(process.env.PULL_REQUEST) - const body = PR.body - const number = PR.number - const sender = PR.user.login - const { default: identify } = await import('${{ github.workspace }}/scripts/workflow/test-route/identify.mjs') - return identify({ github, context, core }, body, number, sender) + - name: Fetch affected routes + id: fetch-route + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + PULL_REQUEST: ${{ steps.pr-data.outputs.data }} + with: + # by default, JSON format returned + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const PR = JSON.parse(process.env.PULL_REQUEST) + const body = PR.body + const number = PR.number + const sender = PR.user.login + const { default: identify } = await import('${{ github.workspace }}/scripts/workflow/test-route/identify.mjs') + return identify({ github, context, core }, body, number, sender) - - name: Fetch Docker image - if: (env.TEST_CONTINUE) - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 - with: - workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} - name: docker-image - path: ../artifacts-${{ github.run_id }} + - name: Fetch Docker image + if: (env.TEST_CONTINUE) + uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + with: + workflow: ${{ github.event.workflow_run.workflow_id }} + run_id: ${{ github.event.workflow_run.id }} + name: docker-image + path: ../artifacts-${{ github.run_id }} - - name: Import Docker image and set up Docker container - if: (env.TEST_CONTINUE) - working-directory: ../artifacts-${{ github.run_id }} - run: | - set -ex - zstd -d --stdout rsshub.tar.zst | docker load - docker run -d \ - --name rsshub \ - -e NODE_ENV=dev \ - -e NODE_OPTIONS='--max-http-header-size=32768' \ - -e LOGGER_LEVEL=debug \ - -e ALLOW_USER_HOTLINK_TEMPLATE=true \ - -e ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true \ - -p 1200:1200 \ - rsshub:latest + - name: Import Docker image and set up Docker container + if: (env.TEST_CONTINUE) + working-directory: ../artifacts-${{ github.run_id }} + run: | + set -ex + zstd -d --stdout rsshub.tar.zst | docker load + docker run -d \ + --name rsshub \ + -e NODE_ENV=dev \ + -e NODE_OPTIONS='--max-http-header-size=32768' \ + -e LOGGER_LEVEL=debug \ + -e ALLOW_USER_HOTLINK_TEMPLATE=true \ + -e ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true \ + -p 1200:1200 \ + rsshub:latest - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - if: (env.TEST_CONTINUE) - with: - node-version: lts/* - cache: 'pnpm' + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + if: (env.TEST_CONTINUE) + with: + node-version: lts/* + cache: 'pnpm' - - name: Install dependencies (pnpm) # require js-beautify - if: (env.TEST_CONTINUE) - run: pnpm i + - name: Install dependencies (pnpm) # require js-beautify + if: (env.TEST_CONTINUE) + run: pnpm i - - name: Generate feedback - if: (env.TEST_CONTINUE) - id: generate-feedback - timeout-minutes: 10 - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - TEST_BASEURL: http://localhost:1200 - TEST_ROUTES: ${{ steps.fetch-route.outputs.result }} - PULL_REQUEST: ${{ steps.pr-data.outputs.data }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const PR = JSON.parse(process.env.PULL_REQUEST) - const link = process.env.TEST_BASEURL - const routes = JSON.parse(process.env.TEST_ROUTES) - const number = PR.number - core.info(`${link}, ${routes}, ${number}`) - const { default: test } = await import('${{ github.workspace }}/scripts/workflow/test-route/test.mjs') - await test({ github, context, core }, link, routes, number) + - name: Generate feedback + if: (env.TEST_CONTINUE) + id: generate-feedback + timeout-minutes: 10 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + TEST_BASEURL: http://localhost:1200 + TEST_ROUTES: ${{ steps.fetch-route.outputs.result }} + PULL_REQUEST: ${{ steps.pr-data.outputs.data }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const PR = JSON.parse(process.env.PULL_REQUEST) + const link = process.env.TEST_BASEURL + const routes = JSON.parse(process.env.TEST_ROUTES) + const number = PR.number + core.info(`${link}, ${routes}, ${number}`) + const { default: test } = await import('${{ github.workspace }}/scripts/workflow/test-route/test.mjs') + await test({ github, context, core }, link, routes, number) - - name: Pull Request Labeler - if: ${{ failure() }} - uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 - with: - actions: 'add-labels' - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ steps.source-run-info.outputs.pullRequestNumber }} - labels: 'auto: DO NOT merge' + - name: Pull Request Labeler + if: ${{ failure() }} + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 + with: + actions: 'add-labels' + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ steps.source-run-info.outputs.pullRequestNumber }} + labels: 'auto: DO NOT merge' - - name: Print Docker container logs - if: ${{ always() }} - run: docker logs rsshub || true # logs/combined.log? Not so readable... + - name: Print Docker container logs + if: ${{ always() }} + run: docker logs rsshub || true # logs/combined.log? Not so readable... - fail-build: - name: Fail build - runs-on: ubuntu-latest - permissions: - pull-requests: write - if: ${{ github.event.workflow_run.conclusion == 'failure' }} - steps: - # https://github.com/orgs/community/discussions/25220 - - name: Search the PR that triggered this workflow - uses: potiuk/get-workflow-origin@e2dae063368361e4cd1f510e8785cd73bca9352e # v1_5 - id: source-run-info - with: - token: ${{ secrets.GITHUB_TOKEN }} - sourceRunId: ${{ github.event.workflow_run.id }} + fail-build: + name: Fail build + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + steps: + # https://github.com/orgs/community/discussions/25220 + - name: Search the PR that triggered this workflow + uses: potiuk/get-workflow-origin@e2dae063368361e4cd1f510e8785cd73bca9352e # v1_5 + id: source-run-info + with: + token: ${{ secrets.GITHUB_TOKEN }} + sourceRunId: ${{ github.event.workflow_run.id }} - - name: Pull Request Labeler - uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 - with: - actions: 'add-labels' - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ steps.source-run-info.outputs.pullRequestNumber }} - labels: 'auto: DO NOT merge' + - name: Pull Request Labeler + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 + with: + actions: 'add-labels' + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ steps.source-run-info.outputs.pullRequestNumber }} + labels: 'auto: DO NOT merge' diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index f44fc61589..650337409e 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -1,76 +1,76 @@ name: PR - Docker build test on: - pull_request: - branches: - - master - paths: - - '.github/workflows/docker-test.yml' - - 'lib/**' - - 'Dockerfile' - - 'package.json' - - 'pnpm-lock.yaml' - types: [opened, reopened, synchronize, edited] - # Please, always create a pull request instead of push to master. + pull_request: + branches: + - master + paths: + - '.github/workflows/docker-test.yml' + - 'lib/**' + - 'Dockerfile' + - 'package.json' + - 'pnpm-lock.yaml' + types: [opened, reopened, synchronize, edited] + # Please, always create a pull request instead of push to master. concurrency: - group: docker-test-${{ github.ref_name }} - cancel-in-progress: true + group: docker-test-${{ github.ref_name }} + cancel-in-progress: true jobs: - test: - name: Docker build & tests - permissions: - pull-requests: write - attestations: write - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + test: + name: Docker build & tests + permissions: + pull-requests: write + attestations: write + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Set up Docker Buildx # needed by `cache-from` - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - name: Set up Docker Buildx # needed by `cache-from` + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 - with: - images: rsshub - flavor: latest=true + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 + with: + images: rsshub + flavor: latest=true - - name: Build Docker image - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - build-args: PUPPETEER_SKIP_DOWNLOAD=0 # also test bundling Chromium - load: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64 # explicit - cache-from: | - type=registry,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled - type=gha,scope=docker-release - outputs: type=docker,compression=zstd,force-compression=true # load: true means docker output type + - name: Build Docker image + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + build-args: PUPPETEER_SKIP_DOWNLOAD=0 # also test bundling Chromium + load: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64 # explicit + cache-from: | + type=registry,ref=${{ secrets.DOCKER_USERNAME }}/rsshub:chromium-bundled + type=gha,scope=docker-release + outputs: type=docker,compression=zstd,force-compression=true # load: true means docker output type - - name: Pull Request Labeler - if: ${{ failure() }} - uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 - with: - actions: 'add-labels' - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ github.event.pull_request.number }} - labels: 'auto: DO NOT merge' + - name: Pull Request Labeler + if: ${{ failure() }} + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 + with: + actions: 'add-labels' + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + labels: 'auto: DO NOT merge' - - name: Test Docker image - run: bash scripts/docker/test-docker.sh + - name: Test Docker image + run: bash scripts/docker/test-docker.sh - - name: Export Docker image - run: docker save rsshub:latest | zstdmt -o rsshub.tar.zst + - name: Export Docker image + run: docker save rsshub:latest | zstdmt -o rsshub.tar.zst - - name: Upload Docker image - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: docker-image - path: rsshub.tar.zst - retention-days: 1 + - name: Upload Docker image + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: docker-image + path: rsshub.tar.zst + retention-days: 1 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 6ee381ee7c..cbe46bd6f7 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -1,30 +1,30 @@ name: Format on: - push: - branches: - - master + push: + branches: + - master jobs: - format: - permissions: - contents: write # for Git to git push - name: Auto format - runs-on: ubuntu-latest - timeout-minutes: 5 + format: + permissions: + contents: write # for Git to git push + name: Auto format + runs-on: ubuntu-latest + timeout-minutes: 5 - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - - run: pnpm i - - run: npm run format - - name: Commit files - run: | - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git status - git diff-index --quiet HEAD || (git commit -m "style: auto format" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" HEAD:master) + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + - run: pnpm i + - run: npm run format + - name: Commit files + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git status + git diff-index --quiet HEAD || (git commit -m "style: auto format" -a --no-verify && git push "https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" HEAD:master) diff --git a/.github/workflows/ghcr-retention.yml b/.github/workflows/ghcr-retention.yml index 76eb950038..777b866991 100644 --- a/.github/workflows/ghcr-retention.yml +++ b/.github/workflows/ghcr-retention.yml @@ -1,26 +1,26 @@ name: 'Clean up GHCR Packages' on: - schedule: - - cron: '0 0 * * 0' - workflow_dispatch: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: jobs: - cleanup: - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - name: Delete old container versions (30+ days) - uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16 - with: - dry-run: false - token: ${{ secrets.GITHUB_TOKEN }} - package: rsshub - older-than: 30 days - keep-n-tagged: 5 - delete-untagged: true - delete-ghost-images: true - delete-orphaned-images: true - delete-partial-images: true + cleanup: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Delete old container versions (30+ days) + uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16 + with: + dry-run: false + token: ${{ secrets.GITHUB_TOKEN }} + package: rsshub + older-than: 30 days + keep-n-tagged: 5 + delete-untagged: true + delete-ghost-images: true + delete-orphaned-images: true + delete-partial-images: true diff --git a/.github/workflows/issue-command.yml b/.github/workflows/issue-command.yml index d7980e0a2a..4a9cd46596 100644 --- a/.github/workflows/issue-command.yml +++ b/.github/workflows/issue-command.yml @@ -1,136 +1,136 @@ name: Issue Command on: - issue_comment: - types: [created] + issue_comment: + types: [created] jobs: - rebase: - name: Automatic Rebase - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') && github.event.comment.author_association == 'COLLABORATOR' - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout the latest code - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - with: - fetch-depth: 0 - - name: Automatic Rebase - uses: cirrus-actions/rebase@1.8 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + rebase: + name: Automatic Rebase + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') && github.event.comment.author_association == 'COLLABORATOR' + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout the latest code + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + fetch-depth: 0 + - name: Automatic Rebase + uses: cirrus-actions/rebase@1.8 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - self-assign: - name: Self Assign - if: ${{ !github.event.issue.pull_request && startsWith(github.event.comment.body, '/wip') }} - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - issues: write - steps: - - uses: bdougie/take-action@1439165ac45a7461c2d89a59952cd7d941964b87 # v1.6.1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - trigger: '/wip' + self-assign: + name: Self Assign + if: ${{ !github.event.issue.pull_request && startsWith(github.event.comment.body, '/wip') }} + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + issues: write + steps: + - uses: bdougie/take-action@1439165ac45a7461c2d89a59952cd7d941964b87 # v1.6.1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + trigger: '/wip' - test-on-demand: - name: Test route on demand - if: startsWith(github.event.comment.body, '/test') - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - attestations: write - issues: write - pull-requests: write - steps: - - name: Fetch PR data (for PR) - if: github.event.issue.pull_request - uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0 - id: pr-data - with: - route: GET /repos/{repo}/pulls/{number} - repo: ${{ github.repository }} - number: ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + test-on-demand: + name: Test route on demand + if: startsWith(github.event.comment.body, '/test') + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + attestations: write + issues: write + pull-requests: write + steps: + - name: Fetch PR data (for PR) + if: github.event.issue.pull_request + uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0 + id: pr-data + with: + route: GET /repos/{repo}/pulls/{number} + repo: ${{ github.repository }} + number: ${{ github.event.issue.number }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Checkout - if: ${{ !github.event.issue.pull_request }} - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - name: Checkout + if: ${{ !github.event.issue.pull_request }} + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Checkout PR - if: github.event.issue.pull_request - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - with: - ref: ${{ fromJson(steps.pr-data.outputs.data).head.ref }} + - name: Checkout PR + if: github.event.issue.pull_request + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + ref: ${{ fromJson(steps.pr-data.outputs.data).head.ref }} - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - name: Install pnpm + uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - name: Use Node.js Active LTS - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' + - name: Use Node.js Active LTS + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' - - name: Install dependencies (pnpm) - run: pnpm i && pnpm rb && pnpx rebrowser-puppeteer browsers install chrome + - name: Install dependencies (pnpm) + run: pnpm i && pnpm rb && pnpx rebrowser-puppeteer browsers install chrome - - name: Fetch affected routes - id: fetch-route - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - EVENT: ${{ toJson(github.event) }} - with: - script: | - const event = JSON.parse(process.env.EVENT) - const body = event.comment.body - const number = event.issue.number - const sender = event.comment.user.login - const { default: identify } = await import('${{ github.workspace }}/scripts/workflow/test-route/identify.mjs') - return identify({ github, context, core }, body, number, sender) + - name: Fetch affected routes + id: fetch-route + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + EVENT: ${{ toJson(github.event) }} + with: + script: | + const event = JSON.parse(process.env.EVENT) + const body = event.comment.body + const number = event.issue.number + const sender = event.comment.user.login + const { default: identify } = await import('${{ github.workspace }}/scripts/workflow/test-route/identify.mjs') + return identify({ github, context, core }, body, number, sender) - - name: Build RSSHub - if: env.TEST_CONTINUE - run: pnpm build + - name: Build RSSHub + if: env.TEST_CONTINUE + run: pnpm build - - name: Start RSSHub - if: env.TEST_CONTINUE - run: pnpm start & - env: - ALLOW_USER_HOTLINK_TEMPLATE: true - ALLOW_USER_SUPPLY_UNSAFE_DOMAIN: true - NODE_ENV: dev - NODE_OPTIONS: '--max-http-header-size=32768' - LOGGER_LEVEL: debug + - name: Start RSSHub + if: env.TEST_CONTINUE + run: pnpm start & + env: + ALLOW_USER_HOTLINK_TEMPLATE: true + ALLOW_USER_SUPPLY_UNSAFE_DOMAIN: true + NODE_ENV: dev + NODE_OPTIONS: '--max-http-header-size=32768' + LOGGER_LEVEL: debug - - name: Generate feedback - if: env.TEST_CONTINUE - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - TEST_BASEURL: http://localhost:1200 - TEST_ROUTES: ${{ steps.fetch-route.outputs.result }} - EVENT: ${{ toJson(github.event) }} - with: - script: | - const event = JSON.parse(process.env.EVENT) - const link = process.env.TEST_BASEURL - const routes = JSON.parse(process.env.TEST_ROUTES) - const number = event.issue.number - core.info(`${link}, ${routes}, ${number}`) - const { default: test } = await import('${{ github.workspace }}/scripts/workflow/test-route/test.mjs') - await test({ github, context, core }, link, routes, number) + - name: Generate feedback + if: env.TEST_CONTINUE + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + TEST_BASEURL: http://localhost:1200 + TEST_ROUTES: ${{ steps.fetch-route.outputs.result }} + EVENT: ${{ toJson(github.event) }} + with: + script: | + const event = JSON.parse(process.env.EVENT) + const link = process.env.TEST_BASEURL + const routes = JSON.parse(process.env.TEST_ROUTES) + const number = event.issue.number + core.info(`${link}, ${routes}, ${number}`) + const { default: test } = await import('${{ github.workspace }}/scripts/workflow/test-route/test.mjs') + await test({ github, context, core }, link, routes, number) - - name: Print logs - if: env.TEST_CONTINUE - run: cat ${{ github.workspace }}/logs/combined.log + - name: Print logs + if: env.TEST_CONTINUE + run: cat ${{ github.workspace }}/logs/combined.log - - name: Upload Artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: logs - path: logs - retention-days: 1 + - name: Upload Artifact + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: logs + path: logs + retention-days: 1 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 56ccbb8f26..5fe19eb739 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,62 +4,62 @@ name: Linter # pull_request includes [opened, reopened, synchronize] events by default # 'edited' is required for title-lint on: - push: {} - pull_request: - types: [opened, reopened, synchronize, edited] - pull_request_target: - types: [opened, reopened, synchronize, edited] + push: {} + pull_request: + types: [opened, reopened, synchronize, edited] + pull_request_target: + types: [opened, reopened, synchronize, edited] jobs: -# https://github.com/actions/starter-workflows/blob/main/code-scanning/eslint.yml - eslint-warning: - name: Lint - if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - security-events: write - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - - run: pnpm i - - name: Lint - run: pnpm run lint - --format @microsoft/eslint-formatter-sarif - --output-file eslint-results.sarif - continue-on-error: true - - name: Upload analysis results to GitHub - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: eslint-results.sarif - wait-for-processing: true + # https://github.com/actions/starter-workflows/blob/main/code-scanning/eslint.yml + eslint-warning: + name: Lint + if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + security-events: write + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + - run: pnpm i + - name: Lint + run: pnpm run lint + --format @microsoft/eslint-formatter-sarif + --output-file eslint-results.sarif + continue-on-error: true + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: eslint-results.sarif + wait-for-processing: true -# https://github.com/amannn/action-semantic-pull-request - title-lint: - if: ${{ github.event_name == 'pull_request_target' && github.repository == 'DIYgod/RSSHub' }} - name: Validate PR title - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ignoreLabels: | - dependencies - wip: true + # https://github.com/amannn/action-semantic-pull-request + title-lint: + if: ${{ github.event_name == 'pull_request_target' && github.repository == 'DIYgod/RSSHub' }} + name: Validate PR title + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ignoreLabels: | + dependencies + wip: true - labeler: - name: Pull Request Labeler - if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && github.repository == 'DIYgod/RSSHub' }} - permissions: - pull-requests: write - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + labeler: + name: Pull Request Labeler + if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && github.repository == 'DIYgod/RSSHub' }} + permissions: + pull-requests: write + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 478c16e5c4..1afec6da3b 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,42 +1,42 @@ name: npm Publish on: - push: - branches: - - master - paths: - - '.github/workflows/npm-publish.yml' - - 'tsdown-lib.config.ts' - - 'scripts/workflow/build-routes.ts' - - 'lib/**' + push: + branches: + - master + paths: + - '.github/workflows/npm-publish.yml' + - 'tsdown-lib.config.ts' + - 'scripts/workflow/build-routes.ts' + - 'lib/**' permissions: - id-token: write # Required for OIDC + id-token: write # Required for OIDC jobs: - build: - name: npm publish - if: github.repository == 'DIYgod/RSSHub' - runs-on: ubuntu-latest - timeout-minutes: 5 - env: - HUSKY: 0 - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - registry-url: 'https://registry.npmjs.org' - - name: Install dependencies (pnpm) - run: pnpm i - - name: Run postinstall script for dependencies - run: pnpm rb - - name: Release - run: | - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - pnpx version-from-git --allow-same-version --template 'master.short' - - name: Publish to npmjs - run: pnpm publish --access public --tag latest + build: + name: npm publish + if: github.repository == 'DIYgod/RSSHub' + runs-on: ubuntu-latest + timeout-minutes: 5 + env: + HUSKY: 0 + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + registry-url: 'https://registry.npmjs.org' + - name: Install dependencies (pnpm) + run: pnpm i + - name: Run postinstall script for dependencies + run: pnpm rb + - name: Release + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + pnpx version-from-git --allow-same-version --template 'master.short' + - name: Publish to npmjs + run: pnpm publish --access public --tag latest diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 7a9410921e..5d0ddb1ebf 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -2,32 +2,32 @@ name: Semgrep # https://semgrep.dev/docs/semgrep-ci/sample-ci-configs/#sample-github-actions-configuration-file on: - pull_request_target: - branches: - - master - push: - branches: - - master - schedule: - # random HH:MM to avoid a load spike on GitHub Actions at 00:00 - - cron: 21 20 * * * + pull_request_target: + branches: + - master + push: + branches: + - master + schedule: + # random HH:MM to avoid a load spike on GitHub Actions at 00:00 + - cron: 21 20 * * * jobs: - semgrep: - name: Scan - runs-on: ubuntu-latest - container: - image: returntocorp/semgrep - if: (github.triggering_actor != 'dependabot[bot]') - permissions: - security-events: write - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - run: semgrep ci --sarif > semgrep.sarif - env: - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} - - name: Upload SARIF file for GitHub Advanced Security Dashboard - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: semgrep.sarif - if: always() + semgrep: + name: Scan + runs-on: ubuntu-latest + container: + image: returntocorp/semgrep + if: (github.triggering_actor != 'dependabot[bot]') + permissions: + security-events: write + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - run: semgrep ci --sarif > semgrep.sarif + env: + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + - name: Upload SARIF file for GitHub Advanced Security Dashboard + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: semgrep.sarif + if: always() diff --git a/.github/workflows/similar-issues.yml b/.github/workflows/similar-issues.yml index 1894bc3bda..60f56b3909 100644 --- a/.github/workflows/similar-issues.yml +++ b/.github/workflows/similar-issues.yml @@ -1,91 +1,91 @@ name: Similar Issues via AI MCP on: - issues: - types: [opened] + issues: + types: [opened] jobs: - find-similar: - permissions: - contents: read - issues: write - models: read - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + find-similar: + permissions: + contents: read + issues: write + models: read + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Prepare prompt variables - id: prepare_input - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const issue = context.payload.issue || {}; - const title = issue.title || ''; - const body = issue.body || ''; - const indent = ' '; - // Indent subsequent lines so YAML block scalar indentation remains valid - const bodyIndented = body.replace(/\n/g, '\n' + indent); - core.setOutput('issue_title_json', JSON.stringify(title)); - core.setOutput('issue_body_indented_json', JSON.stringify(bodyIndented)); - core.setOutput('issue_number', issue.number); + - name: Prepare prompt variables + id: prepare_input + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const issue = context.payload.issue || {}; + const title = issue.title || ''; + const body = issue.body || ''; + const indent = ' '; + // Indent subsequent lines so YAML block scalar indentation remains valid + const bodyIndented = body.replace(/\n/g, '\n' + indent); + core.setOutput('issue_title_json', JSON.stringify(title)); + core.setOutput('issue_body_indented_json', JSON.stringify(bodyIndented)); + core.setOutput('issue_number', issue.number); - - name: Find similar issues with AI (MCP) - id: inference - uses: actions/ai-inference@5022b33bc1431add9b2831934daf8147a2ad9331 # v2.0.2 - with: - prompt-file: ./.github/prompts/similar_issues.prompt.yml - input: | - issue_title: ${{ steps.prepare_input.outputs.issue_title_json }} - issue_body: ${{ steps.prepare_input.outputs.issue_body_indented_json }} - issue_number: ${{ steps.prepare_input.outputs.issue_number }} - repository: ${{ github.repository }} - enable-github-mcp: true - # Inference token can use GITHUB_TOKEN. MCP specifically requires a PAT. - token: ${{ secrets.GITHUB_TOKEN }} - github-mcp-token: ${{ secrets.USER_PAT }} - max-tokens: 8000 + - name: Find similar issues with AI (MCP) + id: inference + uses: actions/ai-inference@5022b33bc1431add9b2831934daf8147a2ad9331 # v2.0.2 + with: + prompt-file: ./.github/prompts/similar_issues.prompt.yml + input: | + issue_title: ${{ steps.prepare_input.outputs.issue_title_json }} + issue_body: ${{ steps.prepare_input.outputs.issue_body_indented_json }} + issue_number: ${{ steps.prepare_input.outputs.issue_number }} + repository: ${{ github.repository }} + enable-github-mcp: true + # Inference token can use GITHUB_TOKEN. MCP specifically requires a PAT. + token: ${{ secrets.GITHUB_TOKEN }} + github-mcp-token: ${{ secrets.USER_PAT }} + max-tokens: 8000 - - name: Prepare comment body - id: prepare - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - AI_RESPONSE: ${{ steps.inference.outputs.response }} - with: - script: | - let data; - try { - data = JSON.parse(process.env.AI_RESPONSE || '{}'); - } catch (e) { - core.setOutput('has_matches', 'false'); - return; - } - const matches = Array.isArray(data.matches) ? data.matches.filter(m => m.number !== context.payload.issue.number) : []; - if (!matches.length) { - core.setOutput('has_matches', 'false'); - return; - } - const lines = []; - lines.push('I found similar issues that might help:'); - for (const m of matches.slice(0, 3)) { - const num = m.number != null ? `#${m.number}` : ''; - const title = m.title || 'Untitled'; - const url = m.url || ''; - const score = typeof m.similarity_score === 'number' ? ` (similarity: ${m.similarity_score.toFixed(2)})` : ''; - lines.push(`- ${url}${score}`.trim()); - } - core.setOutput('has_matches', 'true'); - core.setOutput('comment_body', lines.join('\n')); + - name: Prepare comment body + id: prepare + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + AI_RESPONSE: ${{ steps.inference.outputs.response }} + with: + script: | + let data; + try { + data = JSON.parse(process.env.AI_RESPONSE || '{}'); + } catch (e) { + core.setOutput('has_matches', 'false'); + return; + } + const matches = Array.isArray(data.matches) ? data.matches.filter(m => m.number !== context.payload.issue.number) : []; + if (!matches.length) { + core.setOutput('has_matches', 'false'); + return; + } + const lines = []; + lines.push('I found similar issues that might help:'); + for (const m of matches.slice(0, 3)) { + const num = m.number != null ? `#${m.number}` : ''; + const title = m.title || 'Untitled'; + const url = m.url || ''; + const score = typeof m.similarity_score === 'number' ? ` (similarity: ${m.similarity_score.toFixed(2)})` : ''; + lines.push(`- ${url}${score}`.trim()); + } + core.setOutput('has_matches', 'true'); + core.setOutput('comment_body', lines.join('\n')); - - name: Comment similar issues - if: steps.prepare.outputs.has_matches == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - with: - script: | - const body = ${{ toJson(steps.prepare.outputs.comment_body) }}; - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.issue.number, - body - }); + - name: Comment similar issues + if: steps.prepare.outputs.has_matches == 'true' + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const body = ${{ toJson(steps.prepare.outputs.comment_body) }}; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.issue.number, + body + }); diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c578e79cba..b155d17141 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,37 +1,37 @@ name: 'Close stale issues and PRs' on: - schedule: - - cron: '31 23 * * *' + schedule: + - cron: '31 23 * * *' permissions: - issues: write - pull-requests: write + issues: write + pull-requests: write jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 - with: - # Don't stale issues - days-before-issue-stale: -1 - days-before-pr-stale: 23 - days-before-close: 7 - stale-pr-message: > - This PR is stale because it has been opened for more than 3 weeks with no activity. Comment or this will be closed in 7 days. - close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' - close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' - exempt-issue-labels: 'dependencies,wait for upstream' - exempt-pr-labels: 'dependencies,wait for upstream' - any-of-issue-labels: 'more data required' - lock: - runs-on: ubuntu-latest - steps: - - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1 - with: - github-token: ${{ github.token }} - process-only: 'prs' - pr-inactive-days: '30' - pr-comment: > - This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 + with: + # Don't stale issues + days-before-issue-stale: -1 + days-before-pr-stale: 23 + days-before-close: 7 + stale-pr-message: > + This PR is stale because it has been opened for more than 3 weeks with no activity. Comment or this will be closed in 7 days. + close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' + exempt-issue-labels: 'dependencies,wait for upstream' + exempt-pr-labels: 'dependencies,wait for upstream' + any-of-issue-labels: 'more data required' + lock: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1 + with: + github-token: ${{ github.token }} + process-only: 'prs' + pr-inactive-days: '30' + pr-comment: > + This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. diff --git a/.github/workflows/test-full-routes.yml b/.github/workflows/test-full-routes.yml index 88210b6c57..85b1f964b6 100644 --- a/.github/workflows/test-full-routes.yml +++ b/.github/workflows/test-full-routes.yml @@ -1,39 +1,39 @@ name: Build assets (Full Routes Test Result) on: - workflow_dispatch: - schedule: - - cron: '0 0 * * *' + workflow_dispatch: + schedule: + - cron: '0 0 * * *' jobs: - build: - runs-on: ubuntu-latest - name: Build assets - timeout-minutes: 120 - permissions: - contents: write - steps: - - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Install pnpm - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - name: Use Node.js Active LTS - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: lts/* - cache: 'pnpm' - - name: Install dependencies (yarn) - run: pnpm i - - name: Build assets - run: pnpm build - - name: Build full routes test result - continue-on-error: true - run: pnpm vitest:fullroutes - - name: Deploy - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./assets - user_name: 'github-actions[bot]' - user_email: '41898282+github-actions[bot]@users.noreply.github.com' - keep_files: true + build: + runs-on: ubuntu-latest + name: Build assets + timeout-minutes: 120 + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - name: Install pnpm + uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - name: Use Node.js Active LTS + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: lts/* + cache: 'pnpm' + - name: Install dependencies (yarn) + run: pnpm i + - name: Build assets + run: pnpm build + - name: Build full routes test result + continue-on-error: true + run: pnpm vitest:fullroutes + - name: Deploy + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./assets + user_name: 'github-actions[bot]' + user_email: '41898282+github-actions[bot]@users.noreply.github.com' + keep_files: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3003a2ee45..64c7c4bf03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,147 +1,147 @@ name: Test on: - push: - branches-ignore: - - 'dependabot/**' - paths: - - 'lib/**' - - 'package.json' - - 'pnpm-lock.yaml' - - '.github/workflows/test.yml' - pull_request: {} + push: + branches-ignore: + - 'dependabot/**' + paths: + - 'lib/**' + - 'package.json' + - 'pnpm-lock.yaml' + - '.github/workflows/test.yml' + pull_request: {} permissions: - checks: write + checks: write jobs: - vitest: - runs-on: ubuntu-latest - timeout-minutes: 10 - services: - redis: - image: redis - ports: - - 6379/tcp - options: --entrypoint redis-server - strategy: - fail-fast: false - matrix: - node-version: [ latest, lts/*, lts/-1 ] - name: Vitest on Node ${{ matrix.node-version }} - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - name: Install dependencies (pnpm) - run: pnpm i - - name: Run postinstall script for dependencies - run: pnpm rb && pnpx rebrowser-puppeteer browsers install chrome - - name: Build routes - run: pnpm build - - name: Test all and generate coverage - run: pnpm run vitest:coverage --reporter=github-actions - env: - REDIS_URL: redis://localhost:${{ job.services.redis.ports[6379] }}/ - - name: Upload coverage to Codecov - if: ${{ matrix.node-version == 'lts/*' }} - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos as documented, but seems broken + vitest: + runs-on: ubuntu-latest + timeout-minutes: 10 + services: + redis: + image: redis + ports: + - 6379/tcp + options: --entrypoint redis-server + strategy: + fail-fast: false + matrix: + node-version: [latest, lts/*, lts/-1] + name: Vitest on Node ${{ matrix.node-version }} + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - name: Install dependencies (pnpm) + run: pnpm i + - name: Run postinstall script for dependencies + run: pnpm rb && pnpx rebrowser-puppeteer browsers install chrome + - name: Build routes + run: pnpm build + - name: Test all and generate coverage + run: pnpm run vitest:coverage --reporter=github-actions + env: + REDIS_URL: redis://localhost:${{ job.services.redis.ports[6379] }}/ + - name: Upload coverage to Codecov + if: ${{ matrix.node-version == 'lts/*' }} + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos as documented, but seems broken - puppeteer: - runs-on: ubuntu-latest - timeout-minutes: 10 - strategy: - fail-fast: false - matrix: - node-version: [ latest, lts/*, lts/-1 ] - chromium: - - name: bundled Chromium - dependency: '' - environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "0" }' - - name: Chromium from Ubuntu - dependency: chromium-browser - environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "1" }' - - name: Chrome from Google - dependency: google-chrome-stable - environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "1" }' - name: Vitest puppeteer on Node ${{ matrix.node-version }} with ${{ matrix.chromium.name }} - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - name: Install dependencies (pnpm) - run: pnpm i - env: ${{ fromJSON(matrix.chromium.environment) }} - - name: Run postinstall script for dependencies - run: pnpm rb && pnpx rebrowser-puppeteer browsers install chrome - env: ${{ fromJSON(matrix.chromium.environment) }} - - name: Build routes - run: pnpm build - env: ${{ fromJSON(matrix.chromium.environment) }} - - name: Install Chromium - if: ${{ matrix.chromium.dependency != '' }} - # 'chromium-browser' from Ubuntu APT repo is a dummy package. Its version (85.0.4183.83) means - # nothing since it calls Snap (disgusting!) to install Chromium, which should be up-to-date. - # That's not really a problem since the Chromium-bundled Docker image is based on Debian bookworm, - # which provides up-to-date native packages. - run: | - set -eux - curl -s "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor | - sudo tee /etc/apt/trusted.gpg.d/google-chrome.gpg > /dev/null - echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" | - sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null - sudo apt-get update - sudo apt-get install -yq --no-install-recommends ${{ matrix.chromium.dependency }} - - name: Test puppeteer - run: | - set -eux - export CHROMIUM_EXECUTABLE_PATH="$(which ${{ matrix.chromium.dependency }})" - pnpm run vitest puppeteer - env: ${{ fromJSON(matrix.chromium.environment) }} + puppeteer: + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + node-version: [latest, lts/*, lts/-1] + chromium: + - name: bundled Chromium + dependency: '' + environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "0" }' + - name: Chromium from Ubuntu + dependency: chromium-browser + environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "1" }' + - name: Chrome from Google + dependency: google-chrome-stable + environment: '{ "PUPPETEER_SKIP_DOWNLOAD": "1" }' + name: Vitest puppeteer on Node ${{ matrix.node-version }} with ${{ matrix.chromium.name }} + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - name: Install dependencies (pnpm) + run: pnpm i + env: ${{ fromJSON(matrix.chromium.environment) }} + - name: Run postinstall script for dependencies + run: pnpm rb && pnpx rebrowser-puppeteer browsers install chrome + env: ${{ fromJSON(matrix.chromium.environment) }} + - name: Build routes + run: pnpm build + env: ${{ fromJSON(matrix.chromium.environment) }} + - name: Install Chromium + if: ${{ matrix.chromium.dependency != '' }} + # 'chromium-browser' from Ubuntu APT repo is a dummy package. Its version (85.0.4183.83) means + # nothing since it calls Snap (disgusting!) to install Chromium, which should be up-to-date. + # That's not really a problem since the Chromium-bundled Docker image is based on Debian bookworm, + # which provides up-to-date native packages. + run: | + set -eux + curl -s "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor | + sudo tee /etc/apt/trusted.gpg.d/google-chrome.gpg > /dev/null + echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" | + sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null + sudo apt-get update + sudo apt-get install -yq --no-install-recommends ${{ matrix.chromium.dependency }} + - name: Test puppeteer + run: | + set -eux + export CHROMIUM_EXECUTABLE_PATH="$(which ${{ matrix.chromium.dependency }})" + pnpm run vitest puppeteer + env: ${{ fromJSON(matrix.chromium.environment) }} - all: - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - attestations: write - strategy: - fail-fast: false - matrix: - node-version: [ 24, 22, 20 ] - name: Build radar and maintainer on Node ${{ matrix.node-version }} - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - - run: pnpm i - - name: Build radar and maintainer - run: npm run build - - name: Upload assets - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: generated-assets-${{ matrix.node-version }} - path: assets/build/ + all: + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + attestations: write + strategy: + fail-fast: false + matrix: + node-version: [24, 22, 20] + name: Build radar and maintainer on Node ${{ matrix.node-version }} + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - run: pnpm i + - name: Build radar and maintainer + run: npm run build + - name: Upload assets + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: generated-assets-${{ matrix.node-version }} + path: assets/build/ - automerge: - if: github.triggering_actor == 'dependabot[bot]' && github.event_name == 'pull_request' - needs: [ vitest, puppeteer, all ] - runs-on: ubuntu-latest - permissions: - pull-requests: write - contents: write - steps: - - uses: fastify/github-action-merge-dependabot@1b2ed42db8f9d81a46bac83adedfc03eb5149dff # v3.11.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - target: patch + automerge: + if: github.triggering_actor == 'dependabot[bot]' && github.event_name == 'pull_request' + needs: [vitest, puppeteer, all] + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + steps: + - uses: fastify/github-action-merge-dependabot@1b2ed42db8f9d81a46bac83adedfc03eb5149dff # v3.11.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + target: patch diff --git a/.prettierignore b/.prettierignore index 1edc3e478f..e732478230 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,5 @@ lib/routes-deprecated lib/router.js babel.config.js scripts/docker/minify-docker.js -dist \ No newline at end of file +dist +pnpm-lock.yaml diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e452526ecf..6c0244f8d4 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -10,22 +10,22 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div Examples of behavior that contributes to a positive environment for our community include: -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -- The use of sexualized language or imagery, and sexual attention or - advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email - address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting ## Enforcement Responsibilities diff --git a/README.md b/README.md index a6ac9ff027..a9a901146a 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ RSSHub delivers millions of contents aggregated from all kinds of sources, our v ## Related Projects -- [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) | A browser extension that can help you quickly discover and subscribe to the RSS and RSSHub of current websites. -- [RSSBud](https://github.com/Cay-Zhang/RSSBud) | RSSHub Radar for iOS platform, designed specifically for mobile ecosystem optimization. -- [RSSAid](https://github.com/LeetaoGoooo/RSSAid) | RSSHub Radar for Android platform built with Flutter. -- [DocSearch](https://github.com/Fatpandac/DocSearch) | Link RSSHub DocSearch into Raycast +- [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) | A browser extension that can help you quickly discover and subscribe to the RSS and RSSHub of current websites. +- [RSSBud](https://github.com/Cay-Zhang/RSSBud) | RSSHub Radar for iOS platform, designed specifically for mobile ecosystem optimization. +- [RSSAid](https://github.com/LeetaoGoooo/RSSAid) | RSSHub Radar for Android platform built with Flutter. +- [DocSearch](https://github.com/Fatpandac/DocSearch) | Link RSSHub DocSearch into Raycast ## Contribute @@ -50,6 +50,7 @@ Logo designer [sheldonrrr](https://dribbble.com/sheldonrrr) [![](https://raw.githubusercontent.com/DIYgod/sponsors/main/sponsors.simple.svg)](https://github.com/DIYgod/sponsors)                + ## Author diff --git a/eslint.config.mjs b/eslint.config.mjs index fa70ce26be..9839ce29b2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,7 +5,6 @@ import typescriptEslint from '@typescript-eslint/eslint-plugin'; import tsParser from '@typescript-eslint/parser'; import { importX } from 'eslint-plugin-import-x'; import n from 'eslint-plugin-n'; -import prettier from 'eslint-plugin-prettier'; import simpleImportSort from 'eslint-plugin-simple-import-sort'; import unicorn from 'eslint-plugin-unicorn'; import globals from 'globals'; @@ -30,12 +29,11 @@ export default [ { ignores: ['**/coverage', '**/.vscode', '**/docker-compose.yml', '!.github', 'assets/build', 'lib/routes-deprecated', 'lib/router.js', '**/babel.config.js', 'scripts/docker/minify-docker.js', 'dist', 'dist-lib'], }, - ...compat.extends('eslint:recommended', 'plugin:prettier/recommended', 'plugin:yml/recommended', 'plugin:@typescript-eslint/recommended'), + ...compat.extends('eslint:recommended', 'plugin:yml/recommended', 'plugin:@typescript-eslint/recommended'), n.configs['flat/recommended-script'], unicorn.configs.recommended, { plugins: { - prettier, '@stylistic': stylistic, '@typescript-eslint': typescriptEslint, }, @@ -254,6 +252,7 @@ export default [ 'unicorn/prevent-abbreviations': 'off', 'unicorn/switch-case-braces': ['error', 'avoid'], 'unicorn/text-encoding-identifier-case': 'off', + 'unicorn/number-literal-case': 'off', // formatting rules '@stylistic/arrow-parens': 'error', @@ -261,7 +260,7 @@ export default [ '@stylistic/comma-spacing': 'error', '@stylistic/comma-style': 'error', '@stylistic/function-call-spacing': 'error', - '@stylistic/keyword-spacing': 'error', + '@stylistic/keyword-spacing': 'off', '@stylistic/linebreak-style': 'error', '@stylistic/lines-around-comment': [ @@ -307,8 +306,6 @@ export default [ }, ], - 'prettier/prettier': 'off', - 'yml/quotes': [ 'error', { diff --git a/package.json b/package.json index d74d048709..a46925259a 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ "prepublishOnly": "npm run build:lib", "dev": "cross-env NODE_ENV=dev NODE_OPTIONS='--max-http-header-size=32768' tsx watch --inspect --clear-screen=false lib/index.ts", "dev:cache": "cross-env NODE_ENV=production NODE_OPTIONS='--max-http-header-size=32768' tsx watch --clear-screen=false lib/index.ts", - "format": "eslint --cache --fix \"**/*.{ts,tsx,js,yml}\" --concurrency auto && prettier \"**/*.{ts,tsx,js,json}\" --write --experimental-cli", - "format:check": "eslint --cache \"**/*.{ts,tsx,js,yml}\" --concurrency auto && prettier \"**/*.{ts,tsx,js,json}\" --check --experimental-cli", + "format": "eslint --cache --fix \"**/*.{ts,tsx,js,yml}\" --concurrency auto && prettier . --write --experimental-cli", + "format:check": "eslint --cache \"**/*.{ts,tsx,js,yml}\" --concurrency auto && prettier . --check --experimental-cli", "format:staged": "lint-staged", "lint": "eslint --cache . --concurrency auto", "prepare": "husky || true", @@ -48,15 +48,13 @@ "vitest:watch": "cross-env NODE_ENV=test vitest --watch" }, "lint-staged": { - "*.js": [ - "prettier --ignore-unknown --ignore-path ./.gitignore --write", - "eslint --cache --fix --concurrency auto" + "!(*.ts|*.tsx|*.js|*.yml)": [ + "prettier --write --ignore-unknown" ], - "*.{ts,tsx}": [ - "prettier --ignore-unknown --ignore-path ./.gitignore --write", - "eslint --cache --fix --concurrency auto" - ], - "*.yml": "eslint --cache --fix --concurrency auto" + "*.{ts,tsx,js,yml}": [ + "eslint --cache --fix --concurrency auto", + "prettier --write --ignore-unknown" + ] }, "dependencies": { "@bbob/html": "4.3.1", @@ -180,11 +178,9 @@ "discord-api-types": "0.38.34", "domhandler": "5.0.3", "eslint": "9.39.1", - "eslint-config-prettier": "10.1.8", "eslint-nibble": "9.1.1", "eslint-plugin-import-x": "4.16.1", "eslint-plugin-n": "17.23.1", - "eslint-plugin-prettier": "5.5.4", "eslint-plugin-simple-import-sort": "12.1.1", "eslint-plugin-unicorn": "62.0.0", "eslint-plugin-yml": "1.19.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0072780a5b..91ce878f6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -379,9 +379,6 @@ importers: eslint: specifier: 9.39.1 version: 9.39.1(jiti@2.6.1) - eslint-config-prettier: - specifier: 10.1.8 - version: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-nibble: specifier: 9.1.1 version: 9.1.1(@types/node@24.10.1)(eslint@9.39.1(jiti@2.6.1)) @@ -391,9 +388,6 @@ importers: eslint-plugin-n: specifier: 17.23.1 version: 17.23.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-prettier: - specifier: 5.5.4 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) eslint-plugin-simple-import-sort: specifier: 12.1.1 version: 12.1.1(eslint@9.39.1(jiti@2.6.1)) @@ -3575,12 +3569,6 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-config-prettier@10.1.8: - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - eslint-filtered-fix@0.3.0: resolution: {integrity: sha512-UMHOza9epEn9T+yVT8RiCFf0JdALpVzmoH62Ez/zvxM540IyUNAkr7aH2Frkv6zlm9a/gbmq/sc7C4SvzZQXcA==} hasBin: true @@ -3628,20 +3616,6 @@ packages: peerDependencies: eslint: '>=8.23.0' - eslint-plugin-prettier@5.5.4: - resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - eslint-plugin-simple-import-sort@12.1.1: resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} peerDependencies: @@ -3774,9 +3748,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -5159,10 +5130,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - prettier@3.6.2: resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} @@ -7990,7 +7957,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.2.9': {} + '@pkgr/core@0.2.9': + optional: true '@postlight/ci-failed-test-reporter@1.0.26': dependencies: @@ -9639,10 +9607,6 @@ snapshots: eslint: 9.39.1(jiti@2.6.1) semver: 7.7.3 - eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)): - dependencies: - eslint: 9.39.1(jiti@2.6.1) - eslint-filtered-fix@0.3.0(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -9708,16 +9672,6 @@ snapshots: transitivePeerDependencies: - typescript - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2): - dependencies: - eslint: 9.39.1(jiti@2.6.1) - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 - optionalDependencies: - '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -9949,8 +9903,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - fast-fifo@1.3.2: {} fast-json-stable-stringify@2.1.0: {} @@ -11511,10 +11463,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - prettier@3.6.2: {} process-warning@5.0.0: {} @@ -12110,6 +12058,7 @@ snapshots: synckit@0.11.11: dependencies: '@pkgr/core': 0.2.9 + optional: true system-architecture@0.1.0: {} diff --git a/scripts/ansible/rsshub.yaml b/scripts/ansible/rsshub.yaml index 84c69c1f7e..bfe6944df1 100644 --- a/scripts/ansible/rsshub.yaml +++ b/scripts/ansible/rsshub.yaml @@ -2,109 +2,109 @@ hosts: localhost become: true vars_prompt: - - name: domain_name - prompt: What is the domain name (without www, e.g. rsshub.example.com)? Use "http://localhost" for development in Vagrant VM. - private: no + - name: domain_name + prompt: What is the domain name (without www, e.g. rsshub.example.com)? Use "http://localhost" for development in Vagrant VM. + private: no tasks: - - name: Check OS - fail: - msg: This playbook can only be run on Ubuntu 20.04 at this moment - when: ansible_distribution != 'Ubuntu' or ansible_distribution_version !='20.04' - - name: Install GPG keys for repos - apt_key: - url: '{{ item }}' - state: present - with_items: - - https://deb.nodesource.com/gpgkey/nodesource.gpg.key - - https://download.docker.com/linux/ubuntu/gpg - - https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key - - name: Install repos - apt_repository: - repo: '{{ item }}' - state: present - update_cache: yes - with_items: - - deb https://deb.nodesource.com/node_12.x focal main - - deb https://download.docker.com/linux/ubuntu focal stable - - deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main - - name: Install prerequisites - apt: - name: - - nodejs - - build-essential - - python-is-python2 - - redis-server - - docker-ce - - python3-pip - - virtualenv - - python3-setuptools - - caddy - state: present - update_cache: yes - - name: Install python module for docker - pip: - name: docker - - name: Pull docker image for browserless - docker_image: - name: browserless/chrome - source: pull - - name: Start redis - systemd: - state: restarted - enabled: yes - name: redis - daemon_reload: yes - - name: Copy caddy configuration - template: - src: rsshub.Caddyfile - dest: /etc/caddy/Caddyfile - - name: Start caddy - systemd: - state: restarted - enabled: yes - name: caddy - daemon_reload: yes - - name: Create and start browserless container - docker_container: - name: browserless - image: browserless/chrome - state: started - restart_policy: always - published_ports: - - '3000:3000' - - name: Create the user - user: - name: rsshub - create_home: true - shell: /bin/bash - - name: Clone the repo - git: - repo: https://github.com/DIYgod/RSSHub.git - dest: /home/rsshub/app - update: yes - - name: Install repo dependencies - command: yarn install --production - args: - chdir: /home/rsshub/app - environment: - PUPPETEER_SKIP_DOWNLOAD: true - - name: Copy configuration - copy: - src: rsshub.env - dest: /home/rsshub/app/.env - - name: Own repo to the user - file: - path: /home/rsshub/app - owner: rsshub - group: rsshub - recurse: yes - - name: Install the systemd unit - copy: - src: rsshub.service - dest: /etc/systemd/system/rsshub.service - - name: Start the systemd service - systemd: - state: restarted - enabled: yes - name: rsshub - daemon_reload: yes + - name: Check OS + fail: + msg: This playbook can only be run on Ubuntu 20.04 at this moment + when: ansible_distribution != 'Ubuntu' or ansible_distribution_version !='20.04' + - name: Install GPG keys for repos + apt_key: + url: '{{ item }}' + state: present + with_items: + - https://deb.nodesource.com/gpgkey/nodesource.gpg.key + - https://download.docker.com/linux/ubuntu/gpg + - https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key + - name: Install repos + apt_repository: + repo: '{{ item }}' + state: present + update_cache: yes + with_items: + - deb https://deb.nodesource.com/node_12.x focal main + - deb https://download.docker.com/linux/ubuntu focal stable + - deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main + - name: Install prerequisites + apt: + name: + - nodejs + - build-essential + - python-is-python2 + - redis-server + - docker-ce + - python3-pip + - virtualenv + - python3-setuptools + - caddy + state: present + update_cache: yes + - name: Install python module for docker + pip: + name: docker + - name: Pull docker image for browserless + docker_image: + name: browserless/chrome + source: pull + - name: Start redis + systemd: + state: restarted + enabled: yes + name: redis + daemon_reload: yes + - name: Copy caddy configuration + template: + src: rsshub.Caddyfile + dest: /etc/caddy/Caddyfile + - name: Start caddy + systemd: + state: restarted + enabled: yes + name: caddy + daemon_reload: yes + - name: Create and start browserless container + docker_container: + name: browserless + image: browserless/chrome + state: started + restart_policy: always + published_ports: + - '3000:3000' + - name: Create the user + user: + name: rsshub + create_home: true + shell: /bin/bash + - name: Clone the repo + git: + repo: https://github.com/DIYgod/RSSHub.git + dest: /home/rsshub/app + update: yes + - name: Install repo dependencies + command: yarn install --production + args: + chdir: /home/rsshub/app + environment: + PUPPETEER_SKIP_DOWNLOAD: true + - name: Copy configuration + copy: + src: rsshub.env + dest: /home/rsshub/app/.env + - name: Own repo to the user + file: + path: /home/rsshub/app + owner: rsshub + group: rsshub + recurse: yes + - name: Install the systemd unit + copy: + src: rsshub.service + dest: /etc/systemd/system/rsshub.service + - name: Start the systemd service + systemd: + state: restarted + enabled: yes + name: rsshub + daemon_reload: yes