velogger 0.1.0__tar.gz

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.
Files changed (71) hide show
  1. velogger-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +59 -0
  2. velogger-0.1.0/.github/ISSUE_TEMPLATE/chore.yml +41 -0
  3. velogger-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. velogger-0.1.0/.github/ISSUE_TEMPLATE/docs.yml +30 -0
  5. velogger-0.1.0/.github/ISSUE_TEMPLATE/feature.yml +40 -0
  6. velogger-0.1.0/.github/ISSUE_TEMPLATE/task.yml +30 -0
  7. velogger-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +33 -0
  8. velogger-0.1.0/.github/workflows/api-monitor.yml +81 -0
  9. velogger-0.1.0/.github/workflows/ci.yml +91 -0
  10. velogger-0.1.0/.github/workflows/release.yml +82 -0
  11. velogger-0.1.0/.gitignore +229 -0
  12. velogger-0.1.0/AGENTS.md +104 -0
  13. velogger-0.1.0/CHANGELOG.md +39 -0
  14. velogger-0.1.0/CLAUDE.md +4 -0
  15. velogger-0.1.0/LICENSE +21 -0
  16. velogger-0.1.0/PKG-INFO +226 -0
  17. velogger-0.1.0/README.md +197 -0
  18. velogger-0.1.0/docs/common.md +39 -0
  19. velogger-0.1.0/docs/llm.md +89 -0
  20. velogger-0.1.0/docs/velogger.md +339 -0
  21. velogger-0.1.0/pyproject.toml +120 -0
  22. velogger-0.1.0/references/architecture.md +81 -0
  23. velogger-0.1.0/references/code-style.md +154 -0
  24. velogger-0.1.0/references/development.md +127 -0
  25. velogger-0.1.0/references/output-contract.md +110 -0
  26. velogger-0.1.0/references/provider-conventions.md +126 -0
  27. velogger-0.1.0/references/providers/velogger.md +315 -0
  28. velogger-0.1.0/references/release.md +104 -0
  29. velogger-0.1.0/references/workflow.md +84 -0
  30. velogger-0.1.0/scripts/monitor/api_check.py +419 -0
  31. velogger-0.1.0/src/velogger/__init__.py +1 -0
  32. velogger-0.1.0/src/velogger/__main__.py +5 -0
  33. velogger-0.1.0/src/velogger/api/__init__.py +1 -0
  34. velogger-0.1.0/src/velogger/api/client.py +933 -0
  35. velogger-0.1.0/src/velogger/api/request/__init__.py +1 -0
  36. velogger-0.1.0/src/velogger/api/request/auth.py +14 -0
  37. velogger-0.1.0/src/velogger/api/request/cache.py +28 -0
  38. velogger-0.1.0/src/velogger/api/request/posts.py +40 -0
  39. velogger-0.1.0/src/velogger/api/request/social.py +34 -0
  40. velogger-0.1.0/src/velogger/api/request/users.py +11 -0
  41. velogger-0.1.0/src/velogger/api/request/write.py +81 -0
  42. velogger-0.1.0/src/velogger/api/response/__init__.py +1 -0
  43. velogger-0.1.0/src/velogger/api/response/auth.py +73 -0
  44. velogger-0.1.0/src/velogger/api/response/cache.py +64 -0
  45. velogger-0.1.0/src/velogger/api/response/common.py +65 -0
  46. velogger-0.1.0/src/velogger/api/response/posts.py +118 -0
  47. velogger-0.1.0/src/velogger/api/response/social.py +198 -0
  48. velogger-0.1.0/src/velogger/api/response/users.py +79 -0
  49. velogger-0.1.0/src/velogger/api/response/write.py +136 -0
  50. velogger-0.1.0/src/velogger/cli/__init__.py +0 -0
  51. velogger-0.1.0/src/velogger/cli/app.py +923 -0
  52. velogger-0.1.0/src/velogger/cli/output.py +185 -0
  53. velogger-0.1.0/src/velogger/core/__init__.py +0 -0
  54. velogger-0.1.0/src/velogger/core/errors.py +25 -0
  55. velogger-0.1.0/src/velogger/core/http.py +438 -0
  56. velogger-0.1.0/src/velogger/core/paths.py +21 -0
  57. velogger-0.1.0/src/velogger/core/ratelimit.py +383 -0
  58. velogger-0.1.0/src/velogger/core/schema.py +58 -0
  59. velogger-0.1.0/src/velogger/core/session.py +157 -0
  60. velogger-0.1.0/src/velogger/service/__init__.py +4 -0
  61. velogger-0.1.0/src/velogger/service/auth.py +267 -0
  62. velogger-0.1.0/src/velogger/service/common.py +277 -0
  63. velogger-0.1.0/src/velogger/service/post.py +172 -0
  64. velogger-0.1.0/src/velogger/service/posts.py +80 -0
  65. velogger-0.1.0/src/velogger/service/social.py +266 -0
  66. velogger-0.1.0/src/velogger/service/users.py +137 -0
  67. velogger-0.1.0/src/velogger/service/write.py +579 -0
  68. velogger-0.1.0/tests/conftest.py +11 -0
  69. velogger-0.1.0/tests/test_cli.py +212 -0
  70. velogger-0.1.0/tests/test_monitor.py +54 -0
  71. velogger-0.1.0/tests/test_write.py +238 -0
@@ -0,0 +1,59 @@
1
+ name: ๐Ÿ› ๋ฒ„๊ทธ ์ œ๋ณด
2
+ description: ๋ช…๋ น์ด ๋ฌธ์„œ์™€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๊ฑฐ๋‚˜, ๊ฒฐ๊ณผ๊ฐ€ ์ž˜๋ชป ๋‚˜์˜ฌ ๋•Œ
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ ์ œ๋ณด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ถ™์—ฌ ๋„ฃ๋Š” ๋‚ด์šฉ์—์„œ **ํ† ํฐยท์ฟ ํ‚คยท์ด๋ฉ”์ผ ๊ฐ™์€ ๊ฐœ์ธ์ •๋ณด๋Š” ์ง€์›Œ ์ฃผ์„ธ์š”.**
9
+
10
+ - type: dropdown
11
+ id: area
12
+ attributes:
13
+ label: ์˜์—ญ
14
+ description: ์–ด๋А ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‚˜์š”?
15
+ options:
16
+ - ๋กœ๊ทธ์ธยท์„ธ์…˜ (login, whoami)
17
+ - ์กฐํšŒ (trending, search, post, user ๋“ฑ)
18
+ - ์ž‘์„ฑ (publish, like, comment ๋“ฑ)
19
+ - ์š”์ฒญ ์ œํ•œ (limits, RATE_LIMITED)
20
+ - CLI ์ถœ๋ ฅยท์—๋Ÿฌ ํ˜•์‹
21
+ - ๊ธฐํƒ€ / ์ž˜ ๋ชจ๋ฅด๊ฒ ์Œ
22
+ validations:
23
+ required: true
24
+
25
+ - type: textarea
26
+ id: what-happened
27
+ attributes:
28
+ label: ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜์š”?
29
+ description: ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ์™€ ์‹ค์ œ ๊ฒฐ๊ณผ๋ฅผ ์ ์–ด ์ฃผ์„ธ์š”.
30
+ validations:
31
+ required: true
32
+
33
+ - type: textarea
34
+ id: repro
35
+ attributes:
36
+ label: ์žฌํ˜„ ๋ฐฉ๋ฒ•
37
+ description: ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ๊ฐ€์žฅ ์งง์€ ๋ช…๋ น.
38
+ placeholder: "velogger search fastapi --limit 3"
39
+ render: shell
40
+ validations:
41
+ required: true
42
+
43
+ - type: textarea
44
+ id: output
45
+ attributes:
46
+ label: ์ถœ๋ ฅ ๋˜๋Š” ์—๋Ÿฌ
47
+ description: stdout ๊ฒฐ๊ณผ๋‚˜ stderr ์˜ ์—๋Ÿฌ JSON. `--verbose` ๋กœ๊ทธ๊ฐ€ ์žˆ์œผ๋ฉด ํ•จ๊ป˜ ๋ถ™์—ฌ ์ฃผ์„ธ์š”. ํ† ํฐยท์ฟ ํ‚คยท์ด๋ฉ”์ผ์€ ์ง€์šฐ์„ธ์š”.
48
+ render: shell
49
+ validations:
50
+ required: false
51
+
52
+ - type: input
53
+ id: versions
54
+ attributes:
55
+ label: ํ™˜๊ฒฝ
56
+ description: "`velogger --version` ์ถœ๋ ฅ, Python ๋ฒ„์ „, ์‹คํ–‰ํ•œ ๋‚ ์งœ. ๋น„๊ณต์‹ API ๋ผ ๋‚ ์งœ๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค."
57
+ placeholder: "velogger 0.1.0 (์ปค๋ฐ‹ a1b2c3d), Python 3.11.6, 2026-10-18"
58
+ validations:
59
+ required: false
@@ -0,0 +1,41 @@
1
+ name: ๐Ÿงน ์žก๋ฌด
2
+ description: ์˜์กด์„ฑ, ๋„๊ตฌ, ์„ค์ •, ์ •๋ฆฌ โ€” ๋™์ž‘ ๋ณ€ํ™” ์—†์Œ
3
+ labels: ["chore"]
4
+ body:
5
+ - type: dropdown
6
+ id: kind
7
+ attributes:
8
+ label: ์ข…๋ฅ˜
9
+ options:
10
+ - ์˜์กด์„ฑ ์—…๋ฐ์ดํŠธยท๊ณ ์ •
11
+ - ๋„๊ตฌยทCI
12
+ - ์„ค์ •
13
+ - ๋ฆฌํŒฉํ„ฐ๋งยท์ •๋ฆฌ
14
+ - ๊ธฐํƒ€
15
+ validations:
16
+ required: true
17
+
18
+ - type: textarea
19
+ id: what
20
+ attributes:
21
+ label: ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?
22
+ validations:
23
+ required: true
24
+
25
+ - type: textarea
26
+ id: why
27
+ attributes:
28
+ label: ์™œ ์ง€๊ธˆ ํ•˜๋‚˜์š”?
29
+ description: |
30
+ ๊ทธ๋Œ€๋กœ ๋‘๋ฉด ์–ด๋–ค ๋น„์šฉ์ด ์žˆ๋‚˜์š”? ๋ณด์•ˆ ๊ถŒ๊ณ , ๊นจ์ง„ ๋นŒ๋“œ, ๋‹จ์ˆœํ•œ ์ •๋ฆฌ
31
+ ๋ชจ๋‘ ๊ดœ์ฐฎ์€ ์ด์œ ์ž…๋‹ˆ๋‹ค.
32
+ validations:
33
+ required: true
34
+
35
+ - type: checkboxes
36
+ id: impact
37
+ attributes:
38
+ label: ์˜ํ–ฅ
39
+ options:
40
+ - label: CLI ์ถœ๋ ฅ ํ˜•์‹์ด๋‚˜ ๋ช…๋ นยท์˜ต์…˜์ด ๋ฐ”๋€๋‹ค
41
+ required: false
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: ๐Ÿ’ฌ ์งˆ๋ฌธยท๋…ผ์˜
4
+ url: https://github.com/Rukkakka/velogger/discussions
5
+ about: ์‚ฌ์šฉ๋ฒ•์„ ๋ฌป๊ฑฐ๋‚˜, ์ด์Šˆ๋ฅผ ์˜ฌ๋ฆฌ๊ธฐ ์ „์— ์•„์ด๋””์–ด๋ฅผ ๋…ผ์˜ํ•ฉ๋‹ˆ๋‹ค.
@@ -0,0 +1,30 @@
1
+ name: ๐Ÿ“ ๋ฌธ์„œ
2
+ description: ๋ฌธ์„œ์— ๋น ์กŒ๊ฑฐ๋‚˜, ํ‹€๋ ธ๊ฑฐ๋‚˜, ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด ์žˆ์„ ๋•Œ
3
+ labels: ["docs"]
4
+ body:
5
+ - type: input
6
+ id: location
7
+ attributes:
8
+ label: ์–ด๋””์ธ๊ฐ€์š”?
9
+ description: ํŒŒ์ผ, ์„น์…˜, ๋˜๋Š” docstring.
10
+ placeholder: "README.md โ€” ์š”์ฒญ ์ œํ•œ ํ‘œ"
11
+ validations:
12
+ required: true
13
+
14
+ - type: textarea
15
+ id: problem
16
+ attributes:
17
+ label: ๋ฌด์—‡์ด ํ‹€๋ ธ๊ฑฐ๋‚˜ ๋น ์กŒ๋‚˜์š”?
18
+ description: |
19
+ ๋ฌธ์„œ๊ฐ€ ์ง€๊ธˆ ๋ญ๋ผ๊ณ  ํ•˜๋Š”์ง€, ๊ทธ๊ฒŒ ์™œ ํ‹€๋ ธ๊ฑฐ๋‚˜ ๋‚ก์•˜๊ฑฐ๋‚˜ ๋”ฐ๋ผ๊ฐ€๊ธฐ
20
+ ์–ด๋ ค์šด์ง€ ์ ์–ด ์ฃผ์„ธ์š”.
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: suggestion
26
+ attributes:
27
+ label: ์ œ์•ˆ ๋ฌธ๊ตฌ
28
+ description: ์„ ํƒ โ€” ๋ฐ”๋€Œ์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋ฌธ์žฅ์„ ์ ์–ด ์ฃผ์„ธ์š”.
29
+ validations:
30
+ required: false
@@ -0,0 +1,40 @@
1
+ name: โœจ ๊ธฐ๋Šฅ
2
+ description: ์ƒˆ ๋ช…๋ น, ์˜ต์…˜, ์—”๋“œํฌ์ธํŠธ ์ œ์•ˆ
3
+ labels: ["feature"]
4
+ body:
5
+ - type: textarea
6
+ id: proposal
7
+ attributes:
8
+ label: ๋ฌด์—‡์ด ์žˆ์–ด์•ผ ํ•˜๋‚˜์š”?
9
+ description: |
10
+ ์›ํ•˜๋Š” ๋ช…๋ น, ์˜ต์…˜, ์—”๋“œํฌ์ธํŠธ๋ฅผ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”. ์ƒˆ ์—”๋“œํฌ์ธํŠธ๋ผ๋ฉด
11
+ ํ™•์ธํ•œ ์š”์ฒญยท์‘๋‹ต ์˜ˆ์‹œ๋ฅผ ํ•จ๊ป˜ ์ ์–ด ์ฃผ์„ธ์š”.
12
+ validations:
13
+ required: true
14
+
15
+ - type: textarea
16
+ id: motivation
17
+ attributes:
18
+ label: ์™œ ํ•„์š”ํ•œ๊ฐ€์š”?
19
+ description: ์ง€๊ธˆ ๋ช…๋ น์œผ๋กœ๋Š” ํ•  ์ˆ˜ ์—†๋Š” ์ผ์ด ๋ฌด์—‡์ธ๊ฐ€์š”?
20
+ validations:
21
+ required: true
22
+
23
+ - type: textarea
24
+ id: usage
25
+ attributes:
26
+ label: ์‚ฌ์šฉ ์˜ˆ
27
+ description: ์ƒ๊ธฐ๋ฉด ์“ฐ๊ณ  ์‹ถ์€ ๋ช…๋ น๊ณผ ๊ธฐ๋Œ€ํ•˜๋Š” ์ถœ๋ ฅ์„ ์ ์–ด ์ฃผ์„ธ์š”.
28
+ render: shell
29
+ validations:
30
+ required: false
31
+
32
+ - type: checkboxes
33
+ id: conventions
34
+ attributes:
35
+ label: ๊ทœ์•ฝ
36
+ options:
37
+ - label: ์ƒˆ ์—”๋“œํฌ์ธํŠธ๋ผ๋ฉด references/provider-conventions.md ๋ฅผ ์ฝ์—ˆ๋‹ค
38
+ required: false
39
+ - label: ์ถœ๋ ฅ์ด ๋ฐ”๋€๋‹ค๋ฉด references/output-contract.md ๋ฅผ ์ฝ์—ˆ๋‹ค
40
+ required: false
@@ -0,0 +1,30 @@
1
+ name: โœ… ์ž‘์—…
2
+ description: ๋ฒ„๊ทธยท๊ธฐ๋Šฅยท๋ฌธ์„œยท์žก๋ฌด ์–ด๋””์—๋„ ์†ํ•˜์ง€ ์•Š๋Š” ๊ณ„ํš๋œ ์ž‘์—…
3
+ labels: ["task"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: ์„ค๋ช…
9
+ description: ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: done
15
+ attributes:
16
+ label: ์™„๋ฃŒ ์กฐ๊ฑด
17
+ description: ๋๋‚ฌ๋‹ค๋Š” ๊ฑธ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‚˜์š”?
18
+ placeholder: |
19
+ - [ ] ...
20
+ - [ ] ...
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: context
26
+ attributes:
27
+ label: ๋งฅ๋ฝ
28
+ description: ๊ด€๋ จ ์ด์Šˆ, PR, ๋งํฌ. ์„ ํƒ.
29
+ validations:
30
+ required: false
@@ -0,0 +1,33 @@
1
+ ## ์š”์•ฝ
2
+
3
+ <!-- ๋ฌด์—‡์„ ์™œ ๋ฐ”๊พธ๋‚˜์š”? ๋‹ซ๋Š” ์ด์Šˆ๋ฅผ ์ ์–ด ์ฃผ์„ธ์š”. ์˜ˆ: "Closes #12" -->
4
+
5
+ ## ๋ณ€๊ฒฝ ์ข…๋ฅ˜
6
+
7
+ <!-- ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ์„ ๋ชจ๋‘ ์ฒดํฌํ•˜์„ธ์š”. -->
8
+
9
+ - [ ] `fix` โ€” ๋ฒ„๊ทธ ์ˆ˜์ •
10
+ - [ ] `feature` โ€” ์ƒˆ ๋ช…๋ น, ์˜ต์…˜, ์—”๋“œํฌ์ธํŠธ
11
+ - [ ] `docs` โ€” ๋ฌธ์„œ๋งŒ
12
+ - [ ] `chore` โ€” ์˜์กด์„ฑ, ๋„๊ตฌ, ์„ค์ •, ์ •๋ฆฌ
13
+ - [ ] `task` โ€” ๊ทธ ๋ฐ–์˜ ์ž‘์—…
14
+
15
+ ## ์˜ํ–ฅ ๋ฒ”์œ„
16
+
17
+ <!-- ์˜ˆ: src/velogger/service/posts.py, cli ์ถœ๋ ฅ. ๋ฌธ์„œยท๋„๊ตฌ๋งŒ ๋ฐ”๊ฟจ๋‹ค๋ฉด "์—†์Œ". -->
18
+
19
+ ## ์–ด๋–ป๊ฒŒ ํ…Œ์ŠคํŠธํ–ˆ๋‚˜์š”?
20
+
21
+ <!-- ์‹ค์ œ๋กœ ์‹คํ–‰ํ•œ ๊ฒƒ์„ ์ ์–ด ์ฃผ์„ธ์š”. ์‹ค์ œ API ๋กœ ํ™•์ธํ•œ ๋ช…๋ น(CLI ์ง์ ‘ ์กฐํšŒ)์„ ๋จผ์ €, ๋Œ๋ฆฐ pytest ๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๋‹ค์Œ์—.
22
+ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด ๋“œ๋ฌธ ์—ฃ์ง€์ผ€์ด์Šค์ธ์ง€ ํ•ต์‹ฌ ๋™์ž‘์ธ์ง€ ์ ์–ด ์ฃผ์„ธ์š”. "ํ…Œ์ŠคํŠธ ์•ˆ ํ•จ"๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค โ€” ๊ทธ๋ ‡๋‹ค๊ณ  ์ ์–ด ์ฃผ์„ธ์š”. -->
23
+
24
+ ## ์ฒดํฌ๋ฆฌ์ŠคํŠธ
25
+
26
+ - [ ] [references/code-style.md](https://github.com/Rukkakka/velogger/blob/main/references/code-style.md) ๋ฅผ ๋”ฐ๋ฅธ๋‹ค
27
+ - [ ] ์ƒˆ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฐ”๊พผ ์—”๋“œํฌ์ธํŠธ๊ฐ€ [references/provider-conventions.md](https://github.com/Rukkakka/velogger/blob/main/references/provider-conventions.md) ๋ฅผ ๋”ฐ๋ฅธ๋‹ค
28
+ - [ ] ๋ช…๋ นยท์˜ต์…˜ยท์ถœ๋ ฅ ํ•„๋“œยท์—๋Ÿฌ ์ฝ”๋“œยท์š”์ฒญ ์ œํ•œ์ด ๋ฐ”๋€Œ์—ˆ๋‹ค๋ฉด `docs/<source>.md`ยท`docs/common.md` ์™€ [references/output-contract.md](https://github.com/Rukkakka/velogger/blob/main/references/output-contract.md) ๋ฅผ ๊ณ ์ณค๋‹ค
29
+ - [ ] ๋ช…๋ น์„ ์ถ”๊ฐ€ยท์‚ญ์ œํ–ˆ๊ฑฐ๋‚˜ ์—์ด์ „ํŠธ๊ฐ€ ํ‹€๋ฆฌ๊ธฐ ์‰ฌ์šด ํ•ด์„ ๊ทœ์น™์ด ๋ฐ”๋€Œ์—ˆ๋‹ค๋ฉด `docs/llm.md` ๋ฅผ ๊ณ ์ณค๋‹ค
30
+ - [ ] ๋ช…๋ น์„ ์ถ”๊ฐ€ยท์‚ญ์ œํ–ˆ๋‹ค๋ฉด ๋งค์ผ API ๊ฐ์‹œ ๋ชฉ๋ก(`scripts/monitor/api_check.py` ์˜ `STEPS`, ๊ฐ์‹œํ•˜์ง€ ์•Š์œผ๋ฉด `NOT_MONITORED` ์— ์ด์œ )๋„ ๊ณ ์ณค๋‹ค
31
+ - [ ] ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” ๋ณ€๊ฒฝ์ด๋ฉด `CHANGELOG.md` ์˜ `Unreleased` ์— ์ ์—ˆ๋‹ค ([์“ฐ๋Š” ๋ฒ•](https://github.com/Rukkakka/velogger/blob/main/references/release.md#changelog-์“ฐ๋Š”-๋ฒ•))
32
+ - [ ] ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ยท์ด๋ฆ„ ๋ณ€๊ฒฝยท์‚ญ์ œํ–ˆ๋‹ค๋ฉด `AGENTS.md` ๊ตฌ์กฐ ํ‘œ์™€ ํ•ด๋‹น `references/providers/<source>.md` ๋ฅผ ๊ณ ์ณค๋‹ค
33
+ - [ ] ์ƒˆ ํ”ฝ์Šค์ฒ˜์™€ diff ์— ํ† ํฐยท์ฟ ํ‚คยท์ด๋ฉ”์ผ ๊ฐ™์€ ๊ฐœ์ธ์ •๋ณด๊ฐ€ ์—†๋‹ค
@@ -0,0 +1,81 @@
1
+ # ๋งค์ผ ์ƒˆ๋ฒฝ velogger ์˜ ๋กœ๊ทธ์ธ ์—†๋Š” ์กฐํšŒ ๋ช…๋ น์„ ์‹ค์ œ๋กœ ๋ถˆ๋Ÿฌ ๋น„๊ณต์‹ API ๊ฐ€ ๊นจ์กŒ๋Š”์ง€ ๋ณธ๋‹ค (scripts/monitor/api_check.py,
2
+ # references/development.md '๋งค์ผ API ๊ฐ์‹œ'). ๊ณ ์žฅ์ด๋ฉด api-broken ์ด์Šˆ๋ฅผ ์—ด๊ณ (์—ด๋ ค ์žˆ์œผ๋ฉด ๋Œ“๊ธ€) ์‹คํ–‰์„ ์‹คํŒจ๋กœ ๋๋‚ด GitHub ์ด ๋ฉ”์ผ๋กœ ์•Œ๋ฆฐ๋‹ค.
3
+ # ์š”์ฒญ ์ œํ•œยท์„œ๋ฒ„ ์˜ค๋ฅ˜๋Š” ๊ณ ์žฅ์ด ์•„๋‹ˆ๋ผ 'ํ™•์ธ ๋ชป ํ•จ'์ด๊ณ , ์‚ฌํ˜ ์—ฐ์† ๊ทธ๋Ÿฌ๋ฉด api-blocked ์ด์Šˆ๋กœ ์•Œ๋ฆฐ๋‹ค.
4
+ # ๋กœ๊ทธ์ธยท์“ฐ๊ธฐ(publishยทlikeยทcomment)๋Š” ๋ถ€์ž‘์šฉ์ด ์žˆ๊ณ  CI ์— ์„ธ์…˜๋„ ์—†์–ด ๊ฐ์‹œ์— ๋„ฃ์ง€ ์•Š๋Š”๋‹ค.
5
+ # ๊ฐ์‹œ ํŒŒ์ผ์„ ๊ณ ์นœ PR ์—์„œ๋„ ๋Œ์ง€๋งŒ ์ด์Šˆ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. CI(ci.yml)๋Š” ์—ฌ์ „ํžˆ ์‹ค์ œ API ๋ฅผ ๋ถ€๋ฅด์ง€ ์•Š๋Š”๋‹ค.
6
+ # ์žก ์ด๋ฆ„์€ main ๋ณดํ˜ธ ๊ทœ์น™์˜ ํ•„์ˆ˜ ๊ฒ€์‚ฌ๊ฐ€ ์•„๋‹ˆ๋‹ค (๋ง‰ํžŒ ๋‚ ์—๋„ PR ์„ ๋จธ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ). jibsa ์˜ ๊ฐ์‹œ๋ฅผ ์˜ฎ๊ฒผ๋‹ค.
7
+ name: API ๊ฐ์‹œ
8
+
9
+ on:
10
+ schedule:
11
+ # ํ•œ๊ตญ ์‹œ๊ฐ„ ๋งค์ผ 04:17. ์ •๊ฐ์€ ์˜ˆ์•ฝ ์‹คํ–‰์ด ๋ชฐ๋ ค ๋Šฆ๊ฑฐ๋‚˜ ๋น ์ง„๋‹ค
12
+ - cron: '17 19 * * *'
13
+ workflow_dispatch:
14
+ pull_request:
15
+ paths:
16
+ - 'scripts/monitor/**'
17
+ - '.github/workflows/api-monitor.yml'
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ concurrency:
23
+ group: api-monitor-${{ github.ref }}
24
+
25
+ jobs:
26
+ check:
27
+ name: ์กฐํšŒ ๋ช…๋ น ์‹ค์ œ ํ˜ธ์ถœ
28
+ runs-on: ubuntu-latest
29
+ timeout-minutes: 30
30
+ env:
31
+ PYTHONUTF8: '1'
32
+ steps:
33
+ - uses: actions/checkout@v7
34
+ - uses: actions/setup-python@v7
35
+ with:
36
+ python-version: '3.11'
37
+ cache: pip
38
+ cache-dependency-path: pyproject.toml
39
+ # PyPI ๋ฆด๋ฆฌ์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์ด ์ปค๋ฐ‹์˜ ์ฝ”๋“œ๋ฅผ, ํŽธ์ง‘ ๊ฐ€๋Šฅ ์„ค์น˜๊ฐ€ ์•„๋‹ˆ๋ผ ์„ค์น˜๋ณธ ๊ทธ๋Œ€๋กœ ๋ณธ๋‹ค
40
+ - run: pip install .
41
+ - run: python scripts/monitor/api_check.py run --out result.json
42
+ - uses: actions/upload-artifact@v7
43
+ with:
44
+ name: result
45
+ path: result.json
46
+ retention-days: 7
47
+
48
+ report:
49
+ name: ๊ฒฐ๊ณผ ์ •๋ฆฌ
50
+ needs: check
51
+ # ์กฐํšŒ ์žก์ด ์‹คํŒจํ•ด๋„ ์ •๋ฆฌํ•œ๋‹ค (๊ฒฐ๊ณผ ํŒŒ์ผ์ด ์—†์œผ๋ฉด ๊ณ ์žฅ์œผ๋กœ ๋ณธ๋‹ค)
52
+ if: always()
53
+ runs-on: ubuntu-latest
54
+ permissions:
55
+ contents: read
56
+ issues: write
57
+ # ์•ž์„  ์‹คํ–‰์˜ ๊ฒฐ๊ณผ ํŒŒ์ผ์„ ๋‚ด๋ ค๋ฐ›์•„ ์—ฐ์† ํ™•์ธ ๋ชป ํ•จ์„ ์„ผ๋‹ค
58
+ actions: read
59
+ env:
60
+ PYTHONUTF8: '1'
61
+ GH_TOKEN: ${{ github.token }}
62
+ GH_REPO: ${{ github.repository }}
63
+ steps:
64
+ - uses: actions/checkout@v7
65
+ - uses: actions/setup-python@v7
66
+ with:
67
+ python-version: '3.11'
68
+ - uses: actions/download-artifact@v8
69
+ # ์กฐํšŒ ์žก์ด ์‹คํŒจํ•ด ๊ฒฐ๊ณผ ํŒŒ์ผ์ด ์—†์–ด๋„ ์ •๋ฆฌ ๋‹จ๊ณ„๋Š” ๋ˆ๋‹ค
70
+ continue-on-error: true
71
+ with:
72
+ name: result
73
+ path: results
74
+ - name: ํ‘œ ๋‚จ๊ธฐ๊ธฐยท์ด์Šˆ ๊ณ ์น˜๊ธฐ
75
+ run: python scripts/monitor/api_check.py report results/result.json ${{ github.event_name != 'pull_request' && '--issues' || '' }}
76
+ - uses: actions/upload-artifact@v7
77
+ if: always()
78
+ with:
79
+ name: report
80
+ path: report.json
81
+ retention-days: 7
@@ -0,0 +1,91 @@
1
+ # PR ๊ณผ main push ๋งˆ๋‹ค ๋ฆฐํŠธยทํƒ€์ž… ๊ฒ€์‚ฌยท์ „์ฒด pytestยท์„ค์น˜๋ณธ์„ ํ™•์ธํ•œ๋‹ค. ๋ฐฐํฌ(release.yml)๋„ ์ด ์›Œํฌํ”Œ๋กœ๋ฅผ ๋ถˆ๋Ÿฌ ๊ฐ™์€ ๊ฒ€์‚ฌ๋ฅผ
2
+ # ํ†ต๊ณผํ•œ ๋นŒ๋“œ๋งŒ ์˜ฌ๋ฆฐ๋‹ค. ์žก ์ด๋ฆ„์€ main ๋ณดํ˜ธ ๊ทœ์น™์˜ ํ•„์ˆ˜ ๊ฒ€์‚ฌ๋ผ ๋ฐ”๊พธ๋ฉด ๋ณดํ˜ธ ๊ทœ์น™๋„ ๊ฐ™์ด ๊ณ ์นœ๋‹ค.
3
+ # ํ…Œ์ŠคํŠธ๋Š” ๊ฐ€์งœ ์‘๋‹ต๋งŒ ์“ฐ๊ณ  ์‹ค์ œ API ๋Š” ๋ถ€๋ฅด์ง€ ์•Š๋Š”๋‹ค (references/development.md '๊ฒ€์ฆ๊ณผ ํ…Œ์ŠคํŠธ').
4
+ name: CI
5
+
6
+ on:
7
+ push:
8
+ branches: [main]
9
+ pull_request:
10
+ workflow_call:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ concurrency:
16
+ group: ci-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ lint:
21
+ name: ๋ฆฐํŠธยทํƒ€์ž… ๊ฒ€์‚ฌ
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ - uses: actions/setup-python@v7
26
+ with:
27
+ python-version: '3.11'
28
+ cache: pip
29
+ cache-dependency-path: pyproject.toml
30
+ - run: pip install -e '.[dev]'
31
+ - run: ruff check
32
+ - run: mypy
33
+ - name: docs/llm.md 200์ค„ ์ดํ•˜
34
+ run: |
35
+ lines=$(wc -l < docs/llm.md)
36
+ echo "docs/llm.md: ${lines}์ค„"
37
+ if [ "$lines" -gt 200 ]; then
38
+ echo "::error file=docs/llm.md::${lines}์ค„์ž…๋‹ˆ๋‹ค. 200์ค„ ์ดํ•˜๋กœ ์ค„์ด์„ธ์š” (AGENTS.md '๋ฌธ์„œ ๊ฐฑ์‹ ')"
39
+ exit 1
40
+ fi
41
+
42
+ test:
43
+ name: pytest (${{ matrix.os }}, Python ${{ matrix.python }})
44
+ runs-on: ${{ matrix.os }}
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ os: [ubuntu-latest, macos-latest, windows-latest]
49
+ # ์ง€์›ํ•˜๋Š” ๊ฐ€์žฅ ๋‚ฎ์€ ๋ฒ„์ „๊ณผ ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „
50
+ python: ['3.11', '3.14']
51
+ env:
52
+ # README ์˜ Windows ์„ค์ •(setx PYTHONUTF8 1)๊ณผ ๊ฐ™๊ฒŒ ํ•œ๋‹ค. macOSยทLinux ๋Š” ์›๋ž˜ UTF-8 ์ด๋‹ค
53
+ PYTHONUTF8: '1'
54
+ steps:
55
+ - uses: actions/checkout@v7
56
+ - uses: actions/setup-python@v7
57
+ with:
58
+ python-version: ${{ matrix.python }}
59
+ cache: pip
60
+ cache-dependency-path: pyproject.toml
61
+ - run: pip install -e '.[dev]'
62
+ - run: pytest
63
+
64
+ package:
65
+ name: ์„ค์น˜๋ณธ ํ™•์ธ
66
+ runs-on: ubuntu-latest
67
+ steps:
68
+ - uses: actions/checkout@v7
69
+ - uses: actions/setup-python@v7
70
+ with:
71
+ python-version: '3.11'
72
+ - run: pip install build twine
73
+ - run: python -m build
74
+ # README ๊ฐ€ PyPI ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์—์„œ ๋ Œ๋”๋ง๋˜๋Š”์ง€ (์ƒ๋Œ€ ๋งํฌ๋Š” ์žก์ง€ ๋ชปํ•œ๋‹ค)
75
+ - run: twine check --strict dist/*
76
+ # ํŽธ์ง‘ ๊ฐ€๋Šฅ ์„ค์น˜์™€ ๋‹ฌ๋ฆฌ docs/llm.mdยท์†Œ์Šค ๋ฌธ์„œ๋ฅผ ํŒจํ‚ค์ง€ ์•ˆ ์‚ฌ๋ณธ์œผ๋กœ ์ฝ์œผ๋ฏ€๋กœ ์‚ฌ๋ณธ์ด ๋น ์ง€๊ฑฐ๋‚˜ ๋‹ค๋ฅด๋ฉด ์—ฌ๊ธฐ์„œ ๋“œ๋Ÿฌ๋‚œ๋‹ค
77
+ - name: ์ƒˆ ๊ฐ€์ƒํ™˜๊ฒฝ์— ์„ค์น˜ํ•ด ์‹คํ–‰
78
+ run: |
79
+ python -m venv "$RUNNER_TEMP/velogger-check"
80
+ "$RUNNER_TEMP/velogger-check/bin/pip" install dist/*.whl
81
+ "$RUNNER_TEMP/velogger-check/bin/velogger" --version
82
+ "$RUNNER_TEMP/velogger-check/bin/velogger" guide > "$RUNNER_TEMP/guide.md"
83
+ diff "$RUNNER_TEMP/guide.md" docs/llm.md
84
+ for topic in common velogger; do
85
+ "$RUNNER_TEMP/velogger-check/bin/velogger" guide "$topic" > "$RUNNER_TEMP/$topic.md"
86
+ diff "$RUNNER_TEMP/$topic.md" "docs/$topic.md"
87
+ done
88
+ - uses: actions/upload-artifact@v7
89
+ with:
90
+ name: dist
91
+ path: dist/
@@ -0,0 +1,82 @@
1
+ # v* ํƒœ๊ทธ๋ฅผ push ํ•˜๋ฉด PyPI ์™€ GitHub Release ๋กœ ๋ฐฐํฌํ•œ๋‹ค (references/release.md '๋ฆด๋ฆฌ์Šค ์ ˆ์ฐจ').
2
+ # PyPI ๋Š” API ํ† ํฐ ์—†์ด ์‹ ๋ขฐ ๊ฒŒ์‹œ(Trusted Publishing)๋กœ ์˜ฌ๋ฆฐ๋‹ค. pypi.org ์˜ ๊ฒŒ์‹œ์ž ์„ค์ •์€ ํ”„๋กœ์ ํŠธ velogger,
3
+ # ์ €์žฅ์†Œ Rukkakka/velogger, ์›Œํฌํ”Œ๋กœ release.yml, ํ™˜๊ฒฝ pypi ์ด๊ณ  GitHub ํ™˜๊ฒฝ pypi ๋Š” v* ํƒœ๊ทธ์—์„œ๋งŒ ๋ฐฐํฌ๋ฅผ ๋ฐ›๋Š”๋‹ค.
4
+ name: Release
5
+
6
+ on:
7
+ push:
8
+ tags: ['v*']
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ tag:
15
+ name: ํƒœ๊ทธ ํ™•์ธ
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v7
19
+ with:
20
+ # ํƒœ๊ทธ ์ปค๋ฐ‹์ด main ์— ์žˆ๋Š”์ง€ ๋ณด๋ ค๊ณ  main ๊ธฐ๋ก๊นŒ์ง€ ๋ฐ›๋Š”๋‹ค
21
+ fetch-depth: 0
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: '3.11'
25
+ - name: ํƒœ๊ทธ๊ฐ€ main ์— ์žˆ๊ณ  pyproject.toml ๋ฒ„์ „ยทCHANGELOG ์ ˆ๊ณผ ๋งž๋Š”์ง€
26
+ run: |
27
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
28
+ echo "::error::$GITHUB_REF_NAME ์ด main ์— ์—†๋Š” ์ปค๋ฐ‹์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ํƒœ๊ทธ๋Š” ๋จธ์ง€ ๋’ค main ์—๋งŒ ๋‹จ๋‹ค"
29
+ exit 1
30
+ fi
31
+ version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
32
+ if [ "v$version" != "$GITHUB_REF_NAME" ]; then
33
+ echo "::error::ํƒœ๊ทธ $GITHUB_REF_NAME ์™€ pyproject.toml ๋ฒ„์ „ $version ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค"
34
+ exit 1
35
+ fi
36
+ if ! grep -q "^## $version โ€” " CHANGELOG.md; then
37
+ echo "::error::CHANGELOG.md ์— '## $version โ€” ๋‚ ์งœ' ์ ˆ์ด ์—†์Šต๋‹ˆ๋‹ค"
38
+ exit 1
39
+ fi
40
+
41
+ ci:
42
+ name: CI
43
+ needs: tag
44
+ uses: ./.github/workflows/ci.yml
45
+
46
+ pypi:
47
+ name: PyPI ์— ์˜ฌ๋ฆฌ๊ธฐ
48
+ needs: ci
49
+ runs-on: ubuntu-latest
50
+ environment:
51
+ name: pypi
52
+ url: https://pypi.org/project/velogger/
53
+ permissions:
54
+ # ์‹ ๋ขฐ ๊ฒŒ์‹œ์˜ OIDC ํ† ํฐ
55
+ id-token: write
56
+ steps:
57
+ # CI ์˜ ์„ค์น˜๋ณธ ํ™•์ธ์ด ๋นŒ๋“œยทํ™•์ธํ•œ ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ ์˜ฌ๋ฆฐ๋‹ค
58
+ - uses: actions/download-artifact@v8
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+ - uses: pypa/gh-action-pypi-publish@release/v1
63
+
64
+ github-release:
65
+ name: GitHub Release
66
+ needs: pypi
67
+ runs-on: ubuntu-latest
68
+ permissions:
69
+ contents: write
70
+ steps:
71
+ - uses: actions/checkout@v7
72
+ - uses: actions/download-artifact@v8
73
+ with:
74
+ name: dist
75
+ path: dist/
76
+ - name: CHANGELOG ์˜ ๊ทธ ๋ฒ„์ „ ์ ˆ๋กœ Release ๋งŒ๋“ค๊ธฐ
77
+ env:
78
+ GH_TOKEN: ${{ github.token }}
79
+ run: |
80
+ version="${GITHUB_REF_NAME#v}"
81
+ awk -v head="## $version " 'index($0, head) == 1 {f=1; next} /^## /{if (f) exit} f' CHANGELOG.md > "$RUNNER_TEMP/notes.md"
82
+ gh release create "$GITHUB_REF_NAME" --verify-tag --title "$GITHUB_REF_NAME" --notes-file "$RUNNER_TEMP/notes.md" dist/*