Skip to content

Commit 62e1fbb

Browse files
committed
ci(test): cache Linux engine before queued matches
Pre-upload the compiled AVX2 engine once and publish its artifact key and checksum as workflow metadata. Reuse that key for optional commit-tagged match creation, reconcile deterministic task markers on reruns, and apply the shared equal-time 25,000-game online protocol.
1 parent 4a64b98 commit 62e1fbb

1 file changed

Lines changed: 137 additions & 13 deletions

File tree

‎.github/workflows/testing.yml‎

Lines changed: 137 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515
env:
1616
CC: clang
1717
CXX: clang++
18+
FISHTEST_URL: https://test.pikafish.org/api
1819
defaults:
1920
run:
2021
working-directory: Rapfi
@@ -30,35 +31,158 @@ jobs:
3031
cmake --build . -j2 && strip pbrain-rapfi*
3132
mv -v pbrain-rapfi rapfi-linux-avx2
3233
34+
- name: Pre-upload engine to fishtest
35+
id: fishtest_upload
36+
if: ${{ github.event_name == 'push' }}
37+
env:
38+
FISHTEST_PASSWORD: ${{ secrets.NOTHING }}
39+
run: |
40+
RESPONSE=$(curl --fail-with-body --silent --show-error \
41+
--connect-timeout 30 --max-time 900 \
42+
--retry 3 --retry-all-errors --retry-delay 5 \
43+
"$FISHTEST_URL/pre_upload" \
44+
-F file=@build/rapfi-linux-avx2 \
45+
-F file_type=engine \
46+
-F "password=$FISHTEST_PASSWORD")
47+
48+
ARTIFACT_KEY=$(jq -er '
49+
if .code == 0 and (.url | type == "string") and (.url | length) > 0
50+
then .url
51+
else error(.msg // "Fishtest pre-upload failed")
52+
end
53+
' <<<"$RESPONSE")
54+
ENGINE_MD5=$(md5sum build/rapfi-linux-avx2 | cut -d' ' -f1)
55+
56+
echo "artifact_key=$ARTIFACT_KEY" >> "$GITHUB_OUTPUT"
57+
jq -n \
58+
--arg commit "$GITHUB_SHA" \
59+
--arg artifact_key "$ARTIFACT_KEY" \
60+
--arg md5 "$ENGINE_MD5" \
61+
'{commit: $commit, artifact_key: $artifact_key, md5: $md5}' \
62+
> build/fishtest-upload.json
63+
64+
{
65+
echo "### Fishtest pre-upload"
66+
echo
67+
echo "- Artifact key: \`$ARTIFACT_KEY\`"
68+
echo "- Engine MD5: \`$ENGINE_MD5\`"
69+
} >> "$GITHUB_STEP_SUMMARY"
70+
3371
- name: Upload to fishtest (freestyle-20)
34-
if: ${{ contains(github.event.head_commit.message, 'f20') }}
72+
if: ${{ github.event_name == 'push' && contains(github.event.head_commit.message, 'f20') }}
73+
env:
74+
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
75+
ENGINE_ARTIFACT_KEY: ${{ steps.fishtest_upload.outputs.artifact_key }}
76+
FISHTEST_PASSWORD: ${{ secrets.NOTHING }}
3577
run: |
36-
COMMIT_TITLE=$(echo "${{github.event.head_commit.message}}" | head -n 1)
37-
curl http://test.pikafish.org/api/add_task -F engine=@build/rapfi-linux-avx2 -F variant=gomoku_freestyle20 -F "task_name=[f20] $COMMIT_TITLE" -F "password=${{secrets.NOTHING}}" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "visible=0"
78+
COMMIT_TITLE=$(printf '%s\n' "$COMMIT_MESSAGE" | head -n 1)
79+
TASK_MARKER="[ci:${GITHUB_SHA:0:12}:f20]"
80+
TASK_NAME="[f20] $TASK_MARKER $COMMIT_TITLE"
81+
LOOKUP_RESPONSE=$(curl --fail-with-body --silent --show-error --get "$FISHTEST_URL/task_list" --data-urlencode "page=1" --data-urlencode "page_size=100" --data-urlencode "variant=gomoku_freestyle20" --data-urlencode "keyword=$TASK_MARKER" --data-urlencode "password=$FISHTEST_PASSWORD")
82+
TASK_ID=$(jq -r 'if .code == 0 then (.data[0].task_id // "") else error(.msg // "Task lookup failed") end' <<<"$LOOKUP_RESPONSE")
83+
if [[ -n "$TASK_ID" ]]; then
84+
EXISTING_ENGINE=$(jq -r '.data[0].engine_url' <<<"$LOOKUP_RESPONSE")
85+
[[ "$EXISTING_ENGINE" == "$ENGINE_ARTIFACT_KEY" ]] || { echo "::error::Task marker $TASK_MARKER exists with engine $EXISTING_ENGINE, expected $ENGINE_ARTIFACT_KEY"; exit 1; }
86+
TASK_ACTION="reused"
87+
else
88+
if TASK_RESPONSE=$(curl --fail-with-body --silent --show-error "$FISHTEST_URL/add_task" -F "engine_file_name=$ENGINE_ARTIFACT_KEY" -F variant=gomoku_freestyle20 -F "task_name=$TASK_NAME" -F "password=$FISHTEST_PASSWORD" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "max_games=25000" -F "adjudication=1" -F "visible=0"); then
89+
TASK_ID=$(jq -er 'if .code == 0 and .task_id then .task_id else error(.msg // "Task submission failed") end' <<<"$TASK_RESPONSE")
90+
TASK_ACTION="created"
91+
else
92+
echo "::error::Ambiguous add_task outcome for $TASK_MARKER. Do not retry blindly; rerun the workflow so it reconciles this marker first."
93+
exit 1
94+
fi
95+
fi
96+
echo "- f20 task: \`$TASK_ID\` ($TASK_ACTION)" >> "$GITHUB_STEP_SUMMARY"
3897
3998
- name: Upload to fishtest (freestyle-15)
40-
if: ${{ contains(github.event.head_commit.message, 'f15') }}
99+
if: ${{ github.event_name == 'push' && contains(github.event.head_commit.message, 'f15') }}
100+
env:
101+
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
102+
ENGINE_ARTIFACT_KEY: ${{ steps.fishtest_upload.outputs.artifact_key }}
103+
FISHTEST_PASSWORD: ${{ secrets.NOTHING }}
41104
run: |
42-
COMMIT_TITLE=$(echo "${{github.event.head_commit.message}}" | head -n 1)
105+
COMMIT_TITLE=$(printf '%s\n' "$COMMIT_MESSAGE" | head -n 1)
43106
sleep 10
44-
curl http://test.pikafish.org/api/add_task -F engine=@build/rapfi-linux-avx2 -F variant=gomoku_freestyle15 -F "task_name=[f15] $COMMIT_TITLE" -F "password=${{secrets.NOTHING}}" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "visible=0"
107+
TASK_MARKER="[ci:${GITHUB_SHA:0:12}:f15]"
108+
TASK_NAME="[f15] $TASK_MARKER $COMMIT_TITLE"
109+
LOOKUP_RESPONSE=$(curl --fail-with-body --silent --show-error --get "$FISHTEST_URL/task_list" --data-urlencode "page=1" --data-urlencode "page_size=100" --data-urlencode "variant=gomoku_freestyle15" --data-urlencode "keyword=$TASK_MARKER" --data-urlencode "password=$FISHTEST_PASSWORD")
110+
TASK_ID=$(jq -r 'if .code == 0 then (.data[0].task_id // "") else error(.msg // "Task lookup failed") end' <<<"$LOOKUP_RESPONSE")
111+
if [[ -n "$TASK_ID" ]]; then
112+
EXISTING_ENGINE=$(jq -r '.data[0].engine_url' <<<"$LOOKUP_RESPONSE")
113+
[[ "$EXISTING_ENGINE" == "$ENGINE_ARTIFACT_KEY" ]] || { echo "::error::Task marker $TASK_MARKER exists with engine $EXISTING_ENGINE, expected $ENGINE_ARTIFACT_KEY"; exit 1; }
114+
TASK_ACTION="reused"
115+
else
116+
if TASK_RESPONSE=$(curl --fail-with-body --silent --show-error "$FISHTEST_URL/add_task" -F "engine_file_name=$ENGINE_ARTIFACT_KEY" -F variant=gomoku_freestyle15 -F "task_name=$TASK_NAME" -F "password=$FISHTEST_PASSWORD" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "max_games=25000" -F "adjudication=1" -F "visible=0"); then
117+
TASK_ID=$(jq -er 'if .code == 0 and .task_id then .task_id else error(.msg // "Task submission failed") end' <<<"$TASK_RESPONSE")
118+
TASK_ACTION="created"
119+
else
120+
echo "::error::Ambiguous add_task outcome for $TASK_MARKER. Do not retry blindly; rerun the workflow so it reconciles this marker first."
121+
exit 1
122+
fi
123+
fi
124+
echo "- f15 task: \`$TASK_ID\` ($TASK_ACTION)" >> "$GITHUB_STEP_SUMMARY"
45125
46126
- name: Upload to fishtest (standard-15)
47-
if: ${{ contains(github.event.head_commit.message, 's15') }}
127+
if: ${{ github.event_name == 'push' && contains(github.event.head_commit.message, 's15') }}
128+
env:
129+
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
130+
ENGINE_ARTIFACT_KEY: ${{ steps.fishtest_upload.outputs.artifact_key }}
131+
FISHTEST_PASSWORD: ${{ secrets.NOTHING }}
48132
run: |
49-
COMMIT_TITLE=$(echo "${{github.event.head_commit.message}}" | head -n 1)
133+
COMMIT_TITLE=$(printf '%s\n' "$COMMIT_MESSAGE" | head -n 1)
50134
sleep 10
51-
curl http://test.pikafish.org/api/add_task -F engine=@build/rapfi-linux-avx2 -F variant=gomoku_standard15 -F "task_name=[s15] $COMMIT_TITLE" -F "password=${{secrets.NOTHING}}" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "visible=0"
135+
TASK_MARKER="[ci:${GITHUB_SHA:0:12}:s15]"
136+
TASK_NAME="[s15] $TASK_MARKER $COMMIT_TITLE"
137+
LOOKUP_RESPONSE=$(curl --fail-with-body --silent --show-error --get "$FISHTEST_URL/task_list" --data-urlencode "page=1" --data-urlencode "page_size=100" --data-urlencode "variant=gomoku_standard15" --data-urlencode "keyword=$TASK_MARKER" --data-urlencode "password=$FISHTEST_PASSWORD")
138+
TASK_ID=$(jq -r 'if .code == 0 then (.data[0].task_id // "") else error(.msg // "Task lookup failed") end' <<<"$LOOKUP_RESPONSE")
139+
if [[ -n "$TASK_ID" ]]; then
140+
EXISTING_ENGINE=$(jq -r '.data[0].engine_url' <<<"$LOOKUP_RESPONSE")
141+
[[ "$EXISTING_ENGINE" == "$ENGINE_ARTIFACT_KEY" ]] || { echo "::error::Task marker $TASK_MARKER exists with engine $EXISTING_ENGINE, expected $ENGINE_ARTIFACT_KEY"; exit 1; }
142+
TASK_ACTION="reused"
143+
else
144+
if TASK_RESPONSE=$(curl --fail-with-body --silent --show-error "$FISHTEST_URL/add_task" -F "engine_file_name=$ENGINE_ARTIFACT_KEY" -F variant=gomoku_standard15 -F "task_name=$TASK_NAME" -F "password=$FISHTEST_PASSWORD" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "max_games=25000" -F "adjudication=1" -F "visible=0"); then
145+
TASK_ID=$(jq -er 'if .code == 0 and .task_id then .task_id else error(.msg // "Task submission failed") end' <<<"$TASK_RESPONSE")
146+
TASK_ACTION="created"
147+
else
148+
echo "::error::Ambiguous add_task outcome for $TASK_MARKER. Do not retry blindly; rerun the workflow so it reconciles this marker first."
149+
exit 1
150+
fi
151+
fi
152+
echo "- s15 task: \`$TASK_ID\` ($TASK_ACTION)" >> "$GITHUB_STEP_SUMMARY"
52153
53154
- name: Upload to fishtest (renju-15)
54-
if: ${{ contains(github.event.head_commit.message, 'r15') }}
155+
if: ${{ github.event_name == 'push' && contains(github.event.head_commit.message, 'r15') }}
156+
env:
157+
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
158+
ENGINE_ARTIFACT_KEY: ${{ steps.fishtest_upload.outputs.artifact_key }}
159+
FISHTEST_PASSWORD: ${{ secrets.NOTHING }}
55160
run: |
56-
COMMIT_TITLE=$(echo "${{github.event.head_commit.message}}" | head -n 1)
161+
COMMIT_TITLE=$(printf '%s\n' "$COMMIT_MESSAGE" | head -n 1)
57162
sleep 10
58-
curl http://test.pikafish.org/api/add_task -F engine=@build/rapfi-linux-avx2 -F variant=gomoku_renju15 -F "task_name=[r15] $COMMIT_TITLE" -F "password=${{secrets.NOTHING}}" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "visible=0"
163+
TASK_MARKER="[ci:${GITHUB_SHA:0:12}:r15]"
164+
TASK_NAME="[r15] $TASK_MARKER $COMMIT_TITLE"
165+
LOOKUP_RESPONSE=$(curl --fail-with-body --silent --show-error --get "$FISHTEST_URL/task_list" --data-urlencode "page=1" --data-urlencode "page_size=100" --data-urlencode "variant=gomoku_renju15" --data-urlencode "keyword=$TASK_MARKER" --data-urlencode "password=$FISHTEST_PASSWORD")
166+
TASK_ID=$(jq -r 'if .code == 0 then (.data[0].task_id // "") else error(.msg // "Task lookup failed") end' <<<"$LOOKUP_RESPONSE")
167+
if [[ -n "$TASK_ID" ]]; then
168+
EXISTING_ENGINE=$(jq -r '.data[0].engine_url' <<<"$LOOKUP_RESPONSE")
169+
[[ "$EXISTING_ENGINE" == "$ENGINE_ARTIFACT_KEY" ]] || { echo "::error::Task marker $TASK_MARKER exists with engine $EXISTING_ENGINE, expected $ENGINE_ARTIFACT_KEY"; exit 1; }
170+
TASK_ACTION="reused"
171+
else
172+
if TASK_RESPONSE=$(curl --fail-with-body --silent --show-error "$FISHTEST_URL/add_task" -F "engine_file_name=$ENGINE_ARTIFACT_KEY" -F variant=gomoku_renju15 -F "task_name=$TASK_NAME" -F "password=$FISHTEST_PASSWORD" -F "game_time=10" -F "inc_time=0.1" -F "depth=-1" -F "nodes=-1" -F "elo0=0" -F "elo1=5" -F "alpha=0.05" -F "beta=0.05" -F "max_games=25000" -F "adjudication=1" -F "visible=0"); then
173+
TASK_ID=$(jq -er 'if .code == 0 and .task_id then .task_id else error(.msg // "Task submission failed") end' <<<"$TASK_RESPONSE")
174+
TASK_ACTION="created"
175+
else
176+
echo "::error::Ambiguous add_task outcome for $TASK_MARKER. Do not retry blindly; rerun the workflow so it reconciles this marker first."
177+
exit 1
178+
fi
179+
fi
180+
echo "- r15 task: \`$TASK_ID\` ($TASK_ACTION)" >> "$GITHUB_STEP_SUMMARY"
59181
60182
- name: Upload
61183
uses: actions/upload-artifact@v4
62184
with:
63185
name: Fishtest
64-
path: Rapfi/build/rapfi-linux-avx2
186+
path: |
187+
Rapfi/build/rapfi-linux-avx2
188+
Rapfi/build/fishtest-upload.json

0 commit comments

Comments
 (0)