Titik Buta Glob Git di Build Gate Token
Pola bintang dua di git ternyata melewatkan file komponen yang langsung di src; empat perintah repo tempaan membongkar titik buta build gate token.
Ringkasan
Gue bikin gate buat ngeblok hex kayak #fff123 di Next.js, kirain pola rekursif udah nangkep semua file. Pas dites pakai repo tempaan, file yang langsung di src/ ternyata lolos dari git ls-files. Akhirnya di-fix pakai gabungan pola biar file direct sama nested ketangkep semua, plus nambah dua test regresi.
Cerita ini lanjutan dari pasang-pasang harness test pertama di frontend Next.js buat sebuah project company profile. Di tengah nulis test build gate yang tugasnya nge-blok warna hex seperti #fff123 di luar token sheet, muncul satu pertanyaan mental yang nggak bisa saya buang: gimana kalau ada file komponen yang duduk langsung di bawah src/, bukan di subfolder seperti semua komponen yang sekarang ada?
Intuisi saya saat itu: aman. Pola ** kan artinya kedalaman berapapun, termasuk nggak ada subfolder sama sekali. Ternyata itu salah, dan gate-nya bisa membiarkan file pelanggar lewat tanpa berteriak.
Ngecek Pakai Repo Tempaan
Daripada debat asumsi di kepala sendiri, saya bikin repo tempaan. Satu file langsung di src/, satu nested di src/components/, lalu tanya sama git ls-files:
mkdir -p frontend/src/components
echo "const x = '#fff123'" > frontend/src/Foo.tsx
echo "const y = '#000000'" > frontend/src/components/Bar.tsx
git init && git add .
git ls-files "frontend/src/**/*.tsx"
git ls-files "frontend/src/*.tsx"Jawabannya nyata dan nggak bisa dibantah: pola ** melewatkan Foo.tsx, padahal file itu justru contoh pelanggaran yang paling mau dicegah. git ls-files sendiri secara default nampilin semua file yang terlacak di index [5], jadi hasilnya murni perilaku pencocokan polanya, bukan efek setting aneh di repo saya.
Empat perintah, dua puluh detik, satu asumsi mati. Bandingkan sama skenario alternatifnya: asumsi ini hidup bertahun-tahun di gate, lalu ketahuan pas audit keamanan karena ada file yang nyelip. Ngecek dulu selalu lebih murah daripada percaya dulu.
Kenapa Bisa Begini
Di Git, pathspec [3] itu pola buat membatasi path di perintah Git. Setelah prefix direktori dicocokkan secara harfiah, sisanya dicek pakai fnmatch(3) yang * dan ?-nya bisa mencocokkan pemisah direktori [3].
Mental model yang akurat kira-kira begini. Di pola dir/**/*.ext, bagian dir/ harus kebaca persis dulu. Si ** cuma memperlebar sisa polanya, bukan bikin prefix jadi opsional. Maka file yang persis di frontend/src/ itu terlewat: polanya nyari "sesuatu DI DALAM src", bukan "src-nya sendiri". Nggak ada kedalaman tambahan buat dicocokkan, ya nggak match.
Yang bikin temuan ini masuk daftar perbaikan bukan karena gate-nya gagal jalan. Di praktik dia jalan terus: semua komponen yang sekarang ada kebetulan nested, jadi tiap build gate tetap ngelahin semua file yang relevan. Temuannya murni dari nulis test: ceritanya di log QA, gate-nya dirujuk buat dicek, dan jawabannya baru datang belakangan. Lubang itu nyata, cuma nggak pernah dimanfaatin.
Union dan Test Regresinya
Perbaikannya sesederhana namanya: union. Pattern anak-langsung digabung sama pattern rekursif, jadi daftar file yang dicek nggak lagi tergantung di mana file itu bersarang. Kontrak exit-nya nggak berubah: nol berarti bersih, satu berarti ada pelanggaran. Yang berubah cuma cakupannya.
Dua test baru dibuat khusus buat kasus bentuk direktori ini. Satu naruh Bad.tsx berisi hex terlarang langsung di src/ dan gate harus gagal dengan exit 1, padahal sebelumnya skenario yang sama lolos dengan exit 0. Satu lagi kebalikannya: file bersih langsung di src/ dan gate harus tetap lolos, biar perbaikannya nggak sekadar jadi alarm palsu baru. Suite test-nya nambah dua kasus, dari dua belas jadi empat belas, dan npm run build tetap lulus dengan gate yang udah diperbaiki.
Sisanya menurut saya yang paling penting buat dibawa pulang. Gate ini selama ini aman cuma karena kebetulan semua komponen kebetulan nested. Bahaya dari kebetulan itu: dia nyaman. Nggak ada alarm, nggak ada gejala, sampai suatu hari seseorang sengaja naruh file di src/ buat ngebolatin review, dan gate yang katanya jaga tetap senyum hijau.
Jadi pendapat saya tegas: gate yang lolos hari ini karena keberuntungan struktur folder itu bug yang dicicil. Gate yang tugasnya milih FILE perlu diuji asumsi bentuk direktorinya, kasus anak-langsung dan nested dalam, bukan cuma kasus isi file yang bagus dan yang jahat.
## Sources
[3] https://git-scm.com/docs/gitglossary — gitglossary - A Git Glossary (pathspec definition, fnmatch, * matches directory separators) [5] https://git-scm.com/docs/git-ls-files — git-ls-files - Show information about files in the index and the working tree