diff --git a/.github/ci-deps/packages-ubuntu-24.04-full.txt b/.github/ci-deps/packages-ubuntu-24.04-full.txt index 29344bd4e50..9e4cbc106cf 100644 --- a/.github/ci-deps/packages-ubuntu-24.04-full.txt +++ b/.github/ci-deps/packages-ubuntu-24.04-full.txt @@ -92,6 +92,7 @@ python3-docutils python3-impacket python3-ldb python3-psutil +python3-yaml shellcheck uuid-dev valgrind diff --git a/.github/configs/multi-arch.json b/.github/configs/multi-arch.json new file mode 100644 index 00000000000..8ef2e7f1f7c --- /dev/null +++ b/.github/configs/multi-arch.json @@ -0,0 +1,189 @@ +[ +{"name": "arm64-o0", "minutes": 4, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O0"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-o0", "minutes": 4, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-O0"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "riscv64-o0", "minutes": 4, + "cc": "ccache riscv64-linux-gnu-gcc", + "configure": ["--host=riscv64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-riscv-asm", "CFLAGS=-O0"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-o0", "minutes": 4, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O0"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "arm64-o1-no-fp-ecc", "minutes": 3, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O1 -UFP_ECC"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "arm64-os", "minutes": 3, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "CFLAGS=-Os"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-o1-no-fp-ecc", "minutes": 3, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-O1 -UFP_ECC"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-os", "minutes": 3, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-Os"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "riscv64-o1-no-fp-ecc", "minutes": 3, + "cc": "ccache riscv64-linux-gnu-gcc", + "configure": ["--host=riscv64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-riscv-asm", "CFLAGS=-O1 -UFP_ECC"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "riscv64-os", "minutes": 3, + "cc": "ccache riscv64-linux-gnu-gcc", + "configure": ["--host=riscv64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-riscv-asm", "CFLAGS=-Os"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-o1-no-fp-ecc", "minutes": 3, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", + "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O1 -UFP_ECC"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-os", "minutes": 3, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -Os"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "arm64-o2", "minutes": 2.5, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "arm64-o2-sp-math", "minutes": 2.5, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "--enable-sp-math", + "CFLAGS=-O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "arm64-ofast", "minutes": 2.5, + "cc": "ccache aarch64-linux-gnu-gcc", + "configure": ["--host=aarch64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-armasm", "CFLAGS=-Ofast"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-o2", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-o2-sp-math", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-sp-math", "CFLAGS=-O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armhf-ofast", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabihf-gcc", + "configure": ["--host=arm-linux-gnueabihf", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-Ofast"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "riscv64-o2", "minutes": 2.5, + "cc": "ccache riscv64-linux-gnu-gcc", + "configure": ["--host=riscv64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-riscv-asm", "CFLAGS=-O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "riscv64-ofast", "minutes": 2.5, + "cc": "ccache riscv64-linux-gnu-gcc", + "configure": ["--host=riscv64-linux-gnu", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-riscv-asm", "CFLAGS=-Ofast"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-o2", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-o2-sp-math", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "--enable-sp-math", + "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O2"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, +{"name": "armel-ofast", "minutes": 2.5, + "cc": "ccache arm-linux-gnueabi-gcc", + "configure": ["--host=arm-linux-gnueabi", "--enable-all", + "--disable-examples", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", + "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -Ofast"], + "check": false, + "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]} +] diff --git a/.github/configs/os-check-linux.json b/.github/configs/os-check-linux.json new file mode 100644 index 00000000000..1aeb286d050 --- /dev/null +++ b/.github/configs/os-check-linux.json @@ -0,0 +1,329 @@ +[ +{"name": "all-no-client-auth", "minutes": 9.0, + "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "all-dilithium-cryptocb", "minutes": 8.9, + "configure": ["--enable-all", "--enable-dilithium", "--enable-cryptocb", + "--enable-cryptocbutils", "--enable-pkcallbacks"]}, +{"name": "all-haproxy-quic", "minutes": 8.6, + "configure": ["--enable-all", "--enable-haproxy", "--enable-quic"]}, +{"name": "all-asn-template", "minutes": 8.5, + "configure": ["--enable-all", "--enable-asn=template"]}, +{"name": "all-asn-template-old-oid-sum", "minutes": 8.5, + "configure": ["--enable-all", "--enable-asn=template", "CPPFLAGS=-DWOLFSSL_OLD_OID_SUM"]}, +{"name": "all-asn-original-old-oid-sum", "minutes": 8.4, + "configure": ["--enable-all", "--enable-asn=original", "CPPFLAGS=-DWOLFSSL_OLD_OID_SUM"]}, +{"name": "all-asn-original", "minutes": 8.3, + "configure": ["--enable-all", "--enable-asn=original"]}, +{"name": "all-certgencache", "minutes": 8.3, + "configure": ["--enable-all", "--enable-certgencache"]}, +{"name": "all-dtls13-frag-ch-no-mlkem", "minutes": 8.2, + "configure": ["--enable-all", "--enable-dtls13", "--enable-dtls-frag-ch", + "--disable-mlkem"]}, +{"name": "all-check-mem-zero", "minutes": 7.9, + "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_CHECK_MEM_ZERO"]}, +{"name": "all-secure-renegotiation", "minutes": 7.8, + "configure": ["--enable-all", "--enable-secure-renegotiation"]}, +{"name": "all-debug-certs", "minutes": 7.8, + "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_DEBUG_CERTS"]}, +{"name": "all-hash-keep", "minutes": 7.8, + "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_HASH_KEEP"]}, +{"name": "all-no-pkcs7-stream", "minutes": 7.0, + "comment": "Non-streaming PKCS#7 exercises the multi-certificate decode bound in pkcs7_signed_multi_cert_test(); the streaming default cannot reach that off-by-idx path.", + "configure": ["--enable-all", "CPPFLAGS=-DNO_PKCS7_STREAM"]}, +{"name": "all-no-aes-192-256", "minutes": 7.5, + "configure": ["--enable-all", "CPPFLAGS=-DNO_AES_192 -DNO_AES_256"]}, +{"name": "all-writedup", "minutes": 6.9, + "configure": ["--enable-all", "--enable-writedup"]}, +{"name": "all-no-server", "minutes": 5.0, + "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_SERVER"]}, +{"name": "nonblock-sp-c32", "minutes": 5.0, + "comment": "Same but forcing SP_WORD_SIZE=32 to exercise sp_c32.c on a 64-bit host; the two builds together cover both generated variants of mod_exp__nb / RSA / DH wrappers.", + "configure": ["--enable-curve25519=nonblock", "--enable-ecc=nonblock", + "--enable-rsa=nonblock", "--enable-dh=nonblock", "--enable-sp=yes,nonblock", + "CPPFLAGS=-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM -DSP_WORD_SIZE=32"]}, +{"name": "all-no-server-no-client-auth", "minutes": 4.8, + "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "all-no-client-no-client-auth", "minutes": 4.4, + "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "all-no-client", "minutes": 4.2, + "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_CLIENT"]}, +{"name": "nonblock-sp-c64", "minutes": 4.2, + "comment": "Non-blocking ECC/Curve25519/RSA/DH on the host default SP word size (sp_c64.c on x86_64); RSA/DH non-block require RSA_LOW_MEM (the CRT path is not supported in non-block mode).", + "configure": ["--enable-curve25519=nonblock", "--enable-ecc=nonblock", + "--enable-rsa=nonblock", "--enable-dh=nonblock", "--enable-sp=yes,nonblock", + "CPPFLAGS=-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM"]}, +{"name": "tls13-dtls13-session-misc", "minutes": 3.3, + "configure": ["--enable-tls13", "--enable-session-ticket", "--enable-dtls", + "--enable-dtls13", "--enable-opensslextra", "--enable-sessioncerts", + "CPPFLAGS=-DWOLFSSL_DTLS_NO_HVR_ON_RESUME -DHAVE_EXT_CACHE -DWOLFSSL_TICKET_HAVE_ID -DHAVE_EX_DATA -DSESSION_CACHE_DYNAMIC_MEM"]}, +{"name": "dtls-cid-renego-psk", "minutes": 3.3, + "configure": ["--enable-dtls", "--enable-dtlscid", "--enable-dtls13", + "--enable-secure-renegotiation", "--enable-psk", "--enable-aesccm", + "--enable-nullcipher", "CPPFLAGS=-DWOLFSSL_STATIC_RSA"]}, +{"name": "dtls13-ocspstapling-cert-cb", "minutes": 3.1, + "configure": ["--enable-dtls", "--enable-dtls13", "--enable-ocspstapling", + "--enable-ocspstapling2", "--enable-cert-setup-cb", "--enable-sessioncerts"]}, +{"name": "user-settings-all-compat", "minutes": 3.0, + "comment": "user_settings_all.h with the compatibility layer enabled by flipping its \"#if 0\" block, as a build-dir copy.", + "user_settings": "examples/configs/user_settings_all.h", + "cflags": "", + "configure": ["--enable-usersettings"], "prepare": [["sed", "-i", "s/if 0/if 1/", "user_settings.h"]]}, +{"name": "dtls13-earlydata-psk-no-hrr", "minutes": 2.9, + "configure": ["--enable-dtls", "--enable-dtls13", "--enable-earlydata", + "--enable-session-ticket", "--enable-psk", "CPPFLAGS=-DWOLFSSL_DTLS13_NO_HRR_ON_RESUME"]}, +{"name": "ocsp-responder-nonblock-maxfrag", "minutes": 2.8, + "configure": ["--enable-ocsp", "--enable-ocsp-responder", "--enable-ocspstapling", + "CPPFLAGS=-DWOLFSSL_NONBLOCK_OCSP", "--enable-maxfragment"]}, +{"name": "dtls-records-span-datagrams", "minutes": 2.7, + "configure": ["--enable-dtls", "--enable-dtls13", "--enable-dtls-frag-ch", + "--enable-dtls-mtu", "CPPFLAGS=-DWOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS"]}, +{"name": "opensslextra-no-ca-names", "minutes": 2.6, + "configure": ["--enable-opensslextra", "CPPFLAGS=-DWOLFSSL_NO_CA_NAMES"]}, +{"name": "sessionexport-dtls13", "minutes": 2.6, + "configure": ["--enable-sessionexport", "--enable-dtls", "--enable-dtls13"]}, +{"name": "lms-xmss-verify-only", "minutes": 2.5, + "configure": ["--enable-lms=small,verify-only", "--enable-xmss=small,verify-only"]}, +{"name": "opensslall-rng-seed-cb", "minutes": 2.2, + "configure": ["--enable-opensslall", "--enable-opensslextra", "CPPFLAGS=-DWC_RNG_SEED_CB"]}, +{"name": "opensslall-ecc-zero-hash", "minutes": 2.2, + "configure": ["--enable-opensslall", "--enable-ecc", "CPPFLAGS=-DWC_ALLOW_ECC_ZERO_HASH"]}, +{"name": "she-ext-cmac-no-she-misc", "minutes": 2.2, + "configure": ["--enable-she=extended", "--enable-cmac", "--enable-cryptocb", + "--enable-cryptocbutils", + "CPPFLAGS=-DNO_WC_SHE_GETUID -DNO_WC_SHE_GETCOUNTER -DNO_WC_SHE_EXPORTKEY"]}, +{"name": "she-std-cmac-cryptocb-sw-default", "minutes": 2.2, + "configure": ["--enable-she=standard", "--enable-cmac", "--enable-cryptocb", + "--enable-cryptocbutils", "CPPFLAGS=-DWC_SHE_SW_DEFAULT"]}, +{"name": "sniffer-curves-enckeys", "minutes": 2.2, + "configure": ["--enable-sniffer", "--enable-curve25519", "--enable-curve448", + "--enable-enckeys", "CPPFLAGS=-DWOLFSSL_DH_EXTRA"]}, +{"name": "cryptocb-keygen-utils-aes-setkey", "minutes": 2.2, + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils", + "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, +{"name": "cryptocb-utils-setkey-free", "minutes": 2.2, + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-aesgcm", + "--enable-cryptocbutils=setkey,free", "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, +{"name": "cryptocb-keygen-utils-export", "minutes": 2.2, + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=export"]}, +{"name": "cryptocb-keygen-export-key", "minutes": 2.2, + "configure": ["--enable-cryptocb", "--enable-keygen", + "CPPFLAGS=-DWOLF_CRYPTO_CB_EXPORT_KEY"]}, +{"name": "cryptocb-utils-setkey-export-find", "minutes": 2.2, + "configure": ["--enable-cryptocb", "--enable-keygen", + "--enable-cryptocbutils=setkey,export", "CPPFLAGS=-DWOLF_CRYPTO_CB_FIND"]}, +{"name": "cryptocb-shake", "minutes": 2.2, + "comment": "Exercises the SHAKE128/SHAKE256 crypto callback wiring (wc_CryptoCb_Shake, the sha3.c Update/Final hooks, and the dedicated offload unit tests). A normal (non-ONLY) cryptocb build keeps the host software SHA3/SHAKE present as the callbacks' offload fallback.", + "configure": ["--enable-cryptocb", "--enable-sha3", + "--enable-shake128", "--enable-shake256"]}, +{"name": "cryptocb-aes-cfb-ofb", "minutes": 2.2, + "comment": "Exercises the AES-CFB/OFB crypto callback wiring (wc_CryptoCb_AesCfb/Ofb Encrypt/Decrypt, the aes.c hooks, and the dedicated offload unit tests). A normal (non-ONLY) cryptocb build keeps the host software AES present as the callbacks' offload fallback; WOLF_CRYPTO_CB_ONLY_AES (no software fallback) is covered separately by cryptocb-only.yml via swdev.", + "configure": ["--enable-cryptocb", "--enable-aescfb", + "--enable-aesofb", "--enable-aesctr"]}, +{"name": "opensslall-rng-seed-cb-no-getpid", "minutes": 2.1, + "configure": ["--enable-opensslall", "--enable-opensslextra", + "CPPFLAGS=-DWC_RNG_SEED_CB -DWOLFSSL_NO_GETPID"]}, +{"name": "dtls13-ignore-pt-alert", "minutes": 2.1, + "configure": ["--enable-dtls", "--enable-dtls13", "--enable-tls13", + "CPPFLAGS=-DWOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC"]}, +{"name": "cryptocb-utils-setkey-free-export", "minutes": 2.1, + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-aesgcm", + "--enable-cryptocbutils=setkey,free,export", "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, +{"name": "cryptocb-aesgcm-setkey-free", "minutes": 2.1, + "configure": ["--enable-cryptocb", "--enable-aesgcm", + "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"]}, +{"name": "ecies-sec1-gcm-static-nonce", "minutes": 2.0, + "comment": "ECIES with the AES-GCM DEM in the default SEC1 IV mode; WOLFSSL_ECIES_STATIC_GCM_NONCE opts into the fixed-nonce GCM path so the GCM KAT/round-trip and cryptocb tests run.", + "configure": ["--enable-eccencrypt", "--enable-aesgcm", "--enable-aesctr", + "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", + "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, +{"name": "ecies-geniv-gcm-static-nonce", "minutes": 2.0, + "comment": "Same ECIES-GCM coverage in the WOLFSSL_ECIES_GEN_IV mode (random embedded nonce).", + "configure": ["--enable-eccencrypt=geniv", "--enable-aesgcm", "--enable-aesctr", + "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", + "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, +{"name": "ecies-old-gcm-static-nonce", "minutes": 2.0, + "comment": "Same ECIES-GCM coverage in the legacy WOLFSSL_ECIES_OLD mode (KDF-derived nonce, no ephemeral pubkey prepended).", + "configure": ["--enable-eccencrypt=old", "--enable-aesgcm", "--enable-aesctr", + "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", + "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, +{"name": "opensslextra-x509small", "minutes": 2.0, + "configure": ["--enable-opensslextra=x509small"]}, +{"name": "cryptocb-keygen-find", "minutes": 2.0, + "configure": ["--enable-cryptocb", "--enable-keygen", "CPPFLAGS=-DWOLF_CRYPTO_CB_FIND"]}, +{"name": "user-settings-all", "minutes": 2.0, + "comment": "The user_settings.h header-driven build path is distinct from the autotools-driven --enable-all path; full make check.", + "user_settings": "examples/configs/user_settings_all.h", + "cflags": "", + "configure": ["--enable-usersettings"]}, +{"name": "she-ext-cryptocb-sw-default", "minutes": 1.9, + "configure": ["--enable-she=extended", "--enable-cryptocb", "--enable-cryptocbutils", + "CPPFLAGS=-DWC_SHE_SW_DEFAULT"]}, +{"name": "cryptocb-aesgcm-aes-setkey", "minutes": 1.9, + "configure": ["--enable-cryptocb", "--enable-aesgcm", + "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, +{"name": "cryptocb-keygen-utils-setkey", "minutes": 1.9, + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=setkey"]}, +{"name": "pkcs7-rsa-pss", "minutes": 1.9, + "comment": "PKCS#7 with RSA-PSS (CMS RSASSA-PSS signers)", + "configure": ["--enable-pkcs7", "CPPFLAGS=-DWC_RSA_PSS"]}, +{"name": "blind-private-key", "minutes": 1.9, + "configure": ["CPPFLAGS=-DWOLFSSL_BLIND_PRIVATE_KEY"]}, +{"name": "certgen-no-tls", "minutes": 1.9, + "configure": ["--enable-certreq", "--enable-certext", "--enable-certgen", + "--disable-secure-renegotiation-info", "CPPFLAGS=-DNO_TLS"]}, +{"name": "no-sys-ca-certs", "minutes": 1.8, "configure": ["--disable-sys-ca-certs"]}, +{"name": "no-client-auth", "minutes": 1.8, + "configure": ["CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "harden-tls", "minutes": 1.7, "configure": ["--enable-harden-tls"]}, +{"name": "no-sni-ecc-tls13-scr-info", "minutes": 1.7, + "configure": ["--disable-sni", "--disable-ecc", "--disable-tls13", + "--disable-secure-renegotiation-info"]}, +{"name": "default", "minutes": 1.6}, +{"name": "no-client-no-client-auth", "minutes": 1.6, + "configure": ["CPPFLAGS=-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "ascon-experimental", "minutes": 1.6, + "configure": ["--enable-ascon", "--enable-experimental"]}, +{"name": "ascon-unroll-experimental", "minutes": 1.6, + "configure": ["--enable-ascon", "CPPFLAGS=-DWOLFSSL_ASCON_UNROLL", + "--enable-experimental"]}, +{"name": "wolfssl-extra", "minutes": 1.6, "configure": ["CPPFLAGS=-DWOLFSSL_EXTRA"]}, +{"name": "coding-no", "minutes": 1.5, "configure": ["--enable-coding=no"]}, +{"name": "she-ext-cmac-cryptocb", "minutes": 1.3, + "configure": ["--enable-she=extended", "--enable-cmac", "--enable-cryptocb", + "--enable-cryptocbutils"]}, +{"name": "she-std-cmac-no-import-m123", "minutes": 1.3, + "configure": ["--enable-she=standard", "--enable-cmac", + "CPPFLAGS=-DNO_WC_SHE_IMPORT_M123"]}, +{"name": "pkcs7", "minutes": 1.3, + "comment": "PKCS#7 without RSA-PSS", + "configure": ["--enable-pkcs7"]}, +{"name": "tsp", "minutes": 1.3, + "comment": "Time-Stamp Protocol", + "configure": ["--enable-tsp"]}, +{"name": "tsp-openssl", "minutes": 1.3, + "comment": "Time-Stamp Protocol with OpenSSL compat", + "configure": ["--enable-tsp", "--enable-opensslall"]}, +{"name": "tsp-no-ecc", "minutes": 1.3, + "comment": "Time-Stamp Protocol without ECC", + "configure": ["--enable-tsp", "--disable-ecc"]}, +{"name": "tsp-no-rsa", "minutes": 1.3, + "comment": "Time-Stamp Protocol without RSA", + "configure": ["--enable-tsp", "--disable-rsa"]}, +{"name": "tsp-smallstack", "minutes": 1.3, + "comment": "Time-Stamp Protocol Small Stack", + "configure": ["--enable-tsp", "CPPFLAGS=-DWOLFSSL_SMALL_STACK"]}, +{"name": "tsp-min-hash-str", "minutes": 2.7, + "comment": "Time-Stamp Protocol Minimum 128-bit hash strength", + "configure": ["--enable-tsp", + "CPPFLAGS=-DWC_TSP_MIN_HASH_STRENGTH_BITS=128"]}, +{"name": "tsp-requester", "minutes": 1.3, + "comment": "Time-Stamp Protocol Requester", + "configure": ["--enable-tsp", "--enable-opensslall", + "CPPFLAGS=-DWOLFSSL_TSP_REQUESTER"]}, +{"name": "tsp-responder", "minutes": 1.3, + "comment": "Time-Stamp Protocol Responder", + "configure": ["--enable-tsp", "--enable-opensslall", + "CPPFLAGS=-DWOLFSSL_TSP_RESPONDER"]}, +{"name": "tsp-verifier", "minutes": 1.3, + "comment": "Time-Stamp Protocol Verifier", + "configure": ["--enable-tsp", "--enable-opensslall", + "CPPFLAGS=-DWOLFSSL_TSP_VERIFIER"]}, +{"name": "no-tls-cryptocb-aesgcm-setkey-free", "minutes": 1.3, + "configure": ["--disable-tls", "--enable-cryptocb", "--enable-aesgcm", + "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"]}, +{"name": "she-std-cmac", "minutes": 1.2, + "configure": ["--enable-she=standard", "--enable-cmac"]}, +{"name": "no-verify-oid-fpki", "minutes": 1.2, + "configure": ["CPPFLAGS=-DNO_VERIFY_OID -DWOLFSSL_FPKI"]}, +{"name": "no-verify-oid", "minutes": 1.1, "configure": ["CPPFLAGS=-DNO_VERIFY_OID"]}, +{"name": "no-server-no-client-auth", "minutes": 1.0, + "configure": ["CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH"]}, +{"name": "no-wolfssl-client", "minutes": 1.0, + "configure": ["CPPFLAGS=-DNO_WOLFSSL_CLIENT"]}, +{"name": "testwolfcrypt-ca", "minutes": 1.0, + "comment": "user_settings.h builds running only testwolfcrypt: pure crypto, no platform-specific features, so Linux-only coverage is sufficient. Not converted: user_settings_pq.h (requires --enable-experimental) and user_settings_baremetal.h (static memory, custom platform).", + "user_settings": "examples/configs/user_settings_ca.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-dtls13", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_dtls13.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-ebsnet", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_EBSnet.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-eccnonblock", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_eccnonblock.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-curve25519nonblock", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_curve25519nonblock.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-min-ecc", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_min_ecc.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-openssl-compat", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_openssl_compat.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-pkcs7", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_pkcs7.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-rsa-only", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_rsa_only.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-template", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_template.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-tls12", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_tls12.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-tls13", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_tls13.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-wolfboot-keytools", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_wolfboot_keytools.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-wolfssh", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_wolfssh.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "testwolfcrypt-wolftpm", "minutes": 1.0, + "user_settings": "examples/configs/user_settings_wolftpm.h", + "cflags": "", + "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, +{"name": "no-wolfssl-server", "minutes": 0.9, + "configure": ["CPPFLAGS=-DNO_WOLFSSL_SERVER"]}, +{"name": "dtls13-client-minimal", "minutes": 0.9, + "comment": "Minimal DTLS 1.3 client-only build with the SHA-224/384/512/3 hash families disabled. SHA-256 (used by TLS_AES_128_GCM_SHA256) and SHA-1 remain enabled.", + "configure": ["--enable-dtls13", "--disable-tlsv12", "--disable-oldtls", "--disable-rsa", + "--disable-dh", "--disable-aescbc", "--disable-aesecb", "--disable-md5", + "--disable-chacha", "--disable-poly1305", "--disable-errorstrings", + "--disable-asn-print", "--disable-eccshamir", "--disable-base64encode", + "--disable-coding", "--disable-sni", "--disable-sha224", "--disable-sha384", + "--disable-sha512", "--disable-sha3", "--enable-aesgcm=small", "--enable-sp-math", + "--enable-sp=smallec256", "--disable-sp-asm", + "CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_TLS12 -DNO_SESSION_CACHE -DWOLFSSL_AES_NO_UNROLL -DUSE_SLOW_SHA256 -DWOLFSSL_NO_ASYNC_IO -DWOLFSSL_DTLS_ONLY"]}, +{"name": "opensslextra-no-filesystem-no-bio", "minutes": 0.9, + "configure": ["--enable-opensslextra", "--disable-filesystem", "CPPFLAGS=-DNO_BIO"]}, +{"name": "no-examples-no-malloc", "minutes": 0.8, + "configure": ["--disable-examples", "CPPFLAGS=-DWOLFSSL_NO_MALLOC"]}, +{"comment": "WOLFSSL_NO_ASN_STRICT still enforces the RFC 5280 4.2 and 4.2.1.10 MUSTs", + "name": "no-asn-strict-certs", + "configure": ["--enable-testcert", "--enable-opensslextra", "--enable-certgen", + "--enable-certreq", "--enable-certext", "--enable-ecc", + "CPPFLAGS=-DWOLFSSL_NO_ASN_STRICT -DWOLFSSL_CUSTOM_OID -DHAVE_OID_ENCODING -DWOLFSSL_ALT_NAMES"]}, +{"comment": "wolfSSL <= 5.9.0 DTLS 1.3 legacy_session_id echo compatibility shim", + "name": "dtls13-echo-legacy-session-id", + "configure": ["--enable-dtls", "--enable-dtls13", "--enable-session-ticket", + "--enable-ecc", "CPPFLAGS=-DWOLFSSL_DTLS13_ECHO_LEGACY_SESSION_ID"]} +] diff --git a/.github/configs/os-check-macos.json b/.github/configs/os-check-macos.json new file mode 100644 index 00000000000..8d27f0b715e --- /dev/null +++ b/.github/configs/os-check-macos.json @@ -0,0 +1,28 @@ +[ +{"name": "all-asn-template", "minutes": 3.0, + "comment": "Broad key-crypto + Security.framework + opensslextra in one run (RSA, ECC, AES, SHA-2/3, ChaCha20-Poly1305, Curve25519/448, HMAC, sniffer, DTLS, OCSP, ...). Note: --enable-all does NOT enable cryptocb or SHE, so those have their own entries.", + "configure": ["--enable-all", "--enable-asn=template"]}, +{"name": "dtls-cid-renego-psk", "minutes": 1.5, + "comment": "DTLS over BSD sockets on Darwin: connection-ID, fragmented ClientHello, secure renegotiation, PSK, AES-CCM, null cipher - exercises recvmsg/MTU/datagram handling that differs from Linux.", + "configure": ["--enable-dtls", "--enable-dtlscid", "--enable-dtls13", + "--enable-secure-renegotiation", "--enable-psk", "--enable-aesccm", + "--enable-nullcipher", "CPPFLAGS=-DWOLFSSL_STATIC_RSA"]}, +{"name": "user-settings-all", "minutes": 1.5, + "comment": "The user_settings.h header-driven build path under Apple clang: macOS-specific guard ordering (e.g. WOLFSSL_SYS_CA_CERTS pulling in Security.framework) is distinct from the autotools --enable-all path above.", + "user_settings": "examples/configs/user_settings_all.h", + "cflags": "", + "configure": ["--enable-usersettings"]}, +{"name": "apple-native-cert-validation", "minutes": 1.5, + "comment": "Former macos-apple-native-cert-validation.yml workflow: WOLFSSL_APPLE_NATIVE_CERT_VALIDATION delegates chain verification to Security.framework instead of wolfSSL's verifier, and the TEST define enables its client tests in make check. CFLAGS go to configure (with \"cflags\": \"\" so the make-time --cflags do not override them), exactly like the old standalone job.", + "cflags": "", + "configure": ["CFLAGS=-DWOLFSSL_APPLE_NATIVE_CERT_VALIDATION -DWOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION -DRSA_MIN_SIZE=2048 -DNO_WOLFSSL_CIPHER_SUITE_TEST"]}, +{"name": "cryptocb-keygen-utils-setkey", "minutes": 1.0, + "comment": "Crypto-callback dispatcher under Apple clang. Not covered by --enable-all; verifies the cryptocb find/setkey/keygen path compiles and runs on the macOS toolchain.", + "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=setkey"]}, +{"name": "default", "minutes": 0.5, + "comment": "Default build: --enable-sys-ca-certs is auto-on on macOS, so this exercises Apple keychain / system trust loading in src/ssl_load.c that has no Linux equivalent.", + "configure": []}, +{"name": "no-sys-ca-certs", "minutes": 0.5, + "comment": "Validates the configure-time auto-enable override and that the build compiles out the Security.framework code path cleanly - macOS is the only OS where sys-ca-certs is auto-on by default.", + "configure": ["--disable-sys-ca-certs"]} +] diff --git a/.github/configs/pq-all.json b/.github/configs/pq-all.json new file mode 100644 index 00000000000..eb70043d755 --- /dev/null +++ b/.github/configs/pq-all.json @@ -0,0 +1,205 @@ +[ +{"name": "all-pq-small-noasm", "minutes": 4, + "configure": ["--disable-intelasm", "--enable-all", + "--enable-testcert", "--enable-acert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-quic", "--with-sys-crypto-policy", + "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem,small", + "--enable-lms=yes,small", "--enable-xmss=yes,small", + "--enable-slhdsa=yes,small", "--enable-dilithium=yes,small", + "--enable-dual-alg-certs", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_MLDSA_SIGN_SMALL_MEM -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_MAKE_KEY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, +{"name": "all-pq-small-smallstack-noasm", "minutes": 4, + "configure": ["--disable-intelasm", "--enable-smallstack", + "--enable-smallstackcache", "--enable-all", "--enable-testcert", + "--enable-acert", "--enable-dtls13", "--enable-dtls-mtu", + "--enable-dtls-frag-ch", "--enable-dtlscid", "--enable-quic", + "--with-sys-crypto-policy", "--enable-experimental", + "--enable-mlkem=yes,kyber,ml-kem,small", "--enable-lms=yes,small", + "--enable-xmss=yes,small", "--enable-slhdsa=yes,small", + "--enable-dilithium=yes,small", "--enable-dual-alg-certs", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_MLDSA_SIGN_SMALL_MEM -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_MAKE_KEY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, +{"name": "all-pq-quic", "minutes": 3.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-acert", + "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", + "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", + "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", + "--enable-tls-mlkem-standalone", "--enable-extra-pqc-hybrids", + "--enable-lms", "--enable-xmss", "--enable-slhdsa", + "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_BLIND_PRIVATE_KEY -DWOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"]}, +{"name": "all-pq-sp-math", "minutes": 3.5, + "configure": ["--enable-intelasm", "--enable-sp-math", + "--enable-sp-asm", "--enable-all", "--enable-testcert", + "--enable-acert", "--enable-dtls13", "--enable-dtls-mtu", + "--enable-dtls-frag-ch", "--enable-dtlscid", "--disable-quic", + "--with-sys-crypto-policy", "--enable-experimental", + "--enable-mlkem=yes,kyber,ml-kem", "--enable-tls-mlkem-standalone", + "--enable-extra-pqc-hybrids", "--enable-lms", "--enable-xmss", + "--enable-slhdsa", "--enable-dilithium", "--enable-dual-alg-certs", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_BLIND_PRIVATE_KEY -DWOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"]}, +{"name": "all-pq-smallstack", "minutes": 3.5, + "configure": ["--enable-smallstack", "--enable-smallstackcache", + "--enable-intelasm", "--enable-sp-asm", "--enable-all", + "--enable-testcert", "--enable-acert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-quic", "--with-sys-crypto-policy", + "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", + "--enable-lms", "--enable-xmss", "--enable-slhdsa", + "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-pq-cxx", "minutes": 3.5, + "cc": "ccache c++", + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-acert", + "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", + "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", + "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", + "--enable-lms", "--enable-xmss", "--enable-slhdsa", + "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", + "CPPFLAGS=-Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-pq-verify-only-noasm", "minutes": 3, + "configure": ["--disable-intelasm", "--enable-all", + "--disable-mlkem", "--enable-lms=yes,small,verify-only", + "--enable-xmss=yes,small,verify-only", + "--enable-slhdsa=yes,small,verify-only", + "--enable-dilithium=yes,small,verify-only", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, +{"name": "all-pq-mldsa-no-ctx", "minutes": 3, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-acert", + "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", + "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", + "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", + "--enable-lms", "--enable-xmss", "--enable-slhdsa", + "--enable-dilithium=yes,no-ctx", "--enable-dual-alg-certs", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-frodokem", "minutes": 3.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-experimental", + "--enable-mlkem=yes,kyber,ml-kem", + "--enable-frodokem=aes,ephemeral", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "frodokem-small-smallstack-noasm", "minutes": 2.5, + "configure": ["--disable-intelasm", "--enable-smallstack", + "--enable-smallstackcache", "--enable-experimental", + "--enable-frodokem=aes,ephemeral,small", + "CPPFLAGS=-Wdeclaration-after-statement"]}, +{"name": "frodokem-976-only-noasm", "minutes": 1.5, + "comment": "976-only builds D=16 (q=2^16) alone; no-asm the C path", + "configure": ["--disable-intelasm", "--enable-experimental", + "--enable-frodokem=aes,ephemeral,no-640,no-1344", + "CPPFLAGS=-Wdeclaration-after-statement"]}, +{"name": "frodokem-640-shake-only", "minutes": 1.5, + "comment": "640-only builds D=15 (q=2^15); shake-only, with asm", + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-experimental", + "--enable-frodokem=no-976,no-1344,no-aes", + "CPPFLAGS=-Wdeclaration-after-statement"]}, +{"name": "frodokem-aarch64-armasm", "minutes": 4, "check": false, + "cc": "ccache aarch64-linux-gnu-gcc", + "comment": "Cross-build only (no ARM runner): catches ARM asm link/compile breaks. sve+sme+aes A-gen all live in the .S.", + "configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly", + "--enable-armasm", "--enable-experimental", + "--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]}, +{"name": "frodokem-aarch64-armasm-inline", "minutes": 4, + "check": false, "cc": "ccache aarch64-linux-gnu-gcc", + "comment": "Inline armasm: sve/sme/aes are .S-only, so they must fall back to NEON/C; guards the inline-asm link break.", + "configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly", + "--enable-armasm=inline", "--enable-experimental", + "--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]}, +{"name": "frodokem-arm32-armasm", "minutes": 4, "check": false, + "cc": "ccache arm-linux-gnueabihf-gcc", + "comment": "Cross-build only: AArch32 NEON matrix ops + AES-crypto A-gen.", + "configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly", + "--enable-armasm", "--enable-experimental", + "--enable-frodokem=aes,ephemeral", "--disable-examples"]}, +{"name": "ubsan-mldsa-mlkem", "minutes": 2.5, + "configure": ["--disable-shared", "--enable-dilithium", + "--enable-mlkem", + "CFLAGS=-fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer", + "LDFLAGS=-fsanitize=undefined", + "CPPFLAGS=-DWOLFSSL_MLDSA_ALIGNMENT=4"]}, +{"name": "all-mlkem-512-standalone", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,512", "--enable-tls-mlkem-standalone", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-768", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,768", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-768-standalone", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,768", "--enable-tls-mlkem-standalone", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-768-standalone-no-hybrids", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,768", "--enable-tls-mlkem-standalone", + "--disable-pqc-hybrids", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-1024", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,1024", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-1024-standalone", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,1024", + "--enable-tls-mlkem-standalone", "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "all-mlkem-1024-standalone-no-hybrids", "minutes": 2.5, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-all", "--enable-testcert", "--enable-dtls13", + "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", + "--enable-mlkem=make,enc,dec,1024", + "--enable-tls-mlkem-standalone", "--disable-pqc-hybrids", + "--disable-qt", + "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, +{"name": "mlkem-old-ids", "minutes": 1.2, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-mlkem=yes,kyber,ml-kem", + "CPPFLAGS=-DWOLFSSL_ML_KEM_USE_OLD_IDS"]}, +{"name": "mlkem-dynamic-keys", "minutes": 1.2, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-mlkem=yes,kyber,ml-kem,cache-a", + "CPPFLAGS=-DWOLFSSL_MLKEM_DYNAMIC_KEYS"]}, +{"name": "mldsa-dynamic-keys", "minutes": 1.2, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-dilithium=yes", "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, +{"name": "mldsa-small-dynamic-keys", "minutes": 1.2, + "configure": ["--disable-intelasm", "--enable-dilithium=yes,small", + "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, +{"name": "mldsa-verify-only-dynamic-keys", "minutes": 1.2, + "configure": ["--disable-intelasm", + "--enable-dilithium=44,65,87,verify-only", + "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, +{"name": "mldsa-no-asn1-opensslextra", "minutes": 1.2, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-dilithium=yes", "--enable-opensslextra", + "CPPFLAGS=-DWOLFSSL_MLDSA_NO_ASN1"]}, +{"name": "mldsa-no-asn1-fips204-draft-opensslextra", "minutes": 1.2, + "configure": ["--enable-intelasm", "--enable-sp-asm", + "--enable-dilithium=yes,draft", "--enable-opensslextra", + "CPPFLAGS=-DWOLFSSL_MLDSA_NO_ASN1"]}, +{"name": "pkcs7-mldsa-only", "minutes": 1.2, + "comment": "PKCS#7 SignedData with ML-DSA as the only signature algorithm (no RSA, no ECC); guards the ML-DSA-only PKCS7 build path", + "configure": ["--enable-cryptonly", "--enable-mldsa", + "--enable-pkcs7", "--disable-rsa", "--disable-ecc"]} +] diff --git a/.github/configs/smoke-test.json b/.github/configs/smoke-test.json new file mode 100644 index 00000000000..c60e9bc32cd --- /dev/null +++ b/.github/configs/smoke-test.json @@ -0,0 +1,16 @@ +[ + {"name": "sanitize-asan", "configure": ["--enable-all"], + "cflags": "-fsanitize=address -fno-omit-frame-pointer -g -O1", + "ldflags": "-fsanitize=address"}, + {"name": "opensslextra-norealloc-asan", "configure": ["--enable-opensslextra"], + "cflags": "-DWOLFSSL_NO_REALLOC -fsanitize=address -fno-omit-frame-pointer -g -O1", + "ldflags": "-fsanitize=address"}, + {"name": "enable-all-smallstack", "configure": ["--enable-all", "--enable-smallstack"]}, + {"name": "enable-all", "configure": ["--enable-all"]}, + {"name": "integration", "configure": ["--enable-openssh", "--enable-lighty", "--enable-stunnel", "--enable-opensslextra"]}, + {"name": "dtls-suite", "configure": ["--enable-psk", "--enable-dtls", "--enable-dtls13", "--enable-dtls-mtu", "--enable-aesccm", "--enable-opensslextra"]}, + {"name": "opensslextra", "configure": ["--enable-opensslextra"]}, + {"name": "default"}, + {"name": "cryptonly", "configure": ["--enable-cryptonly"]}, + {"name": "leantls-extra", "configure": ["--enable-leantls", "--enable-session-ticket", "--enable-sni", "--enable-opensslextra"]} +] diff --git a/.github/scripts/check-workflow-health.py b/.github/scripts/check-workflow-health.py new file mode 100755 index 00000000000..8151ed19f95 --- /dev/null +++ b/.github/scripts/check-workflow-health.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python3 +# Detect workflows that GitHub is failing to load, and track them in a +# single GitHub issue. +# +# When GitHub cannot load a workflow file it does not report a normal +# failure: the run ends within 0s with zero jobs, no logs, no annotations +# and no check runs. Among a few hundred other checks that is effectively +# invisible - os-check.yml sat broken on master for ten days in July 2026 +# before anyone noticed. +# +# .github/scripts/check-workflows.py guards the one cause we know about +# (the 21000 character per-run-step cap) before a change merges. This +# script is the net underneath it: it looks for the *symptom* rather than +# any particular cause, so a workflow that stops loading for a reason +# nobody anticipated still gets caught. +# +# Two signals, both cheap: +# +# 1. An active workflow whose registered name equals its path. GitHub +# stores a workflow's `name:` field once it has parsed the file, and +# resets it to the bare path when it cannot. This catches regressions +# as well as files that never parsed: os-check.yml was registered as +# "Ubuntu-Macos-Windows Tests" until it broke, then reverted to +# ".github/workflows/os-check.yml". +# +# 2. A completed run that failed with zero jobs. Prefiltered on +# created_at == updated_at (a load failure takes no measurable time) +# so only a handful of runs need the extra jobs lookup. +# +# Findings are reported into one issue, reused across runs: the body is +# rewritten each time, a comment is added only when the set of affected +# workflows actually changes, and the issue is closed automatically once +# everything loads again. That keeps a persistent problem from generating +# daily notification noise while still making a new one loud. +# +# Requires the gh CLI, authenticated (GH_TOKEN / GITHUB_TOKEN). +# +# Exit status: +# 0 every workflow loads +# 1 at least one workflow is failing to load +# 2 the check could not be carried out (gh call failed: no token, a +# revoked scope, an API outage). Distinct from 1 on purpose - "I +# found a problem" and "I could not look" need different responses. + +import argparse +import json +import subprocess +import sys +import time + +MARKER_PREFIX = "" + +ISSUE_TITLE = "CI: one or more workflows are failing to load" + +# The tracking issue is found by this label through the REST issues +# endpoint, never by searching the title and never via `gh issue list`. +# Title search is unusable outright: it runs off an asynchronous index +# and, worse, ignores --state, so it hands back closed issues and the +# monitor re-closes them forever. `gh issue list` uses GraphQL and can +# read a replica that has not caught up. +# +# The REST endpoint is not instantaneous either - a freshly created issue +# took ~2.4s to appear when measured against a live repository - so +# find_open_issue() re-checks rather than trusting one empty answer. +ISSUE_LABEL = "workflow-health" + + +def gh_api(path: str) -> object: + """GET a REST endpoint via the gh CLI and return parsed JSON.""" + out = subprocess.run(["gh", "api", "-H", "Accept: application/vnd.github+json", + path], + capture_output=True, text=True) + if out.returncode != 0: + raise RuntimeError(f"gh api {path} failed: {out.stderr.strip()}") + return json.loads(out.stdout) + + +def gh_json(args: list[str]) -> object: + out = subprocess.run(["gh"] + args, capture_output=True, text=True) + if out.returncode != 0: + raise RuntimeError(f"gh {' '.join(args)} failed: {out.stderr.strip()}") + return json.loads(out.stdout) if out.stdout.strip() else None + + +def unloadable_workflows(repo: str) -> list[dict]: + """Signal 1: active workflows whose name is just their path.""" + bad = [] + page = 1 + while True: + data = gh_api(f"repos/{repo}/actions/workflows" + f"?per_page=100&page={page}") + items = data.get("workflows", []) if isinstance(data, dict) else [] + for wf in items: + if wf.get("state") != "active": + continue + if wf.get("name") == wf.get("path"): + bad.append({"path": wf["path"], + "why": "registered name is the bare file path, " + "so GitHub has not parsed this file"}) + if len(items) < 100: + break + page += 1 + return bad + + +def zero_job_failures(repo: str, scan: int) -> list[dict]: + """Signal 2: recent completed runs that failed with no jobs at all.""" + bad = {} + seen = 0 + page = 1 + # Paginate rather than clamping to one page: a caller asking for more + # runs than fit in a single response should get them, not a quietly + # truncated scan that looks like full coverage. + while seen < scan: + data = gh_api(f"repos/{repo}/actions/runs" + f"?status=completed&per_page=100&page={page}") + runs = data.get("workflow_runs", []) if isinstance(data, dict) else [] + if not runs: + break + for run in runs[:scan - seen]: + if run.get("conclusion") != "failure": + continue + # A load failure never starts: it is created and completed in + # the same instant. Anything that actually ran is not this. + if run.get("created_at") != run.get("updated_at"): + continue + jobs = gh_api(f"repos/{repo}/actions/runs/{run['id']}/jobs") + if not isinstance(jobs, dict) or jobs.get("total_count", 1) != 0: + continue + path = run.get("path", "?") + bad.setdefault(path, { + "path": path, + "why": f"run {run['id']} on {run.get('head_branch', '?')} " + f"completed as a failure with zero jobs", + }) + seen += len(runs) + if len(runs) < 100: + break + page += 1 + return list(bad.values()) + + +def build_body(findings: list[dict], repo: str) -> str: + paths = sorted({f["path"] for f in findings}) + marker = f"{MARKER_PREFIX} {','.join(paths)} {MARKER_SUFFIX}" + lines = [ + marker, + "", + "One or more workflow files are not being loaded by GitHub " + "Actions. A workflow in this state does **not** fail loudly: its " + "runs complete within 0s with zero jobs, no logs, no annotations " + "and no check runs, so it looks like unrelated flake among the " + "other checks while the coverage it provides is silently gone.", + "", + "| Workflow | Detected by |", + "|---|---|", + ] + for f in sorted(findings, key=lambda x: x["path"]): + lines.append(f"| `{f['path']}` | {f['why']} |") + lines += [ + "", + "### What to check first", + "", + "GitHub caps a single `run:` step at 21000 characters and refuses " + "to load the whole file past that. Run " + "`.github/scripts/check-workflows.py` locally to test for it - " + "that is what broke `os-check.yml` for ten days in July 2026. " + "If the file is under the cap, the cause is something else; the " + "Actions service does not report which.", + "", + f"Opened automatically by `.github/workflows/workflow-health.yml` " + f"in {repo}. It closes itself once every workflow loads again.", + ] + return "\n".join(lines) + + +def marker_of(body: str) -> str: + for line in (body or "").splitlines(): + line = line.strip() + if line.startswith(MARKER_PREFIX): + return line + return "" + + +def ensure_label(repo: str) -> None: + """Create the tracking label if the repository does not have it.""" + subprocess.run(["gh", "label", "create", ISSUE_LABEL, "--repo", repo, + "--color", "B60205", + "--description", + "A workflow file is not being loaded by GitHub Actions"], + capture_output=True, text=True) + + +def find_open_issue(repo: str, attempts: int = 1, + delay: float = 2.0) -> dict | None: + """The open tracking issue, or None. + + Looked up by label through the REST issues endpoint - see ISSUE_LABEL + for why neither search nor `gh issue list` is usable here. The state + is re-checked on the result so a closed issue can never be picked up + and re-closed on every subsequent clean run. + + The title must match as well as the label. The label alone is not + proof of ownership: it is a normal repository label that anyone can + apply, and an adopted issue has its body overwritten wholesale and is + then closed, so a mislabelled one would lose its content. Requiring + the title means the worst case of someone retitling this issue is a + duplicate being opened, which is recoverable, rather than an + unrelated issue being destroyed, which is not. + + Even this endpoint is only eventually consistent: a freshly created + issue took ~2.4s to become visible when measured against a live + repository, so `attempts` re-checks before concluding nothing is + open. + """ + for attempt in range(attempts): + issues = gh_api(f"repos/{repo}/issues" + f"?state=open&labels={ISSUE_LABEL}&per_page=50") + if isinstance(issues, list): + for issue in issues: + # This endpoint returns pull requests as well. + if "pull_request" in issue: + continue + if str(issue.get("state", "")).lower() != "open": + continue + if issue.get("title") != ISSUE_TITLE: + continue + return {"number": issue["number"], + "title": issue.get("title", ""), + "body": issue.get("body") or ""} + if attempt + 1 < attempts: + time.sleep(delay) + return None + + +def manage_issue(repo: str, findings: list[dict]) -> int: + """Reconcile the tracking issue with the current findings. + + Returns the process exit status: non-zero while anything is still + failing to load, so the scheduled run itself goes red as a backstop + behind the issue. + """ + # Re-check on both paths. A stale "no open issue" opens a duplicate + # when there are findings, and silently skips closing a just-opened + # issue when there are none. A few seconds once a day is nothing + # against either. + issue = find_open_issue(repo, attempts=4) + + if not findings: + if issue: + subprocess.run(["gh", "issue", "comment", str(issue["number"]), + "--repo", repo, "--body", + "Every workflow loads again. Closing."], + check=True, capture_output=True, text=True) + subprocess.run(["gh", "issue", "close", str(issue["number"]), + "--repo", repo], + check=True, capture_output=True, text=True) + print(f"closed issue #{issue['number']}") + else: + print("nothing to report and no open issue") + return 0 + + body = build_body(findings, repo) + + if issue is None: + ensure_label(repo) + out = subprocess.run(["gh", "issue", "create", "--repo", repo, + "--title", ISSUE_TITLE, "--body", body, + "--label", ISSUE_LABEL], + capture_output=True, text=True) + if out.returncode != 0: + print(f"failed to open issue: {out.stderr.strip()}", + file=sys.stderr) + return 1 + print(f"opened issue: {out.stdout.strip()}") + return 1 + + changed = marker_of(issue.get("body", "")) != marker_of(body) + subprocess.run(["gh", "issue", "edit", str(issue["number"]), + "--repo", repo, "--body", body], + check=True, capture_output=True, text=True) + if changed: + # Only notify when the affected set actually moved - a standing + # problem should not generate a comment on every scheduled run. + subprocess.run(["gh", "issue", "comment", str(issue["number"]), + "--repo", repo, "--body", + "The set of workflows failing to load has changed; " + "the issue body above lists the current state."], + check=True, capture_output=True, text=True) + print(f"updated issue #{issue['number']} (set changed)") + else: + print(f"issue #{issue['number']} already tracks this; no comment") + return 1 + + +def run(opts: argparse.Namespace) -> int: + """Collect findings and reconcile the issue. See main() for exits.""" + findings = unloadable_workflows(opts.repo) + seen = {f["path"] for f in findings} + for f in zero_job_failures(opts.repo, opts.scan_runs): + if f["path"] not in seen: + findings.append(f) + + if findings: + print(f"{len(findings)} workflow(s) failing to load:") + for f in sorted(findings, key=lambda x: x["path"]): + print(f" {f['path']}: {f['why']}") + else: + print("all workflows load cleanly") + + if opts.report_only: + return 1 if findings else 0 + + return manage_issue(opts.repo, findings) + + +def main() -> int: + p = argparse.ArgumentParser( + description="Detect workflows GitHub is failing to load.") + p.add_argument("--repo", required=True, metavar="OWNER/REPO") + p.add_argument("--scan-runs", type=int, default=100, + help="how many recent completed runs to inspect for " + "zero-job failures (default 100)") + p.add_argument("--report-only", action="store_true", + help="print findings and exit; do not touch issues") + opts = p.parse_args() + + try: + return run(opts) + except (RuntimeError, subprocess.CalledProcessError) as exc: + # A failed gh call means the monitor could not do its job - a + # missing token, a revoked scope, an API outage. Say so in one + # line and exit 2: a traceback here reads like a bug in this + # script, and exiting 1 would be indistinguishable from having + # actually found a broken workflow. + print(f"error: could not query {opts.repo}: {exc}", file=sys.stderr) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/scripts/check-workflows.py b/.github/scripts/check-workflows.py new file mode 100755 index 00000000000..304eeba3664 --- /dev/null +++ b/.github/scripts/check-workflows.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# Static lint for GitHub Actions workflow and composite-action files. +# +# The check that matters: GitHub caps a single `run:` step at 21000 +# characters ("Exceeded max expression length 21000"). Exceeding it does +# not fail the step - GitHub refuses to load the entire workflow file, so +# every run of it ends in failure within 0s with zero jobs, no logs and no +# annotations. That is nearly invisible among a few hundred other checks: +# os-check.yml sat broken on master for ten days in July 2026 after an +# inlined config heredoc pushed one step from 20662 to 21813 characters. +# +# Because the cap is enforced by the Actions service rather than by the +# workflow schema, no YAML validator or actionlint run catches it. Hence +# this script. +# +# Sizes are measured the way GitHub sees them: parse the YAML, then take +# the length of the resulting `run` string. Block-scalar indentation is +# already stripped by the parser, so this needs no guessing about how the +# text was folded in the source file. +# +# Checks per file: +# * the file parses as YAML at all +# * every `run:` step is under the hard cap (error) and under the soft +# warning threshold (warning, so a growing list is noticed with +# runway left rather than at the cliff) +# +# Findings are emitted as GitHub workflow commands (::error / ::warning) +# so they surface as annotations on the run, and as plain text so the log +# is readable when run locally. + +import argparse +import pathlib +import sys + +import yaml + +# GitHub's hard limit on a single run: expression. +HARD_LIMIT = 21000 + +# Report anything this large as a warning: enough runway to move the +# offending content out of the workflow before it becomes a failure. +SOFT_LIMIT = 18000 + + +def iter_run_steps(doc: object) -> list[tuple[str, str]]: + """Yield (location, script) for every `run:` step in a parsed file. + + Covers both workflow files (jobs..steps[]) and composite actions + (runs.steps[]). Anything that is not shaped like a step list is + skipped rather than treated as an error: this script only measures + run steps, it is not a schema validator. + """ + found = [] + + def scan_steps(steps: object, where: str) -> None: + if not isinstance(steps, list): + return + for i, step in enumerate(steps): + if not isinstance(step, dict): + continue + script = step.get("run") + if not isinstance(script, str): + continue + name = step.get("name") or f"step {i + 1}" + found.append((f"{where} / {name}", script)) + + if not isinstance(doc, dict): + return found + + jobs = doc.get("jobs") + if isinstance(jobs, dict): + for job_id, job in jobs.items(): + if isinstance(job, dict): + scan_steps(job.get("steps"), f"jobs.{job_id}") + + runs = doc.get("runs") + if isinstance(runs, dict): + scan_steps(runs.get("steps"), "runs") + + return found + + +def check_file(path: pathlib.Path) -> tuple[int, int, int]: + """Lint one file. Returns (errors, warnings, largest run: step).""" + errors = 0 + warnings = 0 + biggest = 0 + + try: + doc = yaml.safe_load(path.read_text()) + except yaml.YAMLError as exc: + print(f"::error file={path}::not valid YAML: {exc}") + return (1, 0, 0) + + for where, script in iter_run_steps(doc): + biggest = max(biggest, len(script)) + size = len(script) + if size >= HARD_LIMIT: + over = size - HARD_LIMIT + print(f"::error file={path}::{where}: run: step is {size} " + f"characters, {over} over GitHub's {HARD_LIMIT} limit. " + f"GitHub will refuse to load this file and every run " + f"will fail in 0s with zero jobs. Move the bulk of the " + f"step out of the workflow - see .github/configs/ for " + f"the pattern used by the parallel-make-check.py " + f"workflows.") + errors += 1 + elif size >= SOFT_LIMIT: + left = HARD_LIMIT - size + print(f"::warning file={path}::{where}: run: step is {size} " + f"characters, only {left} under GitHub's {HARD_LIMIT} " + f"limit. Move content out of the workflow now - at the " + f"limit the whole file stops loading.") + warnings += 1 + + return (errors, warnings, biggest) + + +def main() -> int: + p = argparse.ArgumentParser( + description="Lint GitHub Actions workflow files for the 21000 " + "character per-run-step limit.") + p.add_argument("paths", nargs="*", metavar="FILE", + help="files to check (default: all workflows and " + "composite actions under .github/)") + opts = p.parse_args() + + if opts.paths: + paths = [pathlib.Path(f) for f in opts.paths] + else: + root = pathlib.Path(".github") + paths = sorted(root.glob("workflows/*.yml")) + paths += sorted(root.glob("workflows/*.yaml")) + paths += sorted(root.glob("actions/*/action.yml")) + paths += sorted(root.glob("actions/*/action.yaml")) + + paths = [f for f in paths if f.is_file()] + if not paths: + print("no workflow files found", file=sys.stderr) + return 1 + + errors = 0 + warnings = 0 + biggest = 0 + for path in paths: + e, w, b = check_file(path) + errors += e + warnings += w + biggest = max(biggest, b) + + print(f"checked {len(paths)} files; largest run: step is {biggest} " + f"characters (limit {HARD_LIMIT})") + if errors: + print(f"FAILED: {errors} step(s) over the limit") + return 1 + if warnings: + print(f"{warnings} step(s) approaching the limit") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/workflows/check-source-text.yml b/.github/workflows/check-source-text.yml index 0e10d8bd7c9..cf3efb95da2 100644 --- a/.github/workflows/check-source-text.yml +++ b/.github/workflows/check-source-text.yml @@ -6,6 +6,9 @@ name: Check Source Text # * check-source-text.sh: trailing whitespace, hard tabs in C/H, CRLF, # BOM / non-ASCII. # * bash -n + shellcheck (warning level) on shell scripts. +# * check-workflows.py: every `run:` step against GitHub's 21000 +# character cap, past which GitHub stops loading the workflow file +# altogether and its runs fail in 0s with zero jobs. # # Scope: # * pull_request: only files changed in the PR (catches new violations @@ -37,10 +40,12 @@ jobs: with: fetch-depth: 0 + # python3-yaml backs check-workflows.py, which measures run: steps + # from the parsed YAML rather than from the raw text. - name: Install shellcheck uses: ./.github/actions/install-apt-deps with: - packages: shellcheck + packages: shellcheck python3-yaml ghcr-debs-tag: ubuntu-24.04-full - name: Collect files to check @@ -65,6 +70,13 @@ jobs: echo "sh_count=$(wc -l < changed-sh.txt)" >> "$GITHUB_OUTPUT" fi + # Always over the whole set, not just PR-changed files: the cap is a + # property of each file on its own, the check takes well under a + # second for the ~110 of them, and a workflow can be pushed over the + # line by a change to a file the PR does not otherwise touch. + - name: Lint workflow files + run: ./.github/scripts/check-workflows.py + - name: Run check-source-text (PR changed files) if: github.event_name == 'pull_request' && steps.files.outputs.count != '0' run: | diff --git a/.github/workflows/multi-arch.yml b/.github/workflows/multi-arch.yml index 8de365c8578..20b8a48b64b 100644 --- a/.github/workflows/multi-arch.yml +++ b/.github/workflows/multi-arch.yml @@ -55,209 +55,23 @@ jobs: # NOTE: the old runner-per-config matrix combined an "include" list # of four architectures with an "opts" axis; GitHub's include-merge # rules made each arch entry overwrite the previous one, so only the - # last (armel) combinations actually ran. The JSON below restores the - # evidently intended aarch64/armhf/riscv64 x opts coverage alongside - # armel, except riscv64 x sp-math: configure rejects --enable-sp-math - # without SP, and riscv64's --enable-riscv-asm (unlike the other - # arches' --enable-sp-asm) does not bring it in. Cross builds run - # testwolfcrypt transparently under qemu-user (binfmt) with the + # last (armel) combinations actually ran. .github/configs/multi-arch.json + # restores the evidently intended aarch64/armhf/riscv64 x opts coverage + # alongside armel, except riscv64 x sp-math: configure rejects + # --enable-sp-math without SP, and riscv64's --enable-riscv-asm (unlike + # the other arches' --enable-sp-asm) does not bring it in. Cross builds + # run testwolfcrypt transparently under qemu-user (binfmt) with the # matching QEMU_LD_PREFIX. + # + # The list is kept out of this file on purpose: GitHub caps a single + # `run:` step at 21000 characters, and an inlined heredoc is what + # silently pushed os-check.yml past that cap - the whole file then + # failed to load and every run reported zero jobs. - name: Build all configs (parallel, out-of-tree) run: | - cat > "$RUNNER_TEMP/multi-arch-configs.json" <<'EOF' - [ - {"name": "arm64-o0", "minutes": 4, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O0"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-o0", "minutes": 4, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-O0"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "riscv64-o0", "minutes": 4, - "cc": "ccache riscv64-linux-gnu-gcc", - "configure": ["--host=riscv64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-riscv-asm", "CFLAGS=-O0"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-o0", "minutes": 4, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O0"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "arm64-o1-no-fp-ecc", "minutes": 3, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O1 -UFP_ECC"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "arm64-os", "minutes": 3, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "CFLAGS=-Os"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-o1-no-fp-ecc", "minutes": 3, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-O1 -UFP_ECC"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-os", "minutes": 3, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-Os"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "riscv64-o1-no-fp-ecc", "minutes": 3, - "cc": "ccache riscv64-linux-gnu-gcc", - "configure": ["--host=riscv64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-riscv-asm", "CFLAGS=-O1 -UFP_ECC"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "riscv64-os", "minutes": 3, - "cc": "ccache riscv64-linux-gnu-gcc", - "configure": ["--host=riscv64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-riscv-asm", "CFLAGS=-Os"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-o1-no-fp-ecc", "minutes": 3, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", - "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O1 -UFP_ECC"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-os", "minutes": 3, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -Os"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "arm64-o2", "minutes": 2.5, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "CFLAGS=-O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "arm64-o2-sp-math", "minutes": 2.5, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "--enable-sp-math", - "CFLAGS=-O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "arm64-ofast", "minutes": 2.5, - "cc": "ccache aarch64-linux-gnu-gcc", - "configure": ["--host=aarch64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-armasm", "CFLAGS=-Ofast"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-o2", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-o2-sp-math", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-sp-math", "CFLAGS=-O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armhf-ofast", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabihf-gcc", - "configure": ["--host=arm-linux-gnueabihf", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-Ofast"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "riscv64-o2", "minutes": 2.5, - "cc": "ccache riscv64-linux-gnu-gcc", - "configure": ["--host=riscv64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-riscv-asm", "CFLAGS=-O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "riscv64-ofast", "minutes": 2.5, - "cc": "ccache riscv64-linux-gnu-gcc", - "configure": ["--host=riscv64-linux-gnu", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-riscv-asm", "CFLAGS=-Ofast"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/riscv64-linux-gnu", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-o2", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-o2-sp-math", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "--enable-sp-math", - "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -O2"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]}, - {"name": "armel-ofast", "minutes": 2.5, - "cc": "ccache arm-linux-gnueabi-gcc", - "configure": ["--host=arm-linux-gnueabi", "--enable-all", - "--disable-examples", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT", - "--enable-sp-asm", "CFLAGS=-marm -DWOLFSSL_SP_ARM_ARCH=6 -Ofast"], - "check": false, - "run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabi", "./wolfcrypt/test/testwolfcrypt"]]} - ] - EOF .github/scripts/parallel-make-check.py \ ${{ github.event_name == 'schedule' && '--build-only' || '' }} \ - "$RUNNER_TEMP/multi-arch-configs.json" + .github/configs/multi-arch.json - name: ccache stats if: always() diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml index 2d39f5f2843..8fb27eff744 100644 --- a/.github/workflows/os-check.yml +++ b/.github/workflows/os-check.yml @@ -19,10 +19,31 @@ on: # Weekday-morning cron (10:00 UTC) seeds the master-scoped ccache that PR runs restore: the # linux and macOS jobs re-run --build-only (compile only, no tests) on the # default branch, where their ccache writes are visible to every PR. Only - # Windows is skipped on schedule (see its job `if`) - seeding the linux and - # macOS shards is where the cold-cache cost lives. + # Windows is skipped on a seed run (see its job `if`) - seeding the linux + # and macOS shards is where the cold-cache cost lives. + # + # The two platforms do not seed identically, so do not read "the seed" as + # one mechanism. Linux sets CCACHE_RECACHE on a seed run and saves only on + # one, so its cache is rebuilt from scratch by seed runs alone. macOS does + # neither: it never sets CCACHE_RECACHE, so a macOS seed only accumulates + # deltas, and its ccache-setup step is read-only purely on pull_request, so + # any non-PR run writes it. Left as-is deliberately; the note is here so + # the difference is not rediscovered from a surprising cache. schedule: - cron: '0 10 * * 1-5' + # Runs the same seed on demand. Needed whenever the cache is empty and + # waiting up to a day for the next cron is not acceptable - after a + # stretch where this workflow was not running, for instance, since a + # cache untouched for 7 days is evicted and only the seed refills it. + # Every PR run stays cold until it is refilled. + workflow_dispatch: + inputs: + seed: + description: > + Seed the ccache: compile only, no tests, and save the result. + Untick to run the full checks instead. + type: boolean + default: true concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -57,11 +78,14 @@ jobs: shard: [1, 2, 3, 4] if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} runs-on: ubuntu-24.04 - # The full set measures ~272 thread-minutes cold (~90 warm), i.e. about - # 68 thread-minutes per shard / 4 worker threads: ~20 min of wall per - # shard cold and well under 10 warm, plus ~2-3 min of - # checkout/deps/autogen overhead. - timeout-minutes: 30 + # Measured cold on a completely empty cache (2026-08-03): ~102 + # thread-minutes per shard / 4 worker threads, i.e. 24-27 min of wall + # per shard including checkout/deps/autogen; warm is well under 10. + # The timeout is set well above the cold figure on purpose - a cold + # run is normal whenever the seed has not run recently, and a shard + # dying on the timeout would look like a test failure rather than a + # cold cache. + timeout-minutes: 40 env: CCACHE_MAXSIZE: 500M steps: @@ -92,9 +116,9 @@ jobs: - name: Pin ccache directory run: echo "CCACHE_DIR=$HOME/.cache/ccache" >> "$GITHUB_ENV" - # PRs restore the cache the weekday seed writes but never save it, so - # PR runs add no per-shard ccache entries to the Actions cache. The - # seed (schedule) saves below. + # PRs restore the cache a seed run writes but never save it, so PR + # runs add no per-shard ccache entries to the Actions cache. Only a + # seed run (the cron, or a manual dispatch) saves, below. - name: Restore ccache uses: actions/cache/restore@v5 with: @@ -108,11 +132,11 @@ jobs: os-check-linux-ccache-${{ matrix.shard }}- os-check-linux-ccache- - # On the weekday seed, force clean recompiles (CCACHE_RECACHE) so the - # saved master ccache is reseeded from scratch rather than only - # accumulating deltas. PR/push runs leave it unset and keep their warm hits. - - name: Force fresh compiles on scheduled reseed - if: github.event_name == 'schedule' + # On a seed run, force clean recompiles (CCACHE_RECACHE) so the saved + # master ccache is reseeded from scratch rather than only accumulating + # deltas. PR/push runs leave it unset and keep their warm hits. + - name: Force fresh compiles on a reseed + if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.seed != 'false') }} run: echo "CCACHE_RECACHE=1" >> "$GITHUB_ENV" - name: autogen @@ -120,8 +144,12 @@ jobs: ccache -z ./autogen.sh - # The JSON list below is the former runner-per-config matrix; add new - # configs here as new entries (a "comment" key is allowed for notes). + # The config list lives in .github/configs/os-check-linux.json; add new + # configs there as new entries (a "comment" key is allowed for notes). + # It is kept out of this file on purpose: a single `run:` step is + # capped at 21000 characters by GitHub, and inlining the list as a + # heredoc silently pushed this workflow past that cap - GitHub then + # refused to load the whole file and every run failed with zero jobs. # "minutes" is the expected duration driving longest-first scheduling # and shard balancing: take it from the Minutes column of a previous # run's step summary, or omit it for a new config (defaults to 1) and @@ -135,347 +163,17 @@ jobs: # certs symlink. - name: Build and make check this shard's configs (parallel, out-of-tree) run: | - cat > "$RUNNER_TEMP/os-check-configs.json" <<'EOF' - [ - {"name": "all-no-client-auth", "minutes": 9.0, - "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "all-dilithium-cryptocb", "minutes": 8.9, - "configure": ["--enable-all", "--enable-dilithium", "--enable-cryptocb", - "--enable-cryptocbutils", "--enable-pkcallbacks"]}, - {"name": "all-haproxy-quic", "minutes": 8.6, - "configure": ["--enable-all", "--enable-haproxy", "--enable-quic"]}, - {"name": "all-asn-template", "minutes": 8.5, - "configure": ["--enable-all", "--enable-asn=template"]}, - {"name": "all-asn-template-old-oid-sum", "minutes": 8.5, - "configure": ["--enable-all", "--enable-asn=template", "CPPFLAGS=-DWOLFSSL_OLD_OID_SUM"]}, - {"name": "all-asn-original-old-oid-sum", "minutes": 8.4, - "configure": ["--enable-all", "--enable-asn=original", "CPPFLAGS=-DWOLFSSL_OLD_OID_SUM"]}, - {"name": "all-asn-original", "minutes": 8.3, - "configure": ["--enable-all", "--enable-asn=original"]}, - {"name": "all-certgencache", "minutes": 8.3, - "configure": ["--enable-all", "--enable-certgencache"]}, - {"name": "all-dtls13-frag-ch-no-mlkem", "minutes": 8.2, - "configure": ["--enable-all", "--enable-dtls13", "--enable-dtls-frag-ch", - "--disable-mlkem"]}, - {"name": "all-check-mem-zero", "minutes": 7.9, - "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_CHECK_MEM_ZERO"]}, - {"name": "all-secure-renegotiation", "minutes": 7.8, - "configure": ["--enable-all", "--enable-secure-renegotiation"]}, - {"name": "all-debug-certs", "minutes": 7.8, - "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_DEBUG_CERTS"]}, - {"name": "all-hash-keep", "minutes": 7.8, - "configure": ["--enable-all", "CPPFLAGS=-DWOLFSSL_HASH_KEEP"]}, - {"name": "all-no-pkcs7-stream", "minutes": 7.0, - "comment": "Non-streaming PKCS#7 exercises the multi-certificate decode bound in pkcs7_signed_multi_cert_test(); the streaming default cannot reach that off-by-idx path.", - "configure": ["--enable-all", "CPPFLAGS=-DNO_PKCS7_STREAM"]}, - {"name": "all-no-aes-192-256", "minutes": 7.5, - "configure": ["--enable-all", "CPPFLAGS=-DNO_AES_192 -DNO_AES_256"]}, - {"name": "all-writedup", "minutes": 6.9, - "configure": ["--enable-all", "--enable-writedup"]}, - {"name": "all-no-server", "minutes": 5.0, - "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_SERVER"]}, - {"name": "nonblock-sp-c32", "minutes": 5.0, - "comment": "Same but forcing SP_WORD_SIZE=32 to exercise sp_c32.c on a 64-bit host; the two builds together cover both generated variants of mod_exp__nb / RSA / DH wrappers.", - "configure": ["--enable-curve25519=nonblock", "--enable-ecc=nonblock", - "--enable-rsa=nonblock", "--enable-dh=nonblock", "--enable-sp=yes,nonblock", - "CPPFLAGS=-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM -DSP_WORD_SIZE=32"]}, - {"name": "all-no-server-no-client-auth", "minutes": 4.8, - "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "all-no-client-no-client-auth", "minutes": 4.4, - "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "all-no-client", "minutes": 4.2, - "configure": ["--enable-all", "CPPFLAGS=-DNO_WOLFSSL_CLIENT"]}, - {"name": "nonblock-sp-c64", "minutes": 4.2, - "comment": "Non-blocking ECC/Curve25519/RSA/DH on the host default SP word size (sp_c64.c on x86_64); RSA/DH non-block require RSA_LOW_MEM (the CRT path is not supported in non-block mode).", - "configure": ["--enable-curve25519=nonblock", "--enable-ecc=nonblock", - "--enable-rsa=nonblock", "--enable-dh=nonblock", "--enable-sp=yes,nonblock", - "CPPFLAGS=-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM"]}, - {"name": "tls13-dtls13-session-misc", "minutes": 3.3, - "configure": ["--enable-tls13", "--enable-session-ticket", "--enable-dtls", - "--enable-dtls13", "--enable-opensslextra", "--enable-sessioncerts", - "CPPFLAGS=-DWOLFSSL_DTLS_NO_HVR_ON_RESUME -DHAVE_EXT_CACHE -DWOLFSSL_TICKET_HAVE_ID -DHAVE_EX_DATA -DSESSION_CACHE_DYNAMIC_MEM"]}, - {"name": "dtls-cid-renego-psk", "minutes": 3.3, - "configure": ["--enable-dtls", "--enable-dtlscid", "--enable-dtls13", - "--enable-secure-renegotiation", "--enable-psk", "--enable-aesccm", - "--enable-nullcipher", "CPPFLAGS=-DWOLFSSL_STATIC_RSA"]}, - {"name": "dtls13-ocspstapling-cert-cb", "minutes": 3.1, - "configure": ["--enable-dtls", "--enable-dtls13", "--enable-ocspstapling", - "--enable-ocspstapling2", "--enable-cert-setup-cb", "--enable-sessioncerts"]}, - {"name": "user-settings-all-compat", "minutes": 3.0, - "comment": "user_settings_all.h with the compatibility layer enabled by flipping its \"#if 0\" block, as a build-dir copy.", - "user_settings": "examples/configs/user_settings_all.h", - "cflags": "", - "configure": ["--enable-usersettings"], "prepare": [["sed", "-i", "s/if 0/if 1/", "user_settings.h"]]}, - {"name": "dtls13-earlydata-psk-no-hrr", "minutes": 2.9, - "configure": ["--enable-dtls", "--enable-dtls13", "--enable-earlydata", - "--enable-session-ticket", "--enable-psk", "CPPFLAGS=-DWOLFSSL_DTLS13_NO_HRR_ON_RESUME"]}, - {"name": "ocsp-responder-nonblock-maxfrag", "minutes": 2.8, - "configure": ["--enable-ocsp", "--enable-ocsp-responder", "--enable-ocspstapling", - "CPPFLAGS=-DWOLFSSL_NONBLOCK_OCSP", "--enable-maxfragment"]}, - {"name": "dtls-records-span-datagrams", "minutes": 2.7, - "configure": ["--enable-dtls", "--enable-dtls13", "--enable-dtls-frag-ch", - "--enable-dtls-mtu", "CPPFLAGS=-DWOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS"]}, - {"name": "opensslextra-no-ca-names", "minutes": 2.6, - "configure": ["--enable-opensslextra", "CPPFLAGS=-DWOLFSSL_NO_CA_NAMES"]}, - {"name": "sessionexport-dtls13", "minutes": 2.6, - "configure": ["--enable-sessionexport", "--enable-dtls", "--enable-dtls13"]}, - {"name": "lms-xmss-verify-only", "minutes": 2.5, - "configure": ["--enable-lms=small,verify-only", "--enable-xmss=small,verify-only"]}, - {"name": "opensslall-rng-seed-cb", "minutes": 2.2, - "configure": ["--enable-opensslall", "--enable-opensslextra", "CPPFLAGS=-DWC_RNG_SEED_CB"]}, - {"name": "opensslall-ecc-zero-hash", "minutes": 2.2, - "configure": ["--enable-opensslall", "--enable-ecc", "CPPFLAGS=-DWC_ALLOW_ECC_ZERO_HASH"]}, - {"name": "she-ext-cmac-no-she-misc", "minutes": 2.2, - "configure": ["--enable-she=extended", "--enable-cmac", "--enable-cryptocb", - "--enable-cryptocbutils", - "CPPFLAGS=-DNO_WC_SHE_GETUID -DNO_WC_SHE_GETCOUNTER -DNO_WC_SHE_EXPORTKEY"]}, - {"name": "she-std-cmac-cryptocb-sw-default", "minutes": 2.2, - "configure": ["--enable-she=standard", "--enable-cmac", "--enable-cryptocb", - "--enable-cryptocbutils", "CPPFLAGS=-DWC_SHE_SW_DEFAULT"]}, - {"name": "sniffer-curves-enckeys", "minutes": 2.2, - "configure": ["--enable-sniffer", "--enable-curve25519", "--enable-curve448", - "--enable-enckeys", "CPPFLAGS=-DWOLFSSL_DH_EXTRA"]}, - {"name": "cryptocb-keygen-utils-aes-setkey", "minutes": 2.2, - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils", - "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, - {"name": "cryptocb-utils-setkey-free", "minutes": 2.2, - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-aesgcm", - "--enable-cryptocbutils=setkey,free", "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, - {"name": "cryptocb-keygen-utils-export", "minutes": 2.2, - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=export"]}, - {"name": "cryptocb-keygen-export-key", "minutes": 2.2, - "configure": ["--enable-cryptocb", "--enable-keygen", - "CPPFLAGS=-DWOLF_CRYPTO_CB_EXPORT_KEY"]}, - {"name": "cryptocb-utils-setkey-export-find", "minutes": 2.2, - "configure": ["--enable-cryptocb", "--enable-keygen", - "--enable-cryptocbutils=setkey,export", "CPPFLAGS=-DWOLF_CRYPTO_CB_FIND"]}, - {"name": "cryptocb-shake", "minutes": 2.2, - "comment": "Exercises the SHAKE128/SHAKE256 crypto callback wiring (wc_CryptoCb_Shake, the sha3.c Update/Final hooks, and the dedicated offload unit tests). A normal (non-ONLY) cryptocb build keeps the host software SHA3/SHAKE present as the callbacks' offload fallback.", - "configure": ["--enable-cryptocb", "--enable-sha3", - "--enable-shake128", "--enable-shake256"]}, - {"name": "cryptocb-aes-cfb-ofb", "minutes": 2.2, - "comment": "Exercises the AES-CFB/OFB crypto callback wiring (wc_CryptoCb_AesCfb/Ofb Encrypt/Decrypt, the aes.c hooks, and the dedicated offload unit tests). A normal (non-ONLY) cryptocb build keeps the host software AES present as the callbacks' offload fallback; WOLF_CRYPTO_CB_ONLY_AES (no software fallback) is covered separately by cryptocb-only.yml via swdev.", - "configure": ["--enable-cryptocb", "--enable-aescfb", - "--enable-aesofb", "--enable-aesctr"]}, - {"name": "opensslall-rng-seed-cb-no-getpid", "minutes": 2.1, - "configure": ["--enable-opensslall", "--enable-opensslextra", - "CPPFLAGS=-DWC_RNG_SEED_CB -DWOLFSSL_NO_GETPID"]}, - {"name": "dtls13-ignore-pt-alert", "minutes": 2.1, - "configure": ["--enable-dtls", "--enable-dtls13", "--enable-tls13", - "CPPFLAGS=-DWOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC"]}, - {"name": "cryptocb-utils-setkey-free-export", "minutes": 2.1, - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-aesgcm", - "--enable-cryptocbutils=setkey,free,export", "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, - {"name": "cryptocb-aesgcm-setkey-free", "minutes": 2.1, - "configure": ["--enable-cryptocb", "--enable-aesgcm", - "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"]}, - {"name": "ecies-sec1-gcm-static-nonce", "minutes": 2.0, - "comment": "ECIES with the AES-GCM DEM in the default SEC1 IV mode; WOLFSSL_ECIES_STATIC_GCM_NONCE opts into the fixed-nonce GCM path so the GCM KAT/round-trip and cryptocb tests run.", - "configure": ["--enable-eccencrypt", "--enable-aesgcm", "--enable-aesctr", - "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", - "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, - {"name": "ecies-geniv-gcm-static-nonce", "minutes": 2.0, - "comment": "Same ECIES-GCM coverage in the WOLFSSL_ECIES_GEN_IV mode (random embedded nonce).", - "configure": ["--enable-eccencrypt=geniv", "--enable-aesgcm", "--enable-aesctr", - "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", - "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, - {"name": "ecies-old-gcm-static-nonce", "minutes": 2.0, - "comment": "Same ECIES-GCM coverage in the legacy WOLFSSL_ECIES_OLD mode (KDF-derived nonce, no ephemeral pubkey prepended).", - "configure": ["--enable-eccencrypt=old", "--enable-aesgcm", "--enable-aesctr", - "--enable-x963kdf", "--enable-cryptocb", "--enable-keygen", - "CPPFLAGS=-DWOLFSSL_ECIES_STATIC_GCM_NONCE"]}, - {"name": "opensslextra-x509small", "minutes": 2.0, - "configure": ["--enable-opensslextra=x509small"]}, - {"name": "cryptocb-keygen-find", "minutes": 2.0, - "configure": ["--enable-cryptocb", "--enable-keygen", "CPPFLAGS=-DWOLF_CRYPTO_CB_FIND"]}, - {"name": "user-settings-all", "minutes": 2.0, - "comment": "The user_settings.h header-driven build path is distinct from the autotools-driven --enable-all path; full make check.", - "user_settings": "examples/configs/user_settings_all.h", - "cflags": "", - "configure": ["--enable-usersettings"]}, - {"name": "she-ext-cryptocb-sw-default", "minutes": 1.9, - "configure": ["--enable-she=extended", "--enable-cryptocb", "--enable-cryptocbutils", - "CPPFLAGS=-DWC_SHE_SW_DEFAULT"]}, - {"name": "cryptocb-aesgcm-aes-setkey", "minutes": 1.9, - "configure": ["--enable-cryptocb", "--enable-aesgcm", - "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY"]}, - {"name": "cryptocb-keygen-utils-setkey", "minutes": 1.9, - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=setkey"]}, - {"name": "pkcs7-rsa-pss", "minutes": 1.9, - "comment": "PKCS#7 with RSA-PSS (CMS RSASSA-PSS signers)", - "configure": ["--enable-pkcs7", "CPPFLAGS=-DWC_RSA_PSS"]}, - {"name": "blind-private-key", "minutes": 1.9, - "configure": ["CPPFLAGS=-DWOLFSSL_BLIND_PRIVATE_KEY"]}, - {"name": "certgen-no-tls", "minutes": 1.9, - "configure": ["--enable-certreq", "--enable-certext", "--enable-certgen", - "--disable-secure-renegotiation-info", "CPPFLAGS=-DNO_TLS"]}, - {"name": "no-sys-ca-certs", "minutes": 1.8, "configure": ["--disable-sys-ca-certs"]}, - {"name": "no-client-auth", "minutes": 1.8, - "configure": ["CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "harden-tls", "minutes": 1.7, "configure": ["--enable-harden-tls"]}, - {"name": "no-sni-ecc-tls13-scr-info", "minutes": 1.7, - "configure": ["--disable-sni", "--disable-ecc", "--disable-tls13", - "--disable-secure-renegotiation-info"]}, - {"name": "default", "minutes": 1.6}, - {"name": "no-client-no-client-auth", "minutes": 1.6, - "configure": ["CPPFLAGS=-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "ascon-experimental", "minutes": 1.6, - "configure": ["--enable-ascon", "--enable-experimental"]}, - {"name": "ascon-unroll-experimental", "minutes": 1.6, - "configure": ["--enable-ascon", "CPPFLAGS=-DWOLFSSL_ASCON_UNROLL", - "--enable-experimental"]}, - {"name": "wolfssl-extra", "minutes": 1.6, "configure": ["CPPFLAGS=-DWOLFSSL_EXTRA"]}, - {"name": "coding-no", "minutes": 1.5, "configure": ["--enable-coding=no"]}, - {"name": "she-ext-cmac-cryptocb", "minutes": 1.3, - "configure": ["--enable-she=extended", "--enable-cmac", "--enable-cryptocb", - "--enable-cryptocbutils"]}, - {"name": "she-std-cmac-no-import-m123", "minutes": 1.3, - "configure": ["--enable-she=standard", "--enable-cmac", - "CPPFLAGS=-DNO_WC_SHE_IMPORT_M123"]}, - {"name": "pkcs7", "minutes": 1.3, - "comment": "PKCS#7 without RSA-PSS", - "configure": ["--enable-pkcs7"]}, - {"name": "tsp", "minutes": 1.3, - "comment": "Time-Stamp Protocol", - "configure": ["--enable-tsp"]}, - {"name": "tsp-openssl", "minutes": 1.3, - "comment": "Time-Stamp Protocol with OpenSSL compat", - "configure": ["--enable-tsp", "--enable-opensslall"]}, - {"name": "tsp-no-ecc", "minutes": 1.3, - "comment": "Time-Stamp Protocol without ECC", - "configure": ["--enable-tsp", "--disable-ecc"]}, - {"name": "tsp-no-rsa", "minutes": 1.3, - "comment": "Time-Stamp Protocol without RSA", - "configure": ["--enable-tsp", "--disable-rsa"]}, - {"name": "tsp-smallstack", "minutes": 1.3, - "comment": "Time-Stamp Protocol Small Stack", - "configure": ["--enable-tsp", "CPPFLAGS=-DWOLFSSL_SMALL_STACK"]}, - {"name": "tsp-min-hash-str", "minutes": 2.7, - "comment": "Time-Stamp Protocol Minimum 128-bit hash strength", - "configure": ["--enable-tsp", - "CPPFLAGS=-DWC_TSP_MIN_HASH_STRENGTH_BITS=128"]}, - {"name": "tsp-requester", "minutes": 1.3, - "comment": "Time-Stamp Protocol Requester", - "configure": ["--enable-tsp", "--enable-opensslall", - "CPPFLAGS=-DWOLFSSL_TSP_REQUESTER"]}, - {"name": "tsp-responder", "minutes": 1.3, - "comment": "Time-Stamp Protocol Responder", - "configure": ["--enable-tsp", "--enable-opensslall", - "CPPFLAGS=-DWOLFSSL_TSP_RESPONDER"]}, - {"name": "tsp-verifier", "minutes": 1.3, - "comment": "Time-Stamp Protocol Verifier", - "configure": ["--enable-tsp", "--enable-opensslall", - "CPPFLAGS=-DWOLFSSL_TSP_VERIFIER"]}, - {"name": "no-tls-cryptocb-aesgcm-setkey-free", "minutes": 1.3, - "configure": ["--disable-tls", "--enable-cryptocb", "--enable-aesgcm", - "CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"]}, - {"name": "she-std-cmac", "minutes": 1.2, - "configure": ["--enable-she=standard", "--enable-cmac"]}, - {"name": "no-verify-oid-fpki", "minutes": 1.2, - "configure": ["CPPFLAGS=-DNO_VERIFY_OID -DWOLFSSL_FPKI"]}, - {"name": "no-verify-oid", "minutes": 1.1, "configure": ["CPPFLAGS=-DNO_VERIFY_OID"]}, - {"name": "no-server-no-client-auth", "minutes": 1.0, - "configure": ["CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH"]}, - {"name": "no-wolfssl-client", "minutes": 1.0, - "configure": ["CPPFLAGS=-DNO_WOLFSSL_CLIENT"]}, - {"name": "testwolfcrypt-ca", "minutes": 1.0, - "comment": "user_settings.h builds running only testwolfcrypt: pure crypto, no platform-specific features, so Linux-only coverage is sufficient. Not converted: user_settings_pq.h (requires --enable-experimental) and user_settings_baremetal.h (static memory, custom platform).", - "user_settings": "examples/configs/user_settings_ca.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-dtls13", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_dtls13.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-ebsnet", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_EBSnet.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-eccnonblock", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_eccnonblock.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-curve25519nonblock", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_curve25519nonblock.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-min-ecc", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_min_ecc.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-openssl-compat", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_openssl_compat.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-pkcs7", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_pkcs7.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-rsa-only", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_rsa_only.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-template", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_template.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-tls12", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_tls12.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-tls13", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_tls13.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-wolfboot-keytools", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_wolfboot_keytools.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-wolfssh", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_wolfssh.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "testwolfcrypt-wolftpm", "minutes": 1.0, - "user_settings": "examples/configs/user_settings_wolftpm.h", - "cflags": "", - "configure": ["--enable-usersettings", "--disable-examples"], "check": false, "run": [["wolfcrypt/test/testwolfcrypt"]]}, - {"name": "no-wolfssl-server", "minutes": 0.9, - "configure": ["CPPFLAGS=-DNO_WOLFSSL_SERVER"]}, - {"name": "dtls13-client-minimal", "minutes": 0.9, - "comment": "Minimal DTLS 1.3 client-only build with the SHA-224/384/512/3 hash families disabled. SHA-256 (used by TLS_AES_128_GCM_SHA256) and SHA-1 remain enabled.", - "configure": ["--enable-dtls13", "--disable-tlsv12", "--disable-oldtls", "--disable-rsa", - "--disable-dh", "--disable-aescbc", "--disable-aesecb", "--disable-md5", - "--disable-chacha", "--disable-poly1305", "--disable-errorstrings", - "--disable-asn-print", "--disable-eccshamir", "--disable-base64encode", - "--disable-coding", "--disable-sni", "--disable-sha224", "--disable-sha384", - "--disable-sha512", "--disable-sha3", "--enable-aesgcm=small", "--enable-sp-math", - "--enable-sp=smallec256", "--disable-sp-asm", - "CPPFLAGS=-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_TLS12 -DNO_SESSION_CACHE -DWOLFSSL_AES_NO_UNROLL -DUSE_SLOW_SHA256 -DWOLFSSL_NO_ASYNC_IO -DWOLFSSL_DTLS_ONLY"]}, - {"name": "opensslextra-no-filesystem-no-bio", "minutes": 0.9, - "configure": ["--enable-opensslextra", "--disable-filesystem", "CPPFLAGS=-DNO_BIO"]}, - {"name": "no-examples-no-malloc", "minutes": 0.8, - "configure": ["--disable-examples", "CPPFLAGS=-DWOLFSSL_NO_MALLOC"]}, - {"comment": "WOLFSSL_NO_ASN_STRICT still enforces the RFC 5280 4.2 and 4.2.1.10 MUSTs", - "name": "no-asn-strict-certs", - "configure": ["--enable-testcert", "--enable-opensslextra", "--enable-certgen", - "--enable-certreq", "--enable-certext", "--enable-ecc", - "CPPFLAGS=-DWOLFSSL_NO_ASN_STRICT -DWOLFSSL_CUSTOM_OID -DHAVE_OID_ENCODING -DWOLFSSL_ALT_NAMES"]}, - {"comment": "wolfSSL <= 5.9.0 DTLS 1.3 legacy_session_id echo compatibility shim", - "name": "dtls13-echo-legacy-session-id", - "configure": ["--enable-dtls", "--enable-dtls13", "--enable-session-ticket", - "--enable-ecc", "CPPFLAGS=-DWOLFSSL_DTLS13_ECHO_LEGACY_SESSION_ID"]} - ] - EOF .github/scripts/parallel-make-check.py \ - ${{ github.event_name == 'schedule' && '--build-only' || '' }} \ + ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.seed != 'false')) && '--build-only' || '' }} \ --shard "${{ matrix.shard }}/${{ strategy.job-total }}" \ --cflags='-pedantic -Wdeclaration-after-statement -Wnull-dereference -Wno-overlength-strings -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE' \ - --private-dir=certs "$RUNNER_TEMP/os-check-configs.json" + --private-dir=certs .github/configs/os-check-linux.json - # Seed runs (schedule) refresh the master-scoped ccache that PR runs - # restore above; PR/push runs never save, so PRs add nothing. + # Seed runs (the cron, or a manual dispatch with `seed` ticked) refresh + # the master-scoped ccache that PR runs restore above; PR/push runs + # never save, so PRs add nothing. - name: Save ccache (seed only) - if: github.event_name == 'schedule' + if: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.seed != 'false') }} uses: actions/cache/save@v5 with: path: ~/.cache/ccache @@ -511,9 +209,9 @@ jobs: # macos-apple-native-cert-validation.yml workflow. make_check_macos: name: make check macos - # Runs on PRs/pushes and on the weekday ccache-seed cron, where it - # --build-only-seeds the macOS ccache (like the linux shards). Only - # Windows is skipped on schedule (no ccache to seed). + # Runs on PRs/pushes and on a seed run (the cron or a manual dispatch), + # where it --build-only-seeds the macOS ccache like the linux shards. + # Windows is the only job skipped on a seed run (no ccache to seed). if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} runs-on: macos-latest # Serial checks: roughly the sum of the per-config minutes plus @@ -543,48 +241,23 @@ jobs: with: workflow-id: os-check-macos max-size: 500M - # PRs read the weekday-seeded macOS ccache; only the seed saves. + # PRs read the seeded macOS ccache and never write it. Note this + # is not the linux rule: there, saving is gated to seed runs, so + # a push writes nothing. Here every non-PR run writes, seed or + # not, so a release/** push and a dispatch with `seed` unticked + # both land in the shared macOS cache. read-only: ${{ github.event_name == 'pull_request' }} - # Same JSON config format as make_check_linux above; "minutes" only - # orders the serial schedule here (longest first). + # Same JSON config format as make_check_linux above, in + # .github/configs/os-check-macos.json; "minutes" only orders the + # serial schedule here (longest first). - name: Build and make check all configs (serial checks, out-of-tree) run: | - cat > "$RUNNER_TEMP/os-check-macos-configs.json" <<'EOF' - [ - {"name": "all-asn-template", "minutes": 3.0, - "comment": "Broad key-crypto + Security.framework + opensslextra in one run (RSA, ECC, AES, SHA-2/3, ChaCha20-Poly1305, Curve25519/448, HMAC, sniffer, DTLS, OCSP, ...). Note: --enable-all does NOT enable cryptocb or SHE, so those have their own entries.", - "configure": ["--enable-all", "--enable-asn=template"]}, - {"name": "dtls-cid-renego-psk", "minutes": 1.5, - "comment": "DTLS over BSD sockets on Darwin: connection-ID, fragmented ClientHello, secure renegotiation, PSK, AES-CCM, null cipher - exercises recvmsg/MTU/datagram handling that differs from Linux.", - "configure": ["--enable-dtls", "--enable-dtlscid", "--enable-dtls13", - "--enable-secure-renegotiation", "--enable-psk", "--enable-aesccm", - "--enable-nullcipher", "CPPFLAGS=-DWOLFSSL_STATIC_RSA"]}, - {"name": "user-settings-all", "minutes": 1.5, - "comment": "The user_settings.h header-driven build path under Apple clang: macOS-specific guard ordering (e.g. WOLFSSL_SYS_CA_CERTS pulling in Security.framework) is distinct from the autotools --enable-all path above.", - "user_settings": "examples/configs/user_settings_all.h", - "cflags": "", - "configure": ["--enable-usersettings"]}, - {"name": "apple-native-cert-validation", "minutes": 1.5, - "comment": "Former macos-apple-native-cert-validation.yml workflow: WOLFSSL_APPLE_NATIVE_CERT_VALIDATION delegates chain verification to Security.framework instead of wolfSSL's verifier, and the TEST define enables its client tests in make check. CFLAGS go to configure (with \"cflags\": \"\" so the make-time --cflags do not override them), exactly like the old standalone job.", - "cflags": "", - "configure": ["CFLAGS=-DWOLFSSL_APPLE_NATIVE_CERT_VALIDATION -DWOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION -DRSA_MIN_SIZE=2048 -DNO_WOLFSSL_CIPHER_SUITE_TEST"]}, - {"name": "cryptocb-keygen-utils-setkey", "minutes": 1.0, - "comment": "Crypto-callback dispatcher under Apple clang. Not covered by --enable-all; verifies the cryptocb find/setkey/keygen path compiles and runs on the macOS toolchain.", - "configure": ["--enable-cryptocb", "--enable-keygen", "--enable-cryptocbutils=setkey"]}, - {"name": "default", "minutes": 0.5, - "comment": "Default build: --enable-sys-ca-certs is auto-on on macOS, so this exercises Apple keychain / system trust loading in src/ssl_load.c that has no Linux equivalent.", - "configure": []}, - {"name": "no-sys-ca-certs", "minutes": 0.5, - "comment": "Validates the configure-time auto-enable override and that the build compiles out the Security.framework code path cleanly - macOS is the only OS where sys-ca-certs is auto-on by default.", - "configure": ["--disable-sys-ca-certs"]} - ] - EOF .github/scripts/parallel-make-check.py \ - ${{ github.event_name == 'schedule' && '--build-only' || '' }} \ + ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.seed != 'false')) && '--build-only' || '' }} \ --threads 1 --cc= \ --cflags='-pedantic -Wdeclaration-after-statement -Wnull-dereference -Wno-overlength-strings -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE' \ - --private-dir=certs "$RUNNER_TEMP/os-check-macos-configs.json" + --private-dir=certs .github/configs/os-check-macos.json - name: ccache stats if: always() @@ -604,8 +277,9 @@ jobs: windows_build: name: Windows Build Test - # Skipped on the weekday ccache-seed cron: no ccache to seed here. - if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'schedule') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} + # Skipped on any seed run - the cron, or a manual dispatch that left + # `seed` ticked: there is no ccache to seed here. + if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'schedule') && (github.event_name != 'workflow_dispatch' || github.event.inputs.seed == 'false') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} runs-on: windows-latest strategy: fail-fast: false diff --git a/.github/workflows/pq-all.yml b/.github/workflows/pq-all.yml index 351281d2a79..15aa2a48346 100644 --- a/.github/workflows/pq-all.yml +++ b/.github/workflows/pq-all.yml @@ -67,8 +67,12 @@ jobs: - name: Allow unprivileged user namespaces (for bwrap) run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true - # The JSON list below is the former runner-per-config matrix; add new - # configs as new entries (a "comment" key is allowed for notes). + # The config list lives in .github/configs/pq-all.json; add new + # configs there as new entries (a "comment" key is allowed for notes). + # It is kept out of this file on purpose: GitHub caps a single `run:` + # step at 21000 characters, and an inlined heredoc is what silently + # pushed os-check.yml past that cap - the whole file then failed to + # load and every run reported zero jobs. # "minutes" is the expected duration driving longest-first scheduling: # take it from the Minutes column of a previous run's step summary, or # omit it for a new config (defaults to 1) and refresh later. The list @@ -76,218 +80,11 @@ jobs: # the values, not list order. - name: Build and make check this shard's configs (parallel, out-of-tree) run: | - cat > "$RUNNER_TEMP/pq-all-configs.json" <<'EOF' - [ - {"name": "all-pq-small-noasm", "minutes": 4, - "configure": ["--disable-intelasm", "--enable-all", - "--enable-testcert", "--enable-acert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-quic", "--with-sys-crypto-policy", - "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem,small", - "--enable-lms=yes,small", "--enable-xmss=yes,small", - "--enable-slhdsa=yes,small", "--enable-dilithium=yes,small", - "--enable-dual-alg-certs", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_MLDSA_SIGN_SMALL_MEM -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_MAKE_KEY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, - {"name": "all-pq-small-smallstack-noasm", "minutes": 4, - "configure": ["--disable-intelasm", "--enable-smallstack", - "--enable-smallstackcache", "--enable-all", "--enable-testcert", - "--enable-acert", "--enable-dtls13", "--enable-dtls-mtu", - "--enable-dtls-frag-ch", "--enable-dtlscid", "--enable-quic", - "--with-sys-crypto-policy", "--enable-experimental", - "--enable-mlkem=yes,kyber,ml-kem,small", "--enable-lms=yes,small", - "--enable-xmss=yes,small", "--enable-slhdsa=yes,small", - "--enable-dilithium=yes,small", "--enable-dual-alg-certs", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_MLDSA_SIGN_SMALL_MEM -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_MAKE_KEY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, - {"name": "all-pq-quic", "minutes": 3.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-acert", - "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", - "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", - "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", - "--enable-tls-mlkem-standalone", "--enable-extra-pqc-hybrids", - "--enable-lms", "--enable-xmss", "--enable-slhdsa", - "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_BLIND_PRIVATE_KEY -DWOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"]}, - {"name": "all-pq-sp-math", "minutes": 3.5, - "configure": ["--enable-intelasm", "--enable-sp-math", - "--enable-sp-asm", "--enable-all", "--enable-testcert", - "--enable-acert", "--enable-dtls13", "--enable-dtls-mtu", - "--enable-dtls-frag-ch", "--enable-dtlscid", "--disable-quic", - "--with-sys-crypto-policy", "--enable-experimental", - "--enable-mlkem=yes,kyber,ml-kem", "--enable-tls-mlkem-standalone", - "--enable-extra-pqc-hybrids", "--enable-lms", "--enable-xmss", - "--enable-slhdsa", "--enable-dilithium", "--enable-dual-alg-certs", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_BLIND_PRIVATE_KEY -DWOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"]}, - {"name": "all-pq-smallstack", "minutes": 3.5, - "configure": ["--enable-smallstack", "--enable-smallstackcache", - "--enable-intelasm", "--enable-sp-asm", "--enable-all", - "--enable-testcert", "--enable-acert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-quic", "--with-sys-crypto-policy", - "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", - "--enable-lms", "--enable-xmss", "--enable-slhdsa", - "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-pq-cxx", "minutes": 3.5, - "cc": "ccache c++", - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-acert", - "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", - "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", - "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", - "--enable-lms", "--enable-xmss", "--enable-slhdsa", - "--enable-dilithium", "--enable-dual-alg-certs", "--disable-qt", - "CPPFLAGS=-Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-pq-verify-only-noasm", "minutes": 3, - "configure": ["--disable-intelasm", "--enable-all", - "--disable-mlkem", "--enable-lms=yes,small,verify-only", - "--enable-xmss=yes,small,verify-only", - "--enable-slhdsa=yes,small,verify-only", - "--enable-dilithium=yes,small,verify-only", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLDSA_VERIFY_SMALL_MEM -DWOLFSSL_MLDSA_NO_LARGE_CODE"]}, - {"name": "all-pq-mldsa-no-ctx", "minutes": 3, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-acert", - "--enable-dtls13", "--enable-dtls-mtu", "--enable-dtls-frag-ch", - "--enable-dtlscid", "--enable-quic", "--with-sys-crypto-policy", - "--enable-experimental", "--enable-mlkem=yes,kyber,ml-kem", - "--enable-lms", "--enable-xmss", "--enable-slhdsa", - "--enable-dilithium=yes,no-ctx", "--enable-dual-alg-certs", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-frodokem", "minutes": 3.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-experimental", - "--enable-mlkem=yes,kyber,ml-kem", - "--enable-frodokem=aes,ephemeral", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "frodokem-small-smallstack-noasm", "minutes": 2.5, - "configure": ["--disable-intelasm", "--enable-smallstack", - "--enable-smallstackcache", "--enable-experimental", - "--enable-frodokem=aes,ephemeral,small", - "CPPFLAGS=-Wdeclaration-after-statement"]}, - {"name": "frodokem-976-only-noasm", "minutes": 1.5, - "comment": "976-only builds D=16 (q=2^16) alone; no-asm the C path", - "configure": ["--disable-intelasm", "--enable-experimental", - "--enable-frodokem=aes,ephemeral,no-640,no-1344", - "CPPFLAGS=-Wdeclaration-after-statement"]}, - {"name": "frodokem-640-shake-only", "minutes": 1.5, - "comment": "640-only builds D=15 (q=2^15); shake-only, with asm", - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-experimental", - "--enable-frodokem=no-976,no-1344,no-aes", - "CPPFLAGS=-Wdeclaration-after-statement"]}, - {"name": "frodokem-aarch64-armasm", "minutes": 4, "check": false, - "cc": "ccache aarch64-linux-gnu-gcc", - "comment": "Cross-build only (no ARM runner): catches ARM asm link/compile breaks. sve+sme+aes A-gen all live in the .S.", - "configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly", - "--enable-armasm", "--enable-experimental", - "--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]}, - {"name": "frodokem-aarch64-armasm-inline", "minutes": 4, - "check": false, "cc": "ccache aarch64-linux-gnu-gcc", - "comment": "Inline armasm: sve/sme/aes are .S-only, so they must fall back to NEON/C; guards the inline-asm link break.", - "configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly", - "--enable-armasm=inline", "--enable-experimental", - "--enable-frodokem=aes,ephemeral,sve,sme", "--disable-examples"]}, - {"name": "frodokem-arm32-armasm", "minutes": 4, "check": false, - "cc": "ccache arm-linux-gnueabihf-gcc", - "comment": "Cross-build only: AArch32 NEON matrix ops + AES-crypto A-gen.", - "configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly", - "--enable-armasm", "--enable-experimental", - "--enable-frodokem=aes,ephemeral", "--disable-examples"]}, - {"name": "ubsan-mldsa-mlkem", "minutes": 2.5, - "configure": ["--disable-shared", "--enable-dilithium", - "--enable-mlkem", - "CFLAGS=-fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer", - "LDFLAGS=-fsanitize=undefined", - "CPPFLAGS=-DWOLFSSL_MLDSA_ALIGNMENT=4"]}, - {"name": "all-mlkem-512-standalone", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,512", "--enable-tls-mlkem-standalone", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-768", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,768", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-768-standalone", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,768", "--enable-tls-mlkem-standalone", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-768-standalone-no-hybrids", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,768", "--enable-tls-mlkem-standalone", - "--disable-pqc-hybrids", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-1024", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,1024", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-1024-standalone", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,1024", - "--enable-tls-mlkem-standalone", "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "all-mlkem-1024-standalone-no-hybrids", "minutes": 2.5, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-all", "--enable-testcert", "--enable-dtls13", - "--enable-dtls-mtu", "--enable-dtls-frag-ch", "--enable-dtlscid", - "--enable-mlkem=make,enc,dec,1024", - "--enable-tls-mlkem-standalone", "--disable-pqc-hybrids", - "--disable-qt", - "CPPFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"]}, - {"name": "mlkem-old-ids", "minutes": 1.2, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-mlkem=yes,kyber,ml-kem", - "CPPFLAGS=-DWOLFSSL_ML_KEM_USE_OLD_IDS"]}, - {"name": "mlkem-dynamic-keys", "minutes": 1.2, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-mlkem=yes,kyber,ml-kem,cache-a", - "CPPFLAGS=-DWOLFSSL_MLKEM_DYNAMIC_KEYS"]}, - {"name": "mldsa-dynamic-keys", "minutes": 1.2, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-dilithium=yes", "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, - {"name": "mldsa-small-dynamic-keys", "minutes": 1.2, - "configure": ["--disable-intelasm", "--enable-dilithium=yes,small", - "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, - {"name": "mldsa-verify-only-dynamic-keys", "minutes": 1.2, - "configure": ["--disable-intelasm", - "--enable-dilithium=44,65,87,verify-only", - "CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}, - {"name": "mldsa-no-asn1-opensslextra", "minutes": 1.2, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-dilithium=yes", "--enable-opensslextra", - "CPPFLAGS=-DWOLFSSL_MLDSA_NO_ASN1"]}, - {"name": "mldsa-no-asn1-fips204-draft-opensslextra", "minutes": 1.2, - "configure": ["--enable-intelasm", "--enable-sp-asm", - "--enable-dilithium=yes,draft", "--enable-opensslextra", - "CPPFLAGS=-DWOLFSSL_MLDSA_NO_ASN1"]}, - {"name": "pkcs7-mldsa-only", "minutes": 1.2, - "comment": "PKCS#7 SignedData with ML-DSA as the only signature algorithm (no RSA, no ECC); guards the ML-DSA-only PKCS7 build path", - "configure": ["--enable-cryptonly", "--enable-mldsa", - "--enable-pkcs7", "--disable-rsa", "--disable-ecc"]} - ] - EOF .github/scripts/parallel-make-check.py \ ${{ github.event_name == 'schedule' && '--build-only' || '' }} \ --shard "${{ matrix.shard }}/${{ strategy.job-total }}" \ --private-dir=certs \ - "$RUNNER_TEMP/pq-all-configs.json" + .github/configs/pq-all.json - name: ccache stats if: always() diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml index e849389f36e..f63b2fb3fe6 100644 --- a/.github/workflows/smoke-test.yml +++ b/.github/workflows/smoke-test.yml @@ -141,30 +141,16 @@ jobs: # List order is schedule order: the worker threads take configs from # the top, so keep the slowest first or they straggle at the end on an # otherwise idle runner. Order by the Minutes column of the step - # summary from a recent (warm-cache) run. + # summary from a recent (warm-cache) run. The list lives in + # .github/configs/smoke-test.json rather than inline here: GitHub caps + # a single `run:` step at 21000 characters, and an inlined heredoc is + # what silently pushed os-check.yml past that cap - the whole file then + # failed to load and every run reported zero jobs. - name: Build and make check all configs (parallel, out-of-tree) if: steps.merge_check.outputs.skip != 'true' run: | - cat > "$RUNNER_TEMP/smoke-configs.json" <<'EOF' - [ - {"name": "sanitize-asan", "configure": ["--enable-all"], - "cflags": "-fsanitize=address -fno-omit-frame-pointer -g -O1", - "ldflags": "-fsanitize=address"}, - {"name": "opensslextra-norealloc-asan", "configure": ["--enable-opensslextra"], - "cflags": "-DWOLFSSL_NO_REALLOC -fsanitize=address -fno-omit-frame-pointer -g -O1", - "ldflags": "-fsanitize=address"}, - {"name": "enable-all-smallstack", "configure": ["--enable-all", "--enable-smallstack"]}, - {"name": "enable-all", "configure": ["--enable-all"]}, - {"name": "integration", "configure": ["--enable-openssh", "--enable-lighty", "--enable-stunnel", "--enable-opensslextra"]}, - {"name": "dtls-suite", "configure": ["--enable-psk", "--enable-dtls", "--enable-dtls13", "--enable-dtls-mtu", "--enable-aesccm", "--enable-opensslextra"]}, - {"name": "opensslextra", "configure": ["--enable-opensslextra"]}, - {"name": "default"}, - {"name": "cryptonly", "configure": ["--enable-cryptonly"]}, - {"name": "leantls-extra", "configure": ["--enable-leantls", "--enable-session-ticket", "--enable-sni", "--enable-opensslextra"]} - ] - EOF .github/scripts/parallel-make-check.py ${{ github.event_name == 'schedule' && '--build-only' || '' }} --cflags=-Werror \ - --private-dir=certs "$RUNNER_TEMP/smoke-configs.json" + --private-dir=certs .github/configs/smoke-test.json # Seed (master pushes + the weekday cron) writes the master-scoped # ccache that PR runs restore; PRs never save. diff --git a/.github/workflows/workflow-health.yml b/.github/workflows/workflow-health.yml new file mode 100644 index 00000000000..dbd42660b0a --- /dev/null +++ b/.github/workflows/workflow-health.yml @@ -0,0 +1,59 @@ +name: Workflow Health + +# Catches workflows that GitHub is failing to load. +# +# Such a workflow does not fail loudly: its runs end within 0s with zero +# jobs, no logs and no annotations, so the coverage it provided is gone +# while the PR page still shows hundreds of green checks. os-check.yml sat +# broken on master for ten days in July 2026 before anyone noticed. +# +# check-source-text.yml lints workflow files pre-merge for the one cause +# we know about (the 21000 character per-run-step cap). This job is the +# net underneath that: it looks for the symptom instead of the cause, so a +# workflow that stops loading for an unanticipated reason is still caught, +# and it files a GitHub issue rather than adding one more red check that +# would blend in with the rest. +# +# Known gap: this workflow cannot detect its own failure to load. If this +# file stops loading it goes quiet in exactly the way it exists to +# prevent, and nothing here reports that. The pre-merge lint covers the +# size cause for this file as much as any other; the remaining causes are +# uncovered, and closing that properly needs a checker outside this +# repository. If the issue this opens has been quiet for a long stretch, +# confirm the workflow is still running rather than assuming all is well. + +on: + schedule: + # Daily, shortly after the weekday os-check ccache seed at 10:00 UTC + # so a load failure there is picked up in the same cycle. + - cron: '30 11 * * *' + # Lets a maintainer confirm a fix without waiting for the next cron. + workflow_dispatch: + +concurrency: + group: workflow-health + cancel-in-progress: false + +permissions: + contents: read + # Reading run/job metadata for every workflow in the repo. + actions: read + # Opening, updating and closing the tracking issue. + issues: write + +jobs: + check: + if: github.repository_owner == 'wolfssl' + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v5 + + # The script exits non-zero while any workflow is failing to load, + # which is what surfaces this run as failed. The issue it files is + # the part meant to be noticed; the red run is a backstop. + - name: Detect workflows failing to load + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + .github/scripts/check-workflow-health.py --repo "$GITHUB_REPOSITORY"