diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 00000000..c1066884 --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,41 @@ +{ + "extends": ["@commitlint/config-conventional"], + "rules": { + "type-enum": [ + 2, + "always", + [ + "feat", + "fix", + "docs", + "style", + "refactor", + "perf", + "test", + "build", + "ci", + "chore", + "revert" + ] + ], + "scope-enum": [ + 2, + "always", + [ + "core", + "math", + "network-client", + "network-server", + "network-shared", + "editor", + "docs", + "ci", + "deps" + ] + ], + "scope-empty": [1, "never"], + "subject-empty": [2, "never"], + "subject-case": [0], + "header-max-length": [2, "always", 100] + } +} diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 00000000..0a4b9e74 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,95 @@ +# GitHub Labels 配置 +# 可以使用 https://github.com/Financial-Times/github-label-sync 来同步标签 + +# Size Labels (PR 大小) +- name: 'size/XS' + color: '00ff00' + description: '极小的改动 (< 10 行)' + +- name: 'size/S' + color: '00ff00' + description: '小改动 (10-100 行)' + +- name: 'size/M' + color: 'ffff00' + description: '中等改动 (100-500 行)' + +- name: 'size/L' + color: 'ff9900' + description: '大改动 (500-1000 行)' + +- name: 'size/XL' + color: 'ff0000' + description: '超大改动 (> 1000 行)' + +# Type Labels +- name: 'bug' + color: 'd73a4a' + description: '错误或问题' + +- name: 'enhancement' + color: 'a2eeef' + description: '新功能或改进' + +- name: 'documentation' + color: '0075ca' + description: '文档相关' + +- name: 'question' + color: 'd876e3' + description: '问题咨询' + +- name: 'performance' + color: 'ff6b6b' + description: '性能相关' + +# Scope Labels +- name: 'core' + color: '5319e7' + description: '核心包相关' + +- name: 'editor' + color: '5319e7' + description: '编辑器相关' + +- name: 'network' + color: '5319e7' + description: '网络相关' + +# Status Labels +- name: 'stale' + color: 'ededed' + description: '长时间无活动' + +- name: 'wip' + color: 'fbca04' + description: '进行中' + +- name: 'help wanted' + color: '008672' + description: '需要帮助' + +- name: 'good first issue' + color: '7057ff' + description: '适合新手' + +- name: 'quick-review' + color: '00ff00' + description: '小改动,快速 Review' + +- name: 'automerge' + color: 'bfdadc' + description: '自动合并' + +- name: 'pinned' + color: 'c2e0c6' + description: '置顶,不会被标记为 stale' + +- name: 'security' + color: 'ee0701' + description: '安全相关,高优先级' + +# Dependencies +- name: 'dependencies' + color: '0366d6' + description: '依赖更新' diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 00000000..a7e8bfb2 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,31 @@ +name: Commit Lint + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: read + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'npm' + + - name: Install commitlint + run: | + npm install --save-dev @commitlint/config-conventional @commitlint/cli + + - name: Validate PR commits + run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose diff --git a/.github/workflows/pr-size-labeler.yml b/.github/workflows/pr-size-labeler.yml new file mode 100644 index 00000000..11fa1feb --- /dev/null +++ b/.github/workflows/pr-size-labeler.yml @@ -0,0 +1,31 @@ +name: PR Size Labeler + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + size-label: + runs-on: ubuntu-latest + steps: + - name: Label PR by size + uses: codelytv/pr-size-labeler@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + xs_label: 'size/XS' + xs_max_size: '10' + s_label: 'size/S' + s_max_size: '100' + m_label: 'size/M' + m_max_size: '500' + l_label: 'size/L' + l_max_size: '1000' + xl_label: 'size/XL' + message_if_xl: | + 这个 PR 改动较大(超过 1000 行),建议拆分成多个小 PR 以便 Review。 + + This PR is quite large (over 1000 lines). Consider splitting it into smaller PRs for easier review. diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml new file mode 100644 index 00000000..e53d4d85 --- /dev/null +++ b/.github/workflows/size-limit.yml @@ -0,0 +1,43 @@ +name: Size Limit + +on: + pull_request: + branches: + - master + - main + paths: + - 'packages/core/src/**' + - 'packages/core/package.json' + - '.size-limit.json' + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + size: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build core package + run: | + cd packages/core + npm run build:npm + + - name: Check bundle size + uses: andresz1/size-limit-action@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + skip_step: install diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..1feaeff0 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,60 @@ +name: Stale Issues and PRs + +on: + schedule: + - cron: '0 0 * * *' # 每天运行一次 + workflow_dispatch: # 允许手动触发 + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - name: Stale Bot + uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + # Issue 配置 + stale-issue-message: | + 这个 issue 已经 60 天没有活动了,将在 14 天后自动关闭。 + 如果这个问题仍然存在,请留言说明情况。 + + This issue has been inactive for 60 days and will be closed in 14 days. + If this issue is still relevant, please leave a comment. + close-issue-message: | + 由于长时间无活动,这个 issue 已被自动关闭。 + 如需重新打开,请留言说明。 + + This issue has been automatically closed due to inactivity. + Please comment if you'd like to reopen it. + days-before-issue-stale: 60 + days-before-issue-close: 14 + stale-issue-label: 'stale' + exempt-issue-labels: 'pinned,security,enhancement,help wanted' + + # PR 配置 + stale-pr-message: | + 这个 PR 已经 30 天没有活动了,将在 7 天后自动关闭。 + 如果你还在处理这个 PR,请更新一下。 + + This PR has been inactive for 30 days and will be closed in 7 days. + If you're still working on it, please update it. + close-pr-message: | + 由于长时间无活动,这个 PR 已被自动关闭。 + 如需继续,请重新打开或创建新的 PR。 + + This PR has been automatically closed due to inactivity. + Please reopen or create a new PR to continue. + days-before-pr-stale: 30 + days-before-pr-close: 7 + stale-pr-label: 'stale' + exempt-pr-labels: 'pinned,security,wip' + + # 其他配置 + operations-per-run: 100 + remove-stale-when-updated: true + ascending: true diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 00000000..7c4fabf9 --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,58 @@ +name: Welcome + +on: + issues: + types: [opened] + pull_request_target: + types: [opened] + +permissions: + issues: write + pull-requests: write + +jobs: + welcome: + runs-on: ubuntu-latest + steps: + - name: Welcome new contributors + uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: | + 👋 你好!感谢你提交第一个 issue! + + 我们会尽快查看并回复。同时,建议你: + - 📚 查看[文档](https://esengine.github.io/ecs-framework/) + - 🤖 使用 [AI 文档助手](https://deepwiki.com/esengine/ecs-framework) + - 💬 加入 [QQ 交流群](https://jq.qq.com/?_wv=1027&k=29w1Nud6) + + --- + + 👋 Hello! Thanks for opening your first issue! + + We'll review it as soon as possible. Meanwhile, you might want to: + - 📚 Check the [documentation](https://esengine.github.io/ecs-framework/) + - 🤖 Use [AI documentation assistant](https://deepwiki.com/esengine/ecs-framework) + + pr-message: | + 👋 你好!感谢你提交第一个 Pull Request! + + 在我们 Review 之前,请确保: + - ✅ 代码遵循项目规范 + - ✅ 通过所有测试 + - ✅ 更新了相关文档 + - ✅ Commit 遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范 + + 查看完整的[贡献指南](https://github.com/esengine/ecs-framework/blob/master/CONTRIBUTING.md)。 + + --- + + 👋 Hello! Thanks for your first Pull Request! + + Before we review, please ensure: + - ✅ Code follows project conventions + - ✅ All tests pass + - ✅ Documentation is updated + - ✅ Commits follow [Conventional Commits](https://www.conventionalcommits.org/) + + See the full [Contributing Guide](https://github.com/esengine/ecs-framework/blob/master/CONTRIBUTING.md). diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 00000000..c8740485 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,84 @@ +queue_rules: + - name: default + conditions: + - check-success=CI + - check-success=Commit Lint + +pull_request_rules: + # 自动合并 Dependabot 的 patch 版本更新 + - name: 自动合并 Dependabot patch 更新 + conditions: + - author=dependabot[bot] + - check-success=CI + - check-success=Commit Lint + - title~=^build\(deps\): bump .* from .* to .* + - files~=^package-lock\.json$ + actions: + review: + type: APPROVE + message: 自动批准 Dependabot 的 patch 更新 + queue: + name: default + method: squash + commit_message_template: | + {{ title }} (#{{ number }}) + + {{ body }} + + # 自动合并有 'automerge' 标签且测试通过的 PR + - name: 自动合并标记的 PR + conditions: + - label=automerge + - check-success=CI + - check-success=Commit Lint + - "#approved-reviews-by>=1" + - "#changes-requested-reviews-by=0" + actions: + queue: + name: default + method: squash + + # 自动给小 PR 添加标签 + - name: 标记小 PR 方便快速 Review + conditions: + - files<=3 + - lines<=50 + actions: + label: + add: + - quick-review + + # 提醒大 PR 需要拆分 + - name: 提醒大 PR + conditions: + - lines>1000 + actions: + comment: + message: | + ⚠️ 这个 PR 改动超过 1000 行,建议拆分成多个小 PR,便于 Review 和测试。 + + ⚠️ This PR has over 1000 lines changed. Consider splitting it into smaller PRs for easier review and testing. + + # 自动更新过期的分支 + - name: 自动更新过期分支 + conditions: + - -draft + - -closed + - base=master + - "#approved-reviews-by>=1" + actions: + update: + method: rebase + + # 感谢首次贡献者 + - name: 感谢新贡献者 + conditions: + - author!=dependabot[bot] + - author!=dependabot-preview[bot] + - "#commits-behind=0" + actions: + comment: + message: | + 🎉 感谢你的贡献!我们会尽快 Review。 + + 🎉 Thanks for your contribution! We'll review it soon. diff --git a/.size-limit.json b/.size-limit.json new file mode 100644 index 00000000..dd0b8c5e --- /dev/null +++ b/.size-limit.json @@ -0,0 +1,25 @@ +[ + { + "name": "@esengine/ecs-framework (ESM)", + "path": "packages/core/dist/esm/index.js", + "import": "*", + "limit": "50 KB", + "webpack": false, + "gzip": true + }, + { + "name": "@esengine/ecs-framework (UMD)", + "path": "packages/core/dist/umd/ecs-framework.js", + "limit": "60 KB", + "webpack": false, + "gzip": true + }, + { + "name": "Core Runtime (Tree-shaking)", + "path": "packages/core/dist/esm/index.js", + "import": "{ Core, Scene, Entity, Component }", + "limit": "30 KB", + "webpack": false, + "gzip": true + } +] diff --git a/package.json b/package.json index 13e6dc18..2af582a3 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,8 @@ "author": "yhh", "license": "MIT", "devDependencies": { + "@commitlint/cli": "^18.6.0", + "@commitlint/config-conventional": "^18.6.0", "@iconify/json": "^2.2.388", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-node-resolve": "^16.0.1", @@ -79,6 +81,7 @@ "@semantic-release/github": "^9.2.6", "@semantic-release/npm": "^11.0.2", "@semantic-release/release-notes-generator": "^12.1.0", + "@size-limit/preset-small-lib": "^11.0.2", "@types/jest": "^29.5.14", "@types/node": "^20.19.0", "@typescript-eslint/eslint-plugin": "^8.46.1", @@ -95,6 +98,7 @@ "semantic-release": "^23.0.0", "semantic-release-monorepo": "^8.0.2", "semver": "^7.6.3", + "size-limit": "^11.0.2", "ts-jest": "^29.4.0", "typedoc": "^0.28.13", "typedoc-plugin-markdown": "^4.9.0",