nandi/frqpublic Fork 0
f912073
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

The layout suite runs in CI

It has caught five regressions the other two suites cannot see, because
what it checks is what Flutter does with the tree rather than what the
tree says: `Expanded` outside a Flex, a `Wrap` handing a child unbounded
width, a scrollbar on a different controller from its view. Every one of
those passed `just test nim` and broke the running app.

The job needs a Flutter toolchain, which is the reason it was left out
and the only reason. Pinned to the version and hash `tools/toolchain.sh`
already uses, since a suite that passes in CI and fails on the
developer's machine is worse than no suite. Flutter unpacks into HOME
rather than /opt: it writes a cache and a version stamp inside its own
directory on the first command, and a root-owned copy fails as whatever
user the job runs as.

It needs the library from the Nim job and nothing from the Dart one, so
it waits on `nim-test` alone.

The header comment went with it. It described handing the build to a
Modal Sandbox for the web bundle, and both the web target and that
container are gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-19T09:40:48-07:00 Browse files
f912073 parent: 5594a62
modified .rickub/workflows/build.yml +69 -8
@@ -1,18 +1,23 @@
1-# The build, on rickub. GitLab CI next door reads source and no more —
2-# check-common on every push — and deliberately builds nothing. This is the
3-# other half: the web bundle, actually compiled.
1+# The build, on rickub. GitLab CI next door reads source and no more, and
2+# deliberately builds nothing. This is the other half: three suites, each one
3+# checking a different seam.
44 #
5-# It is not compiled *here*. The job hands the work to Modal exactly as a
6-# person at a terminal would, and the Sandbox does it against the `devshell`
7-# volume. What a runner contributes is a checkout, a python, and somewhere to
8-# put the result afterwards. The reason it goes to Modal is the volume the
9-# toolchain is cached on, not the size of the build.
5+# Nothing here is handed to Modal. The header used to say this job passed the
6+# work to a Sandbox against the `devshell` volume — that was the web bundle,
7+# and both the web target and the container that built it are gone. What runs
8+# now is small enough for a runner: Nim in about a second, Dart in less, and
9+# Flutter for as long as a Flutter toolchain takes to arrive.
10+#
11+# Every toolchain is a sha256-pinned tarball rather than an apt package or a
12+# third-party setup action, which is this repo's habit — see
13+# `tools/toolchain.sh`, which fetches the same two by the same hashes.
1014 #
1115 # Lives in .rickub/workflows/ rather than .github/workflows/ because rickub
1216 # reads one or the other and never both: with this directory present, a
1317 # .github/workflows/ added later would be silently ignored. There is none
1418 # today, so nothing is being shadowed — see
1519 # https://rickub.com/docs/actions and https://rickub.com/docs/migrating-from-github
20+
1621 name: build
1722
1823 on:
@@ -109,3 +114,59 @@ jobs:
109114 path: build/nim
110115 - run: cd dart/frq_core && dart pub get && dart test -r expanded
111116
117+ # The screens, laid out for real. Widget tests on the Dart VM: headless, no
118+ # GL and no window, which is exactly what makes them the check a Wayland
119+ # window cannot be — a GUI on Wayland cannot be clicked by a script, so for
120+ # a long time the biggest screen in the app went out unverified.
121+ #
122+ # They have caught five regressions that the Nim and Dart suites cannot see,
123+ # because what they check is what Flutter does with the tree rather than
124+ # what the tree says: `Expanded` outside a Flex, a `Wrap` handing a child
125+ # unbounded width, a scrollbar on a different controller from its view.
126+ #
127+ # The cost is a Flutter toolchain, which is why this job is last and why it
128+ # needs neither of the others to pass first — it needs the library the Nim
129+ # job builds, and nothing from Dart.
130+ layout-test:
131+ runs-on: ubuntu-latest
132+ needs: [nim-test]
133+ env:
134+ # The same version and hash `tools/toolchain.sh` pins, because a suite
135+ # that passes here and fails on the developer's machine is worse than no
136+ # suite. Two places rather than one is the price of a workflow file that
137+ # cannot source a shell script it also has to trust.
138+ FLUTTER_VERSION: "3.47.0"
139+ FLUTTER_SHA256: "26cd99d3d94b1367e6b50535a18aeef0282c10a535bbe3ec493534dcdab75296"
140+ steps:
141+ - uses: actions/checkout@v4
142+
143+ - name: Flutter ${{ env.FLUTTER_VERSION }}
144+ run: |
145+ set -euo pipefail
146+ url="https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz"
147+ curl -fsSL -o /tmp/flutter.tar.xz "$url"
148+ echo "${FLUTTER_SHA256} /tmp/flutter.tar.xz" | sha256sum -c -
149+ # Into HOME rather than /opt: flutter writes its own cache and
150+ # version stamp inside its directory on the first command, so a
151+ # root-owned copy fails as whatever user the job runs as.
152+ mkdir -p "$HOME/flutter"
153+ tar -xJf /tmp/flutter.tar.xz -C "$HOME/flutter" --strip-components=1
154+ echo "$HOME/flutter/bin" >> "$GITHUB_PATH"
155+ # The tarball is an unpacked git checkout, and flutter refuses to
156+ # report its own version out of a repository it thinks belongs to
157+ # somebody else. `tools/toolchain.sh` does this too.
158+ git config --global --add safe.directory "$HOME/flutter"
159+
160+ # The .so dlopens OpenSSL at startup; the test loads it through FFI
161+ # exactly as the app does.
162+ - run: sudo apt-get update -qq && sudo apt-get install -y -qq libssl3
163+
164+ - uses: actions/download-artifact@v4
165+ with:
166+ name: libfrqcore
167+ path: build/nim
168+
169+ # `../build/nim/libfrqcore.so` is one of the paths `frq_core` looks in,
170+ # named for this case — `flutter test` runs from `flutter/`.
171+ - name: The layout suite
172+ run: cd flutter && flutter pub get && flutter test test/nim_layout_test.dart
@@ -1,18 +1,23 @@
1-# The build, on rickub. GitLab CI next door reads source and no more —1+# The build, on rickub. GitLab CI next door reads source and no more, and
2-# check-common on every push — and deliberately builds nothing. This is the2+# deliberately builds nothing. This is the other half: three suites, each one
3-# other half: the web bundle, actually compiled.3+# checking a different seam.
4 #4 #
5-# It is not compiled *here*. The job hands the work to Modal exactly as a5+# Nothing here is handed to Modal. The header used to say this job passed the
6-# person at a terminal would, and the Sandbox does it against the `devshell`6+# work to a Sandbox against the `devshell` volume — that was the web bundle,
7-# volume. What a runner contributes is a checkout, a python, and somewhere to7+# and both the web target and the container that built it are gone. What runs
8-# put the result afterwards. The reason it goes to Modal is the volume the8+# now is small enough for a runner: Nim in about a second, Dart in less, and
9-# toolchain is cached on, not the size of the build.9+# Flutter for as long as a Flutter toolchain takes to arrive.
10+#
11+# Every toolchain is a sha256-pinned tarball rather than an apt package or a
12+# third-party setup action, which is this repo's habit — see
13+# `tools/toolchain.sh`, which fetches the same two by the same hashes.
10 #14 #
11 # Lives in .rickub/workflows/ rather than .github/workflows/ because rickub15 # Lives in .rickub/workflows/ rather than .github/workflows/ because rickub
12 # reads one or the other and never both: with this directory present, a16 # reads one or the other and never both: with this directory present, a
13 # .github/workflows/ added later would be silently ignored. There is none17 # .github/workflows/ added later would be silently ignored. There is none
14 # today, so nothing is being shadowed — see18 # today, so nothing is being shadowed — see
15 # https://rickub.com/docs/actions and https://rickub.com/docs/migrating-from-github19 # https://rickub.com/docs/actions and https://rickub.com/docs/migrating-from-github
20+
16 name: build21 name: build
17 22
18 on:23 on:
@@ -109,3 +114,59 @@ jobs:
109 path: build/nim114 path: build/nim
110 - run: cd dart/frq_core && dart pub get && dart test -r expanded115 - run: cd dart/frq_core && dart pub get && dart test -r expanded
111 116
117+ # The screens, laid out for real. Widget tests on the Dart VM: headless, no
118+ # GL and no window, which is exactly what makes them the check a Wayland
119+ # window cannot be — a GUI on Wayland cannot be clicked by a script, so for
120+ # a long time the biggest screen in the app went out unverified.
121+ #
122+ # They have caught five regressions that the Nim and Dart suites cannot see,
123+ # because what they check is what Flutter does with the tree rather than
124+ # what the tree says: `Expanded` outside a Flex, a `Wrap` handing a child
125+ # unbounded width, a scrollbar on a different controller from its view.
126+ #
127+ # The cost is a Flutter toolchain, which is why this job is last and why it
128+ # needs neither of the others to pass first — it needs the library the Nim
129+ # job builds, and nothing from Dart.
130+ layout-test:
131+ runs-on: ubuntu-latest
132+ needs: [nim-test]
133+ env:
134+ # The same version and hash `tools/toolchain.sh` pins, because a suite
135+ # that passes here and fails on the developer's machine is worse than no
136+ # suite. Two places rather than one is the price of a workflow file that
137+ # cannot source a shell script it also has to trust.
138+ FLUTTER_VERSION: "3.47.0"
139+ FLUTTER_SHA256: "26cd99d3d94b1367e6b50535a18aeef0282c10a535bbe3ec493534dcdab75296"
140+ steps:
141+ - uses: actions/checkout@v4
142+
143+ - name: Flutter ${{ env.FLUTTER_VERSION }}
144+ run: |
145+ set -euo pipefail
146+ url="https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz"
147+ curl -fsSL -o /tmp/flutter.tar.xz "$url"
148+ echo "${FLUTTER_SHA256} /tmp/flutter.tar.xz" | sha256sum -c -
149+ # Into HOME rather than /opt: flutter writes its own cache and
150+ # version stamp inside its directory on the first command, so a
151+ # root-owned copy fails as whatever user the job runs as.
152+ mkdir -p "$HOME/flutter"
153+ tar -xJf /tmp/flutter.tar.xz -C "$HOME/flutter" --strip-components=1
154+ echo "$HOME/flutter/bin" >> "$GITHUB_PATH"
155+ # The tarball is an unpacked git checkout, and flutter refuses to
156+ # report its own version out of a repository it thinks belongs to
157+ # somebody else. `tools/toolchain.sh` does this too.
158+ git config --global --add safe.directory "$HOME/flutter"
159+
160+ # The .so dlopens OpenSSL at startup; the test loads it through FFI
161+ # exactly as the app does.
162+ - run: sudo apt-get update -qq && sudo apt-get install -y -qq libssl3
163+
164+ - uses: actions/download-artifact@v4
165+ with:
166+ name: libfrqcore
167+ path: build/nim
168+
169+ # `../build/nim/libfrqcore.so` is one of the paths `frq_core` looks in,
170+ # named for this case — `flutter test` runs from `flutter/`.
171+ - name: The layout suite
172+ run: cd flutter && flutter pub get && flutter test test/nim_layout_test.dart