Skip to content

Commit d89cca3

Browse files
nsheapsclaude
andauthored
fix: improve version bump workflow and CI integration (#73)
* docs: update changelog with version bump improvements * fix: improve version bump preview to show only changed plugins Previously showed all plugins with confusing 'major' type and empty next versions. Now compares base branch (main) vs HEAD to show actual version changes in PR. Changes: - Compare plugin.json versions between branches - Only show plugins that actually changed - Show clear before/after versions - Rename 'Current/Next' to 'Base/Head' for clarity * fix: fetch base branch in version bump preview workflow The preview was showing all plugins as new (0.0.0 -> X.Y.Z) because the base branch wasn't fetched. Now fetches full history and base branch so git can properly compare versions between branches. * chore: `just lint` * docs(research): add Claude Code compact customization findings Documents the current limitations around customizing the compact operation in Claude Code, specifically the inability to configure a specific model for compacting. Includes workarounds and feature request recommendations. Co-Authored-By: Claude Code (~/src/nsheaps/ai) <noreply@anthropic.com> * fix: remove duplicate update-marketplace job from ci.yaml The update-marketplace job was running on all events including PRs, causing marketplace.json to be updated inappropriately in PRs. The cd.yaml workflow already has this job correctly gated to only run on main branch after version bumps. This removes the duplicate. * docs: add changelog entry for workflow improvements * chore: `just lint` --------- Co-authored-by: Claude Code (~/src/nsheaps/ai) <noreply@anthropic.com>
1 parent 1cbab6a commit d89cca3

6 files changed

Lines changed: 165 additions & 66 deletions

File tree

.github/workflows/cd.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ jobs:
2727
steps:
2828
- name: Checkout code
2929
uses: actions/checkout@v6
30+
with:
31+
fetch-depth: 0 # Fetch full history for version comparison
32+
33+
- name: Fetch base branch
34+
run: git fetch origin ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}
3035

3136
- name: mise install -y
3237
uses: jdx/mise-action@v2

.github/workflows/ci.yaml

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -57,48 +57,6 @@ jobs:
5757
echo "Changes made or lint failed! Auto-committed the fixes, but more lint and format issues may remain."
5858
exit 1
5959
60-
update-marketplace:
61-
runs-on: ubuntu-latest
62-
permissions:
63-
contents: write
64-
pull-requests: write
65-
steps:
66-
- name: Checkout code
67-
uses: actions/checkout@v6
68-
with:
69-
persist-credentials: false
70-
71-
- name: Authenticate as GitHub App
72-
id: auth
73-
uses: ./.github/actions/github-app-auth
74-
with:
75-
app-id: ${{ secrets.AUTOMATION_GITHUB_APP_ID }}
76-
private-key: ${{ secrets.AUTOMATION_GITHUB_APP_PRIVATE_KEY }}
77-
78-
- name: mise install -y
79-
uses: jdx/mise-action@v2
80-
with:
81-
install: true
82-
cache: true
83-
84-
- name: just update-marketplace
85-
id: update-marketplace
86-
uses: ./.github/actions/update-marketplace
87-
continue-on-error: true
88-
89-
- name: git push
90-
if: steps.update-marketplace.outputs.changed-or-failed == 'true' && ! cancelled()
91-
id: auto-commit-action
92-
uses: stefanzweifel/git-auto-commit-action@v5
93-
with:
94-
commit_message: 'chore: `just update-marketplace`'
95-
96-
- name: 'exit 1 # changes detected or update failed'
97-
if: ${{ steps.update-marketplace.outputs.changed-or-failed == 'true' && ! cancelled() }}
98-
run: |
99-
echo "Changes made or update-marketplace failed! Auto-committed the fixes, but more issues may remain."
100-
exit 1
101-
10260
validate:
10361
runs-on: ubuntu-latest
10462
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Claude Code Compact Customization Research
2+
3+
**Date:** 2026-01-15
4+
**Status:** Documented limitation - feature request recommended
5+
6+
## Question
7+
8+
Is there any way to customize the compacting process in Claude Code to always use a specific model (e.g., Sonnet 1M context) instead of the currently configured model?
9+
10+
## Summary
11+
12+
**No, there is currently no way to configure a specific model for the compact operation.** Compact always uses whatever model is globally configured.
13+
14+
## Findings
15+
16+
### What Exists
17+
18+
#### Hooks
19+
20+
1. **`PreCompact` hook** - Fires before compact operation
21+
- Matchers: `"manual"` or `"auto"` (based on trigger type)
22+
- Input: `{ trigger: "manual" | "auto", custom_instructions?: string }`
23+
- **Limitation:** Can only observe/log, cannot modify the compact operation itself
24+
25+
2. **`SessionStart` hook** - Fires after compact completes
26+
- Matcher: `"compact"` (based on source)
27+
- Can be used to inject context or set environment variables via `CLAUDE_ENV_FILE`
28+
- This is the closest to a "post-compact" hook
29+
30+
#### Custom Instructions
31+
32+
The `/compact` command accepts optional instructions:
33+
34+
```bash
35+
/compact "focus on TODO items and architectural decisions"
36+
```
37+
38+
This influences what gets summarized but not how (model, parameters, etc.).
39+
40+
### What Doesn't Exist
41+
42+
- No `compactModel` setting in `settings.json`
43+
- No `ANTHROPIC_COMPACT_MODEL` environment variable
44+
- No per-operation model override mechanism
45+
- No `PostCompact` hook
46+
- No way to intercept and modify compact parameters via hooks
47+
48+
### Settings Schema Review
49+
50+
The complete `settings.json` schema was reviewed. Compact-related settings are limited to:
51+
52+
- Hook configuration for `PreCompact` event
53+
- Hook configuration for `SessionStart` with `"compact"` source
54+
55+
No model or behavior overrides exist for compacting.
56+
57+
## Workaround
58+
59+
The only current option is to manually switch models before compacting:
60+
61+
```bash
62+
/model sonnet[1m]
63+
/compact
64+
/model opus # switch back if needed
65+
```
66+
67+
This is manual and not automatable via hooks or settings.
68+
69+
## Recommendation
70+
71+
Submit a feature request via `/feedback` for one of:
72+
73+
1. **`compactModel` setting** in `settings.json`:
74+
75+
```json
76+
{
77+
"compactModel": "claude-sonnet-4-20250514"
78+
}
79+
```
80+
81+
2. **Environment variable** `ANTHROPIC_COMPACT_MODEL` or `CLAUDE_COMPACT_MODEL`
82+
83+
3. **PreCompact hook enhancement** allowing return value to specify model override
84+
85+
## References
86+
87+
- [Claude Code Settings Reference](https://docs.anthropic.com/en/docs/claude-code/settings)
88+
- [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks)
89+
- [Claude Code CLI Reference](https://docs.anthropic.com/en/docs/claude-code/cli)
90+
- [The /compact Command Guide](https://deepwiki.com/FlorianBruniaux/claude-code-ultimate-guide/3.2-the-compact-command)

justfile

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,59 +108,92 @@ _preview-version-bump PLUGIN_PATH=invocation_directory():
108108
[arg('format', pattern='--format=raw|--format=md')]
109109
_preview-version-bumps format='--format=raw':
110110
#!/usr/bin/env bash
111-
# takes optional args:
112-
# --format=raw|md : output format for dry-run report (default: raw)
113-
# gets the json, then formats it accordingly.
111+
# Compare plugin versions between base branch (main) and current HEAD
112+
# Shows actual version changes in PR, not predicted future bumps
113+
#
114114
# format with raw:
115115
# plugin-name: 1.2.2 =( patch )=> 1.2.3
116-
# $plugin: $current =( $type )=> $next
117-
# ...
118116
# format with md:
119-
# | Plugin | Current | Type | Next |
117+
# | Plugin | Base | Type | Head |
120118
# |---|---|---|---|
121119
# | plugin-name | 1.2.2 | patch | 1.2.3 |
122-
# ...
120+
121+
# Determine base branch (origin/main in CI, main locally)
122+
BASE_BRANCH="${GITHUB_BASE_REF:-main}"
123+
if ! git rev-parse --verify "origin/$BASE_BRANCH" >/dev/null 2>&1; then
124+
BASE_BRANCH="main"
125+
else
126+
BASE_BRANCH="origin/$BASE_BRANCH"
127+
fi
128+
123129
case "{{format}}" in
124130
--format=md )
125-
echo "| Plugin | Current | Type | Next |"
131+
echo "| Plugin | Base | Type | Head |"
126132
echo "|---|---|---|---|"
127133
;;
128134
esac
135+
136+
FOUND_CHANGES=0
129137
for plugin_dir in plugins/*; do
130138
if [ ! -d "$plugin_dir" ]; then
131139
continue
132140
fi
133141
PLUGIN_NAME=$(basename "$plugin_dir")
134-
CURRENT=$(just _plugin-current-version "$plugin_dir")
135-
NEXT=$(just _plugin-next-version "$plugin_dir")
136-
# determine type of bump
137-
IFS='.' read -r -a current_parts <<< "$CURRENT"
138-
IFS='.' read -r -a next_parts <<< "$NEXT"
139-
if [ "${current_parts[0]}" != "${next_parts[0]}" ]; then
142+
PLUGIN_JSON="$plugin_dir/.claude-plugin/plugin.json"
143+
144+
# Get version from HEAD (current branch)
145+
HEAD_VERSION=$(jq -r '.version' "$PLUGIN_JSON" 2>/dev/null || echo "")
146+
if [ -z "$HEAD_VERSION" ]; then
147+
continue
148+
fi
149+
150+
# Get version from base branch
151+
BASE_VERSION=$(git show "$BASE_BRANCH:$PLUGIN_JSON" 2>/dev/null | jq -r '.version' 2>/dev/null || echo "")
152+
if [ -z "$BASE_VERSION" ]; then
153+
# Plugin doesn't exist in base branch (new plugin)
154+
BASE_VERSION="0.0.0"
155+
fi
156+
157+
# Skip if versions are the same
158+
if [ "$BASE_VERSION" = "$HEAD_VERSION" ]; then
159+
continue
160+
fi
161+
162+
# Determine type of bump
163+
IFS='.' read -r -a base_parts <<< "$BASE_VERSION"
164+
IFS='.' read -r -a head_parts <<< "$HEAD_VERSION"
165+
if [ "${base_parts[0]}" != "${head_parts[0]}" ]; then
140166
TYPE="major"
141-
elif [ "${current_parts[1]}" != "${next_parts[1]}" ]; then
167+
elif [ "${base_parts[1]}" != "${head_parts[1]}" ]; then
142168
TYPE="minor"
143-
elif [ "${current_parts[2]}" != "${next_parts[2]}" ]; then
169+
elif [ "${base_parts[2]}" != "${head_parts[2]}" ]; then
144170
TYPE="patch"
145171
else
146-
TYPE="none"
147-
fi
148-
149-
# Skip plugins with no version change
150-
if [ "$TYPE" = "none" ]; then
151-
continue
172+
TYPE="unknown"
152173
fi
153174

175+
FOUND_CHANGES=1
154176
case "{{format}}" in
155177
--format=raw|'' )
156-
echo "$PLUGIN_NAME: $CURRENT =( $TYPE )=> $NEXT"
178+
echo "$PLUGIN_NAME: $BASE_VERSION =( $TYPE )=> $HEAD_VERSION"
157179
;;
158180
--format=md )
159-
echo "| $PLUGIN_NAME | $CURRENT | $TYPE | $NEXT |"
181+
echo "| $PLUGIN_NAME | $BASE_VERSION | $TYPE | $HEAD_VERSION |"
160182
;;
161183
esac
162184
done
163185

186+
if [ "$FOUND_CHANGES" -eq 0 ]; then
187+
case "{{format}}" in
188+
--format=md )
189+
echo "| *No version changes detected* | | | |"
190+
;;
191+
* )
192+
echo "No version changes detected"
193+
;;
194+
esac
195+
fi
196+
164197
_plugin-current-versions:
165198
#!/usr/bin/env bash
166199
# returns a list of plugin names and their current versions

plugins/commit-skill/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,12 @@ Contributions welcome! Please:
425425

426426
## Changelog
427427

428+
### Latest
429+
430+
- Improved version bump commit messages with plugin-specific formatting
431+
- Added automatic prettier formatting after version bumps
432+
- Enhanced CI integration by removing skip-ci tags
433+
428434
### Version 1.0.0
429435

430436
- Initial release

plugins/data-serialization/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ For deeply nested or non-uniform data, JSON may be more efficient.
9999
- [jq Manual](https://jqlang.github.io/jq/manual/)
100100
- [yq Documentation](https://mikefarah.gitbook.io/yq/)
101101

102+
## Changelog
103+
104+
### Latest
105+
106+
- Improved version bump workflow with plugin-specific commit messages
107+
- Enhanced CI integration with consistent formatting
108+
102109
## License
103110

104111
MIT

0 commit comments

Comments
 (0)