Skip to content

Commit 2eb0225

Browse files
committed
Add FastLanes Linux mixed-schema retry workflow
1 parent 7b918d8 commit 2eb0225

2 files changed

Lines changed: 274 additions & 0 deletions

File tree

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
name: FastLanes mixed-schema retry
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
numeric_rows:
7+
description: Numeric control row count
8+
required: true
9+
default: "1000000"
10+
type: string
11+
timeout_seconds:
12+
description: Timeout per generated case
13+
required: true
14+
default: "900"
15+
type: string
16+
17+
permissions:
18+
contents: read
19+
20+
env:
21+
FASTLANES_SOURCE_COMMIT: f0edc1020a538f1f8098640fce8347c9ac247a0d
22+
RUN_DIR: runs/fastlanes-linux-${{ github.run_id }}
23+
ARCHIVE: outputs/release/data-format-lab-fastlanes-linux-x86_64-${{ github.run_id }}.tar.zst
24+
25+
jobs:
26+
retry:
27+
name: FastLanes official Python round trip
28+
runs-on: ubuntu-24.04
29+
timeout-minutes: 90
30+
31+
steps:
32+
- name: Initialize evidence directory
33+
run: |
34+
set -euo pipefail
35+
mkdir -p "$RUN_DIR"
36+
printf 'platform=linux-x86_64\nrun_id=%s\n' "$GITHUB_RUN_ID" \
37+
> "$RUN_DIR/context.txt"
38+
39+
- name: Check out public commit
40+
id: checkout
41+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
42+
43+
- name: Install Nix
44+
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
45+
46+
- name: Synchronize frozen lab environment
47+
run: nix develop --command uv sync --frozen
48+
49+
- name: Check out pinned FastLanes source
50+
id: source
51+
continue-on-error: true
52+
run: |
53+
set -euo pipefail
54+
mkdir -p native
55+
git clone --filter=blob:none --no-tags \
56+
https://github.com/cwida/FastLanes.git native/fastlanes
57+
git -C native/fastlanes checkout --detach "$FASTLANES_SOURCE_COMMIT"
58+
git -C native/fastlanes submodule update --init --recursive
59+
git -C native/fastlanes rev-parse HEAD > "$RUN_DIR/source-commit.txt"
60+
61+
- name: Build official Python extension
62+
id: build
63+
if: always()
64+
continue-on-error: true
65+
run: |
66+
set -euo pipefail
67+
mkdir -p "$RUN_DIR"
68+
set +e
69+
(
70+
set -euo pipefail
71+
test -f native/fastlanes/CMakeLists.txt
72+
nix develop --command python -m venv native/fastlanes/.venv
73+
nix develop --command native/fastlanes/.venv/bin/python -m pip install \
74+
--disable-pip-version-check --no-cache-dir \
75+
scikit-build-core==0.11.6 \
76+
cmake==4.4.0 \
77+
ninja==1.13.0 \
78+
pybind11==2.12.1 \
79+
setuptools-scm==8.3.1
80+
CMAKE_BUILD_PARALLEL_LEVEL=4 \
81+
nix develop --command native/fastlanes/.venv/bin/python -m pip install \
82+
--no-build-isolation -e native/fastlanes
83+
native/fastlanes/.venv/bin/python -c \
84+
'import pyfastlanes; print(pyfastlanes.get_version())'
85+
) > "$RUN_DIR/build.log" 2>&1
86+
status=$?
87+
set -e
88+
printf '%s\n' "$status" > "$RUN_DIR/build-status.txt"
89+
exit "$status"
90+
91+
- name: Record reproducibility metadata
92+
if: always()
93+
run: |
94+
set -euo pipefail
95+
{
96+
printf 'source_commit=%s\n' "$FASTLANES_SOURCE_COMMIT"
97+
printf 'requested_numeric_rows=%s\n' '${{ inputs.numeric_rows }}'
98+
printf 'requested_timeout_seconds=%s\n' '${{ inputs.timeout_seconds }}'
99+
printf 'python='; nix develop --command python --version
100+
if test -x native/fastlanes/.venv/bin/python; then
101+
printf 'fastlanes_python='; native/fastlanes/.venv/bin/python --version
102+
fi
103+
printf 'clang='; nix develop --command clang --version
104+
printf 'cmake='; nix develop --command cmake --version
105+
printf 'ninja='; nix develop --command ninja --version
106+
printf 'uname='; uname -a
107+
} > "$RUN_DIR/environment.txt" 2>&1 || true
108+
109+
- name: Run fresh-process FastLanes claims
110+
id: measure
111+
if: steps.build.outcome == 'success'
112+
continue-on-error: true
113+
env:
114+
NUMERIC_ROWS: ${{ inputs.numeric_rows }}
115+
CASE_TIMEOUT_SECONDS: ${{ inputs.timeout_seconds }}
116+
run: |
117+
set -euo pipefail
118+
set +e
119+
PYTHONPATH="$GITHUB_WORKSPACE/src" \
120+
native/fastlanes/.venv/bin/python - "$RUN_DIR/results.json" <<'PY'
121+
import json
122+
import os
123+
import sys
124+
from pathlib import Path
125+
126+
from format_bench.claims.fastlanes import run_fastlanes_claim
127+
128+
output = Path(sys.argv[1])
129+
evidence = run_fastlanes_claim(
130+
output.parent / "claims" / "fastlanes-official",
131+
numeric_rows=int(os.environ["NUMERIC_ROWS"]),
132+
timeout_seconds=float(os.environ["CASE_TIMEOUT_SECONDS"]),
133+
)
134+
payload = {
135+
"schema_version": "1",
136+
"contract_version": "1",
137+
"lane": "claims",
138+
"platform": "linux-x86_64",
139+
"source_commit": "f0edc1020a538f1f8098640fce8347c9ac247a0d",
140+
"evidence": evidence,
141+
}
142+
output.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
143+
PY
144+
status=$?
145+
set -e
146+
printf '%s\n' "$status" > "$RUN_DIR/measure-status.txt"
147+
exit "$status"
148+
149+
- name: Preserve unavailable or failed evidence
150+
if: always()
151+
run: |
152+
set -euo pipefail
153+
if test -s "$RUN_DIR/results.json"; then
154+
exit 0
155+
fi
156+
nix develop --command python - "$RUN_DIR/results.json" \
157+
'${{ steps.source.outcome }}' '${{ steps.build.outcome }}' <<'PY'
158+
import json
159+
import sys
160+
from pathlib import Path
161+
162+
output = Path(sys.argv[1])
163+
source, build = sys.argv[2:]
164+
output.write_text(
165+
json.dumps(
166+
{
167+
"schema_version": "1",
168+
"contract_version": "1",
169+
"lane": "claims",
170+
"platform": "linux-x86_64",
171+
"source_commit": "f0edc1020a538f1f8098640fce8347c9ac247a0d",
172+
"status": "UNSUPPORTED",
173+
"failure_reason": f"source={source}; build={build}",
174+
},
175+
indent=2,
176+
sort_keys=True,
177+
)
178+
+ "\n"
179+
)
180+
PY
181+
182+
- name: Write concise evidence report
183+
if: always()
184+
run: |
185+
set -euo pipefail
186+
nix develop --command python - "$RUN_DIR/results.json" "$RUN_DIR/report.md" <<'PY'
187+
import json
188+
import sys
189+
from pathlib import Path
190+
191+
results = json.loads(Path(sys.argv[1]).read_text())
192+
lines = [
193+
"# FastLanes Linux x86_64 retry",
194+
"",
195+
f"- Source commit: `{results['source_commit']}`",
196+
f"- Platform: `{results['platform']}`",
197+
]
198+
evidence = results.get("evidence")
199+
if evidence:
200+
lines.extend(["", f"- Status: `{evidence.get('status', 'UNKNOWN')}`"])
201+
lines.append(f"- Summary: {evidence.get('summary', 'not available')}")
202+
else:
203+
lines.extend(["", f"- Status: `{results.get('status', 'UNKNOWN')}`"])
204+
lines.append(f"- Failure: {results.get('failure_reason', 'not available')}")
205+
Path(sys.argv[2]).write_text("\n".join(lines) + "\n")
206+
PY
207+
208+
- name: Package evidence
209+
if: always()
210+
run: |
211+
set -euo pipefail
212+
mkdir -p "$(dirname "$ARCHIVE")"
213+
tar --zstd --sort=name --mtime='UTC 2026-07-17' \
214+
-cf "$ARCHIVE" -C "$RUN_DIR" .
215+
sha256sum "$ARCHIVE" > "$ARCHIVE.sha256"
216+
217+
- name: Upload FastLanes evidence
218+
if: always()
219+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
220+
with:
221+
name: data-format-lab-fastlanes-linux-x86_64-${{ github.run_id }}
222+
path: |
223+
${{ env.RUN_DIR }}
224+
${{ env.ARCHIVE }}
225+
${{ env.ARCHIVE }}.sha256
226+
retention-days: 14
227+
if-no-files-found: error
228+
229+
- name: Preserve retry failure status
230+
if: always()
231+
run: |
232+
set -euo pipefail
233+
test '${{ steps.checkout.outcome }}' = success
234+
test '${{ steps.source.outcome }}' = success
235+
test '${{ steps.build.outcome }}' = success
236+
nix develop --command python - "$RUN_DIR/results.json" <<'PY'
237+
import json
238+
import sys
239+
from pathlib import Path
240+
241+
results = json.loads(Path(sys.argv[1]).read_text())
242+
evidence = results.get("evidence", {})
243+
if evidence.get("status") != "MEASURED":
244+
raise SystemExit(f"FastLanes claim status: {evidence.get('status')}")
245+
mixed = evidence.get("mixed", {})
246+
if mixed.get("outcome") != "ROUNDTRIP_EQUAL":
247+
raise SystemExit(f"mixed 13-column outcome: {mixed.get('outcome')}")
248+
PY

‎tests/test_fastlanes_workflow.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from pathlib import Path
2+
3+
4+
WORKFLOW = Path(__file__).parents[1] / ".github/workflows/benchmark-fastlanes.yml"
5+
6+
7+
def test_fastlanes_retry_workflow_is_pinned_and_linux_only() -> None:
8+
workflow = WORKFLOW.read_text(encoding="utf-8")
9+
10+
assert "runs-on: ubuntu-24.04" in workflow
11+
assert "f0edc1020a538f1f8098640fce8347c9ac247a0d" in workflow
12+
assert "uv sync --frozen" in workflow
13+
assert "native/fastlanes/.venv/bin/python -m pip install" in workflow
14+
assert "run_fastlanes_claim" in workflow
15+
assert "mixed 13-column outcome" in workflow
16+
assert "tar --zstd" in workflow
17+
assert "retention-days: 14" in workflow
18+
19+
20+
def test_fastlanes_retry_workflow_preserves_build_and_measurement_logs() -> None:
21+
workflow = WORKFLOW.read_text(encoding="utf-8")
22+
23+
assert '"$RUN_DIR/build.log"' in workflow
24+
assert '"$RUN_DIR/build-status.txt"' in workflow
25+
assert '"$RUN_DIR/measure-status.txt"' in workflow
26+
assert "if: always()" in workflow

0 commit comments

Comments
 (0)