also render unchange table (#3390)

* also render unchange table
* run metrics with circleci (full all boards build)
This commit is contained in:
Ha Thach
2025-12-05 20:12:45 +07:00
committed by GitHub
parent 93b53158f0
commit e73dfde96d
4 changed files with 126 additions and 20 deletions

View File

@ -9,7 +9,7 @@ jobs:
executor: continuation/default executor: continuation/default
docker: docker:
- image: cimg/base:current - image: cimg/base:current
resource_class: small resource_class: large
steps: steps:
- checkout - checkout
- run: - run:
@ -52,8 +52,8 @@ jobs:
else else
echo " - build:" >> .circleci/config2.yml echo " - build:" >> .circleci/config2.yml
fi fi
echo " matrix:" >> .circleci/config2.yml echo " matrix:" >> .circleci/config2.yml
echo " alias: build-${build_system}-${toolchain}" >> .circleci/config2.yml
echo " parameters:" >> .circleci/config2.yml echo " parameters:" >> .circleci/config2.yml
echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " build-system: ['$build_system']" >> .circleci/config2.yml
echo " toolchain: ['$toolchain']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml
@ -62,6 +62,9 @@ jobs:
echo " build-args: ['$build_args']" >> .circleci/config2.yml echo " build-args: ['$build_args']" >> .circleci/config2.yml
} }
# Collect all build aliases for code-metrics requires (cmake only, exclude esp-idf)
BUILD_ALIASES=()
for build_system in "${BUILDSYSTEM_LIST[@]}"; do for build_system in "${BUILDSYSTEM_LIST[@]}"; do
for toolchain in "${TOOLCHAIN_LIST[@]}"; do for toolchain in "${TOOLCHAIN_LIST[@]}"; do
# make does not support these toolchains # make does not support these toolchains
@ -72,9 +75,21 @@ jobs:
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"")
echo "FAMILY_${toolchain}=$FAMILY" echo "FAMILY_${toolchain}=$FAMILY"
gen_build_entry "$build_system" "$toolchain" "$FAMILY" gen_build_entry "$build_system" "$toolchain" "$FAMILY"
# Only add cmake builds: excluding esp-idf or build_args="--one-random" to metrics requirements
if [ "$build_system" == "cmake" ] && [ "$toolchain" != "esp-idf" ] && [ "$toolchain" != "arm-iar" ]; then
BUILD_ALIASES+=("build-${build_system}-${toolchain}")
fi
done done
done done
# Add code-metrics job that requires all build jobs
echo " - code-metrics:" >> .circleci/config2.yml
echo " requires:" >> .circleci/config2.yml
for alias in "${BUILD_ALIASES[@]}"; do
echo " - $alias" >> .circleci/config2.yml
done
- continuation/continue: - continuation/continue:
configuration_path: .circleci/config2.yml configuration_path: .circleci/config2.yml

View File

@ -127,6 +127,35 @@ commands:
python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >> python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >>
fi fi
# Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random)
- when:
condition:
and:
- equal: [ cmake, << parameters.build-system >> ]
- not:
equal: [ esp-idf, << parameters.toolchain >> ]
- not:
equal: [ arm-iar, << parameters.toolchain >> ]
steps:
- run:
name: Collect Metrics
command: |
# Create unique directory per toolchain to avoid workspace conflicts
METRICS_DIR="/tmp/metrics/<< parameters.toolchain >>"
mkdir -p "${METRICS_DIR}"
# Copy all metrics.json files
for f in cmake-build/cmake-build-*/metrics.json; do
if [ -f "$f" ]; then
BOARD_DIR=$(dirname "$f" | xargs basename)
cp "$f" "${METRICS_DIR}/${BOARD_DIR}.json"
fi
done
- persist_to_workspace:
root: /tmp
paths:
- metrics/<< parameters.toolchain >>
jobs: jobs:
# Build using docker # Build using docker
build: build:
@ -146,6 +175,7 @@ jobs:
docker: docker:
- image: cimg/base:current - image: cimg/base:current
working_directory: ~/project/tinyusb
resource_class: << parameters.resource_class >> resource_class: << parameters.resource_class >>
steps: steps:
@ -173,6 +203,7 @@ jobs:
machine: machine:
image: ubuntu-2404:current image: ubuntu-2404:current
working_directory: ~/project/tinyusb
resource_class: << parameters.resource_class >> resource_class: << parameters.resource_class >>
steps: steps:
@ -182,20 +213,79 @@ jobs:
family: << parameters.family >> family: << parameters.family >>
build-args: << parameters.build-args >> build-args: << parameters.build-args >>
# Aggregate code metrics from all builds
code-metrics:
docker:
- image: cimg/python:3.12
resource_class: large
steps:
- checkout
- attach_workspace:
at: /tmp
- run:
name: Aggregate Code Metrics
command: |
python tools/get_deps.py
pip install tools/linkermap/
# Combine all metrics files from all toolchain subdirectories
ls -R /tmp/metrics
if ls /tmp/metrics/*/*.json 1> /dev/null 2>&1; then
python tools/metrics.py combine -j -m -f tinyusb/src /tmp/metrics/*/*.json
else
echo "No metrics files found"
exit 1
fi
- store_artifacts:
path: metrics.json
destination: metrics.json
# Compare with base master metrics on PR branches
- when:
condition:
not:
equal: [ master, << pipeline.git.branch >> ]
steps:
- run:
name: Download Base Branch Metrics
command: |
# Download metrics.json artifact from the latest successful build on master branch
mkdir -p base-metrics
# Use CircleCI API to get the latest artifact
curl -s -L "https://dl.circleci.com/api/v2/project/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/latest/artifacts?branch=master&filter=successful" \
-H "Circle-Token: ${CIRCLE_TOKEN:-}" | \
jq -r '.items[] | select(.path == "metrics.json") | .url' | \
head -1 | xargs -I {} curl -s -L -o base-metrics/metrics.json {} || true
- run:
name: Compare with Base Branch
command: |
if [ -f base-metrics/metrics.json ]; then
python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json
cat metrics_compare.md
else
echo "No base metrics found, skipping comparison"
cp metrics.md metrics_compare.md
fi
- store_artifacts:
path: metrics_compare.md
destination: metrics_compare.md
workflows: workflows:
build: build:
jobs: jobs:
# The jobs below are populated dynamically by config.yml set-matrix job
# Example entries that will be generated:
# - build: # - build:
# matrix: # matrix:
# alias: build-cmake-arm-gcc
# parameters: # parameters:
# toolchain: [ 'arm-gcc' ] # toolchain: [ 'arm-gcc' ]
# build-system: [ 'cmake' ] # build-system: [ 'cmake' ]
# family: [ 'nrf' ] # family: [ 'nrf' ]
# resource_class: ['large'] # resource_class: ['large']
# - build-vm: # - code-metrics:
# matrix: # requires:
# parameters: # - build-cmake-arm-gcc
# toolchain: ['esp-idf']
# build-system: ['cmake']
# family: ['-bespressif_kaluga_1']
# resource_class: ['large']

View File

@ -111,7 +111,7 @@ jobs:
path: metrics.json path: metrics.json
- name: Download Base Branch Metrics - name: Download Base Branch Metrics
if: github.event_name == 'pull_request' if: github.event_name != 'push'
uses: dawidd6/action-download-artifact@v11 uses: dawidd6/action-download-artifact@v11
with: with:
workflow: build.yml workflow: build.yml
@ -121,7 +121,7 @@ jobs:
continue-on-error: true continue-on-error: true
- name: Compare with Base Branch - name: Compare with Base Branch
if: github.event_name == 'pull_request' if: github.event_name != 'push'
run: | run: |
if [ -f base-metrics/metrics.json ]; then if [ -f base-metrics/metrics.json ]; then
python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json
@ -132,7 +132,7 @@ jobs:
fi fi
- name: Post Code Metrics as PR Comment - name: Post Code Metrics as PR Comment
if: github.event_name == 'pull_request' if: github.event_name != 'push'
uses: marocchino/sticky-pull-request-comment@v2 uses: marocchino/sticky-pull-request-comment@v2
with: with:
header: code-metrics header: code-metrics
@ -203,9 +203,7 @@ jobs:
# self-hosted on local VM, for attached hardware checkout HIL_JSON # self-hosted on local VM, for attached hardware checkout HIL_JSON
# --------------------------------------- # ---------------------------------------
hil-tinyusb: hil-tinyusb:
if: | if: github.repository_owner == 'hathach' && github.event_name != 'push'
github.repository_owner == 'hathach' &&
(github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch')
needs: hil-build needs: hil-build
runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ]
steps: steps:
@ -249,7 +247,7 @@ jobs:
if: | if: |
github.repository_owner == 'hathach' && github.repository_owner == 'hathach' &&
github.event.pull_request.head.repo.fork == false && github.event.pull_request.head.repo.fork == false &&
(github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') github.event_name != 'push'
runs-on: [ self-hosted, Linux, X64, hifiphile ] runs-on: [ self-hosted, Linux, X64, hifiphile ]
env: env:
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}

View File

@ -275,11 +275,13 @@ def write_compare_markdown(comparison, path, sort_order='size'):
significant = [] significant = []
minor = [] minor = []
unchanged = []
for f in sorted_files: for f in sorted_files:
# Skip files with no changes no_change = f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections)
if f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections): if no_change:
continue unchanged.append(f)
(significant if is_significant(f) else minor).append(f) else:
(significant if is_significant(f) else minor).append(f)
def render_table(title, rows): def render_table(title, rows):
md_lines.append(f"## {title}") md_lines.append(f"## {title}")
@ -323,6 +325,7 @@ def write_compare_markdown(comparison, path, sort_order='size'):
render_table("Changes >1% in any section", significant) render_table("Changes >1% in any section", significant)
render_table("Changes <1% in all sections", minor) render_table("Changes <1% in all sections", minor)
render_table("No changes", unchanged)
with open(path, "w", encoding="utf-8") as f: with open(path, "w", encoding="utf-8") as f:
f.write("\n".join(md_lines)) f.write("\n".join(md_lines))