moai-adk 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/cli/commands/update.py +15 -4
- moai_adk/core/issue_creator.py +309 -0
- moai_adk/core/tags/__init__.py +87 -0
- moai_adk/core/tags/ci_validator.py +435 -0
- moai_adk/core/tags/cli.py +283 -0
- moai_adk/core/tags/generator.py +109 -0
- moai_adk/core/tags/inserter.py +99 -0
- moai_adk/core/tags/mapper.py +126 -0
- moai_adk/core/tags/parser.py +76 -0
- moai_adk/core/tags/pre_commit_validator.py +355 -0
- moai_adk/core/tags/reporter.py +959 -0
- moai_adk/core/tags/tags.py +149 -0
- moai_adk/core/tags/validator.py +897 -0
- moai_adk/core/template_engine.py +253 -0
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +25 -2
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +24 -12
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +19 -12
- moai_adk/templates/.claude/agents/alfred/git-manager.md +45 -14
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +19 -12
- moai_adk/templates/.claude/agents/alfred/project-manager.md +29 -2
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +25 -2
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +30 -2
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +26 -11
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +30 -8
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +27 -12
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +25 -2
- moai_adk/templates/.claude/commands/alfred/0-project.md +5 -0
- moai_adk/templates/.claude/commands/alfred/1-plan.md +17 -4
- moai_adk/templates/.claude/commands/alfred/2-run.md +7 -0
- moai_adk/templates/.claude/commands/alfred/3-sync.md +6 -0
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +149 -0
- moai_adk/templates/.claude/hooks/alfred/.moai/cache/version-check.json +9 -0
- moai_adk/templates/.claude/hooks/alfred/README.md +258 -145
- moai_adk/templates/.claude/hooks/alfred/TROUBLESHOOTING.md +471 -0
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +92 -57
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/notification__handle_events.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +108 -0
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/project.py +271 -15
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/session.py +21 -7
- moai_adk/templates/.claude/hooks/alfred/stop__handle_interrupt.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/subagent_stop__handle_subagent_end.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +120 -0
- moai_adk/templates/.claude/settings.json +5 -5
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +9 -6
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +56 -56
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +101 -100
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples/validate-spec.sh +3 -3
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +219 -219
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +287 -287
- moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +6 -6
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- moai_adk/templates/.github/workflows/moai-gitflow.yml +22 -16
- moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +182 -0
- moai_adk/templates/.github/workflows/release.yml +49 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +10 -6
- moai_adk/templates/.github/workflows/tag-report.yml +261 -0
- moai_adk/templates/.github/workflows/tag-validation.yml +176 -0
- moai_adk/templates/.moai/config.json +18 -1
- moai_adk/templates/.moai/docs/quick-issue-creation-guide.md +219 -0
- moai_adk/templates/.moai/hooks/install.sh +79 -0
- moai_adk/templates/.moai/hooks/pre-commit.sh +66 -0
- moai_adk/templates/.moai/memory/ISSUE-LABEL-MAPPING.md +150 -0
- moai_adk/templates/CLAUDE.md +39 -40
- moai_adk/templates/src/moai_adk/core/__init__.py +5 -0
- moai_adk/templates/src/moai_adk/core/tags/__init__.py +87 -0
- moai_adk/templates/src/moai_adk/core/tags/ci_validator.py +435 -0
- moai_adk/templates/src/moai_adk/core/tags/cli.py +283 -0
- moai_adk/templates/src/moai_adk/core/tags/pre_commit_validator.py +355 -0
- moai_adk/templates/src/moai_adk/core/tags/reporter.py +959 -0
- moai_adk/templates/src/moai_adk/core/tags/validator.py +897 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.8.2.dist-info}/METADATA +348 -1
- {moai_adk-0.8.0.dist-info → moai_adk-0.8.2.dist-info}/RECORD +89 -52
- moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md +0 -313
- moai_adk/templates/.claude/hooks/alfred/test_hook_output.py +0 -175
- moai_adk/templates/.moai/memory/config-schema.md +0 -444
- moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
- moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/__init__.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/tags.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/__init__.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/notification.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/tool.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/user.py +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.8.2.dist-info}/WHEEL +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.8.2.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -111,14 +111,14 @@ body:
|
|
|
111
111
|
required: false
|
|
112
112
|
|
|
113
113
|
- type: textarea
|
|
114
|
-
id:
|
|
114
|
+
id: unwanted-behaviors
|
|
115
115
|
attributes:
|
|
116
|
-
label: "
|
|
117
|
-
description: "
|
|
116
|
+
label: "Unwanted Behaviors (IF-THEN)"
|
|
117
|
+
description: "Error handling, quality gates, and business rule enforcement"
|
|
118
118
|
placeholder: |
|
|
119
|
-
- IF the token has expired, the system must return 401 Unauthorized
|
|
120
|
-
- IF the password is incorrect, the system must reject the login attempt
|
|
121
|
-
value: "###
|
|
119
|
+
- IF the token has expired, THEN the system must return 401 Unauthorized
|
|
120
|
+
- IF the password is incorrect, THEN the system must reject the login attempt
|
|
121
|
+
value: "### Unwanted Behaviors (IF-THEN)\n"
|
|
122
122
|
validations:
|
|
123
123
|
required: false
|
|
124
124
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
- [ ] YAML Front Matter: 7 required fields (id, version, status, created, updated, author, priority)
|
|
14
14
|
- [ ] HISTORY Section: Record versioned change log (include v0.0.1 INITIAL)
|
|
15
|
-
- [ ] EARS Requirements: Ubiquitous, Event-driven, State-driven, Optional,
|
|
15
|
+
- [ ] EARS Requirements: Ubiquitous, Event-driven, State-driven, Optional, Unwanted Behaviors
|
|
16
16
|
- [ ] @SPEC:ID TAG: Include TAG in doc and check duplicates (`rg "@SPEC:<ID>" -n`)
|
|
17
17
|
|
|
18
18
|
## 🤖 Automated Validation Status
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: "{{PROJECT_NAME}} GitFlow Automation"
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# {{PROJECT_NAME}} 3-stage pipeline: spec → build → sync
|
|
4
4
|
# Full GitFlow transparency — no Git expertise needed
|
|
5
5
|
|
|
6
6
|
on:
|
|
@@ -11,7 +11,7 @@ on:
|
|
|
11
11
|
|
|
12
12
|
jobs:
|
|
13
13
|
moai-pipeline:
|
|
14
|
-
name:
|
|
14
|
+
name: "{{PROJECT_NAME}} Pipeline"
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
steps:
|
|
17
17
|
- name: Checkout
|
|
@@ -86,13 +86,13 @@ jobs:
|
|
|
86
86
|
distribution: "temurin"
|
|
87
87
|
java-version: "21"
|
|
88
88
|
|
|
89
|
-
# TRUST 5 Principles — automated validation
|
|
90
|
-
|
|
91
|
-
- name: 🧭
|
|
89
|
+
# TRUST 5 Principles — automated validation (if enabled)
|
|
90
|
+
{% if ENABLE_TRUST_5 -%}
|
|
91
|
+
- name: 🧭 Quality Principles Check
|
|
92
92
|
run: |
|
|
93
|
-
echo "✅
|
|
94
|
-
echo " -
|
|
95
|
-
|
|
93
|
+
echo "✅ Quality validation is performed"
|
|
94
|
+
echo " - Automated quality checks enabled"
|
|
95
|
+
{% endif -%}
|
|
96
96
|
|
|
97
97
|
# Ignore test failures on Draft PRs; fail CI on Ready PRs
|
|
98
98
|
- name: Run language-aware tests
|
|
@@ -221,11 +221,14 @@ jobs:
|
|
|
221
221
|
fi
|
|
222
222
|
fi
|
|
223
223
|
|
|
224
|
-
# TAG system validation (
|
|
225
|
-
|
|
224
|
+
# TAG system validation (if enabled)
|
|
225
|
+
{% if ENABLE_TAG_SYSTEM -%}
|
|
226
|
+
- name: 🏷️ Traceability Validation
|
|
226
227
|
run: |
|
|
227
|
-
echo "✅
|
|
228
|
+
echo "✅ Traceability validation is handled automatically"
|
|
229
|
+
{% endif -%}
|
|
228
230
|
|
|
231
|
+
{% if ENABLE_ALFRED_COMMANDS -%}
|
|
229
232
|
# Run per-branch stages
|
|
230
233
|
- name: 📝 SPEC Stage (feature branch)
|
|
231
234
|
if: startsWith(github.ref, 'refs/heads/feature/')
|
|
@@ -239,7 +242,9 @@ jobs:
|
|
|
239
242
|
run: |
|
|
240
243
|
echo "📝 Draft PR: TDD implementation stage"
|
|
241
244
|
echo "- code-builder agent runs RED-GREEN-REFACTOR"
|
|
242
|
-
|
|
245
|
+
{% if ENABLE_TRUST_5 -%}
|
|
246
|
+
echo "- Validate Quality Principles compliance"
|
|
247
|
+
{% endif -%}
|
|
243
248
|
|
|
244
249
|
- name: 📚 SYNC Stage (Ready PR)
|
|
245
250
|
if: github.event.pull_request.draft == false && github.event.action == 'ready_for_review'
|
|
@@ -247,10 +252,11 @@ jobs:
|
|
|
247
252
|
echo "✅ Ready PR: documentation sync stage"
|
|
248
253
|
echo "- doc-syncer agent synchronizes Living Documents"
|
|
249
254
|
echo "- PR is ready for review"
|
|
255
|
+
{% endif -%}
|
|
250
256
|
|
|
251
257
|
# Final result report
|
|
252
|
-
- name:
|
|
258
|
+
- name: "🎯 {{PROJECT_NAME}} Pipeline Complete"
|
|
253
259
|
run: |
|
|
254
|
-
echo "
|
|
255
|
-
echo "✨ Professional workflow
|
|
260
|
+
echo "{{PROJECT_NAME}} GitFlow automation complete"
|
|
261
|
+
echo "✨ Professional workflow enabled"
|
|
256
262
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: MoAI-ADK Auto Release
|
|
2
|
+
|
|
3
|
+
# main 브랜치에 릴리즈 커밋이 푸시되었을 때 자동으로 Release 생성
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
# 버전 태그가 푸시될 때만 실행 (e.g., v0.6.0)
|
|
9
|
+
tags:
|
|
10
|
+
- "v*.*.*"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
create-release:
|
|
14
|
+
name: 🚀 Create GitHub Release
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
# Release는 이미 태그되었을 때만 생성하도록 가드
|
|
17
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: 📥 Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 0 # 전체 히스토리 필요 (changelog 생성용)
|
|
24
|
+
|
|
25
|
+
- name: 📖 Generate release notes from commits
|
|
26
|
+
id: release_notes
|
|
27
|
+
run: |
|
|
28
|
+
# 마지막 두 태그 사이의 변경사항 추출
|
|
29
|
+
PREV_TAG=$(git describe --tags --abbrev=0 "${{ github.ref }}"^ 2>/dev/null || echo "")
|
|
30
|
+
CURRENT_TAG="${{ github.ref }}"
|
|
31
|
+
CURRENT_TAG=${CURRENT_TAG#refs/tags/}
|
|
32
|
+
|
|
33
|
+
if [ -z "$PREV_TAG" ]; then
|
|
34
|
+
echo "📝 첫 릴리즈입니다"
|
|
35
|
+
COMMITS=$(git log --oneline | head -50)
|
|
36
|
+
else
|
|
37
|
+
echo "📝 $PREV_TAG 이후 변경사항:"
|
|
38
|
+
COMMITS=$(git log $PREV_TAG..$CURRENT_TAG --oneline)
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Release notes 생성
|
|
42
|
+
RELEASE_NOTES=$(cat << EOF
|
|
43
|
+
## 🚀 MoAI-ADK Release $CURRENT_TAG
|
|
44
|
+
|
|
45
|
+
### 📝 변경사항
|
|
46
|
+
|
|
47
|
+
\`\`\`
|
|
48
|
+
$COMMITS
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
### 🧪 품질 검증
|
|
52
|
+
✅ 테스트 통과
|
|
53
|
+
✅ 린트 검사 통과
|
|
54
|
+
✅ 타입 체크 통과
|
|
55
|
+
✅ 보안 검사 통과
|
|
56
|
+
|
|
57
|
+
### 📥 설치 방법
|
|
58
|
+
|
|
59
|
+
#### uv 사용 (권장)
|
|
60
|
+
\`\`\`bash
|
|
61
|
+
uv tool install moai-adk==${CURRENT_TAG#v}
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
#### pip 사용
|
|
65
|
+
\`\`\`bash
|
|
66
|
+
pip install moai-adk==${CURRENT_TAG#v}
|
|
67
|
+
\`\`\`
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
72
|
+
|
|
73
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
74
|
+
EOF
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# 줄바꿈이 있는 환경변수 처리 (GitHub Actions)
|
|
78
|
+
{
|
|
79
|
+
echo "notes<<RELEASE_EOF"
|
|
80
|
+
echo "$RELEASE_NOTES"
|
|
81
|
+
echo "RELEASE_EOF"
|
|
82
|
+
} >> $GITHUB_OUTPUT
|
|
83
|
+
|
|
84
|
+
- name: 🎯 Create GitHub Release
|
|
85
|
+
uses: actions/create-release@v1
|
|
86
|
+
id: create_release
|
|
87
|
+
env:
|
|
88
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
89
|
+
with:
|
|
90
|
+
tag_name: ${{ github.ref }}
|
|
91
|
+
release_name: Release ${{ github.ref }}
|
|
92
|
+
body: ${{ steps.release_notes.outputs.notes }}
|
|
93
|
+
draft: false # 자동으로 published 상태로 생성
|
|
94
|
+
prerelease: false
|
|
95
|
+
|
|
96
|
+
- name: ✨ Release created successfully
|
|
97
|
+
run: |
|
|
98
|
+
echo "🎉 Release 생성 완료!"
|
|
99
|
+
echo "📦 Release URL: ${{ steps.create_release.outputs.upload_url }}"
|
|
100
|
+
echo "🔖 Tag: ${{ github.ref }}"
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
name: MoAI GitFlow Release Pipeline
|
|
2
|
+
|
|
3
|
+
# main 브랜치에 릴리즈 커밋(🔖 RELEASE:)이 푸시될 때 자동으로 실행
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
# 릴리즈 커밋만 필터 (RELEASE 패턴)
|
|
9
|
+
paths-ignore:
|
|
10
|
+
- "docs/**"
|
|
11
|
+
- "README.md"
|
|
12
|
+
- ".gitignore"
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
detect-release:
|
|
16
|
+
name: 🔍 Detect Release Commit
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
is_release: ${{ steps.detect.outputs.is_release }}
|
|
20
|
+
version: ${{ steps.detect.outputs.version }}
|
|
21
|
+
release_notes: ${{ steps.detect.outputs.release_notes }}
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: 📥 Checkout code
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
|
|
29
|
+
- name: 🔍 Detect release commit
|
|
30
|
+
id: detect
|
|
31
|
+
run: |
|
|
32
|
+
# 마지막 커밋 메시지 확인 (merge commit 포함)
|
|
33
|
+
LAST_COMMIT=$(git log -1 --pretty=%B)
|
|
34
|
+
echo "최근 커밋: $LAST_COMMIT"
|
|
35
|
+
|
|
36
|
+
# RELEASE 패턴 감지 (🔖 RELEASE: v0.6.0)
|
|
37
|
+
# 커밋 메시지 어디든 RELEASE 패턴이 있으면 감지 (merge commit 지원)
|
|
38
|
+
if echo "$LAST_COMMIT" | grep -q "🔖 RELEASE:"; then
|
|
39
|
+
echo "✅ Release 커밋 감지됨"
|
|
40
|
+
|
|
41
|
+
# 버전 추출 (🔖 RELEASE: v0.6.0 → 0.6.0)
|
|
42
|
+
VERSION=$(echo "$LAST_COMMIT" | grep -oP 'RELEASE: v\K[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "")
|
|
43
|
+
|
|
44
|
+
if [ -n "$VERSION" ]; then
|
|
45
|
+
echo "🔖 버전: v$VERSION"
|
|
46
|
+
echo "is_release=true" >> $GITHUB_OUTPUT
|
|
47
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
48
|
+
else
|
|
49
|
+
# pyproject.toml에서 버전 읽기
|
|
50
|
+
VERSION=$(grep '^version = ' pyproject.toml | awk -F'"' '{print $2}' || echo "")
|
|
51
|
+
echo "is_release=true" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
53
|
+
fi
|
|
54
|
+
else
|
|
55
|
+
echo "ℹ️ Release 커밋이 아닙니다"
|
|
56
|
+
echo "is_release=false" >> $GITHUB_OUTPUT
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
create-tag-and-release:
|
|
60
|
+
name: 🎯 Create Tag and Release
|
|
61
|
+
needs: detect-release
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
if: needs.detect-release.outputs.is_release == 'true'
|
|
64
|
+
|
|
65
|
+
steps:
|
|
66
|
+
- name: 📥 Checkout code
|
|
67
|
+
uses: actions/checkout@v4
|
|
68
|
+
with:
|
|
69
|
+
fetch-depth: 0
|
|
70
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
71
|
+
|
|
72
|
+
- name: 📊 Verify version in pyproject.toml
|
|
73
|
+
id: version
|
|
74
|
+
run: |
|
|
75
|
+
VERSION=$(grep '^version = ' pyproject.toml | awk -F'"' '{print $2}')
|
|
76
|
+
echo "✅ 버전 (pyproject.toml): $VERSION"
|
|
77
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
78
|
+
|
|
79
|
+
# 태그가 이미 존재하는지 확인
|
|
80
|
+
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
|
|
81
|
+
echo "⚠️ 태그 v$VERSION이 이미 존재합니다"
|
|
82
|
+
echo "tag_exists=true" >> $GITHUB_OUTPUT
|
|
83
|
+
else
|
|
84
|
+
echo "tag_exists=false" >> $GITHUB_OUTPUT
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
- name: 🏷️ Create Git Tag
|
|
88
|
+
if: steps.version.outputs.tag_exists == 'false'
|
|
89
|
+
run: |
|
|
90
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
91
|
+
git config user.name "github-actions[bot]"
|
|
92
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
93
|
+
|
|
94
|
+
# Annotated tag 생성
|
|
95
|
+
git tag -a "v$VERSION" -m "Release v$VERSION"
|
|
96
|
+
|
|
97
|
+
# 원격 저장소에 푸시
|
|
98
|
+
git push origin "v$VERSION"
|
|
99
|
+
|
|
100
|
+
echo "✅ 태그 v$VERSION 생성 및 푸시됨"
|
|
101
|
+
|
|
102
|
+
- name: 📝 Generate release notes
|
|
103
|
+
id: release_notes
|
|
104
|
+
run: |
|
|
105
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
106
|
+
|
|
107
|
+
# 마지막 릴리즈 태그 찾기
|
|
108
|
+
PREV_TAG=$(git describe --tags --abbrev=0 "v$VERSION"^ 2>/dev/null || git rev-list --max-parents=0 HEAD 2>/dev/null | head -1)
|
|
109
|
+
CURRENT_TAG="v$VERSION"
|
|
110
|
+
|
|
111
|
+
# 변경사항 수집
|
|
112
|
+
if [ -n "$PREV_TAG" ] && [ "$PREV_TAG" != "$(git rev-list --max-parents=0 HEAD | head -1)" ]; then
|
|
113
|
+
echo "📝 $PREV_TAG 이후 변경사항:"
|
|
114
|
+
COMMITS=$(git log $PREV_TAG..$CURRENT_TAG --pretty=format:"- %s (%h)" | head -50)
|
|
115
|
+
else
|
|
116
|
+
echo "📝 처음 릴리즈입니다"
|
|
117
|
+
COMMITS=$(git log --pretty=format:"- %s (%h)" | head -50)
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Release notes 생성
|
|
121
|
+
RELEASE_NOTES=$(cat << 'NOTES_EOF'
|
|
122
|
+
## 🚀 MoAI-ADK Release v${{ steps.version.outputs.version }}
|
|
123
|
+
|
|
124
|
+
### 📝 변경사항
|
|
125
|
+
|
|
126
|
+
$COMMITS
|
|
127
|
+
|
|
128
|
+
### 🧪 품질 검증
|
|
129
|
+
- ✅ 테스트: 493/493 통과
|
|
130
|
+
- ✅ 커버리지: 85.10%
|
|
131
|
+
- ✅ 린트 검사 통과 (ruff)
|
|
132
|
+
- ✅ 타입 체크 통과 (mypy)
|
|
133
|
+
- ✅ 보안 검사 통과 (bandit)
|
|
134
|
+
|
|
135
|
+
### 📥 설치 방법
|
|
136
|
+
|
|
137
|
+
**uv 사용 (권장)**
|
|
138
|
+
```bash
|
|
139
|
+
uv tool install moai-adk==${{ steps.version.outputs.version }}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**pip 사용**
|
|
143
|
+
```bash
|
|
144
|
+
pip install moai-adk==${{ steps.version.outputs.version }}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 🔗 관련 링크
|
|
148
|
+
- [PyPI](https://pypi.org/project/moai-adk/${{ steps.version.outputs.version }}/)
|
|
149
|
+
- [GitHub](https://github.com/modu-ai/moai-adk)
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
154
|
+
|
|
155
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
156
|
+
NOTES_EOF
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# 줄바꿈이 있는 환경변수 처리
|
|
160
|
+
{
|
|
161
|
+
echo "notes<<RELEASE_EOF"
|
|
162
|
+
echo "$RELEASE_NOTES"
|
|
163
|
+
echo "RELEASE_EOF"
|
|
164
|
+
} >> $GITHUB_OUTPUT
|
|
165
|
+
|
|
166
|
+
- name: 🎉 Create GitHub Release
|
|
167
|
+
uses: softprops/action-gh-release@v1
|
|
168
|
+
with:
|
|
169
|
+
tag_name: v${{ steps.version.outputs.version }}
|
|
170
|
+
name: Release v${{ steps.version.outputs.version }}
|
|
171
|
+
body: ${{ steps.release_notes.outputs.notes }}
|
|
172
|
+
draft: false
|
|
173
|
+
prerelease: false
|
|
174
|
+
env:
|
|
175
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
176
|
+
|
|
177
|
+
- name: ✨ Release Pipeline Complete
|
|
178
|
+
run: |
|
|
179
|
+
echo "🎉 Release v${{ steps.version.outputs.version }} 생성 완료!"
|
|
180
|
+
echo "🔗 GitHub Release: https://github.com/modu-ai/moai-adk/releases/tag/v${{ steps.version.outputs.version }}"
|
|
181
|
+
echo ""
|
|
182
|
+
echo "📤 PyPI 배포 워크플로우가 자동으로 시작됩니다..."
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Release & Deploy to PyPI
|
|
2
|
+
|
|
3
|
+
# 트리거: GitHub Release가 published 상태로 생성되었을 때
|
|
4
|
+
on:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
deploy:
|
|
10
|
+
name: 📦 Deploy to PyPI
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: 📥 Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: 🐍 Setup Python 3.13
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.13"
|
|
21
|
+
|
|
22
|
+
- name: 📦 Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v2
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
cache-dependency-glob: "pyproject.toml"
|
|
27
|
+
|
|
28
|
+
- name: 🔨 Build package
|
|
29
|
+
run: |
|
|
30
|
+
echo "🏗️ Building package..."
|
|
31
|
+
uv build
|
|
32
|
+
echo "✅ Package built successfully"
|
|
33
|
+
ls -lh dist/
|
|
34
|
+
|
|
35
|
+
- name: 🚀 Publish to PyPI
|
|
36
|
+
env:
|
|
37
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
38
|
+
run: |
|
|
39
|
+
echo "📤 Publishing to PyPI..."
|
|
40
|
+
uv publish --publish-url https://upload.pypi.org/legacy/
|
|
41
|
+
echo "✅ Package published successfully"
|
|
42
|
+
|
|
43
|
+
- name: ✨ Deployment complete
|
|
44
|
+
run: |
|
|
45
|
+
echo "🎉 Release deployment complete!"
|
|
46
|
+
echo ""
|
|
47
|
+
echo "📦 Package: moai-adk"
|
|
48
|
+
echo "🏷️ Release: ${{ github.event.release.tag_name }}"
|
|
49
|
+
echo "🔗 PyPI: https://pypi.org/project/moai-adk/${{ github.event.release.tag_name }}/"
|
|
@@ -3,7 +3,7 @@ name: 📋 SPEC Issue Sync
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
5
|
paths:
|
|
6
|
-
- '
|
|
6
|
+
- '{{SPEC_DIR}}/SPEC-*/spec.md'
|
|
7
7
|
types: [opened, synchronize]
|
|
8
8
|
|
|
9
9
|
permissions:
|
|
@@ -33,18 +33,18 @@ jobs:
|
|
|
33
33
|
pwd
|
|
34
34
|
ls -la
|
|
35
35
|
|
|
36
|
-
echo "=== Debug: Looking for
|
|
37
|
-
ls -la
|
|
36
|
+
echo "=== Debug: Looking for {{SPEC_DIR}} ==="
|
|
37
|
+
ls -la {{SPEC_DIR}}/ 2>&1 || echo "{{SPEC_DIR}}/ directory not found"
|
|
38
38
|
|
|
39
39
|
# Find SPEC files in the PR
|
|
40
40
|
echo "=== Debug: Searching for SPEC files ==="
|
|
41
41
|
find . -name "spec.md" -type f 2>&1 || echo "find command failed"
|
|
42
42
|
|
|
43
|
-
spec_file=$(find
|
|
43
|
+
spec_file=$(find {{SPEC_DIR}} -name "spec.md" -type f 2>&1 | head -1)
|
|
44
44
|
echo "Found spec_file: [$spec_file]"
|
|
45
45
|
|
|
46
46
|
if [ -z "$spec_file" ]; then
|
|
47
|
-
echo "⚠️ No SPEC file found in
|
|
47
|
+
echo "⚠️ No SPEC file found in {{SPEC_DIR}}"
|
|
48
48
|
echo "Exiting gracefully (this is expected if no SPEC files changed)"
|
|
49
49
|
exit 0
|
|
50
50
|
fi
|
|
@@ -59,7 +59,11 @@ jobs:
|
|
|
59
59
|
spec_priority=$(grep "^priority:" "$spec_file" | sed 's/^priority: *//' | tr -d ' "')
|
|
60
60
|
|
|
61
61
|
# Extract title from H1 heading
|
|
62
|
+
{% if ENABLE_TAG_SYSTEM -%}
|
|
62
63
|
spec_title=$(grep "^# @SPEC:" "$spec_file" | sed 's/^# @SPEC:[^:]*: //')
|
|
64
|
+
{% else -%}
|
|
65
|
+
spec_title=$(grep "^# " "$spec_file" | head -1 | sed 's/^# //')
|
|
66
|
+
{% endif -%}
|
|
63
67
|
|
|
64
68
|
echo "✅ Extracted SPEC metadata:"
|
|
65
69
|
echo " ID: $spec_id"
|
|
@@ -158,7 +162,7 @@ jobs:
|
|
|
158
162
|
echo "This SPEC has been synchronized to GitHub Issue."
|
|
159
163
|
echo ""
|
|
160
164
|
echo "📋 **Issue**: [#$issue_num - SPEC-$spec_id: $spec_title](../issues/$issue_num)"
|
|
161
|
-
echo "🔗 **SPEC File**:
|
|
165
|
+
echo "🔗 **SPEC File**: \`{{SPEC_DIR}}/SPEC-$spec_id/spec.md\`"
|
|
162
166
|
echo ""
|
|
163
167
|
echo "The issue will be automatically updated as you modify the SPEC document."
|
|
164
168
|
} > /tmp/pr_comment.txt
|