<feed xmlns='http://www.w3.org/2005/Atom'>
<title>threadx.git/.github, branch v6.4.1_cert</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/threadx.git/atom/.github?h=v6.4.1_cert</id>
<link rel='self' href='http://cgit.235523.xyz/threadx.git/atom/.github?h=v6.4.1_cert'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/'/>
<updated>2026-09-27T20:29:07Z</updated>
<entry>
<title>Added an opt-in container options input to the regression template</title>
<updated>2026-09-27T20:29:07Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-27T20:29:07Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=559b066c7c1f19a8d19ece5db3f6f1f6ab7f5e6e'/>
<id>urn:sha1:559b066c7c1f19a8d19ece5db3f6f1f6ab7f5e6e</id>
<content type='text'>
The tests run in a container started with the default capability set, which
holds CAP_NET_RAW and not CAP_NET_ADMIN. That is right for every suite that
only compiles and runs code, and wrong for the two NetX Duo interoperability
suites: each of their tests builds a veth pair and addresses it, so every
configuration fails on its first test with "RTNETLINK answers: Operation not
permitted" before anything under test has run. Measured on the certification
branch, not predicted.

The container now takes an options string from the caller, empty unless a
caller sets it, so the two jobs that need CAP_NET_ADMIN ask for it and nothing
else changes. Granting it here for everyone would widen the privileges of five
suites with no use for it.

Proof: the template parses and the input defaults to empty, so every existing
caller produces the same container arguments as before.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Disabled the retry that reported hung and failing tests as passes</title>
<updated>2026-09-17T19:57:36Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-17T19:57:36Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=668e3f5f3ee587ed7e9ee3392eaada3ba89209f8'/>
<id>urn:sha1:668e3f5f3ee587ed7e9ee3392eaada3ba89209f8</id>
<content type='text'>
The regression runs pass ctest --repeat until-pass:2, so a test that fails or
hangs on its first attempt and passes on a second is reported as a pass. These
runs are certification evidence, and a green run has to mean the suite passed
rather than that it passed eventually.

The Test step sets CTEST_REPEAT_FAIL to 1, which the runner turns into
--repeat until-pass:1. The runner script is shared with the monoprocessor suite
by symlink and is unchanged, so running it by hand still retries unless asked
otherwise. Expect this branch to be red more often than it was: the SMP suite is
intermittent, and the retry is what has been hiding that.

Measured over 112 configuration runs of the SMP suite at the parent commit: four
were not green on the first attempt -- two tests hung for the full 1000-second
timeout and two failed outright -- and all fourteen runs reported success. With
the retry off, 108/108 in each of the eight configurations, wall clocks within
1.89 seconds of each other, union coverage 5386/5450 lines and 2812/3608
branches against a gate of 98.60 and 77.30.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Kept the certification branch's coverage reports for 90 days</title>
<updated>2026-09-16T18:00:09Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-16T18:00:09Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=ef4c12f5b19c5715b1846166c8741ff0dcb6808d'/>
<id>urn:sha1:ef4c12f5b19c5715b1846166c8741ff0dcb6808d</id>
<content type='text'>
Both coverage artifacts were uploaded with a one-day life. That is right for a
report whose job is to answer "what moved in this run", and wrong for the same
report on the certification branch, where it is evidence: a day after the run
that produced it, the run resolves to a log and a green tick with no reports
attached, and the figures have to be taken on trust.

The certification branch now keeps both for the repository's own default of 90
days, which is already what the test results from the same job get. Every other
branch is unchanged at one day.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Pinned the regression container by digest as well as by tag</title>
<updated>2026-09-16T17:35:58Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-16T17:35:58Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=f4490360f390cc7801d993eb25d32bb4059d42b4'/>
<id>urn:sha1:f4490360f390cc7801d993eb25d32bb4059d42b4</id>
<content type='text'>
The job named its base image by tag alone. Debian moves that tag on every point
release, so the image the coverage evidence is built on could change with no
change here -- and a certificate that names a tag names something that cannot
be resolved back to what was measured.

The image is now pinned by digest. This fixes the base only: gcc, CMake and
Ninja are installed from the Debian archive at run time and still arrive at
whatever version it carries, which is what the version assertions in
scripts/install.sh are for.

The digest is the one the current evidence run pulled, and the tag still
resolves to it, so nothing about the built environment changes.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Granted the reusable workflow calls the permissions their jobs request</title>
<updated>2026-09-14T23:29:00Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-14T23:29:00Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=63f6ea77bfe34877315f611b48a02deb625ee0da'/>
<id>urn:sha1:63f6ea77bfe34877315f611b48a02deb625ee0da</id>
<content type='text'>
Every run on this branch ended in startup_failure with no jobs scheduled, no
log and no annotation. Dispatching v6.4.1_rel's own unmodified workflow fails
identically, so this predates the certification branch.

A reusable workflow cannot hold more permission than the job that calls it.
regression_template.yml's own jobs ask for checks: write and pull-requests:
write, and its deploy job asks for pages: write and id-token: write, but the
calling jobs here declared nothing at all and so got the repository default.
Once that default became read-only the calls began to be rejected while the run
graph was being built, which is why the failure arrives before any job exists to
carry the error.

Each calling job now spells out the same set, which is what master's successor
branches already do.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Updated the workflow actions so the regression suites can run at all</title>
<updated>2026-09-14T23:27:32Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-14T23:27:32Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=36c5708eaa693ceeb5df03c66791a8695ba1a524'/>
<id>urn:sha1:36c5708eaa693ceeb5df03c66791a8695ba1a524</id>
<content type='text'>
Every workflow run on this branch ended in startup_failure with no jobs
scheduled. The same happens on v6.4.1_rel itself, dispatched unmodified, so this
is the tag's CI configuration having aged out rather than anything the
certification branch changed: the actions it pins date from 2023 and several
declare runtimes GitHub has since removed.

References are now pinned by commit SHA with the version in a trailing comment,
which is both what upstream already runs and the right shape for evidence -- a
tag can be moved, a SHA cannot.

  actions/checkout                           v4      -&gt; v7.0.1
  actions/upload-artifact                    v3.1.3  -&gt; v7.0.1
  actions/download-artifact                  v3      -&gt; v8.0.1
  actions/upload-pages-artifact              v2.0.0  -&gt; v5.0.0
  actions/configure-pages                    v3.0.6  -&gt; v6.0.0
  actions/deploy-pages                       v1.2.9  -&gt; v5.0.0
  EnricoMi/publish-unit-test-result-action   v2.11.0 -&gt; v2.24.0
  LouisBrunner/checks-action                 v1.6.2  -&gt; v3.1.0
  marocchino/sticky-pull-request-comment     v2      -&gt; v3.0.5
  geekyeggo/delete-artifact                  v2      -&gt; v6.0.0
  irongut/CodeCoverageSummary                v1.3.0, pinned to its SHA

One of those is not a version bump on its own. Both suites uploaded an artifact
named coverage_report and relied on the two merging; upload-artifact refuses a
name another job has already used from v4 onwards, so the second suite would
have failed. The name is now unique per job and the deploy job collects them
with a coverage_report-* pattern and merge-multiple, which also keeps the run
timestamp out of the published path. The deletion step matches the same pattern.

The runners are pinned to ubuntu-24.04 for the same reason the container is
pinned: "latest" moves, and this branch is a fixed baseline.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Pinned the certification build environment and enabled CI on the certification branch</title>
<updated>2026-09-14T22:06:27Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-14T22:06:27Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=f38bc2151e1c30390f19d36613537bc5ce4ddec7'/>
<id>urn:sha1:f38bc2151e1c30390f19d36613537bc5ce4ddec7</id>
<content type='text'>
The regression workflows ran on ubuntu-latest with nothing pinned, and the
coverage numbers they produce are certification evidence. Two things follow from
that, and the first is urgent rather than theoretical.

These sources declare cmake_minimum_required(VERSION 3.0.0) and CMake removed
compatibility below 3.5 in 4.0, so this branch stops configuring the day the
hosted image moves to CMake 4.x -- no change here, no warning. Worse, the branch
did not need GitHub's help to get there: scripts/install.sh ran

  pip install --upgrade cmake

which installs exactly the CMake version that cannot configure these sources. It
also installed gcovr 4.1, which is far too old for the tracefile and threshold
options the coverage scripts use, and called sudo, which does not exist in a
container.

The job now runs inside debian:trixie, which carries GCC 14, gcc-multilib and
CMake 3.31.6. Being below 4.x, that configures the sources with no policy
override and no edit to CMakeLists.txt. The coverage build is 32-bit, so multilib
is not optional. install.sh installs the distribution toolchain plus gcovr 8.6,
prints all three versions into the job log, and then asserts them: GCC major 14,
CMake major below 4, gcovr exactly 8.6. The image tag is a moving target that
point releases rebuild, and a toolchain that drifts should fail by name and
number rather than quietly produce evidence built with something else.

git is installed before the checkout, because actions/checkout otherwise falls
back to a REST API tarball and leaves no .git behind, and the commit the evidence
was built from is part of the evidence. The Pages preparation step no longer
calls sudo, since the steps run as root in the container.

Nothing gated on the coverage number before: it was published, not enforced.
coverage.sh --merge now ends with a gcovr pass carrying --fail-under-line and
--fail-under-branch, after the reports are written so a failed gate still leaves
the report that explains it.

  ThreadX   99.50% line   80.00% branch
  SMP       99.40% line   83.00% branch

These are a ratchet, raised as each batch of gaps closes, and deliberately not
100%: a gate nothing can pass gets switched off. They sit below the measured
figures rather than at them, because the same tree does not measure identically
twice -- branches on the resume-from-ISR path are reached or missed depending on
how the host schedules the run, and two clean runs of the ThreadX suite differ by
2 lines and 19 branches. A gate set at the best observation fails on a tree
nobody changed.

Verified by raising each threshold above the measurement: line returns 2, branch
returns 4, the merged report is still written, and run.sh reports the failure
rather than swallowing it -- a run with all 95 tests passing exits 2 when the
line gate is not met.

regression_test.yml now triggers on the certification branch as well as master.
regression_template.yml needed no filter; it is workflow_call only.

Publishing stays on master. The deploy job replaces the project's public coverage
site wholesale and its condition fires on any push, so without a guard the first
push of this branch would have published its numbers as the project's. The
certification branch produces its evidence as workflow artifacts instead.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Instrumented every build configuration and merged their coverage</title>
<updated>2026-09-14T21:37:19Z</updated>
<author>
<name>Frédéric Desbiens</name>
<email>frederic.desbiens@eclipse-foundation.org</email>
</author>
<published>2026-09-14T21:37:19Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=56ba96c1c5910a40f48597d70c6b1aa3badec8f5'/>
<id>urn:sha1:56ba96c1c5910a40f48597d70c6b1aa3badec8f5</id>
<content type='text'>
Only default_build_coverage carried -fprofile-arcs, because the gate was the
build type and it is the only one of five configurations whose name ends in
_coverage. The other four built and ran every test and their coverage was
discarded. That is not redundancy thrown away: each configuration selects a
different set of TX_ feature macros, so the code the other four compile was
absent from the denominator rather than uncovered in it, and 100% against that
report would not have been a measurement of the kernel.

TX_COVERAGE instruments a build regardless of its name, defaulting to OFF so a
single configuration built by hand behaves as before. coverage.sh gains a
--merge mode that unions the per-configuration JSON tracefiles, and
cmake_bootstrap.sh runs it after the test loop so a local run produces the same
merged report CI reads. The workflow template sets TX_COVERAGE for build and
test, and coverage_name moves to the merged report.

Measured on the ThreadX suite, all 95 tests passing in each configuration:

  default_build_coverage           3827 valid   3827 covered
  disable_notify_callbacks_build   3767         3767
  stack_checking_build             3857         3856
  stack_checking_rand_fill_build   3862         3861
  trace_build                      4123         4108
  merged                           4220         4204

The denominator grows by 393 lines and the figure moves from 100.00% to 99.62%.
The second one is honest, and the drop is the point rather than a regression:
the denominator now includes code the old report never counted. The union also
contains a file the old report did not contain at all --
tx_thread_stack_error_handler.c compiles only under TX_ENABLE_STACK_CHECKING, so
it was not listed at 0%, it was simply absent. 177 files becomes 178.

The scoping is the positional search path, not --object-directory. Left as
--object-directory while the gcovr root moved to the repository root, all five
configurations reported the union of every configuration's gcda: five identical
reports, and a merge of five copies of the same thing. Nothing about the
resulting percentage looks wrong, which is what makes it worth stating here.

Coverage collection moved out of test(). A failing ctest used to abort the
function before coverage.sh was reached, so the run whose behaviour changed was
the one that produced no report, and the gcda already existed by that point.
Collection now runs after the whole test loop, one configuration at a time,
which is also what --merge needs: every tracefile has to exist before the union
is taken. A coverage failure turns the run red but does not overwrite a test
failure's status.

Per-configuration output moved under coverage_report/per_configuration/ and is
excluded from the deployed artifact. The deploy merges the ThreadX and SMP
artifacts into one tree and every configuration directory has the same name in
both, so left at the top level one suite's would overwrite the other's on the
published site.

coverage.sh now fails when a report contains no files. gcovr treats an empty
report as success: it exits 0 and writes line-rate="1.0" alongside
lines-valid="0", so every downstream consumer reads "no data at all" as "100%
covered", and a coverage threshold cannot catch it because an empty report
passes any threshold.

The tx and smp runners are symlinks to scripts/cmake_bootstrap.sh, so they are
covered by the one change there.

Assisted-by: Claude Code (Opus 5) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Delete .github/workflows/codeql.yml</title>
<updated>2024-01-18T19:31:07Z</updated>
<author>
<name>Eric Wolz</name>
<email>ericwol@microsoft.com</email>
</author>
<published>2024-01-18T19:31:07Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=66954968b1ce32d5c9a23a666004fad3c18e6c58'/>
<id>urn:sha1:66954968b1ce32d5c9a23a666004fad3c18e6c58</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Update CODEOWNERS</title>
<updated>2024-01-11T21:48:24Z</updated>
<author>
<name>Eric Wolz</name>
<email>ericwol@microsoft.com</email>
</author>
<published>2024-01-11T21:48:24Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/threadx.git/commit/?id=1047cd72617bef305a914928317acf295c082caa'/>
<id>urn:sha1:1047cd72617bef305a914928317acf295c082caa</id>
<content type='text'>
</content>
</entry>
</feed>
