이 글은 Today I Learn 시리즈의 253번째 기록입니다. (총 255개)

내보내기 전에 버전을 올렸다

영어판을 다 넣었는데 번호가 그대로였다. 릴리스를 낼지 말지에서 멈춰 있어서다. 한영 전환 버튼이 생겼는데 번호가 안 올라갈 이유가 없다.

둘을 묶어서 보고 있었던 것이다. 버전을 올리는 것과 새 판을 내보내는 것은 다른 일이다. 번호는 「무엇이 달라졌나」를 적는 일이라 기능이 생긴 순간 올라가야 하고, 내보내는 것은 「지금 사람들에게 줄 것인가」라서 따로 정하면 된다. 묶어서 보면 내보낼지 망설이는 동안 번호도 멈춘다.

번호를 올리고 나니 한 가지가 저절로 정해졌다. 자리를 한 칸 올릴지 두 칸 올릴지인데, 이번에는 설정을 저장하는 방식까지 바뀌어서 큰 쪽으로 갔다. 쓰던 사람 파일을 건드리는 변화는 기능 하나 추가와 무게가 다르다.

내보낼 결심이 서야 번호를 올리는 게 아니다. 달라진 순간 올리고, 내보내는 건 그다음에 정한다.


변경 내역에서 두 줄을 뺐다

변경 내역에 세 줄이 올라왔다. 영어 지원, 창이 조금 넓어진 것, 설정 저장 방식이 바뀐 것. 뒤의 둘은 굳이 있을 이유가 없어 보였다.

빼고 보니 둘 다 사용자에게 줄 게 없었다. 창 폭은 쓰는 사람이 알 필요가 없는 우리 사정이다. 설정 저장 방식은 더 나쁘다 — 결론이 「이전 설정은 그대로 이어받습니다」인데, 그 말은 안심시키는 게 아니라 「내 설정이 날아갈 수도 있나」를 새로 만든다. 그 줄은 설정이 실제로 초기화될 때만 필요하다.

그다음 판에서 또 걸렸다. 「창 제목에 버전이 보입니다. 지금 쓰고 계신 판이 몇인지 바로 알 수 있습니다」로 올라왔다. 앞절이 이미 그 말이라 뒷절을 뺐다. 두 번 다 「그래서 뭐가 좋아지는지」가 뒤에 붙어 있었다.

바뀐 것과 알려야 할 것은 다르다. 그리고 알릴 것을 골랐어도 설명을 붙이고 싶어지는데, 사용자 문서에서는 그게 군더더기다. 한 줄에 한 사실만 적고 멈춘다.


확인 완료를 다시 확인했다

업데이트 알림이 실제로 뜨는지는 오래 확인이 밀려 있었다. 전날 확인했다고 적고 닫았는데, 다음 날 열어 보니 안 떴다.

두 가지가 한꺼번에 드러났다. 먼저 「확인 완료」라고 적혀 있던 것이 반쪽이었다. 새 번호를 받아 오는 데까지만 보고 닫은 것이라, 그 번호를 창에 올리는 쪽은 아예 확인된 적이 없었다. 통과한 줄 알았던 게 실은 돌아간 적도 없는 자리였다.

그런데 띄워서 보니 그쪽도 멀쩡했다. 안 뜬 진짜 이유는 따로였다 — 연 파일이 최신 판이었다. 최신을 쓰는 사람에게 「새 버전이 있다」가 뜨면 그게 고장이다.

이 항목이 오래 안 닫힌 이유도 그제야 보였다. 확인하는 코드가 든 판이 최신인 동안에는 원리상 뜰 일이 없다. 새 판이 올라간 뒤에야 확인되는 항목이었던 것이다.

확인했다는 말에는 무엇을 본 확인인지가 빠져 있다. 적어 두지 않으면 반쪽을 전체로 착각한다. 그리고 목록에 「지금은 확인할 수 없는 것」이 섞여 있으면 볼 때마다 그냥 넘어가게 되니, 그런 줄에는 무엇이 생겨야 확인되는지를 같이 적어야 한다.


창 제목에 버전을 넣었다

그러고 나서 걸린 게 하나 더 있다. 정작 내가 쓰는 판이 몇인지 볼 데가 없었다.

이 앱은 설치를 하지 않고 파일 하나를 받아 쓰는 방식이라, 윈도우의 설치된 프로그램 목록에도 안 뜬다. 창 제목은 이름만 있고, 버전을 보려면 파일을 찾아 속성을 열어야 한다. 쓰는 사람이 「내가 뭘 쓰고 있나」를 알 길이 없었다.

창 제목에 번호를 넣었다. 알림창 제목에는 안 넣었다 — 경고마다 번호가 따라다닐 이유가 없다.

만드는 쪽은 자기가 어느 판을 보고 있는지 늘 안다. 빌드한 게 자기 손이고 번호도 자기가 올렸다. 그래서 「지금 뭘 쓰는지 모르겠다」가 문제로 안 보인다. 받아서 쓰는 사람에게는 그게 첫 번째 질문인데도 그렇다.


남은 확인 넷을 다시 세어 봤다

게임이 깔린 PC를 못 켜는 날이었다. 그래서 앞선 TIL에 적은 방식으로 확인을 돌렸다. 거기까지는 어제 한 얘기다.

오늘 다른 게 나왔다. 남은 확인이 넷이었고 전부 「게임 PC가 있어야 한다」로 묶여 있었는데, 다시 세어 보니 둘은 게임이 필요 없었다. 앱이 게임을 보는 창구가 좁아서, 그 창구만 흉내내면 게임이 켜진 것처럼 보이게 할 수 있다.

탈환 모드에서 봇 설정이 잠기는지, 게임을 앱 밖에서 켰을 때 경고 띠가 뜨는지. 둘 다 그렇게 닫혔다. 남은 둘은 「게임이 진짜로 그렇게 동작하나」라서 흉내로는 못 본다.

못 하는 것으로 묶어 둔 목록은 한 번 다시 세어 봐야 한다. 처음에 묶을 때는 맞았어도, 그 안에 진짜로 묶이는 건 일부일 때가 많다. 넷을 통째로 미뤄 두면 둘까지 같이 밀린다.


알림이 가는 곳을 우리 사이트로 바꿨다

새 버전 알림을 누르면 소스 저장소의 배포 페이지가 열리게 돼 있었다. 일반 사용자라면 뭘 받으라는 건지 당황할 것 같았다.

열어서 세어 보니 받을 것이 네 개였다. 실행 파일, 무결성 확인용 짧은 파일, 그리고 소스 묶음 둘. 뒤의 둘은 그 서비스가 자동으로 붙이는 것이라 우리가 뺄 수 없다. 그중 맞는 건 하나고, 실행 파일이 제일 작아서 큰 쪽을 누를 사람도 있다.

우리 설명서 페이지로 보내게 바꿨다. 거기엔 받는 버튼이 하나뿐이고, 받기 전에 뭐가 바뀌었는지도 볼 수 있다. 앱이 영어면 영어판 주소로 연다.

이 알림은 사용자가 부른 게 아니라 켜자마자 혼자 뜬다. 자기가 찾아간 화면이라면 넷 중에 고르는 수고도 받아들이지만, 묻지도 않고 뜬 것이 고르라고 하면 그건 방해다. 같은 페이지라도 사용자가 어떤 경로로 왔느냐에 따라 적절한지가 갈린다.


두 페이지의 역할을 갈랐다

설명서 페이지와 제품 페이지가 따로 있다. 둘 다 앱을 소개하고 둘 다 받기 버튼이 있다. 이렇게 두 개를 각각 두는 게 맞나 싶었다.

합칠 수가 없었다. 친구가 링크를 받아서 들어오는 참가 페이지가 설명서 쪽에 있고, 앱이 만들어 주는 링크가 그 주소를 가리킨다. 이미 사람들 손에 가 있는 실행 파일 안에 그 주소가 들어 있어서, 주소가 바뀌면 그 파일들이 깨진다. 앱의 물음표 버튼도 같다. 반대로 제품 페이지는 다른 앱들과 나란히 서서 둘러보게 하는 자리라 설명서가 대신할 수 없다.

그래서 역할을 갈랐다. 제품 페이지는 진열창, 설명서 페이지는 쓰는 법과 문제 해결. 가르고 나니 한쪽만 상대를 가리키고 있는 것도 보였다 — 제품 페이지는 설명서로 보내는데 설명서에는 돌아올 링크가 없다.

겹쳐 보인다고 늘 합칠 수 있는 건 아니다. 이미 내보낸 것이 주소를 들고 있으면 그 주소는 우리가 계속 쥐고 있어야 하고, 그러면 자리가 둘로 남는 게 맞다. 합칠 수 없다는 걸 알고 나서야 둘의 역할을 제대로 가를 수 있었다.


Series: Today I Learn

1 | C++ 자료형(Data Type) 2 | MD5 vs pHash 3 | C++에서 함수의 선언과 정의 4 | Tkinter padx, pady 5 | 메모리와 포인터 변수 6 | Call by Value, Call by Reference, Call by Pointer 비교 7 | const 8 | Gemfile — Jekyll 프로젝트의 의존성 파일 9 | kramdown-parser-gfm — Jekyll의 GFM 파서 10 | 파서(Parser) 11 | AHU vs OHU 12 | I might try it vs I'll try it 뉘앙스 차이 13 | SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 | configuration key 15 | Git stash vs discard 16 | subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 | Post 잔디 분석하기 18 | Google Sheets Sync 최적화 19 | DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 | 마크다운 표 그리는 방법 21 | 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 | Django 보안 취약점 점검 및 수정 23 | OOP Object-Oriented Programming 객체 지향 프로그래밍 24 | Fernet 대칭 암호화 25 | Jekyll 코드블록 안의 Liquid 태그 26 | 습관만들기 Pawbit TIL 1 27 | insertOnConflictUpdate vs DoUpdate(target) 28 | 세션 필터 29 | 아코디언(Accordiaon) UI를 펼친상태로 만들기 30 | input의 step 31 | 습관만들기 Pawbit TIL 2 32 | 습관만들기 Pawbit TIL 3 33 | Word Cloud 34 | Google Sheets를 데이터 버스로(with AppSheet) 35 | Django 모델 텍스트 필드 자동 수집 패턴 36 | localStorage로 섹션 토글 상태 유지 37 | 순차 ID 생성(`select_for_update()` + `max()` 조합) 38 | 역참조 검색과 distinct() 39 | xlsx 다운로드와 로딩 오버레이 충돌 40 | Android 파일 공유 MIME 타입 41 | AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 42 | 크레센도 Phaser + TypeScript TIL 1 43 | 크레센도 Phaser + TypeScript TIL 2 44 | 크레센도 Phaser + TypeScript TIL 3 45 | 크레센도 Phaser + TypeScript TIL 4 46 | 크레센도 Phaser + TypeScript TIL 5 47 | 여둘까 Office Layout TIL 1 48 | 습관만들기 Pawbit TIL 4 49 | 여둘까 Office Layout TIL 2 50 | 여둘까 Office Layout TIL 3 51 | 크레센도 Phaser + TypeScript TIL 6 52 | UTF-8 BOM과 PowerShell 파일 쓰기 53 | 소리꽃 KeyBloom TIL 1 54 | 습관만들기 Pawbit TIL 5 55 | 여둘까 Office Layout TIL 4 56 | 소리꽃 KeyBloom TIL 2 57 | 소리꽃 KeyBloom TIL 3 58 | 메트로놈 Simple Metronome TIL 1 59 | 소리꽃 KeyBloom TIL 4 60 | 메트로놈 Simple Metronome TIL 2 61 | 소리꽃 KeyBloom TIL 5 62 | 습관만들기 Pawbit TIL 6 63 | 크레센도 Phaser + TypeScript TIL 7 64 | 메트로놈 Simple Metronome TIL 3 65 | 소설 타임라인 관리 도구 Lumior TIL 1 66 | 습관만들기 Pawbit TIL 7 67 | 정적 블로그 SEO 정비와 Pagefind 검색 도입 68 | 크레센도 Phaser + TypeScript TIL 8 69 | 메트로놈 Simple Metronome TIL 4 70 | 습관만들기 Pawbit TIL 8 71 | 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 72 | 메트로놈 Simple Metronome TIL 5 73 | 모래게임 Sandrop TIL 1 74 | 습관만들기 Pawbit TIL 9 75 | 메트로놈 Simple Metronome TIL 6 76 | 모래게임 Sandrop TIL 2 77 | 모래게임 Sandrop TIL 3 78 | 습관만들기 Pawbit TIL 11 79 | 습관만들기 Pawbit TIL 10 80 | 메트로놈 Simple Metronome TIL 7 81 | 모래게임 Sandrop TIL 4 82 | 모래게임 Sandrop TIL 5 83 | 습관만들기 Pawbit TIL 12 84 | 모래게임 Sandrop TIL 6 85 | 소리꽃 KeyBloom TIL 6 86 | 모래게임 Sandrop TIL 7 87 | 모래게임 Sandrop TIL 8 88 | 소리꽃 KeyBloom TIL 7 89 | 모래게임 Sandrop TIL 9 90 | 소리꽃 KeyBloom TIL 8 91 | 모래게임 Sandrop TIL 10 92 | 소리꽃 KeyBloom TIL 9 93 | 콘티온 ContiOn TIL 1 94 | 소리꽃 KeyBloom TIL 10 95 | 콘티온 ContiOn TIL 2 96 | 습관만들기 Pawbit TIL 13 97 | 콘티온 ContiOn TIL 3 98 | 룸톤 Roomtone TIL 1 99 | 모래게임 Sandrop TIL 11 100 | 소리꽃 KeyBloom TIL 11 101 | 여둘까 Office Layout TIL 5 102 | 모래게임 Sandrop TIL 12 103 | 모래게임 Sandrop TIL 13 104 | 콘티온 ContiOn TIL 4 105 | 모래게임 Sandrop TIL 14 106 | 소리꽃 KeyBloom TIL 12 107 | 습관만들기 Pawbit TIL 14 108 | 모래게임 Sandrop TIL 15 109 | 모래게임 Sandrop TIL 16 110 | 소리꽃 KeyBloom TIL 13 111 | 온실 GreenHouse TIL 1 112 | 콘티온 ContiOn TIL 5 113 | 모래게임 Sandrop TIL 17 114 | 소리꽃 KeyBloom TIL 14 115 | 온실 GreenHouse TIL 2 116 | 콘티온 ContiOn TIL 6 117 | 모래게임 Sandrop TIL 18 118 | 콘티온 ContiOn TIL 7 119 | 모래게임 Sandrop TIL 19 120 | 소리꽃 KeyBloom TIL 15 121 | 룸톤 Roomtone TIL 2 122 | 모래게임 Sandrop TIL 20 123 | 모래게임 Sandrop TIL 21 124 | 소리꽃 KeyBloom TIL 16 125 | 소리꽃 KeyBloom TIL 17 126 | 소리꽃 KeyBloom TIL 18 127 | 여둘까 Office Layout TIL 6 128 | 소리꽃 KeyBloom TIL 19 129 | 소리꽃 KeyBloom TIL 20 130 | 콘티온 ContiOn TIL 8 131 | 콘티온 ContiOn TIL 9 132 | 로그스톤 상표 셀프 출원 TIL 1 133 | 소리꽃 KeyBloom TIL 21 134 | 로그스톤 샵 LogStone Shop TIL 1 135 | 소리꽃 KeyBloom TIL 22 136 | 로그스톤 샵 LogStone Shop TIL 2 137 | 룸톤 Roomtone TIL 3 138 | 소리꽃 KeyBloom TIL 23 139 | 모래게임 Sandrop TIL 22 140 | 모래게임 Sandrop TIL 23 141 | 소리꽃 KeyBloom TIL 24 142 | 로그스톤 샵 LogStone Shop TIL 3 143 | 모래게임 Sandrop TIL 24 144 | 소리꽃 KeyBloom TIL 25 145 | 모래게임 Sandrop TIL 25 146 | MiniMacro TIL 1 147 | 룸톤 Roomtone TIL 4 148 | 모래게임 Sandrop TIL 26 149 | 콘티온 ContiOn TIL 10 150 | Astro가 무엇인지, 왜 옮기는지 151 | 룸톤 Roomtone TIL 5 152 | 룸톤 Roomtone TIL 6 153 | 모래게임 Sandrop TIL 27 154 | 소리꽃 KeyBloom TIL 26 155 | MiniMacro TIL 2 156 | 로그스톤 샵 LogStone Shop TIL 4 157 | 메트로놈 Simple Metronome TIL 8 158 | 모래게임 Sandrop TIL 28 159 | 여둘까 Office Layout TIL 7 160 | 룸톤 Roomtone TIL 7 161 | 메트로놈 Simple Metronome TIL 9 162 | 블로그 Astro 이관 TIL 163 | 여둘까 Office Layout TIL 8 164 | 로그스톤 샵 LogStone Shop TIL 5 165 | 모래게임 Sandrop TIL 29 166 | 오픈데이 Openday TIL 1 167 | 로그스톤 샵 LogStone Shop TIL 6 168 | 모래게임 Sandrop TIL 30 169 | 오픈데이 Openday TIL 2 170 | 모래게임 Sandrop TIL 31 171 | Unreal Engine MCP TIL 1 172 | 모래게임 Sandrop TIL 32 173 | 소리꽃 KeyBloom TIL 27 174 | 콘티온 ContiOn TIL 11 175 | 오픈데이 Openday TIL 3 176 | 로그스톤 샵 LogStone Shop TIL 7 177 | 모래게임 Sandrop TIL 33 178 | 소리꽃 KeyBloom TIL 28 179 | 오픈데이 Openday TIL 4 180 | 여둘까 Office Layout TIL 9 181 | 오픈데이 Openday TIL 5 182 | ScorePlayer TIL 1 183 | 모래게임 Sandrop TIL 34 184 | BuildingHub TIL 1 185 | ScorePlayer TIL 2 186 | 여둘까 Office Layout TIL 10 187 | BuildingHub TIL 2 188 | ScorePlayer TIL 3 189 | Unreal Engine MCP TIL 2 190 | 궁 미로 PalaceMaze TIL 1 191 | 메트로놈 Simple Metronome TIL 11 192 | 메트로놈 Simple Metronome TIL 10 193 | 오픈데이 Openday TIL 6 194 | BuildingHub TIL 3 195 | ScorePlayer TIL 4 196 | Obsidian vault에서 코드만 빼기 — directory junction 197 | 여둘까 Office Layout TIL 11 198 | 오픈데이 Openday TIL 7 199 | URL은 바뀔 수 있는 것에 묶지 않는다 200 | 도구는 기능이 아니라 내 일에 맞는지로 고른다 201 | 돌이키기 힘든 변경은 작게 먼저 확인한다 202 | 궁 미로 PalaceMaze TIL 2 203 | 궁 미로 PalaceMaze TIL 3 204 | 소리꽃 KeyBloom TIL 29 205 | 오픈데이 Openday TIL 8 206 | 룸톤 Roomtone TIL 8 207 | BuildingHub TIL 4 208 | ScorePlayer TIL 5 209 | 로그스톤 샵 LogStone Shop TIL 8 210 | 여둘까 Office Layout TIL 12 211 | 오픈데이 Openday TIL 9 212 | BuildingHub TIL 5 213 | MiniMacro TIL 3 214 | 룸톤 Roomtone TIL 10 215 | 룸톤 Roomtone TIL 9 216 | 소리꽃 KeyBloom TIL 30 217 | 오픈데이 Openday TIL 10 218 | 여둘까 Office Layout TIL 13 219 | 오픈데이 Openday TIL 11 220 | 룸톤 Roomtone TIL 11 221 | 소리꽃 KeyBloom TIL 31 222 | 궁 미로 PalaceMaze TIL 4 223 | 룸톤 Roomtone TIL 12 224 | 로그스톤 샵 LogStone Shop TIL 9 225 | 룸톤 Roomtone TIL 13 226 | 로그스톤 샵 LogStone Shop TIL 10 227 | 룸톤 Roomtone TIL 14 228 | 소리꽃 KeyBloom TIL 32 229 | 룸톤 Roomtone TIL 15 230 | 룸톤 Roomtone TIL 16 231 | 로그스톤 샵 LogStone Shop TIL 11 232 | 룸톤 Roomtone TIL 17 233 | 룸톤 Roomtone TIL 18 234 | 메트로놈 Simple Metronome TIL 12 235 | 콘티온 ContiOn TIL 12 236 | 소리꽃 KeyBloom TIL 33 237 | 온실 GreenHouse TIL 3 238 | 로그스톤 샵 LogStone Shop TIL 12 239 | 룸톤 Roomtone TIL 19 240 | 모래게임 Sandrop TIL 35 241 | 여러 세션을 INBOX 하나로 굴리기 242 | 궁 미로 PalaceMaze TIL 5 243 | CS2 Practice Host TIL 1 244 | 룸톤 Roomtone TIL 20 245 | 여둘까 Office Layout TIL 14 246 | 로그스톤 샵 LogStone Shop TIL 13 247 | 룸톤 Roomtone TIL 21 248 | 여둘까 Office Layout TIL 15 249 | 모래게임 Sandrop TIL 36 250 | CS2 Practice Host TIL 2 251 | CS2 Practice Host TIL 3 252 | 룸톤 Roomtone TIL 22 253 | CS2 Practice Host TIL 4 읽는 중 254 | 룸톤 Roomtone TIL 23 255 | 모래게임 Sandrop TIL 37