Added port consistency checks and wired them into CI and release preparation (#591)

Three defects reached the repository through the port trees recently, and each
of them is mechanically detectable without a cross compiler. Add
scripts/check_ports.sh, which looks for exactly those three, and give CI and
the release process the same command a contributor can run locally.

The generated Cortex-M ports must be reproducible from ports_arch. Fixes were
applied to the generated copies instead of the source for eight months, and the
next run of the copy scripts would have reverted them.

Preprocessor directives must balance. A fix left the Cortex-M85 IAR tx_port.h
with one more #endif than #if, so that header could not compile.

No port header may carry a statement outside a function body. A fix left a
second, headerless copy of a function body in the Cortex-M4 AC6 tx_port.h,
which is issue 569. The check tracks brace depth while skipping preprocessor
lines, multi-line macro bodies and comments, and reports assignments,
dereferences and control statements that land at file scope. Headers under
example_build are excluded, since those trees vendor third party SDK code.

A fourth section reports, without failing the run, on port families that have
no copy script and so cannot be checked for reproducibility. It currently
observes that the Cortex-M0 ac5, ac6 and keil ports lack the barriers their gnu
and iar siblings have.

ports_arch_check now calls the script rather than inlining a copy and diff, so
CI and the command line check the same things by the same definition, and the
workflow now triggers on pull requests to dev as well as master. Triggering on
master alone is why the drift went unseen. prepare_release.sh runs the checks
before it branches or rewrites anything, and stops if they fail, with
SKIP_PORT_CHECKS=1 as the escape hatch.

Each check was verified by reintroducing the defect it exists to catch and
confirming that the script fails, then confirming it passes on a clean tree.

Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
This commit is contained in:
Frédéric Desbiens
2026-08-09 10:48:29 -04:00
committed by GitHub
parent eb4ec4e3b5
commit 08b120d2bc
3 changed files with 262 additions and 20 deletions
+24 -20
View File
@@ -6,7 +6,10 @@ name: ports_arch_check
# events but only for the master branch
on:
pull_request:
branches: [ master ]
# dev is included as well as master. The check only ever ran against master,
# so eight months of port fixes merged into dev without it, and the ports
# drifted from ports_arch unnoticed.
branches: [ master, dev ]
paths:
- ".github/workflows/ports_arch_check.yml"
- 'common/**'
@@ -27,21 +30,20 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout sources recursively
uses: actions/checkout@v2
with:
token: ${{ secrets.REPO_SCOPED_TOKEN }}
submodules: true
# No token input: secrets are not available to pull requests from forks, so
# passing one made this job fail at checkout with "Input required and not
# supplied: token" and the check never evaluated anything. The default
# GITHUB_TOKEN is enough to check out a public repository, and the
# repository has no submodules.
- name: Checkout sources
uses: actions/checkout@v4
# Copy ports arch
- name: Copy ports arch
run: |
scripts/copy_armv7_m.sh && scripts/copy_armv8_m.sh && scripts/copy_module_armv7_m.sh
if [[ -n $(git status --porcelain -uno) ]]; then
echo "Ports for ARM architecture is not updated"
git status
exit 1
fi
# Check the port trees: the generated ports must be reproducible from
# ports_arch, and no port header may be left unbalanced or carrying code
# outside a function. The same script runs locally, so a contributor sees
# exactly what CI sees.
- name: Check ports
run: scripts/check_ports.sh
cortex-a:
# Check ports for cortex-a
@@ -50,11 +52,13 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout sources recursively
uses: actions/checkout@v2
with:
token: ${{ secrets.REPO_SCOPED_TOKEN }}
submodules: true
# No token input: secrets are not available to pull requests from forks, so
# passing one made this job fail at checkout with "Input required and not
# supplied: token" and the check never evaluated anything. The default
# GITHUB_TOKEN is enough to check out a public repository, and the
# repository has no submodules.
- name: Checkout sources
uses: actions/checkout@v4
# Copy ports arch
- name: Copy ports arch
+224
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -78,6 +78,20 @@ printf "\nThreadX release preparation\n"
printf " Repository : %s\n" "${REPO_ROOT}"
printf " Current version : %s\n" "${CURR_VER}"
printf " Target version : %s\n\n" "${VERSION}"
# --------------------------------------------------------------------------
# Port consistency checks
# --------------------------------------------------------------------------
# Run before anything is branched or rewritten, so a release is never cut on
# top of ports that have drifted from ports_arch or headers that cannot
# compile. Set SKIP_PORT_CHECKS=1 to proceed anyway.
if [ "${SKIP_PORT_CHECKS:-0}" = "1" ]; then
printf "Skipping the port consistency checks (SKIP_PORT_CHECKS=1).\n\n"
elif ! "${SCRIPT_DIR}/check_ports.sh"; then
printf "\nRelease preparation stopped: the port consistency checks failed.\n"
printf "Fix the problems above, or set SKIP_PORT_CHECKS=1 to proceed anyway.\n"
exit 1
fi
printf "Proceed with update? [y/N] "
read -r CONFIRM
case "${CONFIRM}" in