Skip to content

[CUBRIDQA-1603] Turn on set -u, link the full failure list, and fail on a missing testcase branch - #7984

Merged
cubridci merged 5 commits into
CUBRID:developfrom
tw-kang:cubridqa-1501-set-euo
Sep 21, 2026
Merged

cubridci merged 5 commits into
CUBRID:developfrom
tw-kang:cubridqa-1501-set-euo

Conversation

@tw-kang

@tw-kang tw-kang commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

http://jira.cubrid.org/browse/CUBRIDQA-1603

Purpose

gha-ci.yml 의 스크립트 34개가 set -eo pipefail 로 시작한다. -u 가 빠져 있다. 그래서 없는 변수는 빈 문자열이 된다. 같은 .github/workflows/tc-branch-sync.yml·tc-branch-finalize.yml·tc-merge-gate.yml·submodule-bump-receiver.yml 은 이미 set -euo pipefail 이다 — gha-ci.yml 만 달랐다.

빈 문자열은 조용하다. 이름을 잘못 적은 변수, 앞 단계가 채우지 못한 변수가 빈 경로나 빈 인자가 되고 스크립트는 그대로 진행한다. 빈 값이 루트 기준 경로를 만드는 모양은 실물로도 봤다 — plan 이 죽은 run 에서 collect 의 정리 단계가 $RUNDIR 를 빈 값으로 읽어 /plan/testtools 를 로그에 찍었다(배치 자식 35240525905).

그 한 건은 이 PR 이 안 잡는다. RUNDIR 은 step 의 env: 로 늘 정의되고 값만 비므로 -u 가 물지 않는다 — 거기에는 조건 가드가 따로 필요하고 별건으로 남겼다. -u 가 잡는 것은 아예 정의되지 않은 이름이다: 오타, 그리고 앞 단계가 $GITHUB_ENV 로 넘겼어야 할 값.

세 번째는 판정 자체를 틀리게 한다. plan 은 tc/pr-<N>(TC Branch Sync 가 PR 을 열 때 만드는 테스트케이스 브랜치)을 찾아본다. 없으면 경고 한 줄을 찍고 develop 의 케이스로 돌았다. 요청자가 고른 적 없는 케이스로 엔진 변경을 채점하고, 그 판정은 여느 초록·빨강과 똑같이 보인다. 같은 자리의 다른 두 끝(네트워크 실패, 이미지의 checkout)은 이미 실패로 끝낸다 — 조용히 넘어가는 갈래는 이것 하나였다.

두 번째 것은 읽는 사람 몫이다. 실패 케이스가 50건을 넘으면 run summary 가 첫 50건만 싣고 나머지는 /home/gha-ci/runs/<id>/<suite>/collect/failed.list 라고 볼륨 경로를 적어 준다. summary 를 보는 사람은 그 경로를 열 수 없다. 산출물 서버가 그 파일을 이미 서빙하고 있고, summary 의 다른 링크는 전부 그 주소로 만들어진다.

Implementation

커밋 셋이다. 되돌릴 때도 셋이 따로 선다.

1. 34개 스크립트 전부 set -euo pipefail 로 바꿨다. 이제 없는 변수를 읽으면 그 자리에서 unbound variable 로 멈춘다.

바뀌는 동작은 하나다. shard 의 always() 단계 둘(Publish results for collect·Verdict)은 SHARD_DIR 같은 값을 첫 단계 Resolve the suite$GITHUB_ENV 에 쓴 것에서 받는다. 그 첫 단계가 죽으면 지금까지는 빈 값으로 계속 돌았다 — mkdir -p "$out/artifacts"/artifacts 가 되고(job pod 은 overlay 를 마운트하므로 root 다), $STAMP 가 빈 >> 대상이 되는 자리에서야 ambiguous redirect 로 멈춘다. 이제는 첫 줄에서 어느 변수가 비었는지 말하고 멈춘다. 그 갈래에서 job 은 어차피 빨강이었다 — 판정은 안 바뀌고, 남기는 쓰레기와 로그만 바뀐다.

나머지 33개는 동작이 같다. 아래 Remarks 의 지역 대조에서 59개 시나리오가 옛 판과 바이트까지 같은 출력을 냈다.

2. 실패 목록 안내를 링크로 바꿨다. _... and N more. The full list is <볼륨 경로>_ARTIFACT_URL_BASE 로 만든 링크로 바꿨다. summary 의 [Artifacts]·[Run directory]·[build log] 가 쓰는 것과 같은 기계다.

- _... and 30 more. The full list is `/home/gha-ci/runs/35334829033/shell/collect/failed.list`_
+ _... and 30 more. The full list is [`failed.list`](http://192.168.1.48:30080/runs/35334829033/shell/collect/failed.list)._

3. tc/pr-<N> 이 없으면 실패로 끝낸다. ::warning::… falling back to develop + TC_BRANCH=develop::error:: + exit 1 로 바꿨다. 메시지는 어느 브랜치가 없는지, 그것을 누가 만드는지(TC Branch Sync), 왜 develop 으로 안 떨어지는지를 말한다.

- ::warning::cubrid-testcases-private-ex has no tc/pr-7981, falling back to develop
+ ::error::cubrid-testcases-private-ex has no tc/pr-7981
+   TC Branch Sync creates tc/pr-<N> when the pull request opens, so check
+   that run, or push the branch. Not falling back to develop: the verdict
+   would be against cases the requester never asked for.

누가 영향을 받나: pr 가 붙은 run 뿐이다. 배치 자식·develop push·pr 를 비운 dispatch 는 애초 TC_BRANCH=develop 이라 그대로다. ⚠ sync 봇보다 먼저 열린 옛 PR(#6585·#6853)에 /run 을 쓰면 이제 실패한다 — 의도한 것이다. 최근 PR run 20건에 폴백 사례는 0건이었다.

Remarks

  • set -u 로 실제로 깨지는 자리가 있는지 34개 블록을 전부 읽고 기계로도 걸렀다. 걸러낸 것은 ① 변수가 조건 갈래 안에서만 대입되고 밖에서 읽히는 자리 ② 앞 단계가 $GITHUB_ENV 로 넘긴 값을 always() 단계가 읽는 자리 ③ 누적 변수(x="$x ...")의 초기화 누락 ④ 연관 배열의 없는 키 읽기다. ②만 남았고 위에 적었다. ④는 ${parent[$c]+set} 로 이미 막혀 있다.

  • 티켓에 적혀 있던 실물 결함 1건은 이미 없다. gate 의 sel="$sel $w"sel 미설정 상태에서 돈다는 지적(2026-09-16)은 그 시점 기준으로는 맞았지만, #7932(develop 69168b3da2, 9/14 머지)이 sel='' 초기화를 이미 넣었다. 지역 대조로 확인했다 — 그 초기화 한 줄을 도로 지운 판을 만들어 /run shell 코멘트를 먹이면 line 104: sel: unbound variable 로 죽고, 지금 develop 판은 정상으로 끝난다. 시험이 그 결함을 잡을 수 있음을 먼저 보이고 나서 없음을 확인했다.

  • 지역 대조 (옛 판 vs 새 판, 블록 15개 · 59 시나리오). 블록을 YAML 에서 그대로 떼어 내고 gh·curl·date 를 스텁으로 바꾼 뒤, GitHub 이 주는 것과 같게 step 의 env: 키를 전부 빈 값으로라도 정의한 상태로 돌려 출력·종료코드·$GITHUB_OUTPUT·$GITHUB_STEP_SUMMARY 를 비교했다. 지역 bash 는 4.4.20 으로 test_rl8.10 이미지와 같은 판이다.

    블록 시나리오 결과
    gate push(develop·feature) · dispatch(shell·all·all+parallelism 거부·nightly·nightly 예행) · 코멘트(shell·all·shell sql·CRLF·rerun·rerun 무실패·문법아님·testtools·base 범위밖·잘못된 run id·잘못된 브랜치명) · schedule · 미지원 이벤트 = 20 전부 동일
    plan 의 Case list and split shell · parallelism 지정 · timings 빈 파일 · limit · sabotage · sql(dir 단위·publish) · rerun · rerun 원본 없음 = 8 전부 동일
    shard 의 Publish results·Verdict shell 통과 · shell 실패+코어 · sql 통과 · sql 실패 · 결과파일 없음 · CTP 안 돎 = 6 전부 동일
    collect 의 Wall clock+Guard 3 초록 · 실패 80건 · 죽은 shard · 빌드 출처 불일치 · rerun · attempt 2 = 6 실패 80건에서 위 링크 한 줄만 다름, 나머지 동일
    collect 의 failed case log·Clean up the CTP seed 실패 80건 · 실패 없음 · 정리 = 3 전부 동일
    plan 의 Refresh testcases (TC 브랜치 결정) tc/pr-<N> 있음 · 없음(pr 지정) · 없음(pr 빈값) · 네트워크 실패 = 4 없음 두 판에서 옛 판은 develop 으로 폴백해 계속, 새 판은 exit 1. 있음·네트워크 실패 두 판은 동일
    nightly · status_pending · build_status · Split summary · Update timings · Check the run directory · 최종 status 창 비었음 · 예행 · HTTP 실패 · debug 빌드 실패 · RUNDIR 빈 값 · verdict 없음 등 = 16 전부 동일
  • 링크가 실제로 열리는지 산출물 서버로 확인했다. http://192.168.1.48:30080/runs/35334829033/shell/collect/failed.list = HTTP 200, 80줄. nginx 의 404 규칙(/_fork·CTP seed)에 걸리지 않는 경로다.

  • 50건 초과는 드물다 — run 1,031건 실측에서 실패 있는 run 175건, 중앙값 2 · p90 15, 50 초과는 3건(0.3%)이다. 그래서 급한 고침이 아니라 이 PR 에 얹었다.

  • Run CTP 단계의 set +eset -e 짝은 그대로 뒀다. set +e-u 를 끄지 않고, 뒤의 set -e-u 를 건드리지 않는다.

  • develop 최신화: #7981 머지 뒤 git merge develop(rebase 안 함) — 충돌 없음. [CUBRIDQA-1575] Put each failed sql and medium case's query and diff in the run summary #7981gha-ci.yml 에 넣은 새 셸(collect 의 실패 로그 awk 한 벌 공유, xml_name 유도)도 set -u 아래서 돈다. 차등 시험 전판을 새 기준선(develop 880a173380)으로 다시 돌렸고 결과는 같다 — 링크 한 줄과 tc/pr 갈래만 다르다.

  • 포크 lane 검증 — 네 판. /run 코멘트로는 워크플로 변경을 검증할 수 없어(항상 develop 사본으로 돈다) workflow_dispatch --ref 로 돌렸다. 세 판이 34개 블록 중 컨테이너가 있어야 도는 19개를 실물로 지나간다 — build 7개(release 다리는 sweep 포함), plan 6개, shard 8개(prune·publish 두 갈래), collect 6개.

    run 결과
    shell (prune 길) 35354702502 전 job 초록. 30 케이스 · shard 2. shard: planned 2 / published 2 / build provenance 2 / tc provenance 2, run 30 / passed 30 / failed 0, shell completed with no failures.
    sql (publish·tar 길) 35356061550 전 job 초록. 5,309 케이스 · 4 단위 · shard 2. plan 이 tar 를 발행하고 shard 가 자기 몫만 풀어 가는 갈래다. run 5309 / passed 5309 / failed 0, sql completed with no failures.
    tc/pr 없는 PR 번호 (새 실패 길) 35562353042 의도대로 멈췄다. pr=999999 로 돌려 plan 의 Refresh testcases 가 실패 — 주석 cubrid-testcases-private-ex has no tc/pr-999999 + 안내 세 줄. shard 는 skipped, collect 는 plan ended failure, so the split stage broke. 로 끝났고 status 는 error 를 찍었다. 옛 판이었다면 develop 케이스로 초록이 났을 자리다
    shell + sabotage=empty-shard (실패 길) 35357648805 가드가 설계대로 물었다. shard 00 = Take my share (guard 2 of 3) 실패 → Publish results for collect(always) 성공(실패 갈래를 set -u 로 통과) → Verdict 실패. collect 는 shards that never ran a case: 1 / cases left unrun: 2, run 4 / passed 4 (of 6), build provenance 1 로 빨강
  • ${d#$CI_ROOT/} 는 옆의 [Artifacts]·[Run directory] 링크와 같은 모양이라 그대로 뒀다 — shellcheck SC2295 가 세 줄 모두에 붙는다. CI_ROOT 는 고정 경로라 글롭이 없다.

  • 이 절(plan 의 테스트케이스 결정)은 곧 다시 쓰인다 — 테스트케이스를 노드 사본으로 옮기는 후속 PR 이다. 그때 이 동작(폴백 없음)을 같이 가져가야 한다.

  • 같은 티켓의 소항목(collect 의 빈 RUNDIR 가드, build sweep 의 tc/*.tmp.*)은 이 PR 에 없다. 순위 없음으로 남겨 둔 것들이다.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CZJ3dG29wnfshtwVKBMyNT

tw-kang and others added 2 commits September 18, 2026 23:10
An unset variable expanded to the empty string in all 34 run blocks, so a
name typed wrong or a value a step did not set became an empty path or an
empty argument and the script carried on. `set -u` makes it stop there.

The 34 blocks were read for the places where that changes what runs. The
only ones that change are the two always() steps of shard: when "Resolve
the suite" dies, nothing has written SHARD_DIR to the environment, and
those two steps used to write into the container root before failing on
an ambiguous redirect. Now they say which variable is unbound and stop.
The job was already red in that case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZJ3dG29wnfshtwVKBMyNT
…obody can open

Over 50 failed cases, the run summary listed the first 50 and pointed at
the rest with `/home/gha-ci/runs/<id>/<suite>/collect/failed.list` -- a
path on the GlusterFS volume, not something a reader of the summary can
open. The artifact server already serves that file, and every other link
in the summary is built from ARTIFACT_URL_BASE. This line now is too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZJ3dG29wnfshtwVKBMyNT
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown

✅ TC Merge Gate — Merge Allowed

All TC PRs are merged, closed, or not present.

TC Repositories & Branches:

  • cubrid-testcases: No open TC PR (merged, closed, or not created)
  • cubrid-testcases-private-ex: No open TC PR (merged, closed, or not created)

@github-actions

Copy link
Copy Markdown

🧪 TC Test Environment Ready

CircleCI Testing:

  • CircleCI will automatically test using the branches below.

TC Repositories & Branches:

Next Steps:

  1. Wait for CircleCI tests to complete
  2. If CircleCI tests failed, please check the test results and fix the issues.
  3. When ready to merge this PR, please merge the TC PR first, then merge this PR.

…is missing

plan probes cubrid-testcases/-private-ex for tc/pr-<N>, the branch TC Branch
Sync creates when the pull request opens. When the probe came back "no such
ref", plan warned and ran develop's cases instead. The run then graded the
engine change against cases the requester never asked for, and the verdict
looked like any other.

The other two ways this probe can end already stop the run: a network
failure after five attempts exits 1, and so does the image's checkout. This
branch was the only one that carried on, so it now says which branch is
missing and where it comes from, and exits 1.

A run with no pull request -- a batch child, a develop push, a dispatch with
pr empty -- asks for develop to begin with and is untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZJ3dG29wnfshtwVKBMyNT
@tw-kang tw-kang changed the title [CUBRIDQA-1501] Turn on set -u in every gha-ci.yml script, and link the full failure list [CUBRIDQA-1501] Turn on set -u, link the full failure list, and fail on a missing testcase branch Sep 21, 2026
tw-kang and others added 2 commits September 21, 2026 14:04
…o fall back on

It described the behaviour the commit before this one removed, and left the
reader an argument for putting it back. What remains is the one fact the code
does not carry: exit 2 means "no such ref", so the retries exist to keep a
network blip apart from it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZJ3dG29wnfshtwVKBMyNT
@tw-kang tw-kang changed the title [CUBRIDQA-1501] Turn on set -u, link the full failure list, and fail on a missing testcase branch [CUBRIDQA-1603] Turn on set -u, link the full failure list, and fail on a missing testcase branch Sep 21, 2026
@tw-kang
tw-kang marked this pull request as ready for review September 21, 2026 06:22
@tw-kang

tw-kang commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@greptile-apps

greptile-apps Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Retrigger

테스트 입력의 정합성과 실패 진단을 강화하는 변경으로, 현재 확인된 범위에서는 안전하게 병합할 수 있습니다.

Reviews (1) · Last reviewed commit: "Merge remote-tracking branch 'origin/dev..."

@tw-kang

tw-kang commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

/run all

1 similar comment
@tw-kang

tw-kang commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

/run all

@tw-kang

tw-kang commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

/run all

@cubridci
cubridci merged commit cad2717 into CUBRID:develop Sep 21, 2026
13 of 19 checks passed
@github-actions

Copy link
Copy Markdown

TC Branch Finalized for cubrid-testcases

Engine PR was merged.

Cleanup Results:

  • Branch tc/pr-7984: Deleted

TC base branch is ready for the next PR.

@github-actions

Copy link
Copy Markdown

TC Branch Finalized for cubrid-testcases-private-ex

Engine PR was merged.

Cleanup Results:

  • Branch tc/pr-7984: Deleted

TC base branch is ready for the next PR.

hyunikn added a commit to hyunikn/cubrid that referenced this pull request Sep 21, 2026
…ure list, and fail on a missing testcase branch (CUBRID#7984)
tw-kang added a commit to tw-kang/cubrid that referenced this pull request Sep 21, 2026
CUBRID#7984 turned on `set -u` across the workflow and made a missing tc/pr-<N>
fail instead of falling back to develop. Both land on steps this branch
rewrites, so the conflicts keep develop's `set -u` and this branch's body;
the three steps this branch deletes stay deleted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B24o3QtfCZrMJgJnsQgzVn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants