@bonvoy/plugin-git 0.1.0 → 0.3.0

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.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @bonvoy/plugin-git 🚢
2
+
3
+ > Git operations plugin for bonvoy
4
+
5
+ Handles git commit, tag, push, and branch operations during the release process.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @bonvoy/plugin-git
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - ✅ Commits version bumps and changelog updates
16
+ - ✅ Creates git tags for each released package
17
+ - ✅ Pushes commits and tags to remote
18
+ - ✅ Branch creation and checkout for PR workflow
19
+ - ✅ Configurable commit message and tag format
20
+ - ✅ Dry-run support
21
+
22
+ ## Configuration
23
+
24
+ ```javascript
25
+ // bonvoy.config.js
26
+ export default {
27
+ git: {
28
+ commitMessage: 'chore(release): :bookmark: {packages} [skip ci]', // default
29
+ tagFormat: '{name}@{version}', // default
30
+ push: true, // default
31
+ },
32
+ };
33
+ ```
34
+
35
+ ### Placeholders
36
+
37
+ | Placeholder | Description |
38
+ |-------------|-------------|
39
+ | `{packages}` | Comma-separated list of released package names |
40
+ | `{name}` | Package name (for tag format) |
41
+ | `{version}` | Package version (for tag format) |
42
+
43
+ ## Hooks
44
+
45
+ This plugin taps into the following hooks:
46
+
47
+ | Hook | Action |
48
+ |------|--------|
49
+ | `beforePublish` | Commits changes, creates tags, pushes to remote |
50
+
51
+ ## Operations
52
+
53
+ The plugin provides these git operations:
54
+
55
+ - `add(files, cwd)` - Stage files
56
+ - `commit(message, cwd)` - Create commit
57
+ - `tag(name, cwd)` - Create tag
58
+ - `push(cwd, branch?)` - Push to remote
59
+ - `pushTags(tags, cwd)` - Push tags
60
+ - `checkout(branch, cwd, create?)` - Checkout or create branch
61
+ - `getCurrentBranch(cwd)` - Get current branch name
62
+ - `getLastTag(cwd)` - Get most recent tag
63
+ - `getCommitsSinceTag(tag, cwd)` - Get commits since tag
64
+
65
+ ## Default Behavior
66
+
67
+ This plugin is loaded automatically by bonvoy. During `beforePublish`:
68
+
69
+ 1. Stage all changes (`git add .`)
70
+ 2. Commit with the configured message
71
+ 3. Create tags for each released package
72
+ 4. Push commits and tags to the remote
73
+
74
+ ## License
75
+
76
+ MIT
package/dist/index.d.mts CHANGED
@@ -1,5 +1,26 @@
1
1
  import { BonvoyPlugin } from "@bonvoy/core";
2
2
 
3
+ //#region src/operations.d.ts
4
+ interface GitOperations {
5
+ add(files: string, cwd: string): Promise<void>;
6
+ commit(message: string, cwd: string): Promise<void>;
7
+ tag(name: string, cwd: string): Promise<void>;
8
+ push(cwd: string, branch?: string): Promise<void>;
9
+ pushTags(tags: string[], cwd: string): Promise<void>;
10
+ checkout(branch: string, cwd: string, create?: boolean): Promise<void>;
11
+ getCurrentBranch(cwd: string): Promise<string>;
12
+ tagExists(name: string, cwd: string): Promise<boolean>;
13
+ getCommitsSinceTag(tag: string | null, cwd: string): Promise<Array<{
14
+ hash: string;
15
+ message: string;
16
+ author: string;
17
+ date: string;
18
+ files: string[];
19
+ }>>;
20
+ getLastTag(cwd: string): Promise<string | null>;
21
+ }
22
+ declare const defaultGitOperations: GitOperations;
23
+ //#endregion
3
24
  //#region src/git.d.ts
4
25
  interface GitPluginConfig {
5
26
  commitMessage?: string;
@@ -9,16 +30,19 @@ interface GitPluginConfig {
9
30
  declare class GitPlugin implements BonvoyPlugin {
10
31
  name: string;
11
32
  private config;
12
- constructor(config?: GitPluginConfig);
33
+ private ops;
34
+ constructor(config?: GitPluginConfig, ops?: GitOperations);
13
35
  apply(bonvoy: {
14
36
  hooks: {
37
+ validateRepo: any;
15
38
  beforePublish: any;
16
39
  };
17
40
  }): void;
18
41
  private commitChanges;
19
42
  private createTags;
20
43
  private pushChanges;
44
+ private validateTags;
21
45
  }
22
46
  //#endregion
23
- export { type GitPluginConfig, GitPlugin as default };
47
+ export { type GitOperations, type GitPluginConfig, GitPlugin as default, defaultGitOperations };
24
48
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,63 +1,170 @@
1
1
  import { execa } from "execa";
2
2
 
3
+ //#region src/operations.ts
4
+ const defaultGitOperations = {
5
+ async add(files, cwd) {
6
+ await execa("git", ["add", files], { cwd });
7
+ },
8
+ async commit(message, cwd) {
9
+ await execa("git", [
10
+ "commit",
11
+ "-m",
12
+ message
13
+ ], { cwd });
14
+ },
15
+ async tag(name, cwd) {
16
+ await execa("git", ["tag", name], { cwd });
17
+ },
18
+ async push(cwd, branch) {
19
+ if (branch) await execa("git", [
20
+ "push",
21
+ "-u",
22
+ "origin",
23
+ branch
24
+ ], { cwd });
25
+ else await execa("git", ["push"], { cwd });
26
+ },
27
+ async pushTags(tags, cwd) {
28
+ await execa("git", [
29
+ "push",
30
+ "origin",
31
+ ...tags
32
+ ], { cwd });
33
+ },
34
+ async checkout(branch, cwd, create = false) {
35
+ await execa("git", create ? [
36
+ "checkout",
37
+ "-b",
38
+ branch
39
+ ] : ["checkout", branch], { cwd });
40
+ },
41
+ async getCurrentBranch(cwd) {
42
+ const { stdout } = await execa("git", [
43
+ "rev-parse",
44
+ "--abbrev-ref",
45
+ "HEAD"
46
+ ], { cwd });
47
+ return stdout.trim();
48
+ },
49
+ async tagExists(name, cwd) {
50
+ try {
51
+ await execa("git", ["rev-parse", `refs/tags/${name}`], { cwd });
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ }
56
+ },
57
+ async getLastTag(cwd) {
58
+ try {
59
+ const { stdout } = await execa("git", [
60
+ "describe",
61
+ "--tags",
62
+ "--abbrev=0"
63
+ ], { cwd });
64
+ return stdout.trim() || null;
65
+ } catch {
66
+ return null;
67
+ }
68
+ },
69
+ async getCommitsSinceTag(tag, cwd) {
70
+ const { stdout } = await execa("git", [
71
+ "log",
72
+ "--pretty=format:%H|%s|%an|%aI",
73
+ "--name-only",
74
+ tag ? `${tag}..HEAD` : "HEAD"
75
+ ], { cwd });
76
+ if (!stdout.trim()) return [];
77
+ const commits = [];
78
+ const entries = stdout.split("\n\n");
79
+ for (const entry of entries) {
80
+ const [firstLine, ...fileLines] = entry.split("\n");
81
+ const [hash, message, author, date] = firstLine.split("|");
82
+ if (hash && message) commits.push({
83
+ hash,
84
+ message,
85
+ author: author || "",
86
+ date: date || "",
87
+ files: fileLines.filter((f) => f.trim())
88
+ });
89
+ }
90
+ return commits;
91
+ }
92
+ };
93
+
94
+ //#endregion
3
95
  //#region src/git.ts
4
96
  var GitPlugin = class {
5
97
  name = "git";
6
98
  config;
7
- constructor(config = {}) {
99
+ ops;
100
+ constructor(config = {}, ops) {
8
101
  this.config = {
9
- commitMessage: config.commitMessage ?? "chore: release {packages}",
102
+ commitMessage: config.commitMessage ?? "chore(release): :bookmark: {packages} [skip ci]",
10
103
  tagFormat: config.tagFormat ?? "{name}@{version}",
11
104
  push: config.push ?? true
12
105
  };
106
+ this.ops = ops ?? defaultGitOperations;
13
107
  }
14
108
  apply(bonvoy) {
109
+ bonvoy.hooks.validateRepo.tapPromise(this.name, async (context) => {
110
+ await this.validateTags(context);
111
+ });
15
112
  bonvoy.hooks.beforePublish.tapPromise(this.name, async (context) => {
16
- console.log("📝 Committing changes...");
113
+ context.logger.info("📝 Committing changes...");
17
114
  await this.commitChanges(context);
18
- console.log("🏷️ Creating git tags...");
115
+ context.logger.info("🏷️ Creating git tags...");
19
116
  await this.createTags(context);
20
117
  if (this.config.push) {
21
- console.log("⬆️ Pushing to remote...");
118
+ context.logger.info("⬆️ Pushing to remote...");
22
119
  await this.pushChanges(context);
23
120
  }
24
121
  });
25
122
  }
26
123
  async commitChanges(context) {
27
- const { packages, isDryRun } = context;
124
+ const { packages, isDryRun, rootPath, logger } = context;
28
125
  if (packages.length === 0) return;
29
- if (!isDryRun) await execa("git", ["add", "."]);
30
126
  const packageNames = packages.map((pkg) => pkg.name).join(", ");
31
127
  const message = this.config.commitMessage.replace("{packages}", packageNames);
32
- console.log(` Commit message: "${message}"`);
33
- if (!isDryRun) await execa("git", [
34
- "commit",
35
- "-m",
36
- message
37
- ]);
128
+ logger.info(` Commit message: "${message}"`);
129
+ if (!isDryRun) {
130
+ await this.ops.add(".", rootPath);
131
+ await this.ops.commit(message, rootPath);
132
+ }
38
133
  }
39
134
  async createTags(context) {
40
- const { packages, isDryRun } = context;
135
+ const { packages, isDryRun, rootPath, logger } = context;
41
136
  for (const pkg of packages) {
42
137
  const tag = this.config.tagFormat.replace("{name}", pkg.name).replace("{version}", pkg.version);
43
- console.log(` Tag: ${tag}`);
44
- if (!isDryRun) await execa("git", ["tag", tag]);
138
+ logger.info(` Tag: ${tag}`);
139
+ if (!isDryRun) await this.ops.tag(tag, rootPath);
45
140
  }
46
141
  }
47
142
  async pushChanges(context) {
48
- const { packages, isDryRun } = context;
49
- console.log(" Pushing commits and tags...");
143
+ const { packages, isDryRun, rootPath, logger } = context;
144
+ logger.info(" Pushing commits and tags...");
50
145
  if (!isDryRun) {
51
- await execa("git", ["push"]);
52
- await execa("git", [
53
- "push",
54
- "origin",
55
- ...packages.map((pkg) => this.config.tagFormat.replace("{name}", pkg.name).replace("{version}", pkg.version))
56
- ]);
146
+ await this.ops.push(rootPath);
147
+ const tags = packages.map((pkg) => this.config.tagFormat.replace("{name}", pkg.name).replace("{version}", pkg.version));
148
+ await this.ops.pushTags(tags, rootPath);
149
+ }
150
+ }
151
+ async validateTags(context) {
152
+ const { changedPackages, versions, rootPath, logger } = context;
153
+ if (!versions) return;
154
+ const existingTags = [];
155
+ for (const pkg of changedPackages) {
156
+ const version = versions[pkg.name];
157
+ if (!version) continue;
158
+ const tag = this.config.tagFormat.replace("{name}", pkg.name).replace("{version}", version);
159
+ if (await this.ops.tagExists(tag, rootPath)) existingTags.push(tag);
160
+ }
161
+ if (existingTags.length > 0) {
162
+ logger.error(`❌ Git tags already exist: ${existingTags.join(", ")}`);
163
+ throw new Error(`Cannot release: git tags already exist (${existingTags.join(", ")}). Delete them first or bump to a new version.`);
57
164
  }
58
165
  }
59
166
  };
60
167
 
61
168
  //#endregion
62
- export { GitPlugin as default };
169
+ export { GitPlugin as default, defaultGitOperations };
63
170
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/git.ts"],"sourcesContent":["import type { BonvoyPlugin, PublishContext } from '@bonvoy/core';\nimport { execa } from 'execa';\n\nexport interface GitPluginConfig {\n commitMessage?: string;\n tagFormat?: string;\n push?: boolean;\n}\n\nexport default class GitPlugin implements BonvoyPlugin {\n name = 'git';\n\n private config: Required<GitPluginConfig>;\n\n constructor(config: GitPluginConfig = {}) {\n this.config = {\n commitMessage: config.commitMessage ?? 'chore: release {packages}',\n tagFormat: config.tagFormat ?? '{name}@{version}',\n push: config.push ?? true,\n };\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Hook types are complex and vary by implementation\n apply(bonvoy: { hooks: { beforePublish: any } }): void {\n bonvoy.hooks.beforePublish.tapPromise(this.name, async (context: PublishContext) => {\n console.log('📝 Committing changes...');\n await this.commitChanges(context);\n console.log('🏷️ Creating git tags...');\n await this.createTags(context);\n\n if (this.config.push) {\n console.log('⬆️ Pushing to remote...');\n await this.pushChanges(context);\n }\n });\n }\n\n private async commitChanges(context: PublishContext): Promise<void> {\n const { packages, isDryRun } = context;\n\n if (packages.length === 0) return;\n\n // Add all changed files\n if (!isDryRun) {\n await execa('git', ['add', '.']);\n }\n\n // Create commit message\n const packageNames = packages.map((pkg) => pkg.name).join(', ');\n const message = this.config.commitMessage.replace('{packages}', packageNames);\n\n console.log(` Commit message: \"${message}\"`);\n\n // Commit changes\n if (!isDryRun) {\n await execa('git', ['commit', '-m', message]);\n }\n }\n\n private async createTags(context: PublishContext): Promise<void> {\n const { packages, isDryRun } = context;\n\n for (const pkg of packages) {\n const tag = this.config.tagFormat\n .replace('{name}', pkg.name)\n .replace('{version}', pkg.version);\n\n console.log(` Tag: ${tag}`);\n\n if (!isDryRun) {\n await execa('git', ['tag', tag]);\n }\n }\n }\n\n private async pushChanges(context: PublishContext): Promise<void> {\n const { packages, isDryRun } = context;\n\n console.log(' Pushing commits and tags...');\n\n if (!isDryRun) {\n // Push commits\n await execa('git', ['push']);\n\n // Push all tags at once to avoid race condition with GitHub\n const tags = packages.map((pkg) =>\n this.config.tagFormat.replace('{name}', pkg.name).replace('{version}', pkg.version),\n );\n await execa('git', ['push', 'origin', ...tags]);\n }\n }\n}\n"],"mappings":";;;AASA,IAAqB,YAArB,MAAuD;CACrD,OAAO;CAEP,AAAQ;CAER,YAAY,SAA0B,EAAE,EAAE;AACxC,OAAK,SAAS;GACZ,eAAe,OAAO,iBAAiB;GACvC,WAAW,OAAO,aAAa;GAC/B,MAAM,OAAO,QAAQ;GACtB;;CAIH,MAAM,QAAiD;AACrD,SAAO,MAAM,cAAc,WAAW,KAAK,MAAM,OAAO,YAA4B;AAClF,WAAQ,IAAI,2BAA2B;AACvC,SAAM,KAAK,cAAc,QAAQ;AACjC,WAAQ,IAAI,4BAA4B;AACxC,SAAM,KAAK,WAAW,QAAQ;AAE9B,OAAI,KAAK,OAAO,MAAM;AACpB,YAAQ,IAAI,2BAA2B;AACvC,UAAM,KAAK,YAAY,QAAQ;;IAEjC;;CAGJ,MAAc,cAAc,SAAwC;EAClE,MAAM,EAAE,UAAU,aAAa;AAE/B,MAAI,SAAS,WAAW,EAAG;AAG3B,MAAI,CAAC,SACH,OAAM,MAAM,OAAO,CAAC,OAAO,IAAI,CAAC;EAIlC,MAAM,eAAe,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK;EAC/D,MAAM,UAAU,KAAK,OAAO,cAAc,QAAQ,cAAc,aAAa;AAE7E,UAAQ,IAAI,sBAAsB,QAAQ,GAAG;AAG7C,MAAI,CAAC,SACH,OAAM,MAAM,OAAO;GAAC;GAAU;GAAM;GAAQ,CAAC;;CAIjD,MAAc,WAAW,SAAwC;EAC/D,MAAM,EAAE,UAAU,aAAa;AAE/B,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,MAAM,KAAK,OAAO,UACrB,QAAQ,UAAU,IAAI,KAAK,CAC3B,QAAQ,aAAa,IAAI,QAAQ;AAEpC,WAAQ,IAAI,UAAU,MAAM;AAE5B,OAAI,CAAC,SACH,OAAM,MAAM,OAAO,CAAC,OAAO,IAAI,CAAC;;;CAKtC,MAAc,YAAY,SAAwC;EAChE,MAAM,EAAE,UAAU,aAAa;AAE/B,UAAQ,IAAI,gCAAgC;AAE5C,MAAI,CAAC,UAAU;AAEb,SAAM,MAAM,OAAO,CAAC,OAAO,CAAC;AAM5B,SAAM,MAAM,OAAO;IAAC;IAAQ;IAAU,GAHzB,SAAS,KAAK,QACzB,KAAK,OAAO,UAAU,QAAQ,UAAU,IAAI,KAAK,CAAC,QAAQ,aAAa,IAAI,QAAQ,CACpF;IAC6C,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/operations.ts","../src/git.ts"],"sourcesContent":["import { execa } from 'execa';\n\nexport interface GitOperations {\n add(files: string, cwd: string): Promise<void>;\n commit(message: string, cwd: string): Promise<void>;\n tag(name: string, cwd: string): Promise<void>;\n push(cwd: string, branch?: string): Promise<void>;\n pushTags(tags: string[], cwd: string): Promise<void>;\n checkout(branch: string, cwd: string, create?: boolean): Promise<void>;\n getCurrentBranch(cwd: string): Promise<string>;\n tagExists(name: string, cwd: string): Promise<boolean>;\n getCommitsSinceTag(\n tag: string | null,\n cwd: string,\n ): Promise<\n Array<{ hash: string; message: string; author: string; date: string; files: string[] }>\n >;\n getLastTag(cwd: string): Promise<string | null>;\n}\n\nexport const defaultGitOperations: GitOperations = {\n async add(files, cwd) {\n await execa('git', ['add', files], { cwd });\n },\n\n async commit(message, cwd) {\n await execa('git', ['commit', '-m', message], { cwd });\n },\n\n async tag(name, cwd) {\n await execa('git', ['tag', name], { cwd });\n },\n\n /* c8 ignore start - real git operations */\n async push(cwd, branch?) {\n if (branch) {\n await execa('git', ['push', '-u', 'origin', branch], { cwd });\n } else {\n await execa('git', ['push'], { cwd });\n }\n },\n\n async pushTags(tags, cwd) {\n await execa('git', ['push', 'origin', ...tags], { cwd });\n },\n\n async checkout(branch, cwd, create = false) {\n const args = create ? ['checkout', '-b', branch] : ['checkout', branch];\n await execa('git', args, { cwd });\n },\n\n async getCurrentBranch(cwd) {\n const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd });\n return stdout.trim();\n },\n\n async tagExists(name, cwd) {\n try {\n await execa('git', ['rev-parse', `refs/tags/${name}`], { cwd });\n return true;\n } catch {\n return false;\n }\n },\n /* c8 ignore stop */\n\n async getLastTag(cwd) {\n try {\n const { stdout } = await execa('git', ['describe', '--tags', '--abbrev=0'], { cwd });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n },\n\n async getCommitsSinceTag(tag, cwd) {\n const range = tag ? `${tag}..HEAD` : 'HEAD';\n const { stdout } = await execa(\n 'git',\n ['log', '--pretty=format:%H|%s|%an|%aI', '--name-only', range],\n { cwd },\n );\n\n if (!stdout.trim()) return [];\n\n const commits: Array<{\n hash: string;\n message: string;\n author: string;\n date: string;\n files: string[];\n }> = [];\n const entries = stdout.split('\\n\\n');\n\n for (const entry of entries) {\n const lines = entry.split('\\n');\n const [firstLine, ...fileLines] = lines;\n const [hash, message, author, date] = firstLine.split('|');\n if (hash && message) {\n commits.push({\n hash,\n message,\n author: author || '',\n date: date || '',\n files: fileLines.filter((f) => f.trim()),\n });\n }\n }\n\n return commits;\n },\n};\n","import type { BonvoyPlugin, Context, PublishContext } from '@bonvoy/core';\n\nimport { defaultGitOperations, type GitOperations } from './operations.js';\n\nexport interface GitPluginConfig {\n commitMessage?: string;\n tagFormat?: string;\n push?: boolean;\n}\n\nexport default class GitPlugin implements BonvoyPlugin {\n name = 'git';\n\n private config: Required<GitPluginConfig>;\n private ops: GitOperations;\n\n constructor(config: GitPluginConfig = {}, ops?: GitOperations) {\n this.config = {\n commitMessage: config.commitMessage ?? 'chore(release): :bookmark: {packages} [skip ci]',\n tagFormat: config.tagFormat ?? '{name}@{version}',\n push: config.push ?? true,\n };\n this.ops = ops ?? defaultGitOperations;\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Hook types are complex and vary by implementation\n apply(bonvoy: { hooks: { validateRepo: any; beforePublish: any } }): void {\n bonvoy.hooks.validateRepo.tapPromise(this.name, async (context: Context) => {\n await this.validateTags(context);\n });\n\n bonvoy.hooks.beforePublish.tapPromise(this.name, async (context: PublishContext) => {\n context.logger.info('📝 Committing changes...');\n await this.commitChanges(context);\n context.logger.info('🏷️ Creating git tags...');\n await this.createTags(context);\n\n if (this.config.push) {\n context.logger.info('⬆️ Pushing to remote...');\n await this.pushChanges(context);\n }\n });\n }\n\n private async commitChanges(context: PublishContext): Promise<void> {\n const { packages, isDryRun, rootPath, logger } = context;\n\n if (packages.length === 0) return;\n\n const packageNames = packages.map((pkg) => pkg.name).join(', ');\n const message = this.config.commitMessage.replace('{packages}', packageNames);\n\n logger.info(` Commit message: \"${message}\"`);\n\n if (!isDryRun) {\n await this.ops.add('.', rootPath);\n await this.ops.commit(message, rootPath);\n }\n }\n\n private async createTags(context: PublishContext): Promise<void> {\n const { packages, isDryRun, rootPath, logger } = context;\n\n for (const pkg of packages) {\n const tag = this.config.tagFormat\n .replace('{name}', pkg.name)\n .replace('{version}', pkg.version);\n\n logger.info(` Tag: ${tag}`);\n\n if (!isDryRun) {\n await this.ops.tag(tag, rootPath);\n }\n }\n }\n\n private async pushChanges(context: PublishContext): Promise<void> {\n const { packages, isDryRun, rootPath, logger } = context;\n\n logger.info(' Pushing commits and tags...');\n\n if (!isDryRun) {\n await this.ops.push(rootPath);\n\n const tags = packages.map((pkg) =>\n this.config.tagFormat.replace('{name}', pkg.name).replace('{version}', pkg.version),\n );\n await this.ops.pushTags(tags, rootPath);\n }\n }\n\n private async validateTags(context: Context): Promise<void> {\n const { changedPackages, versions, rootPath, logger } = context;\n if (!versions) return;\n\n const existingTags: string[] = [];\n\n for (const pkg of changedPackages) {\n const version = versions[pkg.name];\n if (!version) continue;\n\n const tag = this.config.tagFormat.replace('{name}', pkg.name).replace('{version}', version);\n\n if (await this.ops.tagExists(tag, rootPath)) {\n existingTags.push(tag);\n }\n }\n\n if (existingTags.length > 0) {\n logger.error(`❌ Git tags already exist: ${existingTags.join(', ')}`);\n throw new Error(\n `Cannot release: git tags already exist (${existingTags.join(', ')}). Delete them first or bump to a new version.`,\n );\n }\n }\n}\n\nexport { defaultGitOperations, type GitOperations } from './operations.js';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bonvoy/plugin-git",
3
- "version": "0.1.0",
4
- "description": "Git operations plugin for bonvoy",
3
+ "version": "0.3.0",
4
+ "description": "🚢 Git operations plugin for bonvoy",
5
5
  "keywords": [
6
6
  "bonvoy",
7
7
  "plugin",
@@ -27,7 +27,6 @@
27
27
  ".": "./dist/index.mjs",
28
28
  "./package.json": "./package.json"
29
29
  },
30
- "types": "./dist/index.d.mts",
31
30
  "files": [
32
31
  "dist"
33
32
  ],
@@ -38,9 +37,6 @@
38
37
  "dependencies": {
39
38
  "execa": "^9.6.1"
40
39
  },
41
- "devDependencies": {
42
- "vitest": "^4.0.16"
43
- },
44
40
  "engines": {
45
41
  "node": ">= 20.5"
46
42
  }