Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version-file: '.nvmrc'
cache: 'npm'

- name: Install npm dependencies
run: npm ci
Expand Down Expand Up @@ -70,8 +71,11 @@ jobs:
# Configure git to use GITHUB_TOKEN for push
git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

# Disable git hooks for semantic-release commits (CI environment)
# Disable git hooks for automated release commits
# This is intentional - the release commit has already passed all validation
# in the "Run tests" step above. Git hooks (pre-commit, etc.) are designed
# for developer commits and would be redundant here.
git config core.hooksPath /dev/null

# Run semantic-release (handles everything: version bump, commit, push, GitHub release)
# Run semantic-release (handles version bump, commit, push, GitHub release)
npx semantic-release
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
54 changes: 54 additions & 0 deletions .releaserc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,60 @@ function discoverPlugins() {
*/
function updatePluginJsons() {
return {
async verifyConditions(_pluginContext, { lastRelease }) {
// First release - skip verification
if (!lastRelease || !lastRelease.version) {
console.log('First release - skipping version verification');
return;
}

const plugins = discoverPlugins();
const mismatches = [];
const lastVersion = lastRelease.version;

// Check each plugin.json
for (const plugin of plugins) {
const pluginJsonPath = resolve(
process.cwd(),
`plugins/${plugin}/.claude-plugin/plugin.json`
);
const pluginJson = JSON.parse(readFileSync(pluginJsonPath, 'utf8'));

if (pluginJson.version !== lastVersion) {
mismatches.push({
plugin,
current: pluginJson.version,
expected: lastVersion,
});
}
}

// Check marketplace.json
const marketplacePath = resolve(process.cwd(), '.claude-plugin/marketplace.json');
const marketplace = JSON.parse(readFileSync(marketplacePath, 'utf8'));

const marketplaceMismatches = marketplace.plugins.filter(
(p) => p.version !== lastVersion
);

// Log warnings but don't fail the release
if (mismatches.length > 0) {
console.warn('\n⚠️ Plugin version mismatches detected:');
mismatches.forEach(({ plugin, current, expected }) => {
console.warn(` ${plugin}: ${current} (expected ${expected})`);
});
console.warn('These will be synchronized to the next version.\n');
}

if (marketplaceMismatches.length > 0) {
console.warn('⚠️ Marketplace version mismatches:');
marketplaceMismatches.forEach((p) => {
console.warn(` ${p.name}: ${p.version} (expected ${lastVersion})`);
});
console.warn('These will be synchronized to the next version.\n');
}
},

async prepare(_pluginContext, { nextRelease: { version } }) {
const plugins = discoverPlugins();

Expand Down
Loading