This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-7427-e30eb17518dec86b522a2715f6b73c431ed39097 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 114a6100b53c1191a77b23b9b11221fd6607fef1 Author: Yicong Huang <[email protected]> AuthorDate: Sun Aug 9 09:40:04 2026 -0700 docs: define how to pick a PR title's type and scope (#7427) ### What changes were proposed in this PR? `CONTRIBUTING.md` requires Conventional Commits but never says how to pick the type or scope, so recurring cases get decided ad hoc. This writes the convention down: - **Scope** names the module the change lands in (`amber`, `pyamber`, `frontend`, …), not an informal synonym; a cross-module PR is scoped to the module carrying the substantive change. - **Type follows the behavior**, not the diff size: - worked before, broken now → `fix` - adding or removing a functionality, or reworking one so that user-facing behavior intentionally changes → `feat` - leaves the user-facing behavior unchanged → `refactor` A `refactor` keeps user-facing API tests passing untouched; tests mirroring internals may be rewritten with the code. Behavior is defined by the code, so implementing something the docs claimed but never had is a `feat`. - **Tests**: a test-only PR is `test(<module>)`; repairing a broken or flaky test is `fix(test, <module>)`. - **Dependencies**: `fix(deps, <module>)` when the bump patches a CVE, `chore(deps, <module>)` otherwise. GitHub Actions bumps take `ci` as their module (`chore(deps, ci)`); a bare `ci:` is for hand-written CI and workflow changes. - **Backports**: a release-branch PR appends the version as the last scope component, e.g. `fix(deps, frontend, v1.2): ...`. On dependency bumps this documents what the automation already does rather than changing it: `.github/renovate.json5` types every routine bump as `chore(...)` and reserves `fix(...)` for `vulnerabilityAlerts`, and it opens GitHub Actions bumps as `chore(deps, ci)` where the docs said `ci:`. The old runtime-vs-toolchain wording governed only hand-written titles and disagreed with the bot on both counts; the docs now follow it. ### Any related issues, documentation, discussions? Closes #7393 ### How was this PR tested? - Documentation only — no code path changes. - Verified the new title forms pass the CI type gate and the review-time title check, both on `main` and with a version scope on `release/v1.2`. - Cross-checked every rule against the automation that consumes titles: `.github/renovate.json5`, `backport-auto-label.yml`, and `direct-backport-push.yml`'s title rewriter, which already emits the documented backport form. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 5) --------- Signed-off-by: Yicong Huang <[email protected]> Co-authored-by: Claude Opus 5 (1M context) <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]> --- .github/PULL_REQUEST_TEMPLATE | 16 ++++++++-- AGENTS.md | 54 +++++++++++++++++++++++++++------- CONTRIBUTING.md | 39 ++++++++++++++++++++++-- docs/contribution-guidelines/_index.md | 31 ++++++++++++++++++- 4 files changed, 125 insertions(+), 15 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE index 41287564ff..10248925cb 100644 --- a/.github/PULL_REQUEST_TEMPLATE +++ b/.github/PULL_REQUEST_TEMPLATE @@ -4,8 +4,20 @@ Thanks for sending a pull request (PR)! Here are some tips for you: [Contributing to Texera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md) 2. Ensure you have added or run the appropriate tests for your PR 3. If the PR is work in progress, mark it a draft on GitHub. - 4. Please write your PR title to summarize what this PR proposes, we - are following Conventional Commits style for PR titles as well. + 4. Please write your PR title to summarize what this PR proposes, we + are following Conventional Commits style for PR titles as well: + - `fix` is for behavior that worked before and no longer does; adding or + removing a functionality, or reworking one so that user-facing behavior + intentionally changes, is a `feat`; a change that leaves the user-facing + behavior unchanged is a `refactor`. + - A test-only PR is `test(<module>): ...`; repairing a broken test is + `fix(test, <module>): ...`. + - A dependency bump is `fix(deps, <module>): ...` when it patches a CVE + and `chore(deps, <module>): ...` otherwise; GitHub Actions bumps take + `ci` as their module, e.g. `chore(deps, ci): ...`. + - A PR targeting a release branch appends the version as the last scope + component, e.g. `fix(deps, frontend, v1.2): ...`. + See CONTRIBUTING.md for the full convention. 5. Be sure to keep the PR description updated to reflect all changes. --> diff --git a/AGENTS.md b/AGENTS.md index 7118073a78..c94002c86a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -138,18 +138,52 @@ Short, **Conventional Commits**, same shape for branch and commit subject. | Feature | `feat/agent-workflow-edit` | `feat(agent-service): enable workflow edit` | | Bug fix | `fix/marker-replay` | `fix(amber): marker replay during reconfiguration` | | Tests | `test/pyamber-handlers` | `test(pyamber): add handler unit tests` | -| Chore | `chore/angular-21` | `chore(deps): upgrade frontend to Angular 21` | -| CI | `ci/cache-action-bump` | `ci: bump coursier/cache-action to v8.1.0` | +| Chore | `chore/angular-21` | `chore(deps, frontend): upgrade to Angular 21` | +| CI | `ci/merge-queue-stacking` | `ci: stack merge-queue builds by module` | Both ≤ ~60 chars. For code changes, if you use a scope, use the module name (`amber`, `pyamber`, `frontend`, `agent-service`, `file-service`, …) — not -`amber-python`. Dependency-only updates split by semantics: `fix(deps): ...` for -runtime/production dependency bumps (they ship to users), -`chore(deps): ...` for dev/toolchain-only bumps, and `ci: ...` for -CI-only changes (including GitHub Actions bumps). Append the module -as a second scope when the bump is module-specific, e.g. -`fix(deps, pyamber): ...`; omit it for cross-module bumps (sbt). No `Co-authored-by:` trailer for the repo -owner. +`amber-python`. No `Co-authored-by:` trailer for the repo owner. + +**Choosing the type** turns on what happens to the behavior, not on how big +the diff is: + +| The change | Type | +| --- | --- | +| Worked before, broken now | `fix` | +| Support never existed; adding it | `feat` | +| Support exists; removing it | `feat` | +| Reworked so user-facing behavior intentionally changes | `feat` | +| User-facing behavior unchanged | `refactor` | + +Behavior is what the code does, not what a doc or an old PR description claims +it does: implementing something that was never actually there is a `feat`. + +`refactor` claims the **user-facing** behavior is identical. Tests that pin a +user-facing API must pass untouched — editing one of those assertions means +the behavior moved, so it is a `feat` or a `fix`. Tests that pin internals (a +private helper's signature, call order between collaborators, the shape of an +intermediate value) mirror the implementation, so rewriting them alongside the +code they mirror is still a `refactor`. + +**Tests.** A test-only PR is `test(<module>): ...`. Repairing a broken or +flaky test is a bug fix in test code: `fix(test, <module>): ...`. + +**Dependencies.** `fix` only when the bump carries a security fix: + +| Bump | Commit | +| --- | --- | +| Patches a CVE | `fix(deps, <module>): ...` | +| Everything else | `chore(deps, <module>): ...` | +| GitHub Actions | `chore(deps, ci): ...` | + +Omit the module for cross-module bumps (sbt). GitHub Actions bumps take `ci` +as their module — that is what [`.github/renovate.json5`](.github/renovate.json5) +opens them with; a bare `ci: ...` is for hand-written CI and workflow changes. + +**Backports.** A PR targeting `release/vX.Y` appends the version as the last +scope component — `fix(deps, frontend, v1.2): ...`. Version tags belong only +on release-branch PRs, never on one targeting `main`. ### Issues and PRs @@ -193,7 +227,7 @@ write/adjust test (red) -> edit source (green) -> refactor | New feature / behavior change | Failing test, then implement. | | Bug fix | Regression test reproducing the bug, then fix. | | Code with **no tests** | **Characterization tests** pin current behavior first; only then change source. | -| Refactor (no behavior change) | Tests stay green throughout — no assertion edits. | +| Refactor (no user-facing behavior change) | Tests stay green throughout. User-facing API assertions stay untouched; tests that mirror internals may be rewritten with the code. | Every test must cover: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7557eb7a28..99e3e00988 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,8 +51,43 @@ Thank you for your interest in contributing to Texera! Please follow the steps b - All PR titles will be used as the **squashed commit message** when merged into the `main` branch. - Example PR titles: - `feat: add a new join operator` - - `fix(ui): prevent racing of requests` - - `chore(deps): bump numpy to version 2.0.0` + - `fix(frontend): prevent racing of requests` + - `chore(deps, pyamber): bump numpy to version 2.0.0` + +A scope names the module the change lands in — `amber`, `pyamber`, `frontend`, `agent-service`, `file-service`, and so on. Use the module's own name rather than an informal synonym, and when a PR spans modules, scope it to the one carrying the substantive change. + +##### Choosing between `feat`, `fix`, and `refactor` + +The type depends on what happens to the behavior, not on how large the change is. + +| Your change | Type | +| ----------- | ---- | +| A functionality worked before and no longer does | `fix` | +| A functionality or a form of support never existed and you are adding it | `feat` | +| A functionality exists and you are removing support for it | `feat` | +| A functionality is reworked in a way that intentionally changes user-facing behavior | `feat` | +| The change leaves the user-facing behavior unchanged | `refactor` | + +Behavior is defined by the code, not by what a document or an old PR description says the code does. A functionality that was never implemented does not exist, so implementing it is a `feat` even when the docs already described it as present. + +`refactor` is a strong claim: it says the **user-facing** behavior is identical. The test suite is how you check that, but not every test carries the same weight. A test that pins a user-facing API is the contract — if you had to change one of its assertions to make the suite green, the behavior moved, and the PR is a `feat` or a `fix`. A test that pins internals, such as a private helper's signature, the call order between two collaborators, or the shape of an intermediate value, is mir [...] + +##### Tests and dependency bumps + +Test and dependency PRs take the titles below. Where the table shows a two-part scope, it is written as `<type>(<area>, <module>): <description>`: + +| Your change | Title | +| ----------- | ----- | +| A test-only PR — adding or updating tests | `test(<module>): ...`, e.g. `test(amber): add marker replay specs` | +| Repairing a broken or flaky test | `fix(test, <module>): ...`, e.g. `fix(test, frontend): stabilize the dashboard spec` | +| A dependency bump that patches a CVE | `fix(deps, <module>): ...`, e.g. `fix(deps, pyamber): bump protobuf for CVE-2025-4565` | +| Any other dependency bump | `chore(deps, <module>): ...`, e.g. `chore(deps, pyamber): bump numpy to 2.0.0` | + +Omit the module for bumps that span modules. GitHub Actions bumps are dependency bumps too and take the `ci` module — `chore(deps, ci): ...`, or `fix(deps, ci): ...` when the bump patches a CVE — which is the form [`.github/renovate.json5`](.github/renovate.json5) opens them with. Reserve a bare `ci: ...` for hand-written CI and workflow changes. + +##### Backports + +A PR targeting a release branch appends the release version as the **last scope component**, so a backport of `fix(deps, frontend): ...` to `release/v1.2` is titled `fix(deps, frontend, v1.2): ...`. Version tags belong only on release-branch PRs — never put one on a PR targeting `main`. > 💡 You can use the [Conventional Commits > plugin](https://plugins.jetbrains.com/plugin/13389-conventional-commit) in > IntelliJ to help format commit messages correctly. diff --git a/docs/contribution-guidelines/_index.md b/docs/contribution-guidelines/_index.md index eb062a7529..007f9efa9c 100644 --- a/docs/contribution-guidelines/_index.md +++ b/docs/contribution-guidelines/_index.md @@ -68,10 +68,39 @@ Fork the [Texera repository](https://github.com/apache/texera) on GitHub and clo We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/): - Example PR titles: - `feat: add new join operator` - - `fix(ui): resolve workflow panel crash` + - `fix(frontend): resolve workflow panel crash` - `chore(deps): bump dependency versions` - The PR title becomes the final squashed commit message upon merge. +A scope names the module the change lands in — `amber`, `pyamber`, `frontend`, `agent-service`, `file-service`, and so on. Use the module's own name rather than an informal synonym, and when a PR spans modules, scope it to the one carrying the substantive change. + +Pick the type by what happens to the behavior, not by how large the change is: + +| Your change | Type | +| ----------- | ---- | +| A functionality worked before and no longer does | `fix` | +| A functionality or a form of support never existed and you are adding it | `feat` | +| A functionality exists and you are removing support for it | `feat` | +| A functionality is reworked in a way that intentionally changes user-facing behavior | `feat` | +| The change leaves the user-facing behavior unchanged | `refactor` | + +Behavior is defined by the code, not by what a document or an old PR description says the code does. A functionality that was never implemented does not exist, so implementing it is a `feat` even when the docs already described it as present. + +`refactor` claims the **user-facing** behavior is identical. A test that pins a user-facing API must keep passing untouched — changing one of its assertions means the behavior moved, so the PR is a `feat` or a `fix`. A test that pins internals mirrors the implementation and may be rewritten alongside the code it mirrors. + +Test and dependency PRs take the titles below. Where the table shows a two-part scope, it is written as `<type>(<area>, <module>): <description>`: + +| Your change | Title | +| ----------- | ----- | +| A test-only PR — adding or updating tests | `test(<module>): ...` | +| Repairing a broken or flaky test | `fix(test, <module>): ...` | +| A dependency bump that patches a CVE | `fix(deps, <module>): ...` | +| Any other dependency bump | `chore(deps, <module>): ...` | + +Omit the module for bumps that span modules. GitHub Actions bumps are dependency bumps too and take the `ci` module — `chore(deps, ci): ...`, or `fix(deps, ci): ...` when the bump patches a CVE — which is the form Renovate opens them with. Reserve a bare `ci: ...` for hand-written CI and workflow changes. + +A PR targeting a release branch appends the version as the last scope component — a backport of `fix(deps, frontend): ...` to `release/v1.2` becomes `fix(deps, frontend, v1.2): ...`. Never put a version tag on a PR targeting `main`. + #### PR Description Should Include: - **Purpose:** use `Closes #1234` to auto-close an issue. - **Summary:** short overview of your changes.
