728x90 전체 글104 GitHub Actions 아티팩트와 캐시 용도 구분하기: 의존성은 캐시, job 간 결과물은 아티팩트 GitHub Actions 워크플로에서 actions/cache와 actions/upload-artifact는 둘 다 파일을 저장하고 나중에 다시 가져오기 때문에 같은 기능처럼 보입니다. 그래서 npm 패키지를 매번 받지 않으려고 아티팩트에 node_modules를 올리거나, 빌드 결과물을 다음 job에 넘기려고 캐시에 dist/를 넣는 실수가 생깁니다. 두 기능은 저장 기준과 복원 조건이 다르기 때문에, 어떤 파일을 어디에 두어야 하는지 먼저 나눠야 합니다.build job에서 캐시 복원과 artifact 업로드가 test job으로 이어지는 흐름을 직접 그린 도식입니다. PIL로 그린 원본이며 AI 생성 이미지가 아닙니다.결론: 같은 입력이면 다시 쓸 파일은 캐시, 실행 결과를 넘길 파일은 아티팩트캐.. 2026. 10. 29. GitHub Actions matrix 실패와 fail-fast 비교: 조합 수 계산하고 취소 범위 정하기 GitHub Actions에서 strategy.matrix로 여러 조합을 돌리면 두 가지가 자주 헷갈립니다. 하나는 한 조합이 실패했을 때 나머지 조합이 왜 갑자기 취소되는지이고, 다른 하나는 값을 곱했는데 job 수가 왜 그만큼 나오지 않는지입니다. 이 글은 두 질문을 한 예제 워크플로로 나눠서 확인합니다. 워크플로 파일의 matrix를 Python으로 펼쳐 보고, 공식 문서의 예제 두 개를 같은 규칙으로 다시 계산해 맞춰 봅니다.네 개의 조합 목록을 펼치기 스크립트가 출력한 그대로 옮긴 그림입니다. 빨간 줄은 include로 새로 추가된 실험 조합, 파란 줄은 Ubuntu 기본 조합입니다. 로컬 PIL로 그렸으며 AI 생성물이 아닙니다.결론: 실패 취소는 fail-fast, 실패 무시는 continu.. 2026. 10. 29. GitHub Actions 최소 permissions 설정 예제: job마다 GITHUB_TOKEN 권한 나눠 쓰기 GitHub Actions 워크플로는 실행할 때마다 GITHUB_TOKEN을 받습니다. 코드를 읽기만 하는 테스트 job이 쓰기 권한이 넓은 토큰을 갖고 있다면, 그 job의 step 하나가 잘못되었을 때 피해 범위도 넓어집니다. 이 글은 워크플로 파일에 permissions를 적어 job마다 필요한 권한만 남기는 방법을 예제로 정리합니다. 예제는 YAML 파일 네 개를 만들고, 권한 선언을 읽어 보는 짧은 Python 스크립트로 확인합니다.네 샘플 워크플로의 job별 권한을 정적 검사 스크립트가 출력한 결과를 그대로 옮긴 그림입니다. 빨간 줄은 쓰기 권한이 열려 있거나 권한이 선언되지 않은 항목입니다. 로컬 PIL로 그렸으며 AI 생성물이 아닙니다.결론: permissions는 job 단위로 적고, 나.. 2026. 10. 29. Node.js ESM과 CommonJS import 오류 구분하기: 확장자, type, __dirname 실행으로 나누기 Node.js 프로젝트를 옮기거나 파일 하나를 새로 추가하면 SyntaxError: Cannot use import statement outside a module, ERR_MODULE_NOT_FOUND, ReferenceError: __dirname is not defined 같은 에러를 자주 만납니다. 대부분은 코드가 틀린 것이 아니라 같은 파일을 CommonJS로 실행하는지 ES module로 실행하는지가 다르기 때문입니다. 이 글은 외부 네트워크 없이 로컬 파일 일곱 가지 경우를 실행해 보고, 에러 코드를 보면 어느 규칙을 고쳐야 하는지 나누는 방법을 정리합니다.케이스 1부터 7까지 로컬 Node.js v22.15.1에서 실행한 종료 코드와 첫 에러 줄을 원본 그대로 옮긴 실행 결과 그림입니다. .. 2026. 10. 29. npm ci가 package.json과 lock이 어긋나면 멈추는 이유: lock을 고친 뒤 설치 재현하기 CI나 배포 서버에서 npm ci를 쓰라는 말은 많이 듣지만, 막상 package.json에 의존성 한 줄을 추가하고 npm ci를 돌리면 "can only install packages when your package.json and package-lock.json are in sync"라는 에러로 멈추는 경우가 있습니다. 이 글은 외부 레지스트리에 접속하지 않고 로컬 패키지 두 개로 그 상황을 재현하고, 어떤 파일을 어떤 순서로 맞춰야 하는지 정리합니다.같은 package.json에서 npm install은 lock을 갱신하고 npm ci는 lock 불일치로 멈추는 순서를 실제 실행 로그로 옮긴 그림입니다. 로컬 PIL로 그렸으며 AI 생성물이 아닙니다.결론부터: npm ci는 lock 파일을 고치지.. 2026. 10. 29. pip 설치는 성공했는데 import가 실패할 때: 설치한 Python과 실행한 Python 맞추기 실험 pip install이 "Successfully installed"로 끝났는데 코드에서 import가 ModuleNotFoundError로 실패하는 경우가 자주 있습니다. 설치 명령은 성공했으니 패키지가 없는 것은 아닐 텐데, 실행할 때는 같은 이름의 모듈이 보이지 않습니다. 대부분은 pip가 설치한 Python과 코드를 실행하는 Python이 서로 다르기 때문입니다. 이 글은 표준 라이브러리만 써서 그 상황을 재현하고, 설치 대상과 실행 대상을 맞추는 확인 순서를 정리합니다.같은 패키지가 venv 인터프리터에서는 import되고 시스템 인터프리터에서는 ModuleNotFoundError가 나는 순간을 실제 실행 로그로 옮겨 그린 그림입니다. 로컬 PIL로 그렸으며 AI 생성물이 아닙니다.결론부터: pi.. 2026. 10. 29. Python CLI 종료 코드와 stderr 분리하기: 에러가 stdout에 찍히면 소비자가 놓치는 이유 실험 자동화 스크립트가 실패했는지 판단할 때 에러 문구 하나만 보면 부족합니다. 명령은 종료 코드(exit code), 표준 출력(stdout), 표준 에러(stderr)라는 세 채널로 결과를 남기고, 호출하는 쪽이 이 셋을 구분하지 않으면 실패를 성공으로 넘기거나 에러 이유를 찾지 못합니다. 이 글은 표준 라이브러리만으로 작은 명령을 여러 방식으로 실패시켜 보고, 호출하는 쪽이 무엇을 먼저 읽어야 하는지 정리합니다.demo.py를 Python 3.12.3에서 실행한 실제 출력을 옮겨 그린 그림입니다. 종료 코드 0·1·2와 stdout·stderr 위치가 모드마다 어떻게 달랐는지 보여 줍니다. AI로 생성한 이미지가 아닙니다.결론부터: 종료 코드로 성패를 정하고, 이유는 stderr에서 읽는다공식 문서에 따.. 2026. 10. 29. Document Assistant 04: Trace a question through the reverse proxy What happens between someone opening your app and your server receiving the request?Original explanatory diagram for this series. Answer chunks travel back through every hop. Check buffering, deadlines, and disconnects.Document Assistant · Part 4 of 20 · Reverse proxiesA reverse proxy is the front door to our assistant’s application service. It accepts a client connection and forwards requests u.. 2026. 10. 29. Python logging 중복 출력 찾기: 핸들러가 두 번 붙는 경우와 propagate로 한 줄만 남기는 실험 같은 로그 한 줄이 콘솔에 두 번 찍히는 상황은 자동화 스크립트에서 꽤 흔합니다. 진입점 두 곳이 같은 설정 함수를 부르거나, 애플리케이션과 라이브러리가 각각 핸들러를 달아 두면 logger.info() 한 번에 같은 메시지가 두 줄 나옵니다. 이 글은 Python 표준 라이브러리 logging으로 이 현상을 재현하고, 핸들러가 몇 개 붙었는지와 메시지가 어느 로거까지 올라가는지를 기준으로 원인을 나눠 확인하는 방법을 정리합니다.demo.py를 Python 3.12.3에서 직접 실행한 출력을 옮겨 그린 그림입니다. 빨간 줄은 같은 메시지가 두 번 기록된 결과이고, 파란 줄은 한 번만 남은 결과입니다. AI로 생성한 이미지가 아닙니다.결론부터: 같은 메시지가 두 번 나오면 같은 출력 대상에 핸들러가 두 번.. 2026. 10. 28. Python subprocess에서 shell 없이 인수 전달하기: 공백과 세미콜론이 든 값을 한 인수로 넘기는 실험 배치 작업이나 간단한 자동화 스크립트에서는 사용자 입력, CSV 셀, 파일 이름 같은 값을 외부 명령에 넘기는 일이 흔합니다. 값에 공백이 하나 있을 뿐인데 결과가 달라지고, 세미콜론이 섞이면 의도하지 않은 두 번째 명령이 실행될 수도 있습니다. 이 글은 Python subprocess에서 같은 값을 넘길 때 shell=True와 리스트 인수가 어떻게 다르게 처리되는지 표준 라이브러리 실험으로 확인합니다.demo.py를 실행한 실제 출력을 옮긴 그림입니다. 같은 문자열이 셸을 거치면 두 명령으로 나뉘고, 리스트로 넘기면 한 인수로 남습니다. AI가 만든 그림이 아닙니다.결론부터: 리스트로 넘기면 셸이 문자열을 해석하지 않는다공식 문서는 인수를 시퀀스로 넘기는 방식이 일반적으로 더 낫다고 설명합니다. 이 .. 2026. 10. 28. 이전 1 2 3 4 ··· 11 다음 728x90 반응형