diff --git a/.github/workflows/lint.yml b/.github/workflows/ci.yml similarity index 92% rename from .github/workflows/lint.yml rename to .github/workflows/ci.yml index f3751a1..b1c8462 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: lint +name: ci on: pull_request: @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Run shellcheck - # SC2016 제외: add_to_zshrc 'eval "$(...)"' 처럼 리터럴 그대로 .zshrc 에 써야 하는 케이스가 의도된 동작 + # SC2016 제외: append_line_if_missing 으로 리터럴 그대로 .zshrc 에 써야 하는 케이스가 의도된 동작 run: shellcheck --severity=warning --exclude=SC2016 *.sh syntax-check-macos: diff --git a/common.sh b/common.sh index cff9c5c..67ba170 100644 --- a/common.sh +++ b/common.sh @@ -23,8 +23,30 @@ trap 'kill $CAFFEINATE_PID 2>/dev/null' EXIT # ============================================ # Helper Functions # ============================================ -add_to_zshrc() { - grep -qF "$1" ~/.zshrc 2>/dev/null || echo "$1" >> ~/.zshrc +append_block_if_missing() { + local file="$1" + local marker="$2" + + mkdir -p "$(dirname "$file")" + touch "$file" + + if grep -qF "$marker" "$file"; then + return 0 + fi + + if [[ -s "$file" ]]; then + printf "\n" >> "$file" + fi + cat >> "$file" +} + +append_line_if_missing() { + local file="$1" + local line="$2" + + append_block_if_missing "$file" "$line" </dev/null || brew install --cask "$1" + local cask="$1" + + if brew list --cask "$cask" &>/dev/null; then + echo " ↳ Cask $cask already installed" + return 0 + fi + + echo " ↳ Installing cask $cask" + brew install --cask "$cask" || { + echo "⚠️ Cask $cask install failed. Updating Homebrew and retrying..." + brew update + brew install --cask "$cask" + } } # 다운받아 실행한 .sh 파일들을 끝나면 정리 @@ -74,5 +108,5 @@ if ! command -v brew &>/dev/null; then fi eval "$(/opt/homebrew/bin/brew shellenv)" -add_to_zshrc 'eval "$(/opt/homebrew/bin/brew shellenv)"' +append_line_if_missing "$HOME/.zshrc" 'eval "$(/opt/homebrew/bin/brew shellenv)"' echo "✅ Homebrew ready" diff --git a/setup.sh b/setup.sh index dd495e4..8b2d710 100755 --- a/setup.sh +++ b/setup.sh @@ -12,7 +12,7 @@ source "$SCRIPT_DIR/common.sh" # ============================================ echo "🚀 Checking Starship..." brew_install starship -add_to_zshrc 'eval "$(starship init zsh)"' +append_line_if_missing "$HOME/.zshrc" 'eval "$(starship init zsh)"' echo "✅ Starship ready" # ============================================ @@ -80,7 +80,7 @@ echo "✅ Vim ready" # ============================================ echo "🔄 Checking mise..." brew_install mise -add_to_zshrc 'eval "$(mise activate zsh)"' +append_line_if_missing "$HOME/.zshrc" 'eval "$(mise activate zsh)"' eval "$(mise activate bash)" echo "🐹 Setting up Go..." @@ -105,9 +105,9 @@ echo "🐍 Setting up Python..." brew_install pyenv brew_install uv -add_to_zshrc 'export PYENV_ROOT="$HOME/.pyenv"' -add_to_zshrc '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' -add_to_zshrc 'eval "$(pyenv init -)"' +append_line_if_missing "$HOME/.zshrc" 'export PYENV_ROOT="$HOME/.pyenv"' +append_line_if_missing "$HOME/.zshrc" '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' +append_line_if_missing "$HOME/.zshrc" 'eval "$(pyenv init -)"' echo "✅ Python tools ready" diff --git a/work_setup.sh b/work_setup.sh index 070bad3..99956f3 100644 --- a/work_setup.sh +++ b/work_setup.sh @@ -23,6 +23,50 @@ echo "🔐 Installing Okta Verify..." brew_install_cask okta-verify echo "✅ Okta Verify ready" +# ============================================ +# Codex + Work MCP servers +# ============================================ +echo "🤖 Installing Codex and MCP tools..." +brew_install_cask codex +brew_install mcp-grafana + +append_line_if_missing "$HOME/.zshrc" 'export GRAFANA_URL="${GRAFANA_URL:-}"' +append_line_if_missing "$HOME/.zshrc" 'export GRAFANA_SERVICE_ACCOUNT_TOKEN="${GRAFANA_SERVICE_ACCOUNT_TOKEN:-}"' + +append_block_if_missing "$HOME/.codex/config.toml" "[mcp_servers.grafana]" <<'EOF' +[mcp_servers.grafana] +command = "/opt/homebrew/bin/mcp-grafana" +args = [] +env_vars = [ + "GRAFANA_URL", + "GRAFANA_SERVICE_ACCOUNT_TOKEN", +] +EOF +echo " ↳ Codex MCP 'grafana' configured" + +append_block_if_missing "$HOME/.codex/config.toml" "[mcp_servers.datadog]" <<'EOF' +[mcp_servers.datadog] +url = "https://mcp.datadoghq.com/api/unstable/mcp-server/mcp" +EOF +echo " ↳ Codex MCP 'datadog' configured" + +append_block_if_missing "$HOME/.codex/config.toml" "[mcp_servers.channel-teamchat]" <<'EOF' +[mcp_servers.channel-teamchat] +url = "https://cht-teamchat-mcp.dmz.channel.io/mcp" +EOF +echo " ↳ Codex MCP 'channel-teamchat' configured" + +echo " ↳ Grafana reads GRAFANA_URL and GRAFANA_SERVICE_ACCOUNT_TOKEN when Codex starts" +if [[ -n "$SETUP_NONINTERACTIVE" ]]; then + echo " ↳ SETUP_NONINTERACTIVE — Codex MCP OAuth login 스킵" +elif command -v codex &>/dev/null; then + codex mcp login datadog || echo "⚠️ Datadog MCP login skipped" + codex mcp login channel-teamchat || echo "⚠️ Channel Teamchat MCP login skipped" +else + echo "⚠️ codex command not found. Open Codex once, then retry MCP login manually." +fi +echo "✅ Codex ready" + # ============================================ # Interactive Section (사람 필요한 단계 한 번에) # ============================================