From 691db781205184efba350ab24eae6871dad23796 Mon Sep 17 00:00:00 2001 From: Alex J Lennon Date: Mon, 9 Feb 2026 00:11:36 +0000 Subject: [PATCH 1/9] Update release support: whinlatter, remove EOL branches - README: remove walnascar (5.2, EOL Nov 2025) and styhead (5.1, EOL), add whinlatter (5.3, supported until May 2026), fix kirkstone LTS date to Apr. 2026, update status date to Feb 2026 - layer.conf: update LAYERSERIES_COMPAT_mono from styhead to whinlatter - CI: test against whinlatter poky instead of styhead, remove feature/yocto-layer-compliance branch triggers (merged) Co-authored-by: Cursor --- .github/workflows/CI_github.yml | 8 +++----- README.md | 9 ++++----- conf/layer.conf | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index bd050ec..7bac31a 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -4,11 +4,9 @@ on: push: branches: - master - - feature/yocto-layer-compliance pull_request: branches: - master - - feature/yocto-layer-compliance paths-ignore: - "**.md" jobs: @@ -23,11 +21,11 @@ jobs: matrix: dotnet_version: [10.0.100, 8.0.406, 6.0.428] mono_version: [6.12.0.206] - branch: [styhead] + branch: [whinlatter] arch: [x86-64, arm, arm64] exclude: - # styhead GCC build broken for ARM32 - see README "Removal of support for ARM32" and discussions/234 - - branch: styhead + # GCC build broken for ARM32 - see README and discussions/234 + - branch: whinlatter arch: arm env: name: build-and-test diff --git a/README.md b/README.md index 2d192ee..ffd4efe 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,11 @@ meta-mono is an OpenEmbedded layer that builds dotNet, the mono runtime and mono | Branch | Version | Support Status* | Status of Build & Tests | | ------ | ------- | --------------- | ----------------------- | -| walnascar | 5.2 | Future (April 2025) | [![walnascar](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=walnascar&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | -| styhead | 5.1 | Support for 7 months (May 2025) | [![styhead](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=styhead&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | -| scarthgap | 5.0 | Long Term Support (until Apr. 2028) | [![scarthgap](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=scarthgap&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | -| kirkstone | 4.0 | Long Term Support (minimum Apr. 2024) | [![kirkstone](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=kirkstone&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | +| whinlatter | 5.3 | Support for 6 months (until May 2026) | [![whinlatter](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=whinlatter&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | +| scarthgap | 5.0 | Long Term Support (until Apr. 2028) | [![scarthgap](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=scarthgap&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | +| kirkstone | 4.0 | Long Term Support (until Apr. 2026) | [![kirkstone](https://img.shields.io/github/actions/workflow/status/dynamicdevices/meta-mono/CI_github.yml?branch=kirkstone&label=build%20%26%20test)](https://github.com/DynamicDevices/meta-mono/actions/workflows/CI_github.yml) | -*support status as of 21/03/25, follows main Yocto release support schedule [here](https://wiki.yoctoproject.org/wiki/Releases) +*support status as of Feb 2026, follows main Yocto release support schedule [here](https://wiki.yoctoproject.org/wiki/Releases) ## Limitations diff --git a/conf/layer.conf b/conf/layer.conf index 61f503d..8457ce4 100644 --- a/conf/layer.conf +++ b/conf/layer.conf @@ -30,4 +30,4 @@ INSANE_SKIP:msbuild-dev += "buildpaths" INSANE_SKIP:python3-clr-loader += "buildpaths" INSANE_SKIP:python3-pythonnet += "buildpaths" -LAYERSERIES_COMPAT_mono = "styhead" +LAYERSERIES_COMPAT_mono = "whinlatter" From ff62223e3791ac03cfbf0f004faac83cf4ce21ce Mon Sep 17 00:00:00 2001 From: Alex J Lennon Date: Mon, 9 Feb 2026 00:13:32 +0000 Subject: [PATCH 2/9] CI: trigger builds on whinlatter branch Co-authored-by: Cursor --- .github/workflows/CI_github.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index 7bac31a..7ec61a2 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -4,9 +4,11 @@ on: push: branches: - master + - whinlatter pull_request: branches: - master + - whinlatter paths-ignore: - "**.md" jobs: From 94e2bb0a099bb9bce96fe64485e0495c6973eca5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 09:37:51 +0000 Subject: [PATCH 3/9] ci: use HTTPS layer clones on whinlatter Port the master CI workflow so whinlatter builds stop using git:// clones (unreliable via Cloudflare) and share the oe-core/meta-yocto HTTPS setup that already knows how to build this release. Co-authored-by: Alex Lennon --- .github/workflows/CI_github.yml | 301 ++++++++++++++++++++++++++------ 1 file changed, 243 insertions(+), 58 deletions(-) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index 7ec61a2..47f3d0e 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -5,74 +5,178 @@ on: branches: - master - whinlatter + - wrynose + paths-ignore: + - "**.md" pull_request: branches: - master - whinlatter + - wrynose paths-ignore: - "**.md" + +# Self-hosted runner is singular; cancel superseded PR/push runs so a hung +# matrix cell cannot pin the runner until the job timeout elapses. +concurrency: + group: meta-mono-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build-and-test: + # Honor [skip ci] on push (e.g. documentation / workflow-filter merges). + if: | + github.event_name == 'pull_request' || + (github.event_name == 'push' && !contains(github.event.head_commit.message, '[skip ci]')) runs-on: [self-hosted, linux, X64] - timeout-minutes: 960 + # Keep bounded so a wedged bitbake/container cannot pin the sole + # self-hosted runner for a full day (seen with arm64 do_package). + timeout-minutes: 480 container: image: dynamicdevices/yocto-ci-build:latest options: --privileged --platform linux/amd64 -v /dev/net/tun:/dev/net/tun -v /dev/kvm:/dev/kvm strategy: max-parallel: 1 + fail-fast: false + # x86-64 first so native builds validate recipes before slower qemuarm64 + # cross builds on this X64 runner. matrix: - dotnet_version: [10.0.100, 8.0.406, 6.0.428] - mono_version: [6.12.0.206] - branch: [whinlatter] - arch: [x86-64, arm, arm64] - exclude: - # GCC build broken for ARM32 - see README and discussions/234 - - branch: whinlatter - arch: arm + include: + - {dotnet_version: "10.0.100", mono_version: "6.12.0.206", arch: x86-64} + - {dotnet_version: "8.0.406", mono_version: "6.12.0.206", arch: x86-64} + - {dotnet_version: "6.0.428", mono_version: "6.12.0.206", arch: x86-64} + - {dotnet_version: "10.0.100", mono_version: "6.12.0.206", arch: arm64} + - {dotnet_version: "8.0.406", mono_version: "6.12.0.206", arch: arm64} + - {dotnet_version: "6.0.428", mono_version: "6.12.0.206", arch: arm64} env: name: build-and-test MONO_VERSION: ${{ matrix.mono_version }} DOTNET_VERSION: ${{ matrix.dotnet_version }} ARCH: ${{ matrix.arch }} - BRANCH: ${{ matrix.branch }} + WORK_ROOT: work steps: + - name: Free disk space + run: | + echo "=== disk before cleanup ===" + df -h + # Prior CI layouts left per-release trees (styhead/, whinlatter/, …) + # on the persistent self-hosted workspace. A fresh wrynose build of + # clang/llvm/rust needs that space back. Also drop stale deploy/work + # trees from other MACHINE values so arm64/x86-64 matrix cells do not + # starve each other mid-build (hangs with no further bitbake output). + for path in styhead whinlatter scarthgap kirkstone nanbield styhead-test \ + feature \ + "${WORK_ROOT}/build/tmp" \ + "${WORK_ROOT}/build/cache" \ + "${WORK_ROOT}/build/tmp-glibc" \ + "${WORK_ROOT}/build/deploy"; do + if [ -e "$path" ]; then + echo "Removing $path" + rm -rf "$path" + fi + done + # Remove any alternate TMPDIR layouts left by older CI configs. + if [ -d "${WORK_ROOT}/build" ]; then + find "${WORK_ROOT}/build" -maxdepth 1 -type d -name 'tmp-*' -exec rm -rf {} + + fi + echo "=== disk after cleanup ===" + df -h + # Fail early if the runner is already too tight for a sato+mono image. + avail_kb=$(df -Pk . | awk 'NR==2 {print $4}') + if [ "$avail_kb" -lt 20971520 ]; then + echo "Only ${avail_kb}KB free; need at least 20GiB" >&2 + exit 1 + fi - name: Checkout meta-mono - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: clean: false - path: ${{ matrix.branch }}/meta-mono - - name: Update repo poky + path: work/meta-mono + - name: Detect Yocto release run: | - if [ ! -d ${BRANCH}/poky ]; then - git clone git://git.yoctoproject.org/poky -b ${BRANCH} ${BRANCH}/poky - else - cd ${BRANCH}/poky - git pull origin ${BRANCH} - cd ../.. + compat=$(grep '^LAYERSERIES_COMPAT_mono' "${WORK_ROOT}/meta-mono/conf/layer.conf" | sed 's/.*"\([^"]*\)".*/\1/') + if [ -z "$compat" ]; then + echo "Could not read LAYERSERIES_COMPAT_mono from conf/layer.conf" >&2 + exit 1 fi - - name: Update repo meta-openembedded + echo "YOCTO_RELEASE=${compat}" >> "$GITHUB_ENV" + echo "Detected Yocto release: ${compat}" + - name: Setup base layers run: | - if [ ! -d ${BRANCH}/meta-openembedded ]; then - git clone https://github.com/openembedded/meta-openembedded.git -b ${BRANCH} ${BRANCH}/meta-openembedded - else - cd ${BRANCH}/meta-openembedded - git pull origin ${BRANCH} - cd ../.. - fi + clone_or_update() { + local url="$1" branch="$2" dest="$3" + if [ ! -d "$dest" ]; then + git clone "$url" -b "$branch" "$dest" + else + cd "$dest" + git fetch origin "$branch" + git checkout "$branch" + git pull origin "$branch" + cd "$GITHUB_WORKSPACE" + fi + } + + case "$YOCTO_RELEASE" in + whinlatter) + mkdir -p "${WORK_ROOT}/layers" + clone_or_update https://git.openembedded.org/bitbake 2.16 "${WORK_ROOT}/layers/bitbake" + clone_or_update https://git.openembedded.org/openembedded-core whinlatter "${WORK_ROOT}/layers/openembedded-core" + clone_or_update https://git.yoctoproject.org/meta-yocto whinlatter "${WORK_ROOT}/layers/meta-yocto" + clone_or_update https://github.com/openembedded/meta-openembedded.git whinlatter "${WORK_ROOT}/layers/meta-openembedded" + ;; + wrynose) + mkdir -p "${WORK_ROOT}/layers" + clone_or_update https://git.openembedded.org/bitbake 2.18 "${WORK_ROOT}/layers/bitbake" + clone_or_update https://git.openembedded.org/openembedded-core wrynose "${WORK_ROOT}/layers/openembedded-core" + clone_or_update https://git.yoctoproject.org/meta-yocto wrynose "${WORK_ROOT}/layers/meta-yocto" + clone_or_update https://github.com/openembedded/meta-openembedded.git wrynose "${WORK_ROOT}/layers/meta-openembedded" + ;; + *) + # Legacy releases still use the poky monorepo. Use HTTPS: + # git.yoctoproject.org is behind Cloudflare, which does not + # carry the native git:// protocol (port 9418) reliably. + clone_or_update https://git.yoctoproject.org/poky "$YOCTO_RELEASE" "${WORK_ROOT}/poky" + clone_or_update https://github.com/openembedded/meta-openembedded.git "$YOCTO_RELEASE" "${WORK_ROOT}/meta-openembedded" + ;; + esac - name: Configuring run: | - rm -f ${BRANCH}/build/conf/local.conf - rm -f ${BRANCH}/build/conf/bblayers.conf - . ./${BRANCH}/poky/oe-init-build-env ${BRANCH}/build + rm -f ${WORK_ROOT}/build/conf/local.conf + rm -f ${WORK_ROOT}/build/conf/bblayers.conf + + case "$YOCTO_RELEASE" in + whinlatter) + # meta-poky still ships conf/templates/default on whinlatter + TEMPLATECONF=$GITHUB_WORKSPACE/${WORK_ROOT}/layers/meta-yocto/meta-poky/conf/templates/default \ + . ./${WORK_ROOT}/layers/openembedded-core/oe-init-build-env ${WORK_ROOT}/build + meta_oe="${WORK_ROOT}/layers/meta-openembedded" + meta_yocto="${WORK_ROOT}/layers/meta-yocto" + ;; + wrynose) + # wrynose meta-poky dropped conf/templates; use oe-core defaults + # and add poky layers + DISTRO explicitly. + . ./${WORK_ROOT}/layers/openembedded-core/oe-init-build-env ${WORK_ROOT}/build + meta_oe="${WORK_ROOT}/layers/meta-openembedded" + meta_yocto="${WORK_ROOT}/layers/meta-yocto" + echo "POKY_BBLAYERS_CONF_VERSION = \"2\"" >> conf/bblayers.conf + echo "BBLAYERS += '$GITHUB_WORKSPACE/${meta_yocto}/meta-poky'" >> conf/bblayers.conf + echo "BBLAYERS += '$GITHUB_WORKSPACE/${meta_yocto}/meta-yocto-bsp'" >> conf/bblayers.conf + echo "DISTRO = \"poky\"" >> conf/local.conf + ;; + *) + . ./${WORK_ROOT}/poky/oe-init-build-env ${WORK_ROOT}/build + meta_oe="${WORK_ROOT}/meta-openembedded" + ;; + esac - # Append custom variables for regenerated local.conf and bblayers.conf samples echo "### Starting to configure local.conf and bblayers.conf ###" + echo "yocto release: $YOCTO_RELEASE" echo "mono version: $MONO_VERSION" echo "dotnet version: $DOTNET_VERSION" - echo "BBLAYERS += '$GITHUB_WORKSPACE/${BRANCH}/meta-mono'" >> conf/bblayers.conf - echo "BBLAYERS += '$GITHUB_WORKSPACE/${BRANCH}/meta-openembedded/meta-oe'" >> conf/bblayers.conf - echo "BBLAYERS += '$GITHUB_WORKSPACE/${BRANCH}/meta-openembedded/meta-python'" >> conf/bblayers.conf + echo "BBLAYERS += '$GITHUB_WORKSPACE/${WORK_ROOT}/meta-mono'" >> conf/bblayers.conf + echo "BBLAYERS += '$GITHUB_WORKSPACE/${meta_oe}/meta-oe'" >> conf/bblayers.conf + echo "BBLAYERS += '$GITHUB_WORKSPACE/${meta_oe}/meta-python'" >> conf/bblayers.conf echo "BB_DEFAULT_EVENTLOG = \"\"" >> conf/local.conf echo "MACHINE = \"qemu${ARCH}\"" >> conf/local.conf @@ -84,43 +188,124 @@ jobs: echo "PREFERRED_VERSION_dotnet = \"${DOTNET_VERSION}\"" >> conf/local.conf echo "PREFERRED_VERSION_dotnet-native = \"${DOTNET_VERSION}\"" >> conf/local.conf - echo "INHERIT += \" create-spdx cve-check rm_work \"" >> conf/local.conf + case "$YOCTO_RELEASE" in + wrynose) + # cve-check was removed in wrynose; use sbom-cve-check fragment. + # root-login fragment matches test-image-mono IMAGE_FEATURES for qemu testimage. + echo "OE_FRAGMENTS += \"core/yocto/sbom-cve-check core/yocto/root-login-with-empty-password\"" >> conf/local.conf + echo "INHERIT += \"rm_work\"" >> conf/local.conf + # HTTP sstate mirror only: the CDN hashserv (wss) needs Python + # websockets, which this container does not provide to bitbake. + # wrynose defaults to OEEquivHash, which requires BB_HASHSERVE; + # use a local server with the DB on the shared SSTATE_DIR so + # persistent-runner reuse works across matrix cells. + echo "SSTATE_MIRRORS ?= \"file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH\"" >> conf/local.conf + echo "BB_HASHSERVE = \"auto\"" >> conf/local.conf + echo "BB_HASHSERVE_DB_DIR = \"\${SSTATE_DIR}\"" >> conf/local.conf + # IMAGE_VERSION_SUFFIX excludes DATETIME from task hashes, but + # do_create_image_sbom_spdx deploys ${IMAGE_NAME}.spdx.json (which + # includes DATETIME). Setscene can restore a previous filename while + # do_sbom_cve_check looks for the current one. Force that one task to + # re-run each CI build without invalidating the rest of image sstate. + echo "META_MONO_CI_BUILD_ID = \"${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}\"" >> conf/local.conf + echo "do_create_image_sbom_spdx[vardeps] += \"META_MONO_CI_BUILD_ID\"" >> conf/local.conf + ;; + *) + echo "INHERIT += \" create-spdx cve-check rm_work \"" >> conf/local.conf + ;; + esac sed -i 's/#IMAGE_CLASSES += "testimage testsdk"/IMAGE_CLASSES += "testimage "/' conf/local.conf echo "SPDX_PRETTY = \"1\"" >> conf/local.conf - echo "BB_NUMBER_THREADS ?= \"\${@oe.utils.cpu_count()}\"" >> conf/local.conf - echo "PARALLEL_MAKE ?= \"-j \${@oe.utils.cpu_count()} -l \${@oe.utils.cpu_count()*2}\"" >> conf/local.conf - # Flush stale sstate/sysroot to ensure fresh builds with corrected - # host/fxr layout and dotnet wrapper. - # TODO: remove this step once all matrix jobs have rebuilt successfully. - - name: Clean stale sstate - run: | - . ./${BRANCH}/poky/oe-init-build-env ${BRANCH}/build - bitbake -c cleansstate dotnet dotnet-native python3-clr-loader python3-clr-loader-native dotnet-helloworld python3-pythonnet + # Cross-building qemuarm64 on the X64 runner has wedged under full + # parallelism (silent multi-hour stall in do_package). Cap threads. + if [ "$ARCH" = "arm64" ]; then + echo "BB_NUMBER_THREADS ?= \"\${@oe.utils.cpu_count(at_least=1, at_most=4)}\"" >> conf/local.conf + echo "PARALLEL_MAKE ?= \"-j \${@oe.utils.cpu_count(at_least=1, at_most=4)}\"" >> conf/local.conf + else + echo "BB_NUMBER_THREADS ?= \"\${@oe.utils.cpu_count()}\"" >> conf/local.conf + echo "PARALLEL_MAKE ?= \"-j \${@oe.utils.cpu_count()} -l \${@oe.utils.cpu_count()*2}\"" >> conf/local.conf + fi - name: Building Mono Test Image run: | - . ./${BRANCH}/poky/oe-init-build-env ${BRANCH}/build - bitbake test-image-mono + case "$YOCTO_RELEASE" in + whinlatter|wrynose) + . ./${WORK_ROOT}/layers/openembedded-core/oe-init-build-env ${WORK_ROOT}/build + ;; + *) + . ./${WORK_ROOT}/poky/oe-init-build-env ${WORK_ROOT}/build + ;; + esac + # Disk heartbeat in the background; wait on bitbake so failures + # surface immediately (a foreground sleep loop delayed exit by 5m). + bitbake test-image-mono & + bbpid=$! + ( + while kill -0 "$bbpid" 2>/dev/null; do + sleep 300 + echo "=== build heartbeat $(date -u +%H:%M:%S) ===" + df -h . || true + done + ) & + hb=$! + set +e + wait "$bbpid" + rc=$? + set -e + kill "$hb" 2>/dev/null || true + wait "$hb" 2>/dev/null || true + exit "$rc" - name: CVE Check Mono / dotNet run: | - . ./${BRANCH}/poky/oe-init-build-env ${BRANCH}/build + case "$YOCTO_RELEASE" in + whinlatter|wrynose) + . ./${WORK_ROOT}/layers/openembedded-core/oe-init-build-env ${WORK_ROOT}/build + ;; + *) + . ./${WORK_ROOT}/poky/oe-init-build-env ${WORK_ROOT}/build + ;; + esac export TERM=linux - bitbake mono -c cve_check - mv $GITHUB_WORKSPACE/${BRANCH}/build/tmp/log/cve/cve-summary.json $GITHUB_WORKSPACE/${BRANCH}/build/tmp/log/cve/cve-summary-mono.json - bitbake dotnet -c cve_check - mv $GITHUB_WORKSPACE/${BRANCH}/build/tmp/log/cve/cve-summary.json $GITHUB_WORKSPACE/${BRANCH}/build/tmp/log/cve/cve-summary-dotnet.json + cve_dir="$GITHUB_WORKSPACE/${WORK_ROOT}/build/tmp/log/cve" + mkdir -p "$cve_dir" + case "$YOCTO_RELEASE" in + wrynose) + # Image-level sbom-cve-check runs during bitbake test-image-mono. + deploy="$GITHUB_WORKSPACE/${WORK_ROOT}/build/tmp/deploy/images/qemu${ARCH}" + found=$(ls "$deploy"/*.sbom-cve-check*.json 2>/dev/null | wc -l) + if [ "$found" -eq 0 ]; then + echo "No sbom-cve-check reports in $deploy" >&2 + exit 1 + fi + cp "$deploy"/*.sbom-cve-check*.json "$cve_dir/" + ls -la "$cve_dir" + ;; + *) + bitbake mono -c cve_check + mv "$cve_dir/cve-summary.json" "$cve_dir/cve-summary-mono.json" + bitbake dotnet -c cve_check + mv "$cve_dir/cve-summary.json" "$cve_dir/cve-summary-dotnet.json" + ;; + esac - name: Testing run: | - . ./${BRANCH}/poky/oe-init-build-env ${BRANCH}/build + case "$YOCTO_RELEASE" in + whinlatter|wrynose) + . ./${WORK_ROOT}/layers/openembedded-core/oe-init-build-env ${WORK_ROOT}/build + ;; + *) + . ./${WORK_ROOT}/poky/oe-init-build-env ${WORK_ROOT}/build + ;; + esac export TERM=linux bitbake test-image-mono -c testimage - name: Store artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: - name: test-image-mono-${{ matrix.branch }}-${{ matrix.mono_version }}-${{ matrix.dotnet_version }}-${{ github.sha }}-${{ matrix.arch }} - path: ./${{ matrix.branch }}/build/tmp/deploy/images/qemu${{ matrix.arch }}/ + name: test-image-mono-${{ env.YOCTO_RELEASE }}-${{ matrix.mono_version }}-${{ matrix.dotnet_version }}-${{ github.sha }}-${{ matrix.arch }} + path: ./${{ env.WORK_ROOT }}/build/tmp/deploy/images/qemu${{ matrix.arch }}/ - name: Store CVEs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: - name: cve-summary-${{ matrix.branch }}-${{ matrix.mono_version }}-${{ matrix.dotnet_version }}-${{ github.sha }}-${{ matrix.arch }} - path: ./${{ matrix.branch }}/build/tmp/log/cve/*.json + name: cve-summary-${{ env.YOCTO_RELEASE }}-${{ matrix.mono_version }}-${{ matrix.dotnet_version }}-${{ github.sha }}-${{ matrix.arch }} + path: ./${{ env.WORK_ROOT }}/build/tmp/log/cve/*.json From 3b28a417bb5d4347f5ef6f94ccc178f2d65f3776 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 10:14:15 +0000 Subject: [PATCH 4/9] ci: silence hashserve/sstate-mirror warning Clear SSTATE_MIRRORS when using a local BB_HASHSERVE so BitBake stops warning that mirror objects will not match, and bump checkout to v6. Co-authored-by: Alex Lennon --- .github/workflows/CI_github.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index 47f3d0e..f543114 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -88,7 +88,7 @@ jobs: exit 1 fi - name: Checkout meta-mono - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: clean: false path: work/meta-mono @@ -194,12 +194,12 @@ jobs: # root-login fragment matches test-image-mono IMAGE_FEATURES for qemu testimage. echo "OE_FRAGMENTS += \"core/yocto/sbom-cve-check core/yocto/root-login-with-empty-password\"" >> conf/local.conf echo "INHERIT += \"rm_work\"" >> conf/local.conf - # HTTP sstate mirror only: the CDN hashserv (wss) needs Python - # websockets, which this container does not provide to bitbake. - # wrynose defaults to OEEquivHash, which requires BB_HASHSERVE; - # use a local server with the DB on the shared SSTATE_DIR so - # persistent-runner reuse works across matrix cells. - echo "SSTATE_MIRRORS ?= \"file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH\"" >> conf/local.conf + # wrynose defaults to OEEquivHash, which requires BB_HASHSERVE. + # Use a local hashserve DB on the shared SSTATE_DIR for reuse across + # matrix cells on this persistent runner. Do NOT also set + # SSTATE_MIRRORS: BitBake warns that local hashserve + mirrors + # means mirror objects almost never match. + echo "SSTATE_MIRRORS = \"\"" >> conf/local.conf echo "BB_HASHSERVE = \"auto\"" >> conf/local.conf echo "BB_HASHSERVE_DB_DIR = \"\${SSTATE_DIR}\"" >> conf/local.conf # IMAGE_VERSION_SUFFIX excludes DATETIME from task hashes, but @@ -217,6 +217,12 @@ jobs: sed -i 's/#IMAGE_CLASSES += "testimage testsdk"/IMAGE_CLASSES += "testimage "/' conf/local.conf echo "SPDX_PRETTY = \"1\"" >> conf/local.conf + # Poky/meta-poky templates may enable SSTATE_MIRRORS alongside a local + # BB_HASHSERVE; that combination triggers a BitBake warning and makes + # mirror sstate ineffective. Prefer runner-local sstate only. + sed -i '/^SSTATE_MIRRORS/d' conf/local.conf || true + echo "SSTATE_MIRRORS = \"\"" >> conf/local.conf + # Cross-building qemuarm64 on the X64 runner has wedged under full # parallelism (silent multi-hour stall in do_package). Cap threads. if [ "$ARCH" = "arm64" ]; then From 714d56cc7d334c6237a5454166838049c5d1fcb3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 10:20:30 +0000 Subject: [PATCH 5/9] ci: harden wrynose CVE artifact collection globs Collect the sbom-cve-check deploy names OE actually writes (.sbom-cve-check.yocto.json / .sbom-cve-check.spdx.json), plus legacy cve-check filenames, and list the deploy dir on failure. Co-authored-by: Alex Lennon --- .github/workflows/CI_github.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index f543114..7d85f3a 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -277,13 +277,26 @@ jobs: case "$YOCTO_RELEASE" in wrynose) # Image-level sbom-cve-check runs during bitbake test-image-mono. + # OE writes ${IMAGE_NAME}.sbom-cve-check.yocto.json and + # ${IMAGE_NAME}.sbom-cve-check.spdx.json into DEPLOY_DIR_IMAGE + # (see meta/classes/sbom-cve-check-common.bbclass). Also accept + # legacy cve-check names and the docstring alias .sbom-cve-check.json. deploy="$GITHUB_WORKSPACE/${WORK_ROOT}/build/tmp/deploy/images/qemu${ARCH}" - found=$(ls "$deploy"/*.sbom-cve-check*.json 2>/dev/null | wc -l) - if [ "$found" -eq 0 ]; then - echo "No sbom-cve-check reports in $deploy" >&2 + shopt -s nullglob + files=( + "$deploy"/*.sbom-cve-check.yocto.json + "$deploy"/*.sbom-cve-check.spdx.json + "$deploy"/*.sbom-cve-check.json + "$deploy"/*.cve-check.json + "$deploy"/*.cve-check.spdx.json + ) + shopt -u nullglob + if [ "${#files[@]}" -eq 0 ]; then + echo "No sbom-cve-check / cve-check JSON reports in $deploy" >&2 + ls -la "$deploy" >&2 || true exit 1 fi - cp "$deploy"/*.sbom-cve-check*.json "$cve_dir/" + cp -a "${files[@]}" "$cve_dir/" ls -la "$cve_dir" ;; *) From d4ee48ac5c511e33c24f4bb7957df59e560e60b0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 10:33:36 +0000 Subject: [PATCH 6/9] recipes: remove S = ${UNPACKDIR}/git for Whinlatter compliance Yocto 5.3 errors when recipes set S = "${UNPACKDIR}/git" because oe-core bitbake.conf now sets S from BB_GIT_DEFAULT_DESTSUFFIX. This unblocks mono-native do_unpack on the whinlatter CI branch. Co-authored-by: Alex Lennon --- recipes-mono/gtk-sharp/gtk-sharp3_2.99.4.bb | 2 -- recipes-mono/libgdiplus/libgdiplus-common.inc | 2 -- recipes-mono/mono-addins/mono-addins-xbuild.inc | 2 -- recipes-mono/mono-addins/mono-addins.inc | 2 -- recipes-mono/mono-upnp/mono-upnp.inc | 2 -- recipes-mono/mono-xsp/mono-xsp_git.bb | 2 -- recipes-mono/mono/mono-6.12.0.206.inc | 2 -- recipes-mono/mono/mono-git.inc | 2 -- recipes-mono/msbuild/msbuild_16.10.1.bb | 2 -- recipes-mono/taglib-sharp/taglib-sharp.inc | 2 -- 10 files changed, 20 deletions(-) diff --git a/recipes-mono/gtk-sharp/gtk-sharp3_2.99.4.bb b/recipes-mono/gtk-sharp/gtk-sharp3_2.99.4.bb index 11542a1..4761409 100644 --- a/recipes-mono/gtk-sharp/gtk-sharp3_2.99.4.bb +++ b/recipes-mono/gtk-sharp/gtk-sharp3_2.99.4.bb @@ -11,8 +11,6 @@ SRCREV = "9a72bb67fff7e4845b7bb430a608282668c3e4da" SRC_URI = "git://github.com/mono/gtk-sharp.git;protocol=https;branch=master \ file://0001-fixup-gmcs-to-mcs.patch" -S = "${UNPACKDIR}/git" - do_configure:prepend() { export PROFILER_CFLAGS="-D_REENTRANT -I${STAGING_DIR_TARGET}/usr/include/glib-2.0 -I${STAGING_DIR_TARGET}/usr/lib/glib-2.0 -I${STAGING_DIR_TARGET}/usr/lib/glib-2.0/include -I${STAGING_DIR_TARGET}/usr/include/mono-2.0" } diff --git a/recipes-mono/libgdiplus/libgdiplus-common.inc b/recipes-mono/libgdiplus/libgdiplus-common.inc index 33db327..cf50d13 100644 --- a/recipes-mono/libgdiplus/libgdiplus-common.inc +++ b/recipes-mono/libgdiplus/libgdiplus-common.inc @@ -11,8 +11,6 @@ SRC_URI = " \ gitsm://github.com/mono/libgdiplus.git;protocol=https;branch=${BRANCH} \ " -S = "${UNPACKDIR}/git" - inherit autotools pkgconfig FILES:${PN} += "${libdir}/libgdiplus.so" diff --git a/recipes-mono/mono-addins/mono-addins-xbuild.inc b/recipes-mono/mono-addins/mono-addins-xbuild.inc index 21bda78..4bd3fc8 100644 --- a/recipes-mono/mono-addins/mono-addins-xbuild.inc +++ b/recipes-mono/mono-addins/mono-addins-xbuild.inc @@ -13,8 +13,6 @@ SRCBRANCH = "master" SRC_URI = "git://github.com/mono/mono-addins.git;protocol=https;branch=${SRCBRANCH}" -S = "${UNPACKDIR}/git" - do_configure() { } diff --git a/recipes-mono/mono-addins/mono-addins.inc b/recipes-mono/mono-addins/mono-addins.inc index a1ad840..777765a 100644 --- a/recipes-mono/mono-addins/mono-addins.inc +++ b/recipes-mono/mono-addins/mono-addins.inc @@ -14,7 +14,5 @@ SRCBRANCH = "master" SRC_URI = "git://github.com/mono/mono-addins.git;protocol=https;branch=${SRCBRANCH} \ file://0001-configure-mcs.patch" -S = "${UNPACKDIR}/git" - inherit autotools-brokensep pkgconfig inherit mono diff --git a/recipes-mono/mono-upnp/mono-upnp.inc b/recipes-mono/mono-upnp/mono-upnp.inc index 1cd3b7e..72b540b 100644 --- a/recipes-mono/mono-upnp/mono-upnp.inc +++ b/recipes-mono/mono-upnp/mono-upnp.inc @@ -16,8 +16,6 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}-${PV}:" SRC_URI = "git://github.com/mono/mono-upnp.git;protocol=https;branch=${SRCBRANCH} \ " -S = "${UNPACKDIR}/git" - inherit autotools-brokensep pkgconfig do_configure () { diff --git a/recipes-mono/mono-xsp/mono-xsp_git.bb b/recipes-mono/mono-xsp/mono-xsp_git.bb index 7def468..5ca2a44 100644 --- a/recipes-mono/mono-xsp/mono-xsp_git.bb +++ b/recipes-mono/mono-xsp/mono-xsp_git.bb @@ -3,5 +3,3 @@ require mono-xsp-3.x.inc SRCREV= "e272a2c006211b6b03be2ef5bbb9e3f8fefd0768" SRC_URI = "git://github.com/mono/xsp.git;branch=main;protocol=https \ " - -S = "${UNPACKDIR}/git" diff --git a/recipes-mono/mono/mono-6.12.0.206.inc b/recipes-mono/mono/mono-6.12.0.206.inc index b444171..8ff5a75 100644 --- a/recipes-mono/mono/mono-6.12.0.206.inc +++ b/recipes-mono/mono/mono-6.12.0.206.inc @@ -1,3 +1 @@ -S = "${UNPACKDIR}/git" - DEPENDS += " cmake-native" diff --git a/recipes-mono/mono/mono-git.inc b/recipes-mono/mono/mono-git.inc index 5bc1aa3..82ec570 100644 --- a/recipes-mono/mono/mono-git.inc +++ b/recipes-mono/mono/mono-git.inc @@ -23,8 +23,6 @@ SRC_URI = "git://github.com/mono/mono.git;branch=${SRCBRANCH}\ # file://0001-reintroduce-gmcs.patch \ # -S = "${UNPACKDIR}/git" - FILESPATH =. "${FILE_DIRNAME}/mono-4.xx:" FILESPATH =. "${FILE_DIRNAME}/mono-${PV}:" diff --git a/recipes-mono/msbuild/msbuild_16.10.1.bb b/recipes-mono/msbuild/msbuild_16.10.1.bb index 322cfc1..cb204eb 100644 --- a/recipes-mono/msbuild/msbuild_16.10.1.bb +++ b/recipes-mono/msbuild/msbuild_16.10.1.bb @@ -21,8 +21,6 @@ SRC_URI = "git://github.com/mono/linux-packaging-msbuild.git;branch=main;protoco file://0001-Copy-hostfxr.patch \ " -S = "${UNPACKDIR}/git" - do_configure () { sed "s|%libhostfxr%|${STAGING_DIR_TARGET}${libdir}/libhostfxr.so|g" -i ${S}/eng/cibuild_bootstrapped_msbuild.sh diff --git a/recipes-mono/taglib-sharp/taglib-sharp.inc b/recipes-mono/taglib-sharp/taglib-sharp.inc index bc5fc05..368a024 100644 --- a/recipes-mono/taglib-sharp/taglib-sharp.inc +++ b/recipes-mono/taglib-sharp/taglib-sharp.inc @@ -10,8 +10,6 @@ DEPENDS = "mono" SRC_URI = "git://github.com/mono/taglib-sharp.git;protocol=https;branch=${SRCBRANCH}" -S = "${UNPACKDIR}/git" - inherit autotools-brokensep pkgconfig EXTRA_OECONF = " --disable-docs" From 238ddf86abb106c2ba676295411d8e4f2bcf2df7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 18:05:57 +0000 Subject: [PATCH 7/9] recipes: set mono S to UNPACKDIR/BP for whinlatter Removing S = "${UNPACKDIR}/git" left mono-6.xx.inc's S = "${UNPACKDIR}/mono-${@mono_workspace_version(d)}" in effect. That expansion fails at parse (IndexError) for git/gitsm recipes and does not match BB_GIT_DEFAULT_DESTSUFFIX (${BP}). Match master: set S = "${UNPACKDIR}/${BP}" in the 6.12.0.206 and git includes so it overrides mono-6.xx.inc. Co-authored-by: Alex Lennon --- recipes-mono/mono/mono-6.12.0.206.inc | 2 ++ recipes-mono/mono/mono-git.inc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/recipes-mono/mono/mono-6.12.0.206.inc b/recipes-mono/mono/mono-6.12.0.206.inc index 8ff5a75..923fc02 100644 --- a/recipes-mono/mono/mono-6.12.0.206.inc +++ b/recipes-mono/mono/mono-6.12.0.206.inc @@ -1 +1,3 @@ +S = "${UNPACKDIR}/${BP}" + DEPENDS += " cmake-native" diff --git a/recipes-mono/mono/mono-git.inc b/recipes-mono/mono/mono-git.inc index 82ec570..557996f 100644 --- a/recipes-mono/mono/mono-git.inc +++ b/recipes-mono/mono/mono-git.inc @@ -23,6 +23,8 @@ SRC_URI = "git://github.com/mono/mono.git;branch=${SRCBRANCH}\ # file://0001-reintroduce-gmcs.patch \ # +S = "${UNPACKDIR}/${BP}" + FILESPATH =. "${FILE_DIRNAME}/mono-4.xx:" FILESPATH =. "${FILE_DIRNAME}/mono-${PV}:" From 6ed815f4aa36ce27f0fcb335eec792595a81b47a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 09:36:48 +0000 Subject: [PATCH 8/9] recipes: raise btls/boringssl cmake_minimum_required for whinlatter Whinlatter ships CMake that rejects < 3.5; mono 6.12 still declares 2.8.10. Backport master's cmake version bumps so mono-native do_compile can configure BTLS. Co-authored-by: Alex Lennon --- .../0001-Btls-too-old-cmake-version.patch | 30 +++++++++++++++++++ .../boringssl-cmake-version.diff | 10 +++++++ recipes-mono/mono/mono-native_6.12.0.206.bb | 2 ++ recipes-mono/mono/mono_6.12.0.206.bb | 2 ++ 4 files changed, 44 insertions(+) create mode 100644 recipes-mono/mono/mono-6.12.0.206/0001-Btls-too-old-cmake-version.patch create mode 100644 recipes-mono/mono/mono-6.12.0.206/boringssl-cmake-version.diff diff --git a/recipes-mono/mono/mono-6.12.0.206/0001-Btls-too-old-cmake-version.patch b/recipes-mono/mono/mono-6.12.0.206/0001-Btls-too-old-cmake-version.patch new file mode 100644 index 0000000..0ea0c66 --- /dev/null +++ b/recipes-mono/mono/mono-6.12.0.206/0001-Btls-too-old-cmake-version.patch @@ -0,0 +1,30 @@ +From ba1b408ff40e3770785a7774f2bf88758a33a49d Mon Sep 17 00:00:00 2001 +From: Marian Cingel +Date: Mon, 18 May 2026 20:12:28 +0000 +Subject: [PATCH] Btls - too old cmake version + +Upstream-Status: Pending +--- + mono/btls/CMakeLists.txt | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mono/btls/CMakeLists.txt b/mono/btls/CMakeLists.txt +index 992f41e4c7f..012b6d12669 100644 +--- a/mono/btls/CMakeLists.txt ++++ b/mono/btls/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required (VERSION 2.8.10) ++cmake_minimum_required (VERSION 4.0) + + project (mono-btls) + +@@ -129,4 +129,4 @@ endif () + + if (CYGWIN) + target_link_libraries (mono-btls-shared wsock32 ws2_32) +-endif () +\ No newline at end of file ++endif () +-- +2.53.0 + diff --git a/recipes-mono/mono/mono-6.12.0.206/boringssl-cmake-version.diff b/recipes-mono/mono/mono-6.12.0.206/boringssl-cmake-version.diff new file mode 100644 index 0000000..d7871a3 --- /dev/null +++ b/recipes-mono/mono/mono-6.12.0.206/boringssl-cmake-version.diff @@ -0,0 +1,10 @@ +Upstream-Status: Inappropriate [Yocto specific] + +--- mono-6.12.0.206/external/boringssl/CMakeLists.txt.orig 2026-05-18 22:51:14.239405666 +0000 ++++ mono-6.12.0.206/external/boringssl/CMakeLists.txt 2026-05-18 22:51:21.634960290 +0000 +@@ -1,4 +1,4 @@ +-cmake_minimum_required (VERSION 2.8.10) ++cmake_minimum_required (VERSION 4.0) + + # Defer enabling C and CXX languages. + project (BoringSSL NONE) diff --git a/recipes-mono/mono/mono-native_6.12.0.206.bb b/recipes-mono/mono/mono-native_6.12.0.206.bb index d9e65b0..5018293 100644 --- a/recipes-mono/mono/mono-native_6.12.0.206.bb +++ b/recipes-mono/mono/mono-native_6.12.0.206.bb @@ -12,6 +12,8 @@ SRC_URI = "gitsm://github.com/mono/mono.git;protocol=https;branch=2020-02 \ file://shm_open-test-crosscompile.diff \ file://disable-mmap-MAP_32BIT-support.patch \ file://0001-Allow-passing-external-mapfile-C-build-options.patch \ + file://0001-Btls-too-old-cmake-version.patch \ + file://boringssl-cmake-version.diff \ " addtask fixup_config after do_patch before do_configure diff --git a/recipes-mono/mono/mono_6.12.0.206.bb b/recipes-mono/mono/mono_6.12.0.206.bb index 2bf2963..99c9620 100644 --- a/recipes-mono/mono/mono_6.12.0.206.bb +++ b/recipes-mono/mono/mono_6.12.0.206.bb @@ -12,6 +12,8 @@ SRC_URI = "gitsm://github.com/mono/mono.git;protocol=https;branch=2020-02 \ file://disable-mmap-MAP_32BIT-support.patch \ file://0001-Allow-passing-external-mapfile-C-build-options.patch \ file://0001-Add-libusb-1.0-mapping.patch \ + file://0001-Btls-too-old-cmake-version.patch \ + file://boringssl-cmake-version.diff \ " From 9f667f92ee0c0413db318e6495c057886e56f1c9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 10:50:52 +0000 Subject: [PATCH 9/9] ci: requeue whinlatter matrix after runner stall Co-authored-by: Alex Lennon --- .github/workflows/CI_github.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index 7d85f3a..5792fcf 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -242,6 +242,7 @@ jobs: . ./${WORK_ROOT}/poky/oe-init-build-env ${WORK_ROOT}/build ;; esac + # runner-nudge: requeue after self-hosted cancel stall # Disk heartbeat in the background; wait on bitbake so failures # surface immediately (a foreground sleep loop delayed exit by 5m). bitbake test-image-mono &