| # Copyright (c) 2020-2021 Project CHIP Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| name: Lint Code Base |
| |
| on: |
| push: |
| branches-ignore: |
| - 'dependabot/**' |
| pull_request: |
| merge_group: |
| workflow_dispatch: |
| |
| concurrency: |
| group: |
| ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == |
| 'pull_request' && github.event.number) || (github.event_name == |
| 'workflow_dispatch' && github.run_number) || github.sha }} |
| cancel-in-progress: true |
| |
| jobs: |
| code-lints: |
| runs-on: ubuntu-latest |
| if: github.actor != 'restyled-io[bot]' |
| |
| container: |
| image: ghcr.io/project-chip/chip-build:80 |
| |
| steps: |
| - name: Checkout |
| uses: actions/checkout@v4 |
| |
| # Bootstrap and checkout for internal scripts (like idl_lint) |
| # to run |
| - name: Checkout submodules & Bootstrap |
| uses: ./.github/actions/checkout-submodules-and-bootstrap |
| with: |
| platform: linux |
| |
| - name: Check for orphaned gn files |
| if: always() |
| # We should enforce that ALL new files are referenced in our build scripts. |
| # Several things do not have a clear fix path: |
| # - various platform implementations (including darwin-specific files as they |
| # are not using GN) |
| # - app/clusters (they are fetched dynamically - this should probably be fixed) |
| # |
| # All the rest of the exceptions should be driven down to 0: chip should fully |
| # be defined in build rules. |
| # |
| # This check enforces that for any newly added file, it must be part of some |
| # BUILD.gn file |
| run: | |
| ./scripts/run_in_build_env.sh "./scripts/tools/not_known_to_gn.py \ |
| src \ |
| --skip-dir app/clusters \ |
| --skip-dir darwin \ |
| --skip-dir include \ |
| --skip-dir platform/Ameba \ |
| --skip-dir platform/android \ |
| --skip-dir platform/ASR \ |
| --skip-dir platform/Beken \ |
| --skip-dir platform/bouffalolab \ |
| --skip-dir platform/cc13xx_26xx \ |
| --skip-dir platform/cc32xx \ |
| --skip-dir platform/Darwin \ |
| --skip-dir platform/ESP32 \ |
| --skip-dir platform/fake \ |
| --skip-dir platform/FreeRTOS \ |
| --skip-dir platform/Infineon \ |
| --skip-dir platform/Linux \ |
| --skip-dir platform/mbed \ |
| --skip-dir platform/mt793x \ |
| --skip-dir platform/nxp \ |
| --skip-dir platform/OpenThread \ |
| --skip-dir platform/qpg \ |
| --skip-dir platform/silabs \ |
| --skip-dir platform/telink \ |
| --skip-dir platform/webos \ |
| --skip-dir platform/Zephyr \ |
| --skip-dir test_driver \ |
| --skip-dir platform/NuttX \ |
| --known-failure app/app-platform/ContentApp.cpp \ |
| --known-failure app/app-platform/ContentApp.h \ |
| --known-failure app/app-platform/ContentAppPlatform.cpp \ |
| --known-failure app/app-platform/ContentAppPlatform.h \ |
| --known-failure controller/ExamplePersistentStorage.cpp \ |
| --known-failure controller/ExamplePersistentStorage.h \ |
| --known-failure app/AttributeAccessToken.h \ |
| --known-failure app/CommandResponseSender.h \ |
| --known-failure app/CommandSenderLegacyCallback.h \ |
| --known-failure app/ReadHandler.h \ |
| --known-failure app/reporting/reporting.cpp \ |
| --known-failure app/reporting/tests/MockReportScheduler.cpp \ |
| --known-failure app/reporting/tests/MockReportScheduler.h \ |
| --known-failure app/util/attribute-storage.cpp \ |
| --known-failure app/util/attribute-storage-detail.h \ |
| --known-failure app/util/attribute-storage.h \ |
| --known-failure app/util/attribute-table.cpp \ |
| --known-failure app/util/attribute-table-detail.h \ |
| --known-failure app/util/attribute-table.h \ |
| --known-failure app/util/binding-table.cpp \ |
| --known-failure app/util/binding-table.h \ |
| --known-failure app/util/config.h \ |
| --known-failure app/util/DataModelHandler.cpp \ |
| --known-failure app/util/DataModelHandler.h \ |
| --known-failure app/util/ember-compatibility-functions.cpp \ |
| --known-failure app/util/ember-compatibility-functions.h \ |
| --known-failure app/util/ember-global-attribute-access-interface.cpp \ |
| --known-failure app/util/ember-global-attribute-access-interface.h \ |
| --known-failure app/util/ember-io-storage.cpp \ |
| --known-failure app/util/ember-io-storage.h \ |
| --known-failure app/util/endpoint-config-api.h \ |
| --known-failure app/util/generic-callbacks.h \ |
| --known-failure app/util/generic-callback-stubs.cpp \ |
| --known-failure app/util/im-client-callbacks.h \ |
| --known-failure app/util/IMClusterCommandHandler.h \ |
| --known-failure app/util/util.cpp \ |
| --known-failure app/util/util.h \ |
| --known-failure app/WriteHandler.h \ |
| --known-failure platform/DeviceSafeQueue.cpp \ |
| --known-failure platform/DeviceSafeQueue.h \ |
| --known-failure platform/GLibTypeDeleter.h \ |
| --known-failure platform/SingletonConfigurationManager.cpp \ |
| " |
| |
| - name: Check for matter lint errors |
| if: always() |
| run: | |
| for idl_file in $(find . -name '*.matter'); do |
| # TODO: all these conformance failures should be fixed |
| # Issues exist for most of them: |
| # https://github.com/project-chip/connectedhomeip/issues/19176 |
| # https://github.com/project-chip/connectedhomeip/issues/19175 |
| # https://github.com/project-chip/connectedhomeip/issues/19173 |
| if [ "$idl_file" = './examples/log-source-app/log-source-common/log-source-app.matter' ]; then continue; fi |
| if [ "$idl_file" = './examples/placeholder/linux/apps/app1/config.matter' ]; then continue; fi |
| if [ "$idl_file" = './examples/placeholder/linux/apps/app2/config.matter' ]; then continue; fi |
| if [ "$idl_file" = './examples/thermostat/thermostat-common/thermostat.matter' ]; then continue; fi |
| if [ "$idl_file" = './examples/window-app/common/window-app.matter' ]; then continue; fi |
| # Example is intentionally not spe compliant for use in cert testing |
| if [ "$idl_file" = './examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter' ]; then continue; fi |
| |
| # Test files are intentionally small and not spec-compilant, just parse-compliant |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/cluster_struct_attribute.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/global_struct_attribute.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/optional_argument.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/several_clusters.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/simple_attribute.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/large_lighting_app.matter" ]; then continue; fi |
| if [ "$idl_file" = "./scripts/py_matter_idl/matter_idl/tests/inputs/large_all_clusters_app.matter" ]; then continue; fi |
| |
| ./scripts/run_in_build_env.sh "./scripts/idl_lint.py --log-level warn $idl_file" >/dev/null || exit 1 |
| done |
| |
| - name: Check broken links |
| # On-push disabled until the job can run fully green |
| # At that point the step should be enabled. |
| if: github.event_name == 'workflow_dispatch' |
| uses: gaurav-nelson/github-action-markdown-link-check@v1 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: Check for incorrect error use in VerifyOrExit |
| if: always() |
| run: | |
| git grep -I -n "VerifyOrExit(.*, [A-Za-z]*_ERROR" -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of PRI*8, which are not supported on some libcs. |
| if: always() |
| run: | |
| git grep -I -n "PRI.8" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)third_party/lwip/repo/lwip/src/include/lwip/arch.h' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of PRI*16, which are not supported on some |
| libcs. |
| if: always() |
| run: | |
| git grep -I -n "PRI.16" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)third_party/lwip/repo/lwip/src/include/lwip/arch.h' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of PRI*64, which are not supported on some |
| libcs. |
| if: always() |
| run: | |
| # TODO: MessageDefHelper should ideally not be excluded here. |
| # TODO: chip_im_initiatore should ideally not be excluded here. |
| # TODO: TLVDebug should ideally not be excluded here. |
| # TODO: protocol_decoder.cpp should ideally not be excluded here. |
| # TODO: PersistentStorageMacros.h should ideally not be excluded here. |
| git grep -I -n "PRI.64" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)examples/chip-tool' ':(exclude)examples/tv-casting-app' ':(exclude)src/app/MessageDef/MessageDefHelper.cpp' ':(exclude)src/app/tests/integration/chip_im_initiator.cpp' ':(exclude)src/lib/core/TLVDebug.cpp' ':(exclude)src/lib/dnssd/tests/TestTxtFields.cpp' ':(exclude)src/lib/format/protocol_decoder.cpp' ':(exclude)src/lib/support/PersistentStorageMacros.h' ':(exclude)src/messaging/tests/echo/echo_requester.cpp' ':(exclude)src/platform/Linux' ':(exclude)src/platform/Ameba' ':(exclude)src/platform/ESP32' ':(exclude)src/platform/Darwin' ':(exclude)src/darwin' ':(exclude)src/platform/webos' ':(exclude)zzz_generated/chip-tool' ':(exclude)src/tools/chip-cert/Cmd_PrintCert.cpp' ':(exclude)src/platform/NuttX' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: Check for use of %zu, which are not supported on some libcs. |
| if: always() |
| run: | |
| git grep -I -n "%zu" -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # Comments like '{{! ... }}' should be used in zap files |
| - name: Do not allow TODO in generated files |
| if: always() |
| run: | |
| git grep -n 'TODO:' -- ./zzz_generated './*/zap-generated/*' && exit 1 || exit 0 |
| |
| - name: Check for disallowed include files |
| if: always() |
| run: scripts/tools/check_includes.sh |
| |
| - name: Check for zcl.json and extension sync status |
| if: always() |
| run: scripts/tools/check_zcl_file_sync.py . |
| |
| - name: Ensure all PICS are set for tests (to true or false) |
| if: always() |
| run: | |
| scripts/tools/check_test_pics.py src/app/tests/suites/certification/ci-pics-values src/app/tests/suites/certification/PICS.yaml |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of 0x%u and the like, which lead to misleading |
| output. |
| if: always() |
| run: | |
| git grep -I -n '0x%[0-9l.*-]*[^xX"0-9l.*-]' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of '"0x" PRIu*' and the like, which lead to |
| misleading output. |
| if: always() |
| run: | |
| git grep -I -n '0x%[0-9-]*" *PRI[^xX]' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. |
| - name: |
| Check for use of NSLog instead of Matter logging in Matter |
| framework |
| if: always() |
| run: | |
| git grep -n 'NSLog(' -- src/darwin/Framework/CHIP && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself, as well as excluding the files |
| # that implement the type-safe accessors |
| - name: |
| Check for use of 'emberAfReadAttribute' instead of the |
| type-safe getters |
| if: always() |
| run: | |
| git grep -I -n 'emberAfReadAttribute' -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)src/app/util/attribute-table.h' ':(exclude)zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp' ':(exclude)src/app/zap-templates/templates/app/attributes/Accessors-src.zapt' ':(exclude)src/app/util/attribute-table.cpp' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself, as well as excluding the files |
| # that implement the type-safe accessors, attribute writing from the wire, and some |
| # Pigweed RPC code that seems hard to update. |
| - name: |
| Check for use of 'emberAfWriteAttribute' instead of the |
| type-safe setters |
| if: always() |
| run: | |
| git grep -I -n 'emberAfWriteAttribute' -- './*' \ |
| ':(exclude).github/workflows/lint.yml' \ |
| ':(exclude)examples/common/pigweed/rpc_services/Attributes.h' \ |
| ':(exclude)src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp' \ |
| ':(exclude)src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.cpp' \ |
| ':(exclude)src/app/util/attribute-table.cpp' \ |
| ':(exclude)src/app/util/attribute-table.h' \ |
| ':(exclude)src/app/util/ember-compatibility-functions.cpp' \ |
| ':(exclude)src/app/util/mock/CodegenEmberMocks.cpp' \ |
| ':(exclude)src/app/zap-templates/templates/app/attributes/Accessors-src.zapt' \ |
| ':(exclude)zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp' \ |
| && exit 1 || exit 0 |
| |
| # Run ruff python linter |
| - name: Check for errors using ruff Python linter |
| if: always() |
| run: | |
| ruff check |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of "SuccessOrExit(CHIP_ERROR_*)", which should |
| probably be "SuccessOrExit(err = CHIP_ERROR_*)" |
| if: always() |
| run: | |
| git grep -I -n 'SuccessOrExit(CHIP_ERROR' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. And we want to exclude this file, |
| # to avoid our grep regexp matching itself. |
| - name: |
| Check for use of |
| "SuccessOrExit(something-without-assignment(", which should |
| probably be "SuccessOrExit(err = something(" |
| if: always() |
| run: | |
| git grep -I -n 'SuccessOrExit([^=)]*(' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 |
| |
| # git grep exits with 0 if it finds a match, but we want |
| # to fail (exit nonzero) on match. |
| - name: |
| Check for use of "using namespace" outside of a class/function |
| in headers. |
| if: always() |
| run: | |
| # Various platforms have `using namespace chip::Ble` in their BLEManager* headers; just exclude those for now. |
| # |
| # Exclude platform openiotsdk bits that do this in their persistent storage header. |
| # |
| # Also exclude examples (for now) and third_party, which have various instances of this. |
| # |
| # Ignore uses of `System::Clock::Literals`, because that's the only way to have things using _ms32 or whatnot |
| # in a header file. |
| git grep -I -n -e '^using namespace' --and --not -e 'System::Clock::Literals' -- './**/*.h' ':(exclude)src/platform/*/BLEManager*.h' ':(exclude)src/platform/openiotsdk/KVPsaPsStore.h' ':(exclude)./examples' ':(exclude)./third_party' && exit 1 || exit 0 |