From a7cac7eefd326544cb631835a3605441bf774747 Mon Sep 17 00:00:00 2001 From: Clsan Date: Wed, 6 May 2026 11:32:33 +0900 Subject: [PATCH 1/3] Add shellcheck + macOS bash 3.2 parse check CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 셋업 스크립트는 새 맥에서만 실행되는 코드라 회귀를 늦게 발견함. shellcheck 으로 흔한 bash 실수를 PR 단계에서 자동 검출하고, macOS 기본 bash(3.2) 으로 parse-check 해서 fresh mac 에서만 깨지는 bash 4+ 기능 사용을 사전에 막음. SC2016 은 add_to_zshrc 가 리터럴 \$(...) 를 .zshrc 에 써야 하는 의도된 동작이라 제외. SC2064 (common.sh trap) 한 줄은 single quote 으로 수정. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/lint.yml | 28 ++++++++++++++++++++++++++++ common.sh | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..4c37122 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,28 @@ +name: lint + +on: + pull_request: + push: + branches: [master] + +jobs: + shellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run shellcheck + # SC2016 제외: add_to_zshrc 'eval "$(...)"' 처럼 리터럴 그대로 .zshrc 에 써야 하는 케이스가 의도된 동작 + run: shellcheck --severity=warning --exclude=SC2016 *.sh + + syntax-check-macos: + # macOS 기본 bash 는 3.2 — bash 4+ 기능을 무심코 쓰면 fresh mac 에서만 깨짐 + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Parse-check with system bash (3.2) + run: | + /bin/bash --version + for f in *.sh; do + echo "Checking $f..." + /bin/bash -n "$f" + done diff --git a/common.sh b/common.sh index 0da2883..cff9c5c 100644 --- a/common.sh +++ b/common.sh @@ -18,7 +18,7 @@ while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & # ============================================ caffeinate -disu & CAFFEINATE_PID=$! -trap "kill $CAFFEINATE_PID 2>/dev/null" EXIT +trap 'kill $CAFFEINATE_PID 2>/dev/null' EXIT # ============================================ # Helper Functions From 083eadfd710c7397f7a5601edd1ff7cccbace3e4 Mon Sep 17 00:00:00 2001 From: Clsan Date: Wed, 6 May 2026 13:02:48 +0900 Subject: [PATCH 2/3] Add macOS smoke job: actually run setup.sh on each PR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shellcheck 만으로는 'brew install starshipp' 같은 패키지 이름 오타, 사라진 cask, 변경된 mise 식별자, defaults 키 변경 등 진짜 회귀는 못 잡음. macOS 러너에서 setup.sh 를 실제로 끝까지 돌려서 확인. SETUP_NONINTERACTIVE=1 가드: - setup.sh: interactive_setup.sh source 와 colima start 스킵 - work_setup.sh: interactive_setup.sh source 스킵 콜리마는 nested-virt 라 GHA macOS 에서 시작이 느리고, 그 단계의 실패는 스크립트 회귀가 아니라 러너 환경 이슈라 검증 가치가 낮음. 인터랙티브는 gh auth login --web / osascript 알림 같은 사람 손이 필요한 단계라 CI 에서 skip. concurrency 그룹으로 같은 브랜치 푸시 연쇄 시 직전 실행 취소 — 40분 timeout 으로 무한루프 보호. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/lint.yml | 23 +++++++++++++++++++++++ setup.sh | 11 +++++++++-- work_setup.sh | 6 +++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4c37122..54ad8b1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,6 +5,11 @@ on: push: branches: [master] +# 같은 브랜치에서 푸시가 연달아 일어나면 직전 실행 취소 — macOS 분량 절약 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: shellcheck: runs-on: ubuntu-latest @@ -26,3 +31,21 @@ jobs: echo "Checking $f..." /bin/bash -n "$f" done + + smoke-macos: + # 진짜 검증: fresh-ish macOS 러너에서 setup.sh 를 실제로 돌려서 + # brew 패키지 이름 오타, 사라진 cask, mise 식별자 변경, defaults 키 변경 등 + # lint 가 못 잡는 회귀를 끝까지 잡는다. + # SETUP_NONINTERACTIVE=1 로 gh auth 등 인터랙티브 단계와 colima start 만 스킵. + runs-on: macos-latest + timeout-minutes: 40 + env: + SETUP_NONINTERACTIVE: "1" + # GHA 러너에는 Homebrew/Xcode CLT 가 이미 깔려있어 setup.sh 가 알아서 스킵 + HOMEBREW_NO_AUTO_UPDATE: "1" + HOMEBREW_NO_INSTALL_CLEANUP: "1" + HOMEBREW_NO_ENV_HINTS: "1" + steps: + - uses: actions/checkout@v4 + - name: Run setup.sh non-interactively + run: ./setup.sh diff --git a/setup.sh b/setup.sh index 2c9a7e9..dd495e4 100755 --- a/setup.sh +++ b/setup.sh @@ -113,9 +113,12 @@ echo "✅ Python tools ready" # ============================================ # Colima (Docker runtime) +# - SETUP_NONINTERACTIVE: CI 에선 nested-virt 시작이 오래 걸리고 검증 가치도 낮아 스킵 # ============================================ echo "🐳 Checking Colima..." -if colima status 2>&1 | grep -q "not running\|not exist"; then +if [[ -n "$SETUP_NONINTERACTIVE" ]]; then + echo " ↳ SETUP_NONINTERACTIVE — colima start 스킵" +elif colima status 2>&1 | grep -q "not running\|not exist"; then echo "Starting Colima..." # set -e 하에서 colima start 실패가 setup 전체를 죽이지 않도록 격리 if ! colima start; then @@ -136,7 +139,11 @@ source "$SCRIPT_DIR/system_setup.sh" # - source 로 불려왔으면 (work_setup.sh 등) 호출자가 자기 끝에서 처리 # ============================================ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - source "$SCRIPT_DIR/interactive_setup.sh" + if [[ -z "$SETUP_NONINTERACTIVE" ]]; then + source "$SCRIPT_DIR/interactive_setup.sh" + else + echo " ↳ SETUP_NONINTERACTIVE — interactive 단계 스킵" + fi echo "" echo "============================================" diff --git a/work_setup.sh b/work_setup.sh index 878d29f..070bad3 100644 --- a/work_setup.sh +++ b/work_setup.sh @@ -26,7 +26,11 @@ echo "✅ Okta Verify ready" # ============================================ # Interactive Section (사람 필요한 단계 한 번에) # ============================================ -source "$SCRIPT_DIR/interactive_setup.sh" +if [[ -z "$SETUP_NONINTERACTIVE" ]]; then + source "$SCRIPT_DIR/interactive_setup.sh" +else + echo " ↳ SETUP_NONINTERACTIVE — interactive 단계 스킵" +fi # ============================================ # Done! From 4c13b93b479eb9b0221600d194a8de36142ba0e6 Mon Sep 17 00:00:00 2001 From: Clsan Date: Wed, 6 May 2026 13:12:56 +0900 Subject: [PATCH 3/3] Pass GITHUB_TOKEN to mise to avoid GHA rate limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 첫 smoke 실행에서 brew/mise (Go/Node/Java) 까지 다 성공했지만 gradle 단계에서 GitHub API rate limit (60/h, 미인증) 에 걸림. mise 는 GITHUB_TOKEN 환경변수가 있으면 인증된 호출로 바꿔서 한도를 5000/h 로 끌어올림. GHA 워크플로우 자동 토큰 사용. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/lint.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 54ad8b1..f3751a1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -45,6 +45,8 @@ jobs: HOMEBREW_NO_AUTO_UPDATE: "1" HOMEBREW_NO_INSTALL_CLEANUP: "1" HOMEBREW_NO_ENV_HINTS: "1" + # mise 가 GitHub API 로 릴리즈 태그 조회 — 미인증은 IP 공유 러너에서 60/h 한도라 금방 걸림 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v4 - name: Run setup.sh non-interactively