mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
ci: add linter for gitlab yaml files
- remove duplicated artifacts default values - migrate check_artifacts_expire_time.py - migrate check_rules_yml.py
This commit is contained in:
parent
96aeead6f5
commit
b709c880dd
@ -32,8 +32,6 @@
|
|||||||
# keep the size info to help track the binary size
|
# keep the size info to help track the binary size
|
||||||
- size_info.txt
|
- size_info.txt
|
||||||
- "**/build*/size.json"
|
- "**/build*/size.json"
|
||||||
when: always
|
|
||||||
expire_in: 4 days
|
|
||||||
script:
|
script:
|
||||||
# CI specific options start from "--parallel-count xxx". could ignore when running locally
|
# CI specific options start from "--parallel-count xxx". could ignore when running locally
|
||||||
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
|
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
|
||||||
@ -376,12 +374,10 @@ build_only_tools_test_apps:
|
|||||||
BUILD_LOG_CMAKE: "${LOG_PATH}/cmake_@t_@w.txt"
|
BUILD_LOG_CMAKE: "${LOG_PATH}/cmake_@t_@w.txt"
|
||||||
BUILD_COMMAND_ARGS: ""
|
BUILD_COMMAND_ARGS: ""
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- log_template_app/*
|
- log_template_app/*
|
||||||
- size_info.txt
|
- size_info.txt
|
||||||
- build_template_app/**/size.json
|
- build_template_app/**/size.json
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
# Set the variable for 'esp-idf-template' testing
|
# Set the variable for 'esp-idf-template' testing
|
||||||
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
|
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
|
||||||
@ -554,7 +550,6 @@ pytest_build_system:
|
|||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- test_build_system
|
- test_build_system
|
||||||
when: always
|
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
@ -571,7 +566,6 @@ pytest_build_system_macos:
|
|||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- test_build_system
|
- test_build_system
|
||||||
when: always
|
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
@ -603,7 +597,6 @@ pytest_build_system_win:
|
|||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- test_build_system
|
- test_build_system
|
||||||
when: always
|
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
|
@ -345,6 +345,9 @@ default:
|
|||||||
- *setup_tools_and_idf_python_venv
|
- *setup_tools_and_idf_python_venv
|
||||||
- add_gitlab_ssh_keys
|
- add_gitlab_ssh_keys
|
||||||
- fetch_submodules
|
- fetch_submodules
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: always
|
||||||
retry:
|
retry:
|
||||||
max: 2
|
max: 2
|
||||||
when:
|
when:
|
||||||
|
@ -121,7 +121,6 @@ build_docs_html_full:
|
|||||||
artifacts: false
|
artifacts: false
|
||||||
optional: true
|
optional: true
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/*.txt
|
- docs/_build/*/*/*.txt
|
||||||
- docs/_build/*/*/html/*
|
- docs/_build/*/*/html/*
|
||||||
@ -135,7 +134,6 @@ build_docs_html_full_prod:
|
|||||||
- .doc-rules:build:docs-full-prod
|
- .doc-rules:build:docs-full-prod
|
||||||
dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts
|
dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/*.txt
|
- docs/_build/*/*/*.txt
|
||||||
- docs/_build/*/*/html/*
|
- docs/_build/*/*/html/*
|
||||||
@ -152,7 +150,6 @@ build_docs_html_partial:
|
|||||||
artifacts: false
|
artifacts: false
|
||||||
optional: true
|
optional: true
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/*.txt
|
- docs/_build/*/*/*.txt
|
||||||
- docs/_build/*/*/html/*
|
- docs/_build/*/*/html/*
|
||||||
@ -175,7 +172,6 @@ build_docs_pdf:
|
|||||||
artifacts: false
|
artifacts: false
|
||||||
optional: true
|
optional: true
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/latex/*
|
- docs/_build/*/*/latex/*
|
||||||
expire_in: 4 days
|
expire_in: 4 days
|
||||||
@ -188,7 +184,6 @@ build_docs_pdf_prod:
|
|||||||
- .doc-rules:build:docs-full-prod
|
- .doc-rules:build:docs-full-prod
|
||||||
dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts
|
dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/latex/*
|
- docs/_build/*/*/latex/*
|
||||||
expire_in: 4 days
|
expire_in: 4 days
|
||||||
@ -266,11 +261,9 @@ check_doc_links:
|
|||||||
artifacts: false
|
artifacts: false
|
||||||
tags: ["build", "amd64", "internet"]
|
tags: ["build", "amd64", "internet"]
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- docs/_build/*/*/*.txt
|
- docs/_build/*/*/*.txt
|
||||||
- docs/_build/*/*/linkcheck/*.txt
|
- docs/_build/*/*/linkcheck/*.txt
|
||||||
expire_in: 1 week
|
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- cd docs
|
- cd docs
|
||||||
|
@ -28,7 +28,6 @@ test_nvs_coverage:
|
|||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- components/nvs_flash/test_nvs_host/coverage_report
|
- components/nvs_flash/test_nvs_host/coverage_report
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- cd components/nvs_flash/test_nvs_host
|
- cd components/nvs_flash/test_nvs_host
|
||||||
- make coverage_report
|
- make coverage_report
|
||||||
@ -65,7 +64,6 @@ test_reproducible_build:
|
|||||||
- "**/build*/*.bin"
|
- "**/build*/*.bin"
|
||||||
- "**/build*/bootloader/*.bin"
|
- "**/build*/bootloader/*.bin"
|
||||||
- "**/build*/partition_table/*.bin"
|
- "**/build*/partition_table/*.bin"
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
test_spiffs_on_host:
|
test_spiffs_on_host:
|
||||||
extends: .host_test_template
|
extends: .host_test_template
|
||||||
@ -110,7 +108,6 @@ test_cli_installer:
|
|||||||
paths:
|
paths:
|
||||||
- tools/tools.new.json
|
- tools/tools.new.json
|
||||||
- tools/test_idf_tools/test_python_env_logs.txt
|
- tools/test_idf_tools/test_python_env_logs.txt
|
||||||
expire_in: 1 week
|
|
||||||
image:
|
image:
|
||||||
name: $ESP_ENV_IMAGE
|
name: $ESP_ENV_IMAGE
|
||||||
entrypoint: [""] # use system python3. no extra pip package installed
|
entrypoint: [""] # use system python3. no extra pip package installed
|
||||||
@ -130,7 +127,6 @@ test_cli_installer:
|
|||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- components/efuse/${IDF_TARGET}/esp_efuse_table.c
|
- components/efuse/${IDF_TARGET}/esp_efuse_table.c
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- cd ${IDF_PATH}/components/efuse/
|
- cd ${IDF_PATH}/components/efuse/
|
||||||
- ./efuse_table_gen.py -t "${IDF_TARGET}" ${IDF_PATH}/components/efuse/${IDF_TARGET}/esp_efuse_table.csv
|
- ./efuse_table_gen.py -t "${IDF_TARGET}" ${IDF_PATH}/components/efuse/${IDF_TARGET}/esp_efuse_table.csv
|
||||||
@ -173,7 +169,6 @@ test_logtrace_proc:
|
|||||||
paths:
|
paths:
|
||||||
- tools/esp_app_trace/test/logtrace/output
|
- tools/esp_app_trace/test/logtrace/output
|
||||||
- tools/esp_app_trace/test/logtrace/.coverage
|
- tools/esp_app_trace/test/logtrace/.coverage
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- cd ${IDF_PATH}/tools/esp_app_trace/test/logtrace
|
- cd ${IDF_PATH}/tools/esp_app_trace/test/logtrace
|
||||||
- ./test.sh
|
- ./test.sh
|
||||||
@ -185,7 +180,6 @@ test_sysviewtrace_proc:
|
|||||||
paths:
|
paths:
|
||||||
- tools/esp_app_trace/test/sysview/output
|
- tools/esp_app_trace/test/sysview/output
|
||||||
- tools/esp_app_trace/test/sysview/.coverage
|
- tools/esp_app_trace/test/sysview/.coverage
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- cd ${IDF_PATH}/tools/esp_app_trace/test/sysview
|
- cd ${IDF_PATH}/tools/esp_app_trace/test/sysview
|
||||||
- ./test.sh
|
- ./test.sh
|
||||||
@ -194,13 +188,11 @@ test_tools:
|
|||||||
extends:
|
extends:
|
||||||
- .host_test_template
|
- .host_test_template
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- ${IDF_PATH}/*.out
|
- ${IDF_PATH}/*.out
|
||||||
- ${IDF_PATH}/XUNIT_*.xml
|
- ${IDF_PATH}/XUNIT_*.xml
|
||||||
reports:
|
reports:
|
||||||
junit: ${IDF_PATH}/XUNIT_*.xml
|
junit: ${IDF_PATH}/XUNIT_*.xml
|
||||||
expire_in: 1 week
|
|
||||||
variables:
|
variables:
|
||||||
LC_ALL: C.UTF-8
|
LC_ALL: C.UTF-8
|
||||||
INSTALL_QEMU: 1 # for test_idf_qemu.py
|
INSTALL_QEMU: 1 # for test_idf_qemu.py
|
||||||
@ -280,13 +272,11 @@ test_pytest_qemu:
|
|||||||
- .host_test_template
|
- .host_test_template
|
||||||
- .before_script:build
|
- .before_script:build
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- pytest_embedded_log/
|
- pytest_embedded_log/
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
expire_in: 1 week
|
|
||||||
allow_failure: true # IDFCI-1752
|
allow_failure: true # IDFCI-1752
|
||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
@ -316,14 +306,12 @@ test_pytest_linux:
|
|||||||
- .host_test_template
|
- .host_test_template
|
||||||
- .before_script:build
|
- .before_script:build
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- pytest_embedded_log/
|
- pytest_embedded_log/
|
||||||
- "**/build*/build_log.txt"
|
- "**/build*/build_log.txt"
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- run_cmd python tools/ci/ci_build_apps.py components examples tools/test_apps -vv
|
- run_cmd python tools/ci/ci_build_apps.py components examples tools/test_apps -vv
|
||||||
--target linux
|
--target linux
|
||||||
|
@ -84,7 +84,6 @@ check_chip_support_components:
|
|||||||
paths:
|
paths:
|
||||||
- esp_hw_support_part.h
|
- esp_hw_support_part.h
|
||||||
- bootloader_support_part.h
|
- bootloader_support_part.h
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- python tools/ci/check_soc_headers_leak.py
|
- python tools/ci/check_soc_headers_leak.py
|
||||||
- find ${IDF_PATH}/components/soc/*/include/soc/ -name "*_struct.h" -print0 | xargs -0 -n1 ./tools/ci/check_soc_struct_headers.py
|
- find ${IDF_PATH}/components/soc/*/include/soc/ -name "*_struct.h" -print0 | xargs -0 -n1 ./tools/ci/check_soc_struct_headers.py
|
||||||
@ -98,7 +97,6 @@ check_esp_err_to_name:
|
|||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- components/esp_common/esp_err_to_name.c
|
- components/esp_common/esp_err_to_name.c
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- cd ${IDF_PATH}/tools/
|
- cd ${IDF_PATH}/tools/
|
||||||
- ./gen_esp_err_to_name.py
|
- ./gen_esp_err_to_name.py
|
||||||
@ -122,12 +120,6 @@ check_version_tag:
|
|||||||
script:
|
script:
|
||||||
- (git cat-file -t $CI_COMMIT_REF_NAME | grep tag) || (echo "ESP-IDF versions must be annotated tags." && exit 1)
|
- (git cat-file -t $CI_COMMIT_REF_NAME | grep tag) || (echo "ESP-IDF versions must be annotated tags." && exit 1)
|
||||||
|
|
||||||
check_artifacts_expire_time:
|
|
||||||
extends: .pre_check_template
|
|
||||||
script:
|
|
||||||
# check if we have set expire time for all artifacts
|
|
||||||
- python tools/ci/check_artifacts_expire_time.py
|
|
||||||
|
|
||||||
check_test_scripts_build_test_rules:
|
check_test_scripts_build_test_rules:
|
||||||
extends:
|
extends:
|
||||||
- .pre_check_template
|
- .pre_check_template
|
||||||
@ -165,4 +157,3 @@ pipeline_variables:
|
|||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
reports:
|
||||||
dotenv: pipeline.env
|
dotenv: pipeline.env
|
||||||
expire_in: 4 days
|
|
||||||
|
@ -344,9 +344,6 @@
|
|||||||
.if-dev-push: &if-dev-push
|
.if-dev-push: &if-dev-push
|
||||||
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||||
|
|
||||||
.if-merge_request: &if-merge_request
|
|
||||||
if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
||||||
|
|
||||||
.if-schedule: &if-schedule
|
.if-schedule: &if-schedule
|
||||||
if: '$CI_PIPELINE_SOURCE == "schedule"'
|
if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||||
|
|
||||||
@ -356,9 +353,6 @@
|
|||||||
.if-schedule-test-build-system-windows: &if-schedule-test-build-system-windows
|
.if-schedule-test-build-system-windows: &if-schedule-test-build-system-windows
|
||||||
if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_BUILD_SYSTEM_TEST_WIN == "true"'
|
if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_BUILD_SYSTEM_TEST_WIN == "true"'
|
||||||
|
|
||||||
.if-trigger: &if-trigger
|
|
||||||
if: '$CI_PIPELINE_SOURCE == "trigger"'
|
|
||||||
|
|
||||||
.if-label-build-only: &if-label-build-only
|
.if-label-build-only: &if-label-build-only
|
||||||
if: '$CI_JOB_STAGE == "target_test" && $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*For Maintainers: Only Build Tests(?:,[^,\n\r]+)*$/i'
|
if: '$CI_JOB_STAGE == "target_test" && $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*For Maintainers: Only Build Tests(?:,[^,\n\r]+)*$/i'
|
||||||
|
|
||||||
@ -398,10 +392,6 @@
|
|||||||
- <<: *if-protected-no_label
|
- <<: *if-protected-no_label
|
||||||
when: always
|
when: always
|
||||||
|
|
||||||
.rules:mr:
|
|
||||||
rules:
|
|
||||||
- <<: *if-merge_request
|
|
||||||
|
|
||||||
.rules:tag:release:
|
.rules:tag:release:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-tag-release
|
- <<: *if-tag-release
|
||||||
|
@ -6,8 +6,6 @@ clang_tidy_check:
|
|||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- clang_tidy_reports/
|
- clang_tidy_reports/
|
||||||
when: always
|
|
||||||
expire_in: 1 day
|
|
||||||
variables:
|
variables:
|
||||||
IDF_TOOLCHAIN: clang
|
IDF_TOOLCHAIN: clang
|
||||||
script:
|
script:
|
||||||
@ -23,10 +21,8 @@ check_pylint:
|
|||||||
needs:
|
needs:
|
||||||
- pipeline_variables
|
- pipeline_variables
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
reports:
|
reports:
|
||||||
codequality: pylint.json
|
codequality: pylint.json
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- |
|
- |
|
||||||
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
|
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
|
||||||
@ -72,10 +68,8 @@ check_pylint:
|
|||||||
GIT_DEPTH: 0
|
GIT_DEPTH: 0
|
||||||
REPORT_PATTERN: clang_tidy_reports/**/*.txt
|
REPORT_PATTERN: clang_tidy_reports/**/*.txt
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- $REPORT_PATTERN
|
- $REPORT_PATTERN
|
||||||
expire_in: 1 week
|
|
||||||
dependencies: # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
|
dependencies: # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
|
||||||
- clang_tidy_check
|
- clang_tidy_check
|
||||||
|
|
||||||
|
@ -18,13 +18,11 @@
|
|||||||
extends:
|
extends:
|
||||||
- .target_test_template
|
- .target_test_template
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- XUNIT_RESULT.xml
|
- XUNIT_RESULT.xml
|
||||||
- pytest_embedded_log/
|
- pytest_embedded_log/
|
||||||
reports:
|
reports:
|
||||||
junit: XUNIT_RESULT.xml
|
junit: XUNIT_RESULT.xml
|
||||||
expire_in: 1 week
|
|
||||||
script:
|
script:
|
||||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||||
# get runner env config file
|
# get runner env config file
|
||||||
|
@ -91,20 +91,13 @@ repos:
|
|||||||
always_run: true
|
always_run: true
|
||||||
files: '\.gitlab/CODEOWNERS'
|
files: '\.gitlab/CODEOWNERS'
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
- id: check-rules-yml
|
|
||||||
name: Check rules.yml all rules have at lease one job applied, all rules needed exist
|
|
||||||
entry: tools/ci/check_rules_yml.py
|
|
||||||
language: python
|
|
||||||
files: '\.gitlab/ci/.+\.yml|\.gitlab-ci.yml|\.gitmodules'
|
|
||||||
pass_filenames: false
|
|
||||||
additional_dependencies:
|
|
||||||
- PyYAML == 5.3.1
|
|
||||||
- id: check-generated-rules
|
- id: check-generated-rules
|
||||||
name: Check rules are generated (based on .gitlab/ci/dependencies/dependencies.yml)
|
name: Check rules are generated (based on .gitlab/ci/dependencies/dependencies.yml)
|
||||||
entry: tools/ci/generate_rules.py
|
entry: tools/ci/generate_rules.py
|
||||||
language: python
|
language: python
|
||||||
files: '\.gitlab/ci/dependencies/.+|\.gitlab/ci/.*\.yml'
|
files: '\.gitlab/ci/dependencies/.+|\.gitlab/ci/.*\.yml'
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
require_serial: true
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- PyYAML == 5.3.1
|
- PyYAML == 5.3.1
|
||||||
- id: mypy-check
|
- id: mypy-check
|
||||||
@ -185,6 +178,14 @@ repos:
|
|||||||
language: python
|
language: python
|
||||||
always_run: true
|
always_run: true
|
||||||
require_serial: true
|
require_serial: true
|
||||||
|
- id: gitlab-yaml-linter
|
||||||
|
name: Check gitlab yaml files
|
||||||
|
entry: tools/ci/gitlab_yaml_linter.py
|
||||||
|
language: python
|
||||||
|
files: '\.gitlab-ci\.yml|\.gitlab/ci/.+\.yml'
|
||||||
|
pass_filenames: false
|
||||||
|
additional_dependencies:
|
||||||
|
- PyYAML == 5.3.1
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.0.1
|
rev: v4.0.1
|
||||||
hooks:
|
hooks:
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
# internal use only
|
|
||||||
# check if expire time is set for all artifacts
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
IDF_PATH = os.getenv('IDF_PATH')
|
|
||||||
if not IDF_PATH:
|
|
||||||
print('Please set IDF_PATH before running this script')
|
|
||||||
raise SystemExit(-1)
|
|
||||||
|
|
||||||
GITLAB_CONFIG_FILE = os.path.join(IDF_PATH, '.gitlab-ci.yml')
|
|
||||||
|
|
||||||
|
|
||||||
def check_artifacts_expire_time() -> None:
|
|
||||||
with open(GITLAB_CONFIG_FILE, 'r') as f:
|
|
||||||
config = yaml.load(f, Loader=yaml.FullLoader)
|
|
||||||
|
|
||||||
# load files listed in `include`
|
|
||||||
if 'include' in config:
|
|
||||||
for _file in config['include']:
|
|
||||||
with open(os.path.join(IDF_PATH or '', _file)) as f:
|
|
||||||
config.update(yaml.load(f, Loader=yaml.FullLoader))
|
|
||||||
|
|
||||||
print('expire time for jobs:')
|
|
||||||
errors = []
|
|
||||||
|
|
||||||
job_names = list(config.keys())
|
|
||||||
job_names.sort()
|
|
||||||
|
|
||||||
for job_name in job_names:
|
|
||||||
try:
|
|
||||||
if 'expire_in' not in config[job_name]['artifacts']:
|
|
||||||
errors.append(job_name)
|
|
||||||
else:
|
|
||||||
print('{}: {}'.format(job_name, config[job_name]['artifacts']['expire_in']))
|
|
||||||
except (KeyError, TypeError):
|
|
||||||
# this is not job, or the job does not have artifacts
|
|
||||||
pass
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
print('\n\nThe following jobs did not set expire time for its artifacts')
|
|
||||||
for error in errors:
|
|
||||||
print(error)
|
|
||||||
raise SystemExit(-2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
check_artifacts_expire_time()
|
|
@ -1,157 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
"""
|
|
||||||
Check if all rules in rules.yml used or not in CI yaml files.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
from copy import deepcopy
|
|
||||||
from typing import Any, Dict, List, Optional, Set, Union
|
|
||||||
|
|
||||||
import yaml
|
|
||||||
from idf_ci_utils import IDF_PATH
|
|
||||||
|
|
||||||
ROOT_YML_FP = os.path.join(IDF_PATH, '.gitlab-ci.yml')
|
|
||||||
|
|
||||||
|
|
||||||
def load_yaml(file_path: str) -> Any:
|
|
||||||
return yaml.load(open(file_path), Loader=yaml.FullLoader)
|
|
||||||
|
|
||||||
|
|
||||||
class YMLConfig:
|
|
||||||
def __init__(self, root_yml_file_path: str) -> None:
|
|
||||||
self._config: Optional[Dict] = None
|
|
||||||
self._all_extends: Optional[Set] = None
|
|
||||||
|
|
||||||
self.root_yml = load_yaml(root_yml_file_path)
|
|
||||||
assert self.root_yml
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _list(str_or_list: Union[str, List]) -> List:
|
|
||||||
if isinstance(str_or_list, str):
|
|
||||||
return [str_or_list]
|
|
||||||
if isinstance(str_or_list, list):
|
|
||||||
return str_or_list
|
|
||||||
raise ValueError(
|
|
||||||
'Wrong type: {}. Only supports str or list.'.format(type(str_or_list))
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def config(self) -> Dict:
|
|
||||||
if self._config:
|
|
||||||
return self._config
|
|
||||||
|
|
||||||
all_config = dict()
|
|
||||||
for item in self.root_yml['include']:
|
|
||||||
all_config.update(load_yaml(os.path.join(IDF_PATH, item)))
|
|
||||||
self._config = all_config
|
|
||||||
return self._config
|
|
||||||
|
|
||||||
@property
|
|
||||||
def all_extends(self) -> Set:
|
|
||||||
if self._all_extends:
|
|
||||||
return self._all_extends
|
|
||||||
|
|
||||||
res = set([])
|
|
||||||
for v in self.config.values():
|
|
||||||
if 'extends' in v:
|
|
||||||
for item in self._list(v['extends']):
|
|
||||||
if item.startswith('.rules:'):
|
|
||||||
res.add(item)
|
|
||||||
self._all_extends = res
|
|
||||||
return self._all_extends
|
|
||||||
|
|
||||||
def exists(self, key: str) -> bool:
|
|
||||||
if key in self.all_extends:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
YML_CONFIG = YMLConfig(ROOT_YML_FP)
|
|
||||||
|
|
||||||
|
|
||||||
def get_needed_rules() -> Set[str]:
|
|
||||||
return deepcopy(YML_CONFIG.all_extends)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_needed_rules(rules_yml: 'os.PathLike[str]') -> int:
|
|
||||||
res = 0
|
|
||||||
needed_rules = deepcopy(YML_CONFIG.all_extends)
|
|
||||||
with open(rules_yml) as fr:
|
|
||||||
for index, line in enumerate(fr):
|
|
||||||
if line.startswith('.rules:'):
|
|
||||||
key = line.strip().rsplit(':', 1)[0]
|
|
||||||
if not YML_CONFIG.exists(key):
|
|
||||||
print(
|
|
||||||
'{}:{}:WARNING:rule "{}" unused'.format(rules_yml, index, key)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
needed_rules.remove(key)
|
|
||||||
|
|
||||||
if needed_rules:
|
|
||||||
for item in needed_rules:
|
|
||||||
print('ERROR: missing rule: "{}"'.format(item))
|
|
||||||
res = 1
|
|
||||||
|
|
||||||
if res == 0:
|
|
||||||
print('Pass')
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def parse_submodule_paths(
|
|
||||||
gitsubmodules: str = os.path.join(IDF_PATH, '.gitmodules')
|
|
||||||
) -> List[str]:
|
|
||||||
path_regex = re.compile(r'^\s+path = (.+)$', re.MULTILINE)
|
|
||||||
with open(gitsubmodules, 'r') as f:
|
|
||||||
data = f.read()
|
|
||||||
|
|
||||||
res = []
|
|
||||||
for item in path_regex.finditer(data):
|
|
||||||
res.append(item.group(1))
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def validate_submodule_patterns() -> int:
|
|
||||||
submodule_paths = sorted(['.gitmodules'] + parse_submodule_paths())
|
|
||||||
submodule_paths_in_patterns = sorted(
|
|
||||||
YML_CONFIG.config.get('.patterns-submodule', [])
|
|
||||||
)
|
|
||||||
|
|
||||||
res = 0
|
|
||||||
if submodule_paths != submodule_paths_in_patterns:
|
|
||||||
res = 1
|
|
||||||
print('please update the pattern ".patterns-submodule"')
|
|
||||||
should_remove = set(submodule_paths_in_patterns) - set(submodule_paths)
|
|
||||||
if should_remove:
|
|
||||||
print(f'- should remove: {should_remove}')
|
|
||||||
should_add = set(submodule_paths) - set(submodule_paths_in_patterns)
|
|
||||||
if should_add:
|
|
||||||
print(f'- should add: {should_add}')
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
|
||||||
parser.add_argument(
|
|
||||||
'rules_yml',
|
|
||||||
nargs='?',
|
|
||||||
default=os.path.join(IDF_PATH, '.gitlab', 'ci', 'rules.yml'),
|
|
||||||
help='rules.yml file path',
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
exit_code = 0
|
|
||||||
if validate_needed_rules(args.rules_yml):
|
|
||||||
exit_code = 1
|
|
||||||
if validate_submodule_patterns():
|
|
||||||
exit_code = 1
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
@ -40,3 +40,4 @@ tools/templates/sample_component/main.c
|
|||||||
tools/ci/cleanup_ignore_lists.py
|
tools/ci/cleanup_ignore_lists.py
|
||||||
tools/ci/artifacts_handler.py
|
tools/ci/artifacts_handler.py
|
||||||
tools/unit-test-app/**/*
|
tools/unit-test-app/**/*
|
||||||
|
tools/ci/gitlab_yaml_linter.py
|
||||||
|
@ -62,7 +62,6 @@ tools/ci/check_kconfigs.py
|
|||||||
tools/ci/check_readme_links.py
|
tools/ci/check_readme_links.py
|
||||||
tools/ci/check_requirement_files.py
|
tools/ci/check_requirement_files.py
|
||||||
tools/ci/check_rules_components_patterns.py
|
tools/ci/check_rules_components_patterns.py
|
||||||
tools/ci/check_rules_yml.py
|
|
||||||
tools/ci/check_soc_struct_headers.py
|
tools/ci/check_soc_struct_headers.py
|
||||||
tools/ci/check_tools_files_patterns.py
|
tools/ci/check_tools_files_patterns.py
|
||||||
tools/ci/check_type_comments.py
|
tools/ci/check_type_comments.py
|
||||||
@ -74,6 +73,7 @@ tools/ci/fix_empty_prototypes.sh
|
|||||||
tools/ci/generate_rules.py
|
tools/ci/generate_rules.py
|
||||||
tools/ci/get-full-sources.sh
|
tools/ci/get-full-sources.sh
|
||||||
tools/ci/get_supported_examples.sh
|
tools/ci/get_supported_examples.sh
|
||||||
|
tools/ci/gitlab_yaml_linter.py
|
||||||
tools/ci/mirror-submodule-update.sh
|
tools/ci/mirror-submodule-update.sh
|
||||||
tools/ci/multirun_with_pyenv.sh
|
tools/ci/multirun_with_pyenv.sh
|
||||||
tools/ci/push_to_github.sh
|
tools/ci/push_to_github.sh
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@ -11,8 +11,7 @@ from collections import defaultdict
|
|||||||
from itertools import product
|
from itertools import product
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from check_rules_yml import get_needed_rules
|
from idf_ci_utils import IDF_PATH, GitlabYmlConfig
|
||||||
from idf_ci_utils import IDF_PATH
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pygraphviz as pgv
|
import pygraphviz as pgv
|
||||||
@ -100,6 +99,7 @@ class RulesWriter:
|
|||||||
self.cfg = self.expand_matrices()
|
self.cfg = self.expand_matrices()
|
||||||
self.rules = self.expand_rules()
|
self.rules = self.expand_rules()
|
||||||
|
|
||||||
|
self.yml_config = GitlabYmlConfig()
|
||||||
self.graph = None
|
self.graph = None
|
||||||
|
|
||||||
def expand_matrices(self): # type: () -> dict
|
def expand_matrices(self): # type: () -> dict
|
||||||
@ -201,7 +201,7 @@ class RulesWriter:
|
|||||||
def new_rules_str(self): # type: () -> str
|
def new_rules_str(self): # type: () -> str
|
||||||
res = []
|
res = []
|
||||||
for k, v in sorted(self.rules.items()):
|
for k, v in sorted(self.rules.items()):
|
||||||
if '.rules:' + k not in get_needed_rules():
|
if '.rules:' + k not in self.yml_config.used_rules:
|
||||||
print(f'WARNING: unused rule: {k}, skipping...')
|
print(f'WARNING: unused rule: {k}, skipping...')
|
||||||
continue
|
continue
|
||||||
res.append(self.RULES_TEMPLATE.format(k, self._format_rule(k, v)))
|
res.append(self.RULES_TEMPLATE.format(k, self._format_rule(k, v)))
|
||||||
|
100
tools/ci/gitlab_yaml_linter.py
Executable file
100
tools/ci/gitlab_yaml_linter.py
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
"""
|
||||||
|
Check gitlab ci yaml files
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import typing as t
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
from idf_ci_utils import IDF_PATH, GitlabYmlConfig, get_submodule_dirs
|
||||||
|
|
||||||
|
|
||||||
|
class YmlLinter:
|
||||||
|
def __init__(self, yml_config: GitlabYmlConfig) -> None:
|
||||||
|
self.yml_config = yml_config
|
||||||
|
|
||||||
|
self._errors: t.List[str] = []
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def lint_functions(self) -> t.List[str]:
|
||||||
|
funcs = []
|
||||||
|
for func in dir(self):
|
||||||
|
if func.startswith('_lint_'):
|
||||||
|
funcs.append(func)
|
||||||
|
|
||||||
|
return funcs
|
||||||
|
|
||||||
|
def lint(self) -> None:
|
||||||
|
exit_code = 0
|
||||||
|
|
||||||
|
for func in self.lint_functions:
|
||||||
|
getattr(self, func)()
|
||||||
|
|
||||||
|
if self._errors:
|
||||||
|
print(f'Errors found while running {func}:')
|
||||||
|
exit_code = 1
|
||||||
|
print('\t- ' + '\n\t- '.join(self._errors))
|
||||||
|
self._errors = [] # reset
|
||||||
|
|
||||||
|
exit(exit_code)
|
||||||
|
|
||||||
|
# name it like _1_ to make it run first
|
||||||
|
def _lint_1_yml_parser(self) -> None:
|
||||||
|
for k, v in self.yml_config.config.items():
|
||||||
|
if (
|
||||||
|
k not in self.yml_config.global_keys
|
||||||
|
and k not in self.yml_config.anchors
|
||||||
|
and k not in self.yml_config.jobs
|
||||||
|
):
|
||||||
|
raise SystemExit(f'Parser incorrect. Key {k} not in global keys, rules or jobs')
|
||||||
|
|
||||||
|
def _lint_default_values_artifacts(self) -> None:
|
||||||
|
defaults_artifacts = self.yml_config.default.get('artifacts', {})
|
||||||
|
|
||||||
|
for job_name, d in self.yml_config.jobs.items():
|
||||||
|
for k, v in d.get('artifacts', {}).items():
|
||||||
|
if k not in defaults_artifacts:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if v == defaults_artifacts[k]:
|
||||||
|
self._errors.append(f'job {job_name} key {k} has same value as default value {v}')
|
||||||
|
|
||||||
|
def _lint_submodule_patterns(self) -> None:
|
||||||
|
submodule_paths = sorted(['.gitmodules'] + get_submodule_dirs())
|
||||||
|
submodule_paths_in_patterns = sorted(self.yml_config.config.get('.patterns-submodule', []))
|
||||||
|
|
||||||
|
if submodule_paths != submodule_paths_in_patterns:
|
||||||
|
unused_patterns = set(submodule_paths_in_patterns) - set(submodule_paths)
|
||||||
|
if unused_patterns:
|
||||||
|
for item in unused_patterns:
|
||||||
|
self._errors.append(f'non-exist pattern {item}. Please remove {item} from .patterns-submodule')
|
||||||
|
undefined_patterns = set(submodule_paths) - set(submodule_paths_in_patterns)
|
||||||
|
if undefined_patterns:
|
||||||
|
for item in undefined_patterns:
|
||||||
|
self._errors.append(f'undefined pattern {item}. Please add {item} to .patterns-submodule')
|
||||||
|
|
||||||
|
def _lint_gitlab_yml_rules(self) -> None:
|
||||||
|
unused_rules = self.yml_config.rules - self.yml_config.used_rules
|
||||||
|
for item in unused_rules:
|
||||||
|
self._errors.append(f'Unused rule: {item}, please remove it')
|
||||||
|
undefined_rules = self.yml_config.used_rules - self.yml_config.rules
|
||||||
|
for item in undefined_rules:
|
||||||
|
self._errors.append(f'Undefined rule: {item}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
'--root-yml-filepath', help='root yml file path', default=os.path.join(IDF_PATH, '.gitlab-ci.yml')
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
config = GitlabYmlConfig(args.root_yml_filepath)
|
||||||
|
linter = YmlLinter(config)
|
||||||
|
linter.lint()
|
@ -8,12 +8,13 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from typing import Any, List
|
import typing as t
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..')))
|
IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||||
|
|
||||||
|
|
||||||
def get_submodule_dirs(full_path: bool = False) -> List[str]:
|
def get_submodule_dirs(full_path: bool = False) -> t.List[str]:
|
||||||
"""
|
"""
|
||||||
To avoid issue could be introduced by multi-os or additional dependency,
|
To avoid issue could be introduced by multi-os or additional dependency,
|
||||||
we use python and git to get this output
|
we use python and git to get this output
|
||||||
@ -71,7 +72,7 @@ def is_executable(full_path: str) -> bool:
|
|||||||
return os.access(full_path, os.X_OK)
|
return os.access(full_path, os.X_OK)
|
||||||
|
|
||||||
|
|
||||||
def get_git_files(path: str = IDF_PATH, full_path: bool = False) -> List[str]:
|
def get_git_files(path: str = IDF_PATH, full_path: bool = False) -> t.List[str]:
|
||||||
"""
|
"""
|
||||||
Get the result of git ls-files
|
Get the result of git ls-files
|
||||||
:param path: path to run git ls-files
|
:param path: path to run git ls-files
|
||||||
@ -102,7 +103,10 @@ def is_in_directory(file_path: str, folder: str) -> bool:
|
|||||||
return os.path.realpath(file_path).startswith(os.path.realpath(folder) + os.sep)
|
return os.path.realpath(file_path).startswith(os.path.realpath(folder) + os.sep)
|
||||||
|
|
||||||
|
|
||||||
def to_list(s: Any) -> List[Any]:
|
def to_list(s: t.Any) -> t.List[t.Any]:
|
||||||
|
if not s:
|
||||||
|
return []
|
||||||
|
|
||||||
if isinstance(s, (set, tuple)):
|
if isinstance(s, (set, tuple)):
|
||||||
return list(s)
|
return list(s)
|
||||||
|
|
||||||
@ -110,3 +114,67 @@ def to_list(s: Any) -> List[Any]:
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
return [s]
|
return [s]
|
||||||
|
|
||||||
|
|
||||||
|
class GitlabYmlConfig:
|
||||||
|
def __init__(self, root_yml_filepath: str = os.path.join(IDF_PATH, '.gitlab-ci.yml')) -> None:
|
||||||
|
self._config: t.Dict[str, t.Any] = {}
|
||||||
|
self._defaults: t.Dict[str, t.Any] = {}
|
||||||
|
|
||||||
|
self._load(root_yml_filepath)
|
||||||
|
|
||||||
|
def _load(self, root_yml_filepath: str) -> None:
|
||||||
|
# avoid unused import in other pre-commit hooks
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
all_config = dict()
|
||||||
|
root_yml = yaml.load(open(root_yml_filepath), Loader=yaml.FullLoader)
|
||||||
|
for item in root_yml['include']:
|
||||||
|
all_config.update(yaml.load(open(os.path.join(IDF_PATH, item)), Loader=yaml.FullLoader))
|
||||||
|
|
||||||
|
if 'default' in all_config:
|
||||||
|
self._defaults = all_config.pop('default')
|
||||||
|
|
||||||
|
self._config = all_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default(self) -> t.Dict[str, t.Any]:
|
||||||
|
return self._defaults
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config(self) -> t.Dict[str, t.Any]:
|
||||||
|
return self._config
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def global_keys(self) -> t.List[str]:
|
||||||
|
return ['default', 'include', 'workflow', 'variables', 'stages']
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def anchors(self) -> t.Dict[str, t.Any]:
|
||||||
|
return {k: v for k, v in self.config.items() if k.startswith('.')}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def jobs(self) -> t.Dict[str, t.Any]:
|
||||||
|
return {k: v for k, v in self.config.items() if not k.startswith('.') and k not in self.global_keys}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def rules(self) -> t.Set[str]:
|
||||||
|
return {k for k, _ in self.anchors.items() if self._is_rule_key(k)}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def used_rules(self) -> t.Set[str]:
|
||||||
|
res = set()
|
||||||
|
|
||||||
|
for v in self.config.values():
|
||||||
|
if not isinstance(v, dict):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for item in to_list(v.get('extends')):
|
||||||
|
if self._is_rule_key(item):
|
||||||
|
res.add(item)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_rule_key(key: str) -> bool:
|
||||||
|
return key.startswith('.rules:') or key.endswith('template')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user