mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 13:53:12 -06:00
CI: give the parity baselines the tags they judge against
main has been red since 4f7b4e3 for a reason visible nowhere in its diff.
The player-parity baselines describe what an UN-UPDATED display can do, so
they are judged against the SHIPPED source — `git show <latest tag>:…` —
rather than the working tree. actions/checkout defaults to a shallow clone
with no tags, so that lookup found nothing and the suite fell back to the
working tree. In a tree where today's QA had just fixed the players'
set_volume payload bug, the biconditional then demanded that
BASELINE.web/tizen gain audio.volume — for displays that cannot possibly
have the fix yet. Green locally, red in CI, and the failing assertion names
a baseline rather than the checkout that caused it.
So fetch the tags in the test job, and make the biconditionals SKIP when
there are none instead of asserting against the wrong source. That fallback
was never a slightly-early assertion; it was an inverted one. A skipped
assertion announces itself, a wrong one does not.
Verified both ways: with tags 15/15 pass, in a tagless shallow clone 13
pass + 2 skip + 0 fail (previously 1 fail).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014skWYXJUWhF73EvNPgB2AS
This commit is contained in:
parent
59489b3b20
commit
89cdd1052a
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
|
@ -25,6 +25,15 @@ jobs:
|
|||
working-directory: server
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
# The player-parity baselines judge a claim against the SHIPPED source
|
||||
# (`git show <latest tag>:…`), because a baseline describes what an
|
||||
# UN-UPDATED display can do. The default shallow checkout has no tags, so
|
||||
# the suite silently fell back to the working tree and the biconditionals
|
||||
# inverted: fixing a player's payload bug made CI demand a baseline change
|
||||
# for displays that cannot possibly have the fix yet. Green locally, red
|
||||
# here, for a reason found nowhere in the diff.
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20'
|
||||
|
|
|
|||
|
|
@ -41,17 +41,32 @@ const read = (p) => fs.readFileSync(path.join(ROOT, p), 'utf8');
|
|||
* displays that cannot possibly have the fix yet. A baseline entry should move when a fix SHIPS, not
|
||||
* when it is written.
|
||||
*
|
||||
* Falls back to the working tree when the tags are not available (a shallow CI clone), because a
|
||||
* missing tag is a worse reason to fail a build than a slightly-early assertion.
|
||||
* Falls back to the working tree when the tags are not available (a shallow CI clone) — but the
|
||||
* BICONDITIONAL tests below then SKIP rather than assert, because that fallback is not a
|
||||
* slightly-early assertion, it is an inverted one. It cost a red build to learn: with no tags, CI
|
||||
* judged the baselines against a working tree in which a player's payload bug had just been fixed,
|
||||
* so the matrix was told to move a baseline for displays that cannot possibly have the fix yet.
|
||||
* Green locally, red in CI, for a reason visible nowhere in the diff. A skipped assertion announces
|
||||
* itself; a wrong one does not. (ci.yml now checks out with fetch-depth: 0 so this stays a backstop.)
|
||||
*/
|
||||
let shippedFromTag = false;
|
||||
function readShipped(rel) {
|
||||
try {
|
||||
const tag = execSync("git tag --list 'v*' --sort=-v:refname | head -1", { cwd: ROOT, encoding: 'utf8' }).trim();
|
||||
if (tag) return execSync(`git show ${tag}:${rel}`, { cwd: ROOT, encoding: 'utf8', maxBuffer: 1 << 26 });
|
||||
if (tag) {
|
||||
const src = execSync(`git show ${tag}:${rel}`, { cwd: ROOT, encoding: 'utf8', maxBuffer: 1 << 26 });
|
||||
shippedFromTag = true;
|
||||
return src;
|
||||
}
|
||||
} catch (e) { /* no tags, or the path did not exist in that release */ }
|
||||
return read(rel);
|
||||
}
|
||||
|
||||
// A biconditional compares a baseline against the SHIPPED player. Without a tag there is no
|
||||
// shipped player to compare against, and the working tree is the wrong answer, not a close one.
|
||||
const needsShippedSource = (t) =>
|
||||
shippedFromTag ? false : (t.skip('no release tag available — cannot judge a baseline against shipped source'), true);
|
||||
|
||||
const SRC = {
|
||||
web: readShipped('server/player/index.html'),
|
||||
android: [
|
||||
|
|
@ -158,7 +173,8 @@ test('the capture bootstrap is not gated on the capability it creates', () => {
|
|||
|
||||
/* ---- baselines, pinned to the players ------------------------------------------------------- */
|
||||
|
||||
test('BICONDITIONAL: audio.volume in a baseline iff that player reads the payload the dashboard sends', () => {
|
||||
test('BICONDITIONAL: audio.volume in a baseline iff that player reads the payload the dashboard sends', (t) => {
|
||||
if (needsShippedSource(t)) return;
|
||||
/*
|
||||
* frontend/js/views/device-detail.js sends set_volume as `{ level: 0..1 }`. Android reads
|
||||
* payload.level. The web player reads `payload?.value ?? data.value` and Tizen reads
|
||||
|
|
@ -195,7 +211,8 @@ test('audio.mute is real on all four, unlike its neighbour', () => {
|
|||
}
|
||||
});
|
||||
|
||||
test('BICONDITIONAL: offline.cache in a baseline iff that player has a media cache', () => {
|
||||
test('BICONDITIONAL: offline.cache in a baseline iff that player has a media cache', (t) => {
|
||||
if (needsShippedSource(t)) return;
|
||||
// Tizen's media cache is a NEW file — it was not in v1.9.28 — so the baseline must not claim it
|
||||
// even though HEAD's capabilities.js declares it at runtime. BrightSign's widget is not known to
|
||||
// permit a service worker at all.
|
||||
|
|
|
|||
Loading…
Reference in a new issue