diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 690475d9..b11c7f6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,13 +39,20 @@ jobs: mkdir -p .codex-build/hostlink-codec/library-deps pio pkg install --global --storage-dir .codex-build/hostlink-codec/library-deps --library "rweather/Crypto@0.4.0" --skip-dependencies pio pkg install --global --storage-dir .codex-build/hostlink-codec/library-deps --library "nanopb/Nanopb@0.4.92" --skip-dependencies + - name: Prepare pinned native SHA-256 source without installing an ESP SDK + run: | + curl --fail --location --retry 3 https://codeload.github.com/Mbed-TLS/mbedtls/tar.gz/e185d7fd85499c8ce5ca2a54f5cf8fe7dbe3f8df --output "$RUNNER_TEMP/trail-mate-native-mbedtls.tar.gz" + echo "052dccf3a404dce25a467c6fe044b0c858d609ace8e883b59e9dfd479fdd4528 $RUNNER_TEMP/trail-mate-native-mbedtls.tar.gz" | sha256sum --check + mkdir -p .codex-build/hostlink-codec/mbedtls-source + tar --extract --gzip --file "$RUNNER_TEMP/trail-mate-native-mbedtls.tar.gz" --directory .codex-build/hostlink-codec/mbedtls-source --strip-components=1 - name: Verify packet bridge pacing and origin boundaries working-directory: tools/geocaching run: ../../.codex-build/reticulum-directory/venv/bin/python -m unittest test_packet_bridge test_packet_bridge_pacing - name: Verify native protocol, storage policy and cryptographic vectors run: | - cmake -S tests/hostlink -B .codex-build/hostlink-codec/native -DCMAKE_BUILD_TYPE=Debug -DTRAIL_MATE_ARDUINO_CRYPTO_DIR="$PWD/.codex-build/hostlink-codec/library-deps/Crypto" -DTRAIL_MATE_MODULE_NANOPB_DIR="$PWD/.codex-build/hostlink-codec/library-deps/Nanopb" -DTRAIL_MATE_REQUIRE_RADIO_IDENTITY_TESTS=ON + cmake -S tests/hostlink -B .codex-build/hostlink-codec/native -DCMAKE_BUILD_TYPE=Debug -DTRAIL_MATE_ARDUINO_CRYPTO_DIR="$PWD/.codex-build/hostlink-codec/library-deps/Crypto" -DTRAIL_MATE_MODULE_NANOPB_DIR="$PWD/.codex-build/hostlink-codec/library-deps/Nanopb" -DTRAIL_MATE_REQUIRE_RADIO_IDENTITY_TESTS=ON -DTRAIL_MATE_MBEDTLS_DIR="$PWD/.codex-build/hostlink-codec/mbedtls-source" cmake --build .codex-build/hostlink-codec/native --parallel 2 + test -x .codex-build/hostlink-codec/native/track_snapshot_owner ctest --test-dir .codex-build/hostlink-codec/native --output-on-failure cmake -S tests/tracker_recording -B .codex-build/tracker-recording -DCMAKE_BUILD_TYPE=Debug cmake --build .codex-build/tracker-recording --parallel 2 diff --git a/docs/releases/1.0.0.md b/docs/releases/1.0.0.md index 2ea8f40f..455f860c 100644 --- a/docs/releases/1.0.0.md +++ b/docs/releases/1.0.0.md @@ -84,6 +84,18 @@ and what recipients can see. Tracker card interaction checks and the site build. Its deployment job is intentionally skipped on this review branch. Broader firmware/browser CI confirmation remains separate from this result. + Run `38559416114` passes all ten firmware targets and the configuration/ + identity browser stage. Its KML stage cannot advance because CI omitted the + Mbed TLS source path required to build `track_snapshot_owner`, and the + attachment harness did not propagate process-start failure to its ready + promise. The same missing local fixture reproduces that wait; with the + existing cache available, the attachment test passes in about six seconds. + The correction pins native SHA-256 source matching the existing SDK's + Mbed TLS 3.6.5, enables the existing CMake tests, requires the executable and + propagates startup failure. No ESP SDK is installed for this host test. + Both affected CI runs were canceled after their firmware builds had finished. + All sixteen existing KML workspace/file browser cases pass locally after + restoring the shared native/Python caches; final CI confirmation remains open. 2. Complete the original real-Wio publication-confirmation task. The reviewed Card/location build `4be4f572` was flashed on 2026-10-14 and returned to COM69 after watchdog reset. Original author/RF public keys and the 309-field configuration diff --git a/tests/site/track-attachments.browser.mjs b/tests/site/track-attachments.browser.mjs index cb0fba6f..ea69f133 100644 --- a/tests/site/track-attachments.browser.mjs +++ b/tests/site/track-attachments.browser.mjs @@ -81,10 +81,13 @@ const script=bundle.outputFiles.find(file=>file.path.endsWith('.js')).text,css=b const server=http.createServer((req,res)=>{res.setHeader('Content-Type','text/html');res.end('
');});await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve)); const browser=await chromium.launch({channel:process.env.TRAIL_MATE_TEST_BROWSER_CHANNEL,headless:true}); const child=spawn(path.resolve('.codex-build/hostlink-codec/native/track_snapshot_owner'+(process.platform==='win32'?'.exe':'')),['package-protocol'],{stdio:['pipe','pipe','pipe']}),pending=[]; -let stderr='';child.stderr.on('data',chunk=>stderr+=chunk); -const ready=new Promise((resolve,reject)=>pending.push({resolve,reject})),exit=new Promise((resolve,reject)=>{child.on('error',reject);child.on('exit',code=>code===0?resolve():reject(Error('Native package fixture failed: '+stderr)));});exit.catch(()=>{}); +let stderr='',nativeFailure=null;child.stderr.on('data',chunk=>stderr+=chunk); +const ready=new Promise((resolve,reject)=>pending.push({resolve,reject})),exit=new Promise((resolve,reject)=>{ + child.on('error',error=>{nativeFailure=error;for(const waiter of pending.splice(0))waiter.reject(error);reject(error);}); + child.on('exit',code=>{const error=nativeFailure??Error('Native package fixture exited '+code+': '+stderr);for(const waiter of pending.splice(0))waiter.reject(error);code===0?resolve():reject(error);}); +});exit.catch(()=>{});ready.catch(()=>{}); createInterface({input:child.stdout}).on('line',line=>{const wait=pending.shift();if(!wait)return;const [code,hex]=line.split(' ');Number(code)===0?wait.resolve(new Uint8Array(Buffer.from(hex,'hex'))):wait.reject(Object.assign(Error('Native status '+code),{code:Number(code)}));}); -const send=line=>new Promise((resolve,reject)=>{pending.push({resolve,reject});child.stdin.write(line+'\n');}); +const send=line=>new Promise((resolve,reject)=>{if(nativeFailure||child.exitCode!==null){reject(nativeFailure??Error('Native fixture already exited'));return;}pending.push({resolve,reject});child.stdin.write(line+'\n');}); const session={request:async(op,body)=>decode(await send(op+' '+Buffer.from(encode(body)).toString('hex')),471)}; try{ const page=await browser.newPage({viewport:{width:1200,height:1000}}),url=`http://127.0.0.1:${server.address().port}`; @@ -118,4 +121,4 @@ try{ const edited=await page.evaluate(()=>editTest());assert.equal(edited.count,1);assert.equal(edited.bytes,photo.length);assert.equal(edited.same,true); assert.equal(await page.evaluate(()=>corruptTest()),'DRAFT_CORRUPT');assert.deepEqual(await page.evaluate(()=>removeTest()),{empty:true,jobs:1}); console.log('Attachment UI/storage passed legacy v2 migration, exact files/index, stable retry IDs, reload, 11 locales, mobile/RTL, CAS, invalidation, corruption and cleanup.'); -}finally{await send('close');child.stdin.end();await exit;assert.equal(stderr,'');await browser.close();await new Promise(resolve=>server.close(resolve));} +}finally{if(!nativeFailure&&child.exitCode===null)await send('close');child.stdin.end();await exit.catch(error=>{console.error(error);process.exitCode=1;});assert.equal(stderr,'');await browser.close();await new Promise(resolve=>server.close(resolve));}