Skip to content

Commit e980e92

Browse files
sjnimsclaude
andcommitted
chore: improve workflow consistency and add YAML linting
- semantic-labeler: add dynamic label fetching, mutually-exclusive handling, model specification, persist-credentials - stale: add timeout, exempt active work labels, exempt assignees/drafts - sync-labels: add timeout and persist-credentials - validate-workflows: add persist-credentials - yaml-lint: new workflow to enforce .yamllint.yml in CI - Remove unused weekly-maintenance workflow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8f4cc25 commit e980e92

6 files changed

Lines changed: 124 additions & 284 deletions

File tree

Lines changed: 57 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# yamllint disable rule:line-length
12
name: Semantic Labeler
23

34
# Claude-powered semantic labeling for both issues and PRs
@@ -34,81 +35,49 @@ jobs:
3435
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3536
with:
3637
fetch-depth: 1
38+
persist-credentials: false
3739

3840
- name: Label issue with Claude
41+
id: labeler
3942
uses: anthropics/claude-code-action@f64219702d7454cf29fe32a74104be6ed43dc637 # v1.0.34
4043
with:
4144
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
4245
prompt: |
43-
Analyze this GitHub issue and apply appropriate labels.
46+
Label GitHub issue #${{ github.event.issue.number }}.
4447
45-
## Issue Details
46-
- Repository: ${{ github.repository }}
47-
- Issue #${{ github.event.issue.number }}
48-
- Title: ${{ github.event.issue.title }}
49-
- Author: ${{ github.event.issue.user.login }}
50-
51-
## Issue Body
48+
**Title**: ${{ github.event.issue.title }}
49+
**Author**: ${{ github.event.issue.user.login }}
50+
**Body**:
5251
${{ github.event.issue.body }}
5352
5453
## Instructions
5554
56-
Based on the issue content, determine and apply appropriate labels using `gh issue edit`.
57-
58-
### Label Categories
59-
60-
**TYPE (choose ONE):**
61-
- `bug` - Something isn't working correctly
62-
- `enhancement` - New feature or improvement request
63-
- `documentation` - Documentation improvements or additions
64-
- `question` - Asking for help or clarification
65-
- `refactor` - Code restructuring without behavior change
66-
- `chore` - Maintenance tasks (dependencies, CI, etc.)
67-
68-
**COMPONENT (choose ALL that apply based on what the issue discusses):**
69-
- `component:command` - Related to /plugin-dev:* slash commands
70-
- `component:skill` - Related to methodology skills
71-
- `component:agent` - Related to agents
72-
- `component:hook` - Related to hooks
73-
- `component:docs` - General documentation
74-
- `github-actions` - CI/CD and GitHub workflows
75-
76-
**PRIORITY (choose ONE based on impact/urgency):**
77-
- `priority:critical` - Blocking, security issues, or data loss
78-
- `priority:high` - Significant impact, should address soon
79-
- `priority:medium` - Moderate impact, normal priority
80-
- `priority:low` - Minor issues, nice to have
81-
82-
**EFFORT (choose ONE based on estimated complexity):**
83-
- `effort:small` - < 1 hour of work
84-
- `effort:medium` - 1-4 hours of work
85-
- `effort:large` - > 4 hours of work
86-
87-
**IMPACT (only if applicable):**
88-
- `breaking` - Would require breaking changes
89-
- `security` - Security-related issue
90-
91-
**COMMUNITY (only if clearly appropriate):**
92-
- `good first issue` - Simple, well-documented, good for newcomers
93-
- `help wanted` - Could use community contribution
94-
95-
### Rules
96-
1. Always apply exactly ONE type label
97-
2. Always apply exactly ONE priority label
98-
3. Always apply exactly ONE effort label
99-
4. Apply component labels only if clearly related
100-
5. Apply impact/community labels only when clearly applicable
101-
6. Don't guess - if unsure about a category, skip it (except required ones)
102-
103-
### Execution
104-
Apply labels using:
55+
1. **Get available labels**: `gh label list --json name,description -q '.[] | "\(.name): \(.description)"'`
56+
2. **Get current labels**: `gh issue view ${{ github.event.issue.number }} --json labels -q '.labels[].name'`
57+
3. **Analyze** the issue content and determine appropriate labels
58+
4. **Apply labels** using `gh issue edit`, removing conflicting mutually-exclusive labels first
59+
60+
## Label Rules (see .github/LABELS.md for full details)
61+
62+
**Required (exactly ONE each):**
63+
- TYPE: bug | enhancement | documentation | question | refactor | chore
64+
- PRIORITY: priority:critical | priority:high | priority:medium | priority:low
65+
- EFFORT: effort:small | effort:medium | effort:large
66+
67+
**Contextual (apply only if clearly relevant):**
68+
- COMPONENT: component:skill | component:agent | component:command | component:hook | component:docs | github-actions
69+
- SPECIAL: breaking | security
70+
- COMMUNITY: help wanted | good first issue (only if clearly appropriate)
71+
72+
## Execution
73+
74+
For mutually exclusive categories (type, priority, effort), remove existing labels before adding new ones:
10575
```bash
106-
gh issue edit ${{ github.event.issue.number }} --add-label "label1,label2,label3"
76+
gh issue edit ${{ github.event.issue.number }} --remove-label "priority:low" --add-label "priority:high,bug,effort:medium"
10777
```
10878
10979
After applying labels, briefly explain your reasoning.
110-
claude_args: |
111-
--allowedTools "Bash(gh issue:*)"
80+
claude_args: '--model claude-opus-4-5-20251101 --allowedTools "Bash(gh label:*),Bash(gh issue:*)"'
11281

11382
label-pr:
11483
name: Label Pull Request
@@ -129,73 +98,46 @@ jobs:
12998
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
13099
with:
131100
fetch-depth: 1
101+
persist-credentials: false
132102

133103
- name: Label PR with Claude
104+
id: labeler
134105
uses: anthropics/claude-code-action@f64219702d7454cf29fe32a74104be6ed43dc637 # v1.0.34
135106
with:
136107
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
137108
prompt: |
138-
Analyze this pull request and apply appropriate labels.
109+
Label pull request #${{ github.event.pull_request.number }}.
139110
140-
## PR Details
141-
- Repository: ${{ github.repository }}
142-
- PR #${{ github.event.pull_request.number }}
143-
- Title: ${{ github.event.pull_request.title }}
144-
- Author: ${{ github.event.pull_request.user.login }}
145-
146-
## PR Description
111+
**Title**: ${{ github.event.pull_request.title }}
112+
**Author**: ${{ github.event.pull_request.user.login }}
113+
**Description**:
147114
${{ github.event.pull_request.body }}
148115
149116
## Instructions
150117
151-
1. First, get the PR diff to understand what changed:
152-
```bash
153-
gh pr diff ${{ github.event.pull_request.number }}
154-
```
155-
156-
2. Analyze the changes and apply appropriate labels.
157-
158-
### Label Categories
159-
160-
**TYPE (choose ONE based on the nature of changes):**
161-
- `enhancement` - New feature or capability
162-
- `bug` - Bug fix
163-
- `documentation` - Documentation-only changes
164-
- `refactor` - Code restructuring without behavior change
165-
- `chore` - Maintenance (dependencies, CI config, tooling)
166-
167-
**COMPONENT (choose ALL that apply based on files changed):**
168-
- `component:command` - Changes to `plugins/plugin-dev/commands/**`
169-
- `component:skill` - Changes to `plugins/plugin-dev/skills/**`
170-
- `component:agent` - Changes to `plugins/plugin-dev/agents/**`
171-
- `component:hook` - Changes to `plugins/plugin-dev/hooks/**`
172-
- `component:docs` - Changes to root-level `*.md` or `.github/**/*.md`
173-
- `github-actions` - Changes to `.github/workflows/**` (except labeler configs)
174-
- `dependencies` - Changes to `.github/dependabot.yml`
175-
176-
**EFFORT (choose ONE based on diff size and complexity):**
177-
- `effort:small` - Few files, simple changes
178-
- `effort:medium` - Multiple files, moderate complexity
179-
- `effort:large` - Many files, significant changes, or architectural impact
180-
181-
**IMPACT (only if applicable):**
182-
- `breaking` - Contains breaking changes to existing functionality or APIs
183-
- `security` - Security-related changes
184-
185-
### Rules
186-
1. Always apply exactly ONE type label
187-
2. Apply component labels based on actual files changed
188-
3. Always apply exactly ONE effort label
189-
4. Apply impact labels only when clearly applicable
190-
5. For type, infer from the PR title/description and nature of changes
191-
192-
### Execution
193-
Apply labels using:
118+
1. **Get available labels**: `gh label list --json name,description -q '.[] | "\(.name): \(.description)"'`
119+
2. **Get current labels**: `gh pr view ${{ github.event.pull_request.number }} --json labels -q '.labels[].name'`
120+
3. **Get the PR diff** to understand what changed: `gh pr diff ${{ github.event.pull_request.number }}`
121+
4. **Read key modified files** to understand context - use Read and Glob tools to examine important changed files in detail
122+
5. **Analyze** the changes and determine appropriate labels
123+
6. **Apply labels** using `gh pr edit`, removing conflicting mutually-exclusive labels first
124+
125+
## Label Rules (see .github/LABELS.md for full details)
126+
127+
**Required (exactly ONE each):**
128+
- TYPE (based on nature of changes): bug | enhancement | documentation | refactor | chore
129+
- EFFORT (based on diff size/complexity): effort:small | effort:medium | effort:large
130+
131+
**Contextual (apply based on files changed):**
132+
- COMPONENT: component:skill (skills/**) | component:agent (agents/**) | component:command (commands/**) | component:hook (hooks/**) | component:docs (*.md, .github/**/*.md) | github-actions (.github/workflows/**)
133+
- SPECIAL: breaking | security
134+
135+
## Execution
136+
137+
For mutually exclusive categories (type, effort), remove existing labels before adding new ones:
194138
```bash
195-
gh pr edit ${{ github.event.pull_request.number }} --add-label "label1,label2,label3"
139+
gh pr edit ${{ github.event.pull_request.number }} --remove-label "effort:small" --add-label "effort:medium,enhancement,component:skill"
196140
```
197141
198142
After applying labels, briefly explain your reasoning.
199-
# PR job needs Read,Glob to analyze file changes for accurate component detection
200-
claude_args: |
201-
--allowedTools "Bash(gh pr:*),Read,Glob"
143+
claude_args: '--model claude-opus-4-5-20251101 --allowedTools "Bash(gh label:*),Bash(gh pr:*),Read,Glob"'

.github/workflows/stale.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Manage Stale Issues and PRs
22

33
on:
44
schedule:
5-
- cron: '0 0 * * 1,3,5' # Mon/Wed/Fri at midnight UTC
5+
- cron: "0 0 * * 1,3,5" # Mon/Wed/Fri at midnight UTC
66
workflow_dispatch:
77

88
concurrency:
@@ -16,18 +16,31 @@ permissions:
1616
jobs:
1717
stale:
1818
runs-on: ubuntu-latest
19+
timeout-minutes: 10
1920
steps:
2021
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
2122
with:
22-
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
23-
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.'
24-
close-issue-message: 'This issue was closed because it has been stale for 7 days with no activity.'
25-
close-pr-message: 'This PR was closed because it has been stale for 7 days with no activity.'
23+
stale-issue-message: >-
24+
This issue has been automatically marked as stale because it has
25+
not had recent activity. It will be closed if no further activity
26+
occurs. Thank you for your contributions.
27+
stale-pr-message: >-
28+
This PR has been automatically marked as stale because it has not
29+
had recent activity. It will be closed if no further activity
30+
occurs.
31+
close-issue-message: >-
32+
This issue was closed because it has been stale for 7 days with
33+
no activity.
34+
close-pr-message: >-
35+
This PR was closed because it has been stale for 7 days with no
36+
activity.
2637
days-before-stale: 60
2738
days-before-close: 7
28-
stale-issue-label: 'stale'
29-
stale-pr-label: 'stale'
30-
exempt-issue-labels: 'pinned,security,roadmap'
31-
exempt-pr-labels: 'pinned,security'
32-
operations-per-run: 100 # Limit API calls per run to avoid rate limiting
33-
enable-statistics: true # Log statistics for monitoring
39+
stale-issue-label: "stale"
40+
stale-pr-label: "stale"
41+
exempt-issue-labels: "pinned,security,roadmap,bug,priority:critical,status:in-progress,status:blocked"
42+
exempt-pr-labels: "pinned,security,status:in-progress,status:blocked"
43+
exempt-all-issue-assignees: true
44+
exempt-draft-pr: true
45+
operations-per-run: 100
46+
enable-statistics: true

.github/workflows/sync-labels.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ jobs:
1919
sync:
2020
name: Sync Labels from labels.yml
2121
runs-on: ubuntu-latest
22+
timeout-minutes: 5
2223
permissions:
2324
issues: write
2425
steps:
2526
- name: Checkout code
2627
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
28+
with:
29+
persist-credentials: false
2730

2831
- name: Sync labels
2932
# Uses GITHUB_TOKEN automatically (provided by GitHub Actions)

.github/workflows/validate-workflows.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ jobs:
2626
steps:
2727
- name: Checkout code
2828
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29+
with:
30+
persist-credentials: false
2931

3032
- name: Run actionlint with reviewdog
3133
uses: reviewdog/action-actionlint@83e4ed25b168066ad8f62f5afbb29ebd8641d982 # v1.69.1

0 commit comments

Comments
 (0)