diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..1303475 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,81 @@ +name: 🐛 Bug Report / 报告问题 +description: Report a bug / 报告问题 + +body: + + - type: textarea + id: description + attributes: + label: Description / 问题描述 + description: | + Describe what happened. + 描述发生的问题。 + validations: + required: true + + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce / 复现步骤 + description: | + Describe how to reproduce the issue. + 描述如何复现问题。 + placeholder: | + 1. Add card... + 2. Configure card... + 3. See error... + + + - type: input + id: ha_version + attributes: + label: Home Assistant Version / Home Assistant 版本 + description: | + Settings → About + 设置 → 关于 Home Assistant + placeholder: "2026.3.0" + validations: + required: true + + + - type: input + id: card_version + attributes: + label: Card Version / 卡片版本 + description: | + Card version from installed resource. + 已安装资源中的卡片版本。 + placeholder: "1.0.0" + validations: + required: true + + + - type: textarea + id: additional + attributes: + label: Additional Information / 其他说明 + description: | + Provide any additional information, including: + - Card YAML configuration + - Screenshots + - Browser console logs + - Other useful details + + 请提供其他相关信息,包括: + - 卡片 YAML 配置 + - 截图 + - 浏览器控制台日志 + - 其他有帮助的信息 + + placeholder: | + Card YAML: + + ```yaml + type: custom:example-card + entity: sensor.example + ``` + + Screenshots / Logs: + Paste screenshots or logs here. + 请在此处粘贴截图或日志。 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..50ab278 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,35 @@ +name: ✨ Feature Request / 功能建议 +description: Suggest an idea or improvement / 提出功能建议 +title: "feat: " +labels: + - "enhancement" + +body: + + - type: textarea + id: description + attributes: + label: Description / 功能描述 + description: | + Describe your idea. + 描述你的需求。 + validations: + required: true + + + - type: textarea + id: use_case + attributes: + label: Use case / 使用场景 + description: | + Why is this useful? + 为什么需要这个功能? + + + - type: textarea + id: additional + attributes: + label: Additional information / 补充信息 + description: | + Add screenshots or examples if available. + 如有截图或示例,请提供。 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..62c1d27 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,59 @@ +## Description / 变更描述 + + + + +## Type of change / 变更类型 + +- [ ] bugfix: Bug fix / 问题修复 +- [ ] new feature: New feature / 新功能 +- [ ] refactor: Code refactoring / 重构 +- [ ] breaking: Breaking change / 破坏性变更 +- [ ] docs: Documentation / 文档更新 + +## Testing / 测试 + + + +- HA Version / HA版本: +- Integration Version / 集成版本: +- Test Result / 测试结果: + +## Checklist / 自检清单 + +- [ ] Code follows project standards / 代码符合项目规范 +- [ ] No debug code or unrelated files / 无调试代码或无关文件 + + diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..7eca412 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,63 @@ +# ============================ +# Default GitHub Labels (with Chinese translation) +# ============================ + +- name: bug + color: d73a4a + description: Something isn't working / 出现了问题或功能异常 + +- name: documentation + color: 0075ca + description: Improvements or additions to documentation / 文档改进或补充 + +- name: duplicate + color: cfd3d7 + description: This issue or pull request already exists / 重复的问题或拉取请求 + +- name: enhancement + color: a2eeef + description: New feature or request / 新功能或改进请求 + +- name: good first issue + color: 7057ff + description: Good for newcomers / 适合新贡献者的简单问题 + +- name: help wanted + color: 008672 + description: Extra attention is needed / 需要额外帮助或关注 + +- name: invalid + color: e4e669 + description: This doesn't seem right / 无效或不符合要求的问题 + +- name: question + color: d876e3 + description: Further information is requested / 需要进一步信息或澄清 + +- name: wontfix + color: ffffff + description: This will not be worked on / 不会处理或修复的问题 + +# ============================ +# Custom Labels (Your Labels) +# ============================ + +- name: 🐛 Bug Fix + color: d73a4a + description: Bug fixes and issue corrections / 修复问题和错误 + +- name: ✨ Feature + color: a2eeef + description: New features and functionality improvements / 新功能和功能增强 + +- name: 🔧 Refactor + color: fbca04 + description: Code refactoring and internal improvements / 代码重构和内部优化 + +- name: ⚠️ Breaking + color: b60205 + description: Breaking changes that may affect existing behavior / 可能影响现有行为的破坏性变更 + +- name: 📝 Docs + color: 0075ca + description: Documentation updates and improvements / 文档更新和改进 diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..f83a62e --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,25 @@ +changelog: + categories: + - title: "✨ Features / 新功能" + labels: + - "✨ Feature" + + - title: "🐛 Bug Fixes / 问题修复" + labels: + - "🐛 Bug Fix" + + - title: "🔧 Refactor / 重构" + labels: + - "🔧 Refactor" + + - title: "📝 Documentation / 文档" + labels: + - "📝 Docs" + + - title: "⚠️ Breaking Changes / 破坏性变更" + labels: + - "⚠️ Breaking" + + - title: "Other Changes / 其他" + labels: + - "*" diff --git a/.github/workflows/pr-label.yml b/.github/workflows/pr-label.yml new file mode 100644 index 0000000..70e6905 --- /dev/null +++ b/.github/workflows/pr-label.yml @@ -0,0 +1,113 @@ +name: Auto Label PR Type + +on: + pull_request: + types: [opened, edited, synchronize] + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + label: + runs-on: ubuntu-latest + + steps: + - name: Detect change type and sync label + env: + PR_BODY: ${{ github.event.pull_request.body }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + shell: bash + run: | + + echo "Checking change type" + + + PR_TYPE=$(echo "$PR_BODY" \ + | grep -E '\[x\].*(bugfix|new feature|refactor|breaking|docs):' \ + | sed -E 's/.*\] ([^:]+):.*/\1/') + + + if [[ -z "$PR_TYPE" ]]; then + echo "❌ No change type selected" + exit 1 + fi + + + echo "Detected type: $PR_TYPE" + + + case "$PR_TYPE" in + bugfix) + LABEL="🐛 Bug Fix" + ;; + "new feature") + LABEL="✨ Feature" + ;; + refactor) + LABEL="🔧 Refactor" + ;; + breaking) + LABEL="⚠️ Breaking" + ;; + docs) + LABEL="📝 Docs" + ;; + *) + echo "❌ Invalid type: $PR_TYPE" + exit 1 + ;; + esac + + + echo "Target label: $LABEL" + + + CURRENT_LABELS=$(gh pr view "$PR_NUMBER" \ + --repo "$REPO" \ + --json labels \ + -q '.labels[].name') + + + if echo "$CURRENT_LABELS" | grep -Fxq "$LABEL"; then + echo "✅ Label already exists: $LABEL" + exit 0 + fi + + + echo "Updating labels" + + + OLD_LABELS=( + "🐛 Bug Fix" + "✨ Feature" + "🔧 Refactor" + "⚠️ Breaking" + "📝 Docs" + ) + + + for OLD_LABEL in "${OLD_LABELS[@]}"; do + if echo "$CURRENT_LABELS" | grep -Fxq "$OLD_LABEL"; then + echo "Removing old label: $OLD_LABEL" + + gh pr edit "$PR_NUMBER" \ + --repo "$REPO" \ + --remove-label "$OLD_LABEL" + fi + done + + + echo "Adding label: $LABEL" + + + gh pr edit "$PR_NUMBER" \ + --repo "$REPO" \ + --add-label "$LABEL" + + + echo "✅ Label updated: $LABEL" diff --git a/.github/workflows/pr-validate.yml b/.github/workflows/pr-validate.yml new file mode 100644 index 0000000..1039cb9 --- /dev/null +++ b/.github/workflows/pr-validate.yml @@ -0,0 +1,97 @@ +name: Validate PR + +on: + pull_request: + types: [opened, edited, synchronize] + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + + # Validate PR title + - name: Validate PR title + env: + PR_TITLE: ${{ github.event.pull_request.title }} + shell: bash + run: | + echo "Checking PR title" + + if [[ -z "$PR_TITLE" ]]; then + echo "❌ PR title is empty" + exit 1 + fi + + # 如果包含冒号,则要求格式为 : + if [[ "$PR_TITLE" == *:* ]]; then + if [[ ! "$PR_TITLE" =~ ^[^:]+:[[:space:]]*.+ ]]; then + echo "❌ Invalid PR title format" + echo "Format: : " + exit 1 + fi + fi + + echo "✅ PR title passed" + + # Validate PR body + - name: Validate PR content + env: + PR_BODY: ${{ github.event.pull_request.body }} + shell: bash + run: | + echo "Checking PR content" + + if [[ -z "$PR_BODY" ]]; then + echo "❌ PR body is empty" + exit 1 + fi + + # Description check + DESCRIPTION=$(echo "$PR_BODY" \ + | sed '//d' \ + | awk ' + /^## Description/ {flag=1; next} + /^## / {flag=0} + flag + ' \ + | sed '/^[[:space:]]*$/d') + + if [[ -z "$DESCRIPTION" ]]; then + echo "❌ Description is empty" + exit 1 + fi + + echo "✅ Description passed" + + # Change type check + TYPE_COUNT=$(echo "$PR_BODY" \ + | grep -Ec '\[x\].*(bugfix|new feature|refactor|breaking|docs):') + + + if [[ "$TYPE_COUNT" -ne 1 ]]; then + echo "❌ Select exactly one change type" + exit 1 + fi + + PR_TYPE=$(echo "$PR_BODY" \ + | grep -E '\[x\].*(bugfix|new feature|refactor|breaking|docs):' \ + | sed -E 's/.*\] ([^:]+):.*/\1/') + + echo "✅ Change type: $PR_TYPE" + + # Validate branch + - name: Validate branch + env: + BRANCH: ${{ github.event.pull_request.head.ref }} + shell: bash + run: | + echo "Checking branch: $BRANCH" + + if [[ "$BRANCH" == "main" || + "$BRANCH" == "master" ]]; then + echo "❌ Direct PR from main/master is forbidden" + exit 1 + fi + + echo "✅ Branch passed" diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml new file mode 100644 index 0000000..fcb01fb --- /dev/null +++ b/.github/workflows/sync-labels.yml @@ -0,0 +1,22 @@ +name: Sync GitHub Labels + +on: + workflow_dispatch: + +permissions: + contents: write + issues: write + +jobs: + sync-labels: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Sync Labels + uses: crazy-max/ghaction-github-labeler@v5 + with: + yaml-file: .github/labels.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}