diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml new file mode 100644 index 0000000..5cbd4c6 --- /dev/null +++ b/.github/workflows/create-release-pr.yml @@ -0,0 +1,94 @@ +name: Create Release PR + +on: + push: + branches: [main] + +jobs: + create-release-pr: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if release PR already exists + id: check + env: + GH_TOKEN: ${{ github.token }} + run: | + EXISTING=$(gh pr list --base release --head main --state open --json number --jq '.[0].number') + if [ -n "$EXISTING" ]; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "pr_number=$EXISTING" >> $GITHUB_OUTPUT + else + echo "exists=false" >> $GITHUB_OUTPUT + fi + + - name: Check if release is behind main + id: diff + run: | + git fetch origin release + BEHIND=$(git rev-list --count origin/release..origin/main) + echo "behind=$BEHIND" >> $GITHUB_OUTPUT + + - name: Create Release PR + if: steps.check.outputs.exists == 'false' && steps.diff.outputs.behind != '0' + env: + GH_TOKEN: ${{ github.token }} + run: | + # Collect commit summary + COMMITS=$(git log --oneline origin/release..origin/main --no-merges) + COMMIT_COUNT=$(echo "$COMMITS" | wc -l | tr -d ' ') + + gh pr create \ + --base release \ + --head main \ + --title "release: main → release (${COMMIT_COUNT} commits)" \ + --body "$(cat <> $GITHUB_OUTPUT + elif echo "$COMMITS" | grep -qi "^[a-f0-9]* feat"; then + echo "type=minor" >> $GITHUB_OUTPUT + else + echo "type=patch" >> $GITHUB_OUTPUT + fi + + - name: Get current version + id: current + run: | + VERSION=$(jq -r '.version' .claude-plugin/plugin.json) + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Calculate new version + id: new + run: | + IFS='.' read -r major minor patch <<< "${{ steps.current.outputs.version }}" + case "${{ steps.bump.outputs.type }}" in + major) major=$((major+1)); minor=0; patch=0 ;; + minor) minor=$((minor+1)); patch=0 ;; + patch) patch=$((patch+1)) ;; + esac + echo "version=${major}.${minor}.${patch}" >> $GITHUB_OUTPUT + + - name: Update version files + run: | + NEW_VERSION="${{ steps.new.outputs.version }}" + # plugin.json + jq --arg v "$NEW_VERSION" '.version = $v' .claude-plugin/plugin.json > tmp.json && mv tmp.json .claude-plugin/plugin.json + # marketplace.json (top-level and plugin entry) + jq --arg v "$NEW_VERSION" '.version = $v | .plugins[0].version = $v' .claude-plugin/marketplace.json > tmp.json && mv tmp.json .claude-plugin/marketplace.json + + - name: Commit version bump + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add .claude-plugin/plugin.json .claude-plugin/marketplace.json + git commit -m "release: v${{ steps.new.outputs.version }}" + git push + + - name: Create tag + run: | + git tag "v${{ steps.new.outputs.version }}" + git push origin "v${{ steps.new.outputs.version }}" + + - name: Generate changelog + id: changelog + run: | + PREV_TAG=$(git tag --sort=-v:refname | head -2 | tail -1) + if [ -z "$PREV_TAG" ]; then + CHANGELOG=$(git log --oneline --no-merges HEAD) + else + CHANGELOG=$(git log --oneline --no-merges ${PREV_TAG}..HEAD) + fi + echo "changelog<> $GITHUB_OUTPUT + echo "$CHANGELOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: "v${{ steps.new.outputs.version }}" + name: "v${{ steps.new.outputs.version }}" + body: | + ## Changes + ${{ steps.changelog.outputs.changelog }} + + ## Install / Update + ``` + /plugin marketplace add git-goods/gitanimals-buddy + /plugin install gitanimals-buddy@gitanimals-buddy + ``` + + Already installed? Run: + ``` + /plugin marketplace update gitanimals-buddy + /plugin update gitanimals-buddy@gitanimals-buddy + ``` + + - name: Run tests + run: | + bash tests/test-mood.sh + bash tests/test-bubble.sh + bash tests/test-sprite-renderer.sh + + sync-main: + needs: release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + + - name: Sync version back to main + run: | + git fetch origin release + git checkout origin/release -- .claude-plugin/plugin.json .claude-plugin/marketplace.json + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add .claude-plugin/plugin.json .claude-plugin/marketplace.json + git diff --cached --quiet || git commit -m "chore: sync version from release" + git push diff --git a/.gitignore b/.gitignore index 3b90588..9375be7 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ Icon docs/superpowers +.bkit + diff --git a/README.md b/README.md index 5e2d1be..f3a93e8 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ echo '{"username": "YOUR_GITHUB_USERNAME", "hidden": false}' > ~/.claude/gitanim | 커맨드 | 설명 | |--------|------| | `/animals` | 현재 활성 펫 표시 | -| `/animals login ` | GitAnimals 유저네임 설정 | +| `/animals login` | GitAnimals 웹에서 로그인 후 username 확인 | +| `/animals login ` | GitAnimals 유저네임 검증 후 설정 | | `/animals list` | 보유 펫 목록 조회 | | `/animals select ` | 활성 펫 변경 | | `/animals usage` | Usage 모니터링 상태 확인 | diff --git a/skills/login/SKILL.md b/skills/login/SKILL.md index 7c6cbbd..e00ac0e 100644 --- a/skills/login/SKILL.md +++ b/skills/login/SKILL.md @@ -6,25 +6,47 @@ description: GitAnimals 유저네임 설정 GitAnimals GitHub 유저네임을 설정합니다. ## Usage -`/gitanimals-buddy:login ` +- `/gitanimals-buddy:login` — 브라우저에서 gitanimals.org로 이동하여 username 확인 +- `/gitanimals-buddy:login ` — username 검증 후 바로 설정 ## Implementation -사용자가 제공한 username으로 `~/.claude/gitanimals.json`을 설정하고, pet 데이터를 fetch합니다. - ```bash USERNAME="$ARGUMENTS" + if [ -z "$USERNAME" ]; then - echo "❌ 유저네임을 입력해주세요: /gitanimals-buddy:login " + echo "🌐 GitAnimals 웹에서 로그인 후 username을 확인하세요." + open "https://www.gitanimals.org/en_US/auth/claude-code" 2>/dev/null || \ + xdg-open "https://www.gitanimals.org/en_US/auth/claude-code" 2>/dev/null || \ + echo " 👉 https://www.gitanimals.org/en_US/auth/claude-code" + echo "" + echo " 확인 후 아래 명령어를 실행하세요:" + echo " /gitanimals-buddy:login " + exit 0 +fi + +# Username 검증 +RESPONSE=$(curl -s --max-time 5 "https://render.gitanimals.org/users/${USERNAME}" 2>/dev/null) +if [ -z "$RESPONSE" ] || ! echo "$RESPONSE" | jq -e '.personas' >/dev/null 2>&1; then + echo "❌ '${USERNAME}' 유저를 찾을 수 없습니다." + echo " GitAnimals에 가입된 GitHub username인지 확인해주세요." + echo " 👉 https://www.gitanimals.org" exit 0 fi + +# Config 저장 mkdir -p "$HOME/.claude" if [ -f "$HOME/.claude/gitanimals.json" ]; then - jq --arg u "$USERNAME" '.username = $u' "$HOME/.claude/gitanimals.json" > /tmp/ga-tmp.json && mv /tmp/ga-tmp.json "$HOME/.claude/gitanimals.json" + jq --arg u "$USERNAME" '.username = $u' "$HOME/.claude/gitanimals.json" > /tmp/ga-tmp.json && \ + mv /tmp/ga-tmp.json "$HOME/.claude/gitanimals.json" else echo "{\"username\": \"$USERNAME\", \"hidden\": false}" > "$HOME/.claude/gitanimals.json" fi -echo "✅ GitAnimals username set to: $USERNAME" + +PET_COUNT=$(echo "$RESPONSE" | jq '[.personas[]? | select(.type != null)] | length' 2>/dev/null) +echo "✅ GitAnimals 로그인 완료: ${USERNAME}" +echo " 보유 펫: ${PET_COUNT}마리" echo " Your top pet will appear in the statusLine." + bash "${CLAUDE_PLUGIN_ROOT}/scripts/fetch-pet.sh" 2>/dev/null & ```