Skip to content

Commit 22675af

Browse files
claudedgellow
authored andcommitted
feat: add --tag-strategy flag to switch between github API and git CLI
1 parent c827c19 commit 22675af

3 files changed

Lines changed: 45 additions & 11 deletions

File tree

src/cli.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ ${bold('ARGUMENTS:')}
7171
7272
${bold('OPTIONS:')}
7373
--storage <type> Storage backend: local (default) or github
74+
--tag-strategy <s> Tag creation: github (API, default) or git (CLI)
7475
--execute Actually create the release (default is dry-run)
7576
--force Skip safety checks and create release
7677
--owner <owner> GitHub repository owner (auto-detected from git remote)
@@ -108,9 +109,10 @@ async function main(): Promise<void> {
108109

109110
const args = parseArgs(Deno.args, {
110111
boolean: ['help', 'version', 'execute', 'force'],
111-
string: ['storage', 'owner', 'repo', 'token'],
112+
string: ['storage', 'owner', 'repo', 'token', 'tag-strategy'],
112113
default: {
113114
storage: 'local',
115+
'tag-strategy': 'github',
114116
},
115117
});
116118

@@ -219,10 +221,12 @@ async function main(): Promise<void> {
219221
console.log(yellow('\n🔍 DRY RUN MODE (use --execute to create release)\n'));
220222
}
221223

224+
const tagStrategy = args['tag-strategy'] as 'github' | 'git';
222225
const release = await releaseManager.createRelease(
223226
bump,
224227
changes.currentSha,
225228
isDryRun,
229+
tagStrategy,
226230
);
227231

228232
if (!isDryRun) {

src/core/mod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { Detector } from './detector.ts';
22
export { Version } from './version.ts';
3-
export { ReleaseManager } from './release.ts';
3+
export { ReleaseManager, type TagStrategy } from './release.ts';
44
export { type PrereleaseType, type TransitionTarget, VersionTransition } from './transition.ts';
55
export { type PullRequest, type PullRequestOptions, ReleasePullRequest } from './pull-request.ts';

src/core/release.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { ensureFile } from '@std/fs';
44
import { updateAllVersions } from '../manifest/mod.ts';
55
import { setVersion as setVersionsManifest } from '../versions/mod.ts';
66

7+
export type TagStrategy = 'github' | 'git';
8+
79
export class ReleaseManager {
810
constructor(private storage: Storage) {}
911

@@ -184,6 +186,7 @@ export class ReleaseManager {
184186
bump: VersionBump,
185187
sha: string,
186188
dryRun = false,
189+
tagStrategy: TagStrategy = 'github',
187190
): Promise<Release> {
188191
const tag = `v${bump.to}`;
189192
const notes = this.generateReleaseNotes(bump);
@@ -253,18 +256,45 @@ export class ReleaseManager {
253256
release.sha = new TextDecoder().decode(amendedShaResult.stdout).trim();
254257
}
255258

256-
// Push commit to remote (tag will be created by storage.saveRelease via API)
257-
const pushCommand = new Deno.Command('git', {
258-
args: ['push', 'origin', 'HEAD'],
259-
});
260-
const pushResult = await pushCommand.output();
259+
if (tagStrategy === 'git') {
260+
// Create tag locally using git CLI
261+
const tagCommand = new Deno.Command('git', {
262+
args: ['tag', '-a', tag, '-m', `Release ${tag}`],
263+
});
264+
const { code, stderr } = await tagCommand.output();
265+
266+
if (code !== 0) {
267+
const error = new TextDecoder().decode(stderr);
268+
throw new PlsError(
269+
`Failed to create git tag: ${error}`,
270+
'GIT_TAG_ERROR',
271+
);
272+
}
273+
274+
// Push commit and tag to remote
275+
const pushCommand = new Deno.Command('git', {
276+
args: ['push', 'origin', 'HEAD', '--follow-tags'],
277+
});
278+
const pushResult = await pushCommand.output();
261279

262-
if (pushResult.code !== 0) {
263-
const error = new TextDecoder().decode(pushResult.stderr);
264-
console.warn(`Warning: Failed to push to remote: ${error}`);
280+
if (pushResult.code !== 0) {
281+
const error = new TextDecoder().decode(pushResult.stderr);
282+
console.warn(`Warning: Failed to push to remote: ${error}`);
283+
}
284+
} else {
285+
// Push commit only (tag will be created by storage.saveRelease via API)
286+
const pushCommand = new Deno.Command('git', {
287+
args: ['push', 'origin', 'HEAD'],
288+
});
289+
const pushResult = await pushCommand.output();
290+
291+
if (pushResult.code !== 0) {
292+
const error = new TextDecoder().decode(pushResult.stderr);
293+
console.warn(`Warning: Failed to push to remote: ${error}`);
294+
}
265295
}
266296

267-
// Save release to storage (creates GitHub release + tag via API)
297+
// Save release to storage (creates GitHub release, and tag if using github strategy)
268298
await this.storage.saveRelease(release);
269299

270300
// Update CHANGELOG.md

0 commit comments

Comments
 (0)