@mridang/semantic-release-gomod 1.0.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,134 @@
1
+ # Semantic Release - Gomod
2
+
3
+ A [semantic-release](https://github.com/semantic-release/semantic-release)
4
+ plugin to automatically tag and release multi-module Go repositories.
5
+
6
+ This plugin automates the release workflow for Go monorepos that use the
7
+ multi-module pattern. During `prepare`, it pins every submodule `go.mod`
8
+ require line that references the root module to the new release version and
9
+ optionally runs `go mod tidy`. During `publish`, it creates and pushes a
10
+ per-module git tag for every `go.mod` in the repository, following the
11
+ standard `<subpath>/vX.Y.Z` naming that the Go module proxy requires. This
12
+ eliminates the need for manual tagging scripts, ensuring every module in
13
+ your monorepo is consistently released together.
14
+
15
+ ## Why?
16
+
17
+ Releasing a multi-module Go repository involves more than just creating a
18
+ single Git tag. For each submodule to be resolvable by the Go module proxy
19
+ and `go get`, it must have its own version tag in the form
20
+ `<path>/vX.Y.Z` (e.g., `assert/cert/manager/v1.2.3`). Keeping require
21
+ lines pinned to the new version across all submodules adds further
22
+ complexity. This multi-step process is a common point of friction in an
23
+ otherwise automated pipeline.
24
+
25
+ Without this plugin, developers typically face one of two issues:
26
+
27
+ - **Manual Tagging:** The most common method is a shell script that walks
28
+ the repository, updates require lines, and pushes tags for each `go.mod`.
29
+ This adds toil, is error-prone, and is not reusable across projects.
30
+ - **Incomplete Automation:** Other tooling may create the root tag but
31
+ skip submodule tags, leaving submodules unreachable via `go get` until
32
+ someone manually creates the missing tags.
33
+
34
+ This plugin provides a lightweight and direct solution. It auto-discovers
35
+ every `go.mod` in the repository, pins inter-module dependencies to the
36
+ new version, and creates the correct per-module tag for each one — all
37
+ within a standard `semantic-release` pipeline with zero required
38
+ configuration.
39
+
40
+ ## Installation
41
+
42
+ Install using NPM with the following command:
43
+
44
+ ```sh
45
+ npm install --save-dev @mridang/semantic-release-gomod
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ To use this plugin, add it to your semantic-release configuration file
51
+ (e.g., `.releaserc.js`, `release.config.js`, or in your `package.json`).
52
+
53
+ The plugin's `prepare` step pins require lines in submodule `go.mod` files.
54
+ For these changes to be included in the release commit, the plugin should be
55
+ placed **before** `@semantic-release/git` in the `plugins` array.
56
+
57
+ > [!IMPORTANT]
58
+ > This plugin updates `go.mod` files during the `prepare` step. For these
59
+ > changes to be included in your release commit, you **must** configure
60
+ > the `@semantic-release/git` plugin to include your `go.mod` and `go.sum`
61
+ > files in its `assets` array.
62
+
63
+ ### Example Configuration (`.releaserc.js`)
64
+
65
+ ```javascript
66
+ module.exports = {
67
+ branches: ['main', 'next'],
68
+ plugins: [
69
+ '@semantic-release/commit-analyzer',
70
+ '@mridang/semantic-release-gomod',
71
+ '@semantic-release/release-notes-generator',
72
+ '@semantic-release/github',
73
+ [
74
+ '@semantic-release/git',
75
+ {
76
+ assets: ['go.mod', 'go.sum', '**/go.mod', '**/go.sum'],
77
+ message:
78
+ 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
79
+ },
80
+ ],
81
+ ],
82
+ };
83
+ ```
84
+
85
+ ### Configuration Options
86
+
87
+ All options are case-sensitive and lowercased in the JSON configuration.
88
+
89
+ - **`modules` (string | string[], optional):**
90
+ Glob patterns (relative to the repository root) matching submodule
91
+ `go.mod` files. When omitted, the plugin auto-discovers every `go.mod`
92
+ in the repository except the root-level one.
93
+ Example: `["assert/**/go.mod", "env/**/go.mod"]`.
94
+
95
+ - **`skipGoModTidy` (boolean, optional):**
96
+ Skip running `go mod tidy` in each submodule directory after pinning the
97
+ require version. Useful when Go is not available in the CI environment or
98
+ for debugging. Default: `false`.
99
+
100
+ - **`pushTags` (boolean, optional):**
101
+ Push the created submodule tags to the remote origin after creating them
102
+ locally. Set to `false` to create tags locally only. Default: `true`.
103
+
104
+ ## Tag Naming
105
+
106
+ The git tag created for each module is derived from the relative path of
107
+ its `go.mod` directory to the repository root:
108
+
109
+ | `go.mod` location | Git tag |
110
+ | ------------------------------ | ---------------------------- |
111
+ | `./go.mod` | `v1.2.3` |
112
+ | `./assert/cert/manager/go.mod` | `assert/cert/manager/v1.2.3` |
113
+ | `./env/flux/helm/go.mod` | `env/flux/helm/v1.2.3` |
114
+
115
+ ## Known Issues
116
+
117
+ - None.
118
+
119
+ ## Useful links
120
+
121
+ - **[Go Modules Reference](https://go.dev/ref/mod):** Official Go modules
122
+ documentation.
123
+ - **[Module version numbering](https://go.dev/doc/modules/version-numbers):**
124
+ How Go module version numbers work.
125
+
126
+ ## Contributing
127
+
128
+ If you have suggestions for how this plugin could be improved, or
129
+ want to report a bug, open an issue — we'd love all and any
130
+ contributions.
131
+
132
+ ## License
133
+
134
+ Apache License 2.0 © 2024 Mridang Agarwalla
package/dist/exec.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { type ExecSyncOptions } from 'child_process';
2
+ /**
3
+ * A function that executes a shell command synchronously.
4
+ * Accepting this as a parameter makes the callers unit-testable
5
+ * without needing to mock Node.js built-in modules.
6
+ *
7
+ * Implementations must throw when the command exits with a non-zero
8
+ * status (matching the default behaviour of Node's `execSync`).
9
+ * Callers are responsible for catching and handling failures.
10
+ */
11
+ export type ExecFn = (cmd: string, opts?: ExecSyncOptions) => void;
12
+ /**
13
+ * Default executor that delegates to Node's built-in `execSync`.
14
+ */
15
+ export declare const defaultExec: ExecFn;
package/dist/exec.js ADDED
@@ -0,0 +1,8 @@
1
+ import { execSync as nodeExecSync } from 'child_process';
2
+ /**
3
+ * Default executor that delegates to Node's built-in `execSync`.
4
+ */
5
+ export const defaultExec = (cmd, opts) => {
6
+ nodeExecSync(cmd, opts);
7
+ };
8
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAwB,MAAM,eAAe,CAAC;AAa/E;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAC/C,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { type ExecFn } from './exec.js';
2
+ /**
3
+ * Minimal logger interface compatible with the semantic-release context logger.
4
+ */
5
+ interface Logger {
6
+ log(message: string, ...args: unknown[]): void;
7
+ warn(message: string, ...args: unknown[]): void;
8
+ }
9
+ /**
10
+ * Walk `root` recursively and return the absolute paths of every
11
+ * go.mod file found, excluding the root-level go.mod itself.
12
+ *
13
+ * When `globPatterns` are provided the walk is skipped and the
14
+ * patterns are expanded against `root` instead.
15
+ *
16
+ * @param root Absolute path to the repository root.
17
+ * @param globPatterns Optional array of glob patterns relative to root.
18
+ * @returns Sorted array of absolute go.mod paths (submodules only).
19
+ */
20
+ export declare function discoverSubmoduleGoMods(root: string, globPatterns?: readonly string[]): readonly string[];
21
+ /**
22
+ * Read a go.mod file and extract the module declaration.
23
+ *
24
+ * @param goModPath Absolute path to the go.mod file.
25
+ * @returns The module import path, e.g. `"github.com/mridang/wilhelm"`.
26
+ * @throws Error if no `module` line is found.
27
+ */
28
+ export declare function readModulePath(goModPath: string): string;
29
+ /**
30
+ * Update every `require` line in a go.mod file whose import path
31
+ * starts with `rootModule`, replacing the version with `newVersion`.
32
+ * Lines with `// indirect` comments are preserved as-is.
33
+ *
34
+ * Handles both single-line requires and require blocks.
35
+ *
36
+ * @param filePath Absolute path to the go.mod file to rewrite.
37
+ * @param rootModule Root module import path (e.g. `"github.com/mridang/wilhelm"`).
38
+ * @param newVersion New semver string without leading `v` (e.g. `"1.2.3"`).
39
+ */
40
+ export declare function updateGoModRequires(filePath: string, rootModule: string, newVersion: string): void;
41
+ /**
42
+ * Derive the git tag prefix for a submodule given its go.mod path
43
+ * and the repository root.
44
+ *
45
+ * - Root module (`./go.mod`) → `""` (tag = `"v1.2.3"`)
46
+ * - Submodule (`./assert/cert/manager/go.mod`) → `"assert/cert/manager"`
47
+ *
48
+ * @param goModPath Absolute path to the go.mod file.
49
+ * @param repoRoot Absolute path to the repository root.
50
+ * @returns Tag prefix string (empty string for the root module).
51
+ */
52
+ export declare function deriveTagPrefix(goModPath: string, repoRoot: string): string;
53
+ /**
54
+ * Create a git tag locally and optionally push it to origin.
55
+ * Silently ignores the case where the tag already exists so the
56
+ * plugin can be called idempotently.
57
+ *
58
+ * @param repoRoot Absolute path to the repository root.
59
+ * @param tag Full tag string, e.g. `"assert/cert/manager/v1.2.3"`.
60
+ * @param push When true, push the tag to `origin`.
61
+ * @param logger semantic-release logger.
62
+ * @param exec Command executor (injectable for testing).
63
+ */
64
+ export declare function createAndPushTag(repoRoot: string, tag: string, push: boolean, logger: Logger, exec?: ExecFn): void;
65
+ export {};
package/dist/gomod.js ADDED
@@ -0,0 +1,177 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { defaultExec } from './exec.js';
4
+ /**
5
+ * Read a directory, returning an empty array on any I/O error.
6
+ */
7
+ function safeReadDir(dir) {
8
+ try {
9
+ return fs.readdirSync(dir, { withFileTypes: true });
10
+ }
11
+ catch {
12
+ return [];
13
+ }
14
+ }
15
+ /**
16
+ * Walk `root` recursively and return the absolute paths of every
17
+ * go.mod file found, excluding the root-level go.mod itself.
18
+ *
19
+ * When `globPatterns` are provided the walk is skipped and the
20
+ * patterns are expanded against `root` instead.
21
+ *
22
+ * @param root Absolute path to the repository root.
23
+ * @param globPatterns Optional array of glob patterns relative to root.
24
+ * @returns Sorted array of absolute go.mod paths (submodules only).
25
+ */
26
+ export function discoverSubmoduleGoMods(root, globPatterns) {
27
+ if (globPatterns && globPatterns.length > 0) {
28
+ const results = globPatterns.flatMap((pattern) => expandGlob(root, pattern));
29
+ return [...new Set(results)].sort();
30
+ }
31
+ // Auto-discover: walk the tree
32
+ return walkForGoMods(root)
33
+ .filter((f) => f !== path.join(root, 'go.mod'))
34
+ .sort();
35
+ }
36
+ /**
37
+ * Recursively walk `dir` and return absolute paths of all go.mod files.
38
+ */
39
+ function walkForGoMods(dir) {
40
+ return safeReadDir(dir).flatMap((entry) => {
41
+ if (entry.name === 'vendor' || entry.name === 'node_modules')
42
+ return [];
43
+ const full = path.join(dir, entry.name);
44
+ if (entry.isDirectory())
45
+ return [...walkForGoMods(full)];
46
+ if (entry.isFile() && entry.name === 'go.mod')
47
+ return [full];
48
+ return [];
49
+ });
50
+ }
51
+ /**
52
+ * Minimal glob expander supporting `**` as a recursive wildcard.
53
+ * Only handles the patterns this plugin actually uses, e.g.
54
+ * `"assert/**\/go.mod"` or `"env/*\/go.mod"`.
55
+ */
56
+ function expandGlob(root, pattern) {
57
+ return matchParts(root, pattern.split('/'));
58
+ }
59
+ function matchParts(dir, parts) {
60
+ if (parts.length === 0)
61
+ return [];
62
+ const [head, ...tail] = parts;
63
+ if (head === '**') {
64
+ // Zero levels: continue with tail from current dir.
65
+ // One or more levels: descend into each subdirectory.
66
+ return [
67
+ ...matchParts(dir, tail),
68
+ ...safeReadDir(dir)
69
+ .filter((e) => e.isDirectory())
70
+ .flatMap((e) => matchParts(path.join(dir, e.name), parts)),
71
+ ];
72
+ }
73
+ if (tail.length === 0) {
74
+ // Last segment — must be a file (single statSync avoids TOCTOU)
75
+ const candidate = path.join(dir, head);
76
+ try {
77
+ return fs.statSync(candidate).isFile() ? [candidate] : [];
78
+ }
79
+ catch {
80
+ return [];
81
+ }
82
+ }
83
+ if (head === '*') {
84
+ // Single-level wildcard
85
+ return safeReadDir(dir)
86
+ .filter((e) => e.isDirectory())
87
+ .flatMap((e) => matchParts(path.join(dir, e.name), tail));
88
+ }
89
+ // Literal segment — safeReadDir handles missing/unreadable paths gracefully
90
+ return matchParts(path.join(dir, head), tail);
91
+ }
92
+ /**
93
+ * Read a go.mod file and extract the module declaration.
94
+ *
95
+ * @param goModPath Absolute path to the go.mod file.
96
+ * @returns The module import path, e.g. `"github.com/mridang/wilhelm"`.
97
+ * @throws Error if no `module` line is found.
98
+ */
99
+ export function readModulePath(goModPath) {
100
+ const content = fs.readFileSync(goModPath, 'utf8');
101
+ for (const line of content.split('\n')) {
102
+ const m = line.match(/^module\s+(\S+)/);
103
+ if (m)
104
+ return m[1];
105
+ }
106
+ throw new Error(`No module declaration found in ${goModPath}`);
107
+ }
108
+ /**
109
+ * Update every `require` line in a go.mod file whose import path
110
+ * starts with `rootModule`, replacing the version with `newVersion`.
111
+ * Lines with `// indirect` comments are preserved as-is.
112
+ *
113
+ * Handles both single-line requires and require blocks.
114
+ *
115
+ * @param filePath Absolute path to the go.mod file to rewrite.
116
+ * @param rootModule Root module import path (e.g. `"github.com/mridang/wilhelm"`).
117
+ * @param newVersion New semver string without leading `v` (e.g. `"1.2.3"`).
118
+ */
119
+ export function updateGoModRequires(filePath, rootModule, newVersion) {
120
+ const content = fs.readFileSync(filePath, 'utf8');
121
+ // Escape slashes and dots in the module path for use in regex
122
+ const escaped = rootModule.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
123
+ // Match: <module_path_starting_with_root> <v-prefixed-version> [optional comment]
124
+ const pattern = new RegExp(`(${escaped}[^\\s]*)\\s+v[0-9]\\S*`, 'g');
125
+ const updated = content.replace(pattern, `$1 v${newVersion}`);
126
+ if (updated !== content) {
127
+ fs.writeFileSync(filePath, updated, 'utf8');
128
+ }
129
+ }
130
+ /**
131
+ * Derive the git tag prefix for a submodule given its go.mod path
132
+ * and the repository root.
133
+ *
134
+ * - Root module (`./go.mod`) → `""` (tag = `"v1.2.3"`)
135
+ * - Submodule (`./assert/cert/manager/go.mod`) → `"assert/cert/manager"`
136
+ *
137
+ * @param goModPath Absolute path to the go.mod file.
138
+ * @param repoRoot Absolute path to the repository root.
139
+ * @returns Tag prefix string (empty string for the root module).
140
+ */
141
+ export function deriveTagPrefix(goModPath, repoRoot) {
142
+ return path.relative(repoRoot, path.dirname(goModPath));
143
+ }
144
+ /**
145
+ * Create a git tag locally and optionally push it to origin.
146
+ * Silently ignores the case where the tag already exists so the
147
+ * plugin can be called idempotently.
148
+ *
149
+ * @param repoRoot Absolute path to the repository root.
150
+ * @param tag Full tag string, e.g. `"assert/cert/manager/v1.2.3"`.
151
+ * @param push When true, push the tag to `origin`.
152
+ * @param logger semantic-release logger.
153
+ * @param exec Command executor (injectable for testing).
154
+ */
155
+ export function createAndPushTag(repoRoot, tag, push, logger, exec = defaultExec) {
156
+ try {
157
+ exec(`git tag "${tag}"`, { cwd: repoRoot, stdio: 'pipe' });
158
+ logger.log('Created tag %s', tag);
159
+ }
160
+ catch (err) {
161
+ const msg = err instanceof Error ? err.message : String(err);
162
+ if (msg.includes('already exists')) {
163
+ logger.log('Tag %s already exists, skipping', tag);
164
+ }
165
+ else {
166
+ throw err;
167
+ }
168
+ }
169
+ if (push) {
170
+ exec(`git push origin "refs/tags/${tag}"`, {
171
+ cwd: repoRoot,
172
+ stdio: 'pipe',
173
+ });
174
+ logger.log('Pushed tag %s', tag);
175
+ }
176
+ }
177
+ //# sourceMappingURL=gomod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gomod.js","sourceRoot":"","sources":["../src/gomod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { PrepareContext, PublishContext, VerifyConditionsContext } from 'semantic-release';
2
+ import { type ExecFn } from './exec.js';
3
+ import { GomodPluginConfig } from './plugin-config.js';
4
+ /**
5
+ * Verify that all preconditions for the plugin are met:
6
+ * - A root `go.mod` exists in the working directory.
7
+ * - `git` is available on PATH.
8
+ *
9
+ * A warning (not an error) is emitted when no submodule go.mod files
10
+ * are found, since the plugin is still useful for single-module repos
11
+ * (it will create the root tag in the publish step).
12
+ *
13
+ * @param pluginConfig The plugin configuration.
14
+ * @param context The semantic-release context.
15
+ * @param exec Command executor (injectable for testing).
16
+ */
17
+ export declare function verifyConditions(pluginConfig: GomodPluginConfig, context: VerifyConditionsContext, exec?: ExecFn): Promise<void>;
18
+ /**
19
+ * Pin every submodule `go.mod` require line that references the root
20
+ * module (or any of its sub-paths) to the new release version.
21
+ *
22
+ * Optionally runs `go mod tidy` in each submodule directory afterward.
23
+ * The actual commit is handled by `@semantic-release/git`.
24
+ *
25
+ * @param pluginConfig The plugin configuration.
26
+ * @param context The semantic-release context.
27
+ * @param exec Command executor (injectable for testing).
28
+ */
29
+ export declare function prepare(pluginConfig: GomodPluginConfig, context: PrepareContext, exec?: ExecFn): Promise<void>;
30
+ /**
31
+ * Create and push a git tag for every module in the repository,
32
+ * including the root module.
33
+ *
34
+ * semantic-release creates the root tag (`vX.Y.Z`) before calling
35
+ * publish; this step creates it silently when it already exists and
36
+ * then creates all submodule tags
37
+ * (e.g. `assert/cert/manager/vX.Y.Z`).
38
+ *
39
+ * @param pluginConfig The plugin configuration.
40
+ * @param context The semantic-release context.
41
+ * @param exec Command executor (injectable for testing).
42
+ */
43
+ export declare function publish(pluginConfig: GomodPluginConfig, context: PublishContext, exec?: ExecFn): Promise<void>;
44
+ declare const _default: {
45
+ readonly verifyConditions: typeof verifyConditions;
46
+ readonly prepare: typeof prepare;
47
+ readonly publish: typeof publish;
48
+ };
49
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import SemanticReleaseError from '@semantic-release/error';
4
+ import { defaultExec } from './exec.js';
5
+ import { GomodConfig } from './plugin-config.js';
6
+ import { createAndPushTag, deriveTagPrefix, discoverSubmoduleGoMods, readModulePath, updateGoModRequires, } from './gomod.js';
7
+ /**
8
+ * Verify that all preconditions for the plugin are met:
9
+ * - A root `go.mod` exists in the working directory.
10
+ * - `git` is available on PATH.
11
+ *
12
+ * A warning (not an error) is emitted when no submodule go.mod files
13
+ * are found, since the plugin is still useful for single-module repos
14
+ * (it will create the root tag in the publish step).
15
+ *
16
+ * @param pluginConfig The plugin configuration.
17
+ * @param context The semantic-release context.
18
+ * @param exec Command executor (injectable for testing).
19
+ */
20
+ export async function verifyConditions(pluginConfig, context, exec = defaultExec) {
21
+ const { logger } = context;
22
+ const cwd = context.cwd ?? process.cwd();
23
+ const config = new GomodConfig(pluginConfig);
24
+ const rootGoMod = path.join(cwd, 'go.mod');
25
+ if (!fs.existsSync(rootGoMod)) {
26
+ throw new SemanticReleaseError('go.mod not found.', 'EMISSINGGOMOD', `A \`go.mod\` file is required at the repository root but was not found in ${cwd}. Ensure the plugin is configured for a Go module repository.`);
27
+ }
28
+ try {
29
+ exec('git --version', { stdio: 'pipe' });
30
+ }
31
+ catch {
32
+ throw new SemanticReleaseError('git is not available.', 'ENOGIT', 'The `git` executable could not be found. Ensure git is installed and available on PATH.');
33
+ }
34
+ const submodules = discoverSubmoduleGoMods(cwd, config.getModules());
35
+ if (submodules.length === 0) {
36
+ logger.log('No submodule go.mod files found — operating in single-module mode.');
37
+ }
38
+ else {
39
+ logger.log('Found %d submodule(s).', submodules.length);
40
+ }
41
+ }
42
+ /**
43
+ * Pin every submodule `go.mod` require line that references the root
44
+ * module (or any of its sub-paths) to the new release version.
45
+ *
46
+ * Optionally runs `go mod tidy` in each submodule directory afterward.
47
+ * The actual commit is handled by `@semantic-release/git`.
48
+ *
49
+ * @param pluginConfig The plugin configuration.
50
+ * @param context The semantic-release context.
51
+ * @param exec Command executor (injectable for testing).
52
+ */
53
+ export async function prepare(pluginConfig, context, exec = defaultExec) {
54
+ const { logger, nextRelease: { version }, } = context;
55
+ const cwd = context.cwd ?? process.cwd();
56
+ const config = new GomodConfig(pluginConfig);
57
+ const rootGoMod = path.join(cwd, 'go.mod');
58
+ const rootModule = readModulePath(rootGoMod);
59
+ logger.log('Root module: %s', rootModule);
60
+ const submodules = discoverSubmoduleGoMods(cwd, config.getModules());
61
+ if (submodules.length === 0) {
62
+ logger.log('No submodules to update.');
63
+ return;
64
+ }
65
+ for (const goModPath of submodules) {
66
+ logger.log('Pinning requires in %s', path.relative(cwd, goModPath));
67
+ updateGoModRequires(goModPath, rootModule, version);
68
+ if (!config.isSkipGoModTidy()) {
69
+ const modDir = path.dirname(goModPath);
70
+ try {
71
+ exec('go mod tidy', { cwd: modDir, stdio: 'pipe' });
72
+ logger.log('go mod tidy OK in %s', path.relative(cwd, modDir));
73
+ }
74
+ catch (err) {
75
+ const msg = err instanceof Error ? err.message : String(err);
76
+ logger.warn('go mod tidy failed in %s: %s', path.relative(cwd, modDir), msg);
77
+ }
78
+ }
79
+ }
80
+ logger.log('Prepared %d submodule(s) for v%s.', submodules.length, version);
81
+ }
82
+ /**
83
+ * Create and push a git tag for every module in the repository,
84
+ * including the root module.
85
+ *
86
+ * semantic-release creates the root tag (`vX.Y.Z`) before calling
87
+ * publish; this step creates it silently when it already exists and
88
+ * then creates all submodule tags
89
+ * (e.g. `assert/cert/manager/vX.Y.Z`).
90
+ *
91
+ * @param pluginConfig The plugin configuration.
92
+ * @param context The semantic-release context.
93
+ * @param exec Command executor (injectable for testing).
94
+ */
95
+ export async function publish(pluginConfig, context, exec = defaultExec) {
96
+ const { logger, nextRelease: { version }, } = context;
97
+ const cwd = context.cwd ?? process.cwd();
98
+ const config = new GomodConfig(pluginConfig);
99
+ // All go.mod files: submodules + root
100
+ const submodules = discoverSubmoduleGoMods(cwd, config.getModules());
101
+ const allGoMods = [
102
+ path.join(cwd, 'go.mod'),
103
+ ...submodules,
104
+ ];
105
+ for (const goModPath of allGoMods) {
106
+ const prefix = deriveTagPrefix(goModPath, cwd);
107
+ const tag = prefix ? `${prefix}/v${version}` : `v${version}`;
108
+ createAndPushTag(cwd, tag, config.isPushTagsEnabled(), logger, exec);
109
+ }
110
+ logger.log('Tagged %d module(s) at v%s.', allGoMods.length, version);
111
+ }
112
+ export default { verifyConditions, prepare, publish };
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { Config } from 'semantic-release';
2
+ /**
3
+ * Raw plugin configuration as provided by the user in their
4
+ * semantic-release config file. All fields are optional — the
5
+ * plugin works with zero configuration by auto-detecting all
6
+ * submodule go.mod files in the repository.
7
+ */
8
+ export interface GomodPluginConfig extends Config {
9
+ /**
10
+ * Glob patterns (relative to cwd) that match submodule go.mod files.
11
+ * When omitted, the plugin walks the repository and treats every
12
+ * go.mod file except the root-level one as a submodule.
13
+ *
14
+ * @example ["assert/**\/go.mod", "env/**\/go.mod"]
15
+ */
16
+ readonly modules?: string | readonly string[];
17
+ /**
18
+ * Skip running `go mod tidy` in each submodule directory after
19
+ * pinning the require version. Useful when Go is not available in
20
+ * the CI environment or for debugging. Defaults to false.
21
+ */
22
+ readonly skipGoModTidy?: boolean;
23
+ /**
24
+ * Push the created submodule tags to the remote origin after
25
+ * creating them locally. Set to false to create tags locally only.
26
+ * Defaults to true.
27
+ */
28
+ readonly pushTags?: boolean;
29
+ }
30
+ /**
31
+ * GomodConfig wraps the raw plugin config and exposes derived values
32
+ * with sensible defaults. It centralises option reading so the plugin
33
+ * lifecycle hooks stay small and consistent.
34
+ */
35
+ export declare class GomodConfig {
36
+ private readonly config;
37
+ constructor(config: GomodPluginConfig);
38
+ /**
39
+ * Returns the user-supplied glob patterns for submodule go.mod files,
40
+ * normalised to an array. Returns undefined when not configured,
41
+ * which signals the plugin to auto-discover.
42
+ *
43
+ * @returns Readonly array of glob strings, or undefined for auto-detection.
44
+ */
45
+ getModules(): readonly string[] | undefined;
46
+ /**
47
+ * Whether to skip `go mod tidy` after pinning submodule versions.
48
+ *
49
+ * @returns true only when explicitly set to true.
50
+ */
51
+ isSkipGoModTidy(): boolean;
52
+ /**
53
+ * Whether to push submodule tags to origin after creating them.
54
+ *
55
+ * @returns true unless explicitly disabled.
56
+ */
57
+ isPushTagsEnabled(): boolean;
58
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * GomodConfig wraps the raw plugin config and exposes derived values
3
+ * with sensible defaults. It centralises option reading so the plugin
4
+ * lifecycle hooks stay small and consistent.
5
+ */
6
+ export class GomodConfig {
7
+ config;
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ /**
12
+ * Returns the user-supplied glob patterns for submodule go.mod files,
13
+ * normalised to an array. Returns undefined when not configured,
14
+ * which signals the plugin to auto-discover.
15
+ *
16
+ * @returns Readonly array of glob strings, or undefined for auto-detection.
17
+ */
18
+ getModules() {
19
+ const { modules } = this.config;
20
+ if (!modules)
21
+ return undefined;
22
+ if (typeof modules === 'string')
23
+ return [modules];
24
+ return modules;
25
+ }
26
+ /**
27
+ * Whether to skip `go mod tidy` after pinning submodule versions.
28
+ *
29
+ * @returns true only when explicitly set to true.
30
+ */
31
+ isSkipGoModTidy() {
32
+ return this.config.skipGoModTidy === true;
33
+ }
34
+ /**
35
+ * Whether to push submodule tags to origin after creating them.
36
+ *
37
+ * @returns true unless explicitly disabled.
38
+ */
39
+ isPushTagsEnabled() {
40
+ return this.config.pushTags !== false;
41
+ }
42
+ }
43
+ //# sourceMappingURL=plugin-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-config.js","sourceRoot":"","sources":["../src/plugin-config.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACO;IAA7B,YAA6B,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAE1D;;;;;;OAMG;IACH,UAAU;QACR,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,IAAI,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC;IACxC,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@mridang/semantic-release-gomod",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "prepack": "tsc",
7
+ "build": "tsc",
8
+ "test": "jest --verbose --config=jest.config.mjs --runInBand",
9
+ "test:watch": "npm run test -- --watch",
10
+ "test:debug": "jest --verbose --config=jest.config.mjs --runInBand --detectOpenHandles",
11
+ "format": "prettier --write .",
12
+ "format:check": "prettier --check .",
13
+ "lint": "npx eslint .",
14
+ "lint:fix": "npx eslint . --fix"
15
+ },
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "keywords": [
19
+ "semver",
20
+ "nodejs",
21
+ "semantic-release",
22
+ "go",
23
+ "golang",
24
+ "gomod"
25
+ ],
26
+ "author": {
27
+ "name": "Mridang Agarwalla",
28
+ "email": "mridang.agarwalla@gmail.com",
29
+ "url": "https://github.com/mridang"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "license": "Apache-2.0",
35
+ "description": "Semantic Release plugin for multi-module Go repositories: pins submodule require lines and creates per-module git tags",
36
+ "private": false,
37
+ "engines": {
38
+ "node": ">=22.0.0"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/mridang/semantic-release-gomod.git"
43
+ },
44
+ "homepage": "https://github.com/mridang/semantic-release-gomod",
45
+ "bugs": "https://github.com/mridang/semantic-release-gomod/issues",
46
+ "dependencies": {
47
+ "@semantic-release/error": "^4.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@jest/globals": "^30.0.3",
51
+ "@mridang/eslint-defaults": "^1.4.0",
52
+ "@semantic-release/commit-analyzer": "^13.0.1",
53
+ "@semantic-release/git": "^10.0.1",
54
+ "@semantic-release/github": "^12.0.0",
55
+ "@semantic-release/npm": "^13.1.1",
56
+ "@semantic-release/release-notes-generator": "^14.1.0",
57
+ "@tsconfig/node22": "^22.0.2",
58
+ "@types/jest": "^30.0.0",
59
+ "@types/node": "^22.18.12",
60
+ "@types/semantic-release__error": "^3.0.3",
61
+ "eslint": "^9.27.0",
62
+ "jest": "^30.0.3",
63
+ "jest-junit": "^17.0.0",
64
+ "knip": "^5.43.6",
65
+ "prettier": "^3.1.1",
66
+ "semantic-release": "^25.0.1",
67
+ "ts-jest": "^29.4.0",
68
+ "typescript": "^5.9.3"
69
+ },
70
+ "publishConfig": {
71
+ "access": "public"
72
+ }
73
+ }