diff --git a/.github/DISCUSSION_TEMPLATE/standards-conformance.yml b/.github/DISCUSSION_TEMPLATE/standards-conformance.yml index 85d565ec..134829b9 100644 --- a/.github/DISCUSSION_TEMPLATE/standards-conformance.yml +++ b/.github/DISCUSSION_TEMPLATE/standards-conformance.yml @@ -53,7 +53,7 @@ body: attributes: label: Function or module involved description: Leave empty if your question is whether it exists at all. - placeholder: "phonometry.levels.equivalent_level" + placeholder: "phonometry.leq" validations: required: false diff --git a/.github/ISSUE_TEMPLATE/01-bug-report.yml b/.github/ISSUE_TEMPLATE/01-bug-report.yml new file mode 100644 index 00000000..725f16ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01-bug-report.yml @@ -0,0 +1,85 @@ +name: Bug report +description: A reproducible failure with no standard in play +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Use this for a crash, a result that contradicts the library's own documentation, + or a broken installation. + + A value that disagrees with a standard or with a reference implementation is not + this, even when it reproduces every time. That goes to + [Standards & conformance](https://github.com/jmrplens/phonometry/discussions/categories/standards-conformance), + because settling it means reading the clause first. + + - type: textarea + id: what + attributes: + label: What happens + description: What you observed, and what you expected instead. + validations: + required: true + + - type: textarea + id: reproduce + attributes: + label: Minimal reproducible example + description: > + Self-contained code that fails when run. If it needs a signal, generate it in the + snippet rather than attaching a file where you can. For an installation failure + there is no snippet: give the install command instead, and put its output in the + next field. + render: python + validations: + required: true + + - type: textarea + id: traceback + attributes: + label: Traceback or output + description: The full traceback if it raises, or the values you got if it does not. + render: text + validations: + required: false + + - type: input + id: version + attributes: + label: phonometry version + description: > + Run: python -c "import phonometry; print(phonometry.__version__)" + If the installation itself failed, give the version you were trying to install. + placeholder: "3.3.0" + validations: + required: true + + - type: input + id: environment + attributes: + label: Python version and operating system + placeholder: "Python 3.13 on Ubuntu 24.04" + validations: + required: true + + - type: dropdown + id: install + attributes: + label: How did you install it? + options: + - pip from PyPI + - conda or mamba + - from source + - other + validations: + required: false + + - type: checkboxes + id: checks + attributes: + label: Before submitting + options: + - label: This is not a disagreement with a standard or a reference implementation. + required: true + - label: I am on the latest released version, or I checked that the problem is still present there. + required: false diff --git a/.github/ISSUE_TEMPLATE/02-conformance-defect.yml b/.github/ISSUE_TEMPLATE/02-conformance-defect.yml new file mode 100644 index 00000000..df3008a6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-conformance-defect.yml @@ -0,0 +1,80 @@ +name: Conformance defect +description: A confirmed disagreement between the library and a standard +labels: ["conformance"] +body: + - type: markdown + attributes: + value: | + For a discrepancy that has already been established: the library computes a value + that does not match what the standard requires. + + If it has not been looked at yet, start in + [Standards & conformance](https://github.com/jmrplens/phonometry/discussions/categories/standards-conformance) + instead. Most reported discrepancies turn out to be a different edition, a + different clause, or a difference in the input conditions, and the discussion is + where that gets sorted out. + + **Cite clauses and tables by number rather than pasting the text.** Standards are + copyrighted. + + - type: input + id: discussion + attributes: + label: Discussion where this was established + description: Leave empty only if the defect is self-evident from the numbers below. + placeholder: "https://github.com/jmrplens/phonometry/discussions/..." + validations: + required: false + + - type: input + id: standard + attributes: + label: Standard, edition and year + placeholder: "IEC 61672-1:2013" + validations: + required: true + + - type: input + id: clause + attributes: + label: Clause, table, annex or equation + placeholder: "Clause 5.4.11, Table 3, Eq. (12)" + validations: + required: true + + - type: input + id: api + attributes: + label: Function or module affected + placeholder: "phonometry.leq" + validations: + required: true + + - type: textarea + id: numbers + attributes: + label: Required value against computed value + description: > + State both, with the input conditions they correspond to, and say where the + required value comes from. Tolerances matter: give the one the standard allows. + validations: + required: true + + - type: textarea + id: reproduce + attributes: + label: Code that reproduces it + render: python + validations: + required: true + + - type: dropdown + id: origin + attributes: + label: Where does the defect appear to be? + options: + - In the library + - In the published standard itself, and belongs in docs/ERRATA.md + - Not established yet + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/03-new-standard.yml b/.github/ISSUE_TEMPLATE/03-new-standard.yml new file mode 100644 index 00000000..3da8c008 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03-new-standard.yml @@ -0,0 +1,83 @@ +name: Implement a standard or method +description: An agreed piece of work to cover something not implemented yet +labels: ["new standard"] +body: + - type: markdown + attributes: + value: | + This is a work item, not a proposal. Open proposals in + [Ideas](https://github.com/jmrplens/phonometry/discussions/categories/ideas) + first, where the scope and the validation data get worked out. + + What decides whether this can be built is the reference data. Every method here + comes from the standard itself and is checked against normative values, so an + item without an oracle stays blocked no matter how well specified it is. + + - type: input + id: standard + attributes: + label: Standard, edition and year + description: Or the paper or book, if no standard defines the method. + placeholder: "ISO 3746:2010" + validations: + required: true + + - type: textarea + id: scope + attributes: + label: Scope + description: > + Which clauses, tables and annexes are in, and which are deliberately out. Being + explicit about the exclusions is what keeps the conformance claim honest. + validations: + required: true + + - type: input + id: module + attributes: + label: Proposed module and public names + description: > + A concept name in snake_case, never a standard number. See the naming conventions + in CONTRIBUTING.md. + placeholder: "emission/survey_sound_power.py, survey_sound_power()" + validations: + required: false + + - type: textarea + id: oracle + attributes: + label: Reference data for validation + description: > + Worked examples in the standard, published tables, a reference implementation, or + measurements. Say which of these is available and where it is, or state plainly + that none is known. + validations: + required: true + + - type: dropdown + id: source + attributes: + label: Is the document itself available? + options: + - Yes, available + - No, needs to be obtained + - Partially, only the parts quoted in secondary sources + validations: + required: true + + - type: checkboxes + id: deliverables + attributes: + label: Deliverables + description: The usual set for a new method. Untick anything that does not apply. + options: + - label: Implementation with type annotations + required: false + - label: Tests against the reference values, including edge cases + required: false + - label: Conformance check registered in the report + required: false + - label: Teaching-style guide page, English and Spanish + required: false + - label: Figure generated by scripts/generate_graphs.py + required: false diff --git a/.github/ISSUE_TEMPLATE/04-documentation.yml b/.github/ISSUE_TEMPLATE/04-documentation.yml new file mode 100644 index 00000000..a331b367 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/04-documentation.yml @@ -0,0 +1,59 @@ +name: Documentation defect +description: Something in the documentation is wrong or broken +labels: ["documentation"] +body: + - type: markdown + attributes: + value: | + For a concrete defect: a wrong value or formula, an example that no longer runs, a + broken link, a figure that does not match the text. + + If an explanation is simply hard to follow, or a guide is missing, that is + [Documentation & learning](https://github.com/jmrplens/phonometry/discussions/categories/documentation-learning) + instead. It is worth raising there, it just does not start as an issue. + + When the code and the documentation disagree and you cannot tell which one is + wrong, file it as a bug report. Use this form only when the documentation is + clearly the mistaken part. + + - type: input + id: page + attributes: + label: Page + description: The URL on the documentation site, or the file under docs/. + placeholder: "https://jmrplens.github.io/phonometry/guides/filter-banks/" + validations: + required: true + + - type: dropdown + id: language + attributes: + label: Language + options: + - English + - Spanish + - Both + validations: + required: true + + - type: dropdown + id: kind + attributes: + label: What is wrong? + options: + - A wrong value, formula or unit + - An example that does not run + - Documented behaviour the library never had, so the text is the wrong part + - A broken link or a missing image + - A figure that disagrees with the text + - Something else + validations: + required: true + + - type: textarea + id: detail + attributes: + label: What it says, and what it should say + description: Quote the passage. If you know the correction, give it. + validations: + required: true diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..8bd6b426 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,176 @@ +# Path-based labels applied to pull requests by .github/workflows/labeler.yml. +# Label names must already exist in the repository; the action does not create them. + +# --- Kind of change ----------------------------------------------------------- + +documentation: + - changed-files: + - any-glob-to-any-file: + - docs/** + - README.md + - CONTRIBUTING.md + - CHANGELOG.md + +site: + - changed-files: + - any-glob-to-any-file: + - site/** + +i18n: + - changed-files: + - any-glob-to-any-file: + - site/src/content/docs/es/** + - site/src/content/i18n/** + - src/phonometry/_i18n.py + +figures: + - changed-files: + - any-glob-to-any-file: + - .github/images/** + - scripts/generate_graphs.py + - scripts/generate_diagrams.py + - scripts/check_figures.py + - src/phonometry/_plot/** + - src/phonometry/_plotting.py + - requirements-figures.txt + +reports: + - changed-files: + - any-glob-to-any-file: + - src/phonometry/_report/** + - .github/reports/** + - scripts/generate_reports.py + - scripts/generate_site_reports.py + +conformance: + - changed-files: + - any-glob-to-any-file: + - docs/CONFORMANCE.md + - scripts/conformance_report.py + - scripts/check_conformance_claims.py + +errata: + - changed-files: + - any-glob-to-any-file: + - docs/ERRATA.md + +validation: + - changed-files: + - any-glob-to-any-file: + - tests/data/** + - tests/golden_data.py + - tests/reference_data.py + +performance: + - changed-files: + - any-glob-to-any-file: + - scripts/bench.py + - tests/test_performance.py + +api: + - changed-files: + - any-glob-to-any-file: + - src/phonometry/__init__.py + - docs/api-reference.md + - scripts/api_taxonomy.py + - scripts/generate_api_docs.py + - scripts/check_api_reference.py + +packaging: + - changed-files: + - any-glob-to-any-file: + - pyproject.toml + - MANIFEST.in + - VERSION + - requirements.txt + - stub/** + +ci: + - changed-files: + - any-glob-to-any-file: + - .github/workflows/** + - .github/scripts/** + - .github/labeler.yml + - .github/dependabot.yml + - Makefile + - hooks/** + - requirements-dev.txt + - codecov.yml + - sonar-project.properties + +# --- Acoustic domain ---------------------------------------------------------- +# One per package under src/phonometry/. tests/ mirrors the same names, so an +# implementation and its tests land on the same label. Keep this list in step +# with the packages: a new one without an entry here goes out unlabelled. + +# Shared code that belongs to no single domain, plus the cross-cutting suites at +# the root of tests/. Without this, a change to code every package depends on +# would carry no area label at all. +"area: core": + - changed-files: + - any-glob-to-any-file: + - src/phonometry/_internal/** + - src/phonometry/_compat.py + - src/phonometry/_version.py + - src/phonometry/_i18n.py + - tests/*.py + +"area: aircraft": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/aircraft/**", "tests/aircraft/**"] + +"area: broadcast": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/broadcast/**", "tests/broadcast/**"] + +"area: building": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/building/**", "tests/building/**"] + +"area: electroacoustics": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/electroacoustics/**", "tests/electroacoustics/**"] + +"area: emission": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/emission/**", "tests/emission/**"] + +"area: environmental": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/environmental/**", "tests/environmental/**"] + +"area: hearing": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/hearing/**", "tests/hearing/**"] + +"area: materials": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/materials/**", "tests/materials/**"] + +"area: metrology": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/metrology/**", "tests/metrology/**"] + +"area: noise control": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/noise_control/**", "tests/noise_control/**"] + +"area: psychoacoustics": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/psychoacoustics/**", "tests/psychoacoustics/**"] + +"area: room": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/room/**", "tests/room/**"] + +"area: simulation": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/simulation/**", "tests/simulation/**", "scripts/fdtd2d.py"] + +"area: underwater": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/underwater/**", "tests/underwater/**"] + +"area: vibration": + - changed-files: + - any-glob-to-any-file: ["src/phonometry/vibration/**", "tests/vibration/**"] diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000..fae3604e --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,23 @@ +name: Labeler + +# pull_request_target so that pull requests from forks also get labelled: the +# default GITHUB_TOKEN is read-only for fork pull requests under `pull_request`. +# The action only reads the changed file list and never checks out or runs the +# pull request's code, so the elevated token is not exposed to it. +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + name: Label by changed paths + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v7 + with: + # Keep labels added by hand. Only ever add, never remove. + sync-labels: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70325f0b..75ac0a7b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,10 +170,19 @@ skipped). ## 🚀 How to Contribute ### Reporting Bugs -If you find a bug, check the [Issues](https://github.com/jmrplens/phonometry/issues). If not reported, open a new issue with: -- Steps to reproduce -- Expected vs Actual behavior -- Environment details (OS, Python version) +Search the [Issues](https://github.com/jmrplens/phonometry/issues) first, then open a +new one. There is a form for each kind: + +| Form | For | +|---|---| +| Bug report | A crash, a result that contradicts the library's own documentation, or a broken installation | +| Conformance defect | A disagreement with a standard that has already been established, usually in a discussion | +| Implement a standard or method | An agreed work item, once the scope and the reference data are settled | +| Documentation defect | A wrong value or formula, an example that no longer runs, a broken link | + +Pull requests are labelled automatically from the paths they touch, through +`.github/labeler.yml`. Adding a package under `src/phonometry/` means adding its +`area:` entry there too. ### Pull Requests 1. **Fork** the repository.