@simplysf/simply-project 1.3.1 → 1.4.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 CHANGED
@@ -20,9 +20,101 @@ This package is part of the [`@simplysf/simply`](https://github.com/SimplySF/sim
20
20
 
21
21
  <!-- commands -->
22
22
 
23
+ - [`sf simply project release create`](#sf-simply-project-release-create)
23
24
  - [`sf simply project release roll-forward`](#sf-simply-project-release-roll-forward)
24
25
  - [`sf simply project update api-version`](#sf-simply-project-update-api-version)
25
26
 
27
+ ## `sf simply project release create`
28
+
29
+ Cut the next release branch, with its version bumped in sfdx-project.json.
30
+
31
+ ```
32
+ USAGE
33
+ $ sf simply project release create [--json] [--flags-dir <value>] [-t major|minor|patch] [--source <value>]
34
+ [--package-release-branch-prefix <value>] [--remote <value>] [--message <value>] [--create-release] [--release-tag
35
+ <value>] [-s] [--vcs-provider gitlab|github] [--vcs-host <value>] [--vcs-project-id <value>] [--vcs-token <value>]
36
+ [--dry-run] [--no-prompt]
37
+
38
+ FLAGS
39
+ -s, --set-default Make the new branch the project's default branch after pushing.
40
+ -t, --type=<option> Version to bump: major, minor, or patch. Asked for when omitted in a
41
+ terminal.
42
+ <options: major|minor|patch>
43
+ --create-release Publish a GitLab or GitHub release for the source's version before
44
+ cutting.
45
+ --dry-run Print the plan, including the tag a release would use, without changing
46
+ anything.
47
+ --message=<value> Commit message template, with an optional {VERSION} placeholder. Defaults
48
+ to "chore: bump version to {VERSION}".
49
+ --no-prompt Don't ask for confirmation, or for --type.
50
+ --package-release-branch-prefix=<value> [default: release/] Prefix identifying release branches. Branch names
51
+ must then be `[v]MAJOR.MINOR[.PATCH]`.
52
+ --release-tag=<value> Tag to publish the release from, instead of the latest build tag. Implies
53
+ --create-release.
54
+ --remote=<value> [default: origin] Remote holding the release branches.
55
+ --source=<value> Release branch to cut from. Defaults to the current branch.
56
+ --vcs-host=<value> VCS hostname, for a self-hosted instance. Defaults to SIMPLY_VCS_HOST,
57
+ then vcs.host in .sfdevrc.json.
58
+ --vcs-project-id=<value> GitLab project ID or GitHub owner/repo. Defaults to
59
+ SIMPLY_VCS_PROJECT_ID, then vcs.projectId in .sfdevrc.json.
60
+ --vcs-provider=<option> VCS platform. Defaults to SIMPLY_VCS_PROVIDER, then vcs.provider in
61
+ .sfdevrc.json, then gitlab.
62
+ <options: gitlab|github>
63
+ --vcs-token=<value> [env: SIMPLY_VCS_TOKEN] VCS API token, needed only with --create-release,
64
+ --release-tag, or --set-default.
65
+
66
+ GLOBAL FLAGS
67
+ --flags-dir=<value> Import flag values from a directory.
68
+ --json Format output as json.
69
+
70
+ DESCRIPTION
71
+ Cut the next release branch, with its version bumped in sfdx-project.json.
72
+
73
+ Run this from a local clone, on the release branch to cut from, or pass `--source`. The new branch, such as
74
+ `release/v1.3.0` from `release/v1.2.0`, starts from the remote's copy of the source, never from local commits, and
75
+ gets one commit that bumps `sfdx-project.json`: `versionNumber` becomes `1.3.0.NEXT` in every package directory on the
76
+ source's version, and the version inside `versionName` is replaced in place. Then the branch is pushed. A version that
77
+ already has a branch is refused. A patch on an older line is allowed while newer releases exist, for hotfixes.
78
+
79
+ With `--create-release`, a GitLab or GitHub release for the version being closed out is published first, from the
80
+ highest `v<version>.<build>` tag that is reachable from the source and on the remote. Fallback tags are skipped. A
81
+ release that already exists is reported, not recreated. With `--set-default`, the new branch becomes the project's
82
+ default after the push. Both need a token, from `--vcs-token` or `SIMPLY_VCS_TOKEN`, and a project ID, from
83
+ `--vcs-project-id`, `SIMPLY_VCS_PROJECT_ID`, or `vcs.projectId` in `.sfdevrc.json`. These are checked before anything
84
+ changes.
85
+
86
+ Your repository's commit hooks always run. The default commit message is `chore: bump version to {VERSION}`; use
87
+ `--message` if your rules need something else, such as a ticket number. If a hook rejects the commit, nothing is
88
+ pushed, and the bump stays staged on the new local branch. Run `git commit` with an accepted message, then run this
89
+ command again from that branch.
90
+
91
+ The command never force-pushes or pushes tags. Pushing the new branch triggers a normal release-branch build, which
92
+ creates the new release's first package version.
93
+
94
+ EXAMPLES
95
+ Cut the next minor release from the current release branch:
96
+
97
+ $ sf simply project release create --type minor
98
+
99
+ See what would happen, without changing anything:
100
+
101
+ $ sf simply project release create --type minor --dry-run
102
+
103
+ Cut a hotfix from an older release:
104
+
105
+ $ sf simply project release create --type patch --source release/v1.2.0
106
+
107
+ Also publish a release for the current version and make the new branch the default:
108
+
109
+ $ sf simply project release create --type minor --create-release --set-default
110
+
111
+ Use a commit message your repository's rules accept:
112
+
113
+ $ sf simply project release create --type minor --message "chore: PROJ-123 bump version to {VERSION}"
114
+ ```
115
+
116
+ _See code: [lib/commands/simply/project/release/create.js](https://github.com/SimplySF/simply-plugins/blob/@simplysf/simply-project@1.4.0/packages/simply-project/lib/commands/simply/project/release/create.js)_
117
+
26
118
  ## `sf simply project release roll-forward`
27
119
 
28
120
  Merge each release branch into the next higher one, keeping version tags in the target's history.
@@ -97,7 +189,7 @@ EXAMPLES
97
189
  $ sf simply project release roll-forward --no-push
98
190
  ```
99
191
 
100
- _See code: [lib/commands/simply/project/release/roll-forward.js](https://github.com/SimplySF/simply-plugins/blob/@simplysf/simply-project@1.3.1/packages/simply-project/lib/commands/simply/project/release/roll-forward.js)_
192
+ _See code: [lib/commands/simply/project/release/roll-forward.js](https://github.com/SimplySF/simply-plugins/blob/@simplysf/simply-project@1.4.0/packages/simply-project/lib/commands/simply/project/release/roll-forward.js)_
101
193
 
102
194
  ## `sf simply project update api-version`
103
195
 
@@ -136,7 +228,7 @@ FLAG DESCRIPTIONS
136
228
  The path to the Salesforce project directory to scan for metadata files.
137
229
  ```
138
230
 
139
- _See code: [lib/commands/simply/project/update/api-version.js](https://github.com/SimplySF/simply-plugins/blob/@simplysf/simply-project@1.3.1/packages/simply-project/lib/commands/simply/project/update/api-version.js)_
231
+ _See code: [lib/commands/simply/project/update/api-version.js](https://github.com/SimplySF/simply-plugins/blob/@simplysf/simply-project@1.4.0/packages/simply-project/lib/commands/simply/project/update/api-version.js)_
140
232
  <!-- commandsstop -->
141
233
 
142
234
  ## License
@@ -0,0 +1,30 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ import { type CreateReleaseResult, type ReleaseType } from '@simplysf/simply-project-core';
3
+ export type ProjectReleaseCreateResult = CreateReleaseResult;
4
+ /** Cuts the next release branch, and optionally publishes a release and sets the default branch. */
5
+ export default class ProjectReleaseCreate extends SfCommand<ProjectReleaseCreateResult> {
6
+ static readonly summary: string;
7
+ static readonly description: string;
8
+ static readonly examples: string[];
9
+ static readonly enableJsonFlag = true;
10
+ static readonly flags: {
11
+ type: import("@oclif/core/interfaces").OptionFlag<ReleaseType | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ source: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'package-release-branch-prefix': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ remote: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ message: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ 'create-release': import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
+ 'release-tag': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ 'set-default': import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
+ 'vcs-provider': import("@oclif/core/interfaces").OptionFlag<"gitlab" | "github" | undefined, import("@oclif/core/interfaces").CustomOptions>;
20
+ 'vcs-host': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ 'vcs-project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ 'vcs-token': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
23
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
24
+ 'no-prompt': import("@oclif/core/interfaces").BooleanFlag<boolean>;
25
+ 'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
26
+ };
27
+ run(): Promise<ProjectReleaseCreateResult>;
28
+ protected promptForType(): Promise<ReleaseType>;
29
+ private confirmPlan;
30
+ }
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Copyright (c) 2026, SimplySF.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { select } from '@inquirer/prompts';
17
+ import { Messages } from '@salesforce/core';
18
+ import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
19
+ import { VCS_PROVIDER_KINDS } from '@simplysf/simply-core';
20
+ import { createRelease, RELEASE_TYPES, resolveReleaseVcs, } from '@simplysf/simply-project-core';
21
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
22
+ const messages = Messages.loadMessages('@simplysf/simply-project', 'simply.project.release.create');
23
+ /** Cuts the next release branch, and optionally publishes a release and sets the default branch. */
24
+ export default class ProjectReleaseCreate extends SfCommand {
25
+ static summary = messages.getMessage('summary');
26
+ static description = messages.getMessage('description');
27
+ static examples = messages.getMessages('examples');
28
+ static enableJsonFlag = true;
29
+ static flags = {
30
+ ...SfCommand.baseFlags,
31
+ type: Flags.custom({ options: [...RELEASE_TYPES] })({
32
+ char: 't',
33
+ summary: messages.getMessage('flags.type.summary'),
34
+ }),
35
+ source: Flags.string({ summary: messages.getMessage('flags.source.summary') }),
36
+ 'package-release-branch-prefix': Flags.string({
37
+ summary: messages.getMessage('flags.package-release-branch-prefix.summary'),
38
+ default: 'release/',
39
+ }),
40
+ remote: Flags.string({ summary: messages.getMessage('flags.remote.summary'), default: 'origin' }),
41
+ message: Flags.string({ summary: messages.getMessage('flags.message.summary') }),
42
+ 'create-release': Flags.boolean({ summary: messages.getMessage('flags.create-release.summary'), default: false }),
43
+ 'release-tag': Flags.string({ summary: messages.getMessage('flags.release-tag.summary') }),
44
+ 'set-default': Flags.boolean({
45
+ char: 's',
46
+ summary: messages.getMessage('flags.set-default.summary'),
47
+ default: false,
48
+ }),
49
+ 'vcs-provider': Flags.custom({ options: [...VCS_PROVIDER_KINDS] })({
50
+ summary: messages.getMessage('flags.vcs-provider.summary'),
51
+ }),
52
+ 'vcs-host': Flags.string({ summary: messages.getMessage('flags.vcs-host.summary') }),
53
+ 'vcs-project-id': Flags.string({ summary: messages.getMessage('flags.vcs-project-id.summary') }),
54
+ 'vcs-token': Flags.string({ summary: messages.getMessage('flags.vcs-token.summary'), env: 'SIMPLY_VCS_TOKEN' }),
55
+ 'dry-run': Flags.boolean({ summary: messages.getMessage('flags.dry-run.summary'), default: false }),
56
+ 'no-prompt': Flags.boolean({ summary: messages.getMessage('flags.no-prompt.summary'), default: false }),
57
+ };
58
+ async run() {
59
+ const { flags } = await this.parse(ProjectReleaseCreate);
60
+ const interactive = !flags['no-prompt'] && !flags['dry-run'] && !this.jsonEnabled();
61
+ const type = flags.type ?? (interactive ? await this.promptForType() : undefined);
62
+ if (!type) {
63
+ this.error(messages.getMessage('error.typeRequired'));
64
+ }
65
+ const wantsVcs = flags['create-release'] || flags['release-tag'] !== undefined || flags['set-default'];
66
+ const vcs = wantsVcs
67
+ ? resolveReleaseVcs({
68
+ provider: flags['vcs-provider'],
69
+ host: flags['vcs-host'],
70
+ projectId: flags['vcs-project-id'],
71
+ token: flags['vcs-token'],
72
+ warn: (message) => this.warn(message),
73
+ })
74
+ : undefined;
75
+ const result = await createRelease({
76
+ type,
77
+ source: flags.source,
78
+ packageReleaseBranchPrefix: flags['package-release-branch-prefix'],
79
+ remote: flags.remote,
80
+ message: flags.message,
81
+ createRelease: flags['create-release'],
82
+ releaseTag: flags['release-tag'],
83
+ setDefault: flags['set-default'],
84
+ vcs,
85
+ dryRun: flags['dry-run'],
86
+ confirm: interactive ? (plan) => this.confirmPlan(plan) : undefined,
87
+ });
88
+ this.table({
89
+ title: messages.getMessage('tableTitle'),
90
+ data: [
91
+ { field: 'Source', value: result.source },
92
+ { field: 'Branch', value: result.branch },
93
+ { field: 'Status', value: result.status },
94
+ { field: 'Commit', value: result.commit ?? '' },
95
+ ...(result.release
96
+ ? [
97
+ {
98
+ field: 'Release',
99
+ value: `${result.release.name} (${result.release.tagName}): ${result.release.status}`,
100
+ },
101
+ ]
102
+ : []),
103
+ ...(result.release?.webUrl ? [{ field: 'Release URL', value: result.release.webUrl }] : []),
104
+ ...(result.defaultBranch ? [{ field: 'Default branch', value: result.defaultBranch.status }] : []),
105
+ ],
106
+ });
107
+ if (result.status === 'Commit rejected') {
108
+ process.exitCode = 1;
109
+ }
110
+ return result;
111
+ }
112
+ // eslint-disable-next-line class-methods-use-this -- kept as a method so tests can stub the prompt
113
+ async promptForType() {
114
+ return select({
115
+ message: messages.getMessage('prompt.type'),
116
+ choices: RELEASE_TYPES.map((value) => ({
117
+ value,
118
+ name: value,
119
+ description: messages.getMessage(`type.${value}`),
120
+ })),
121
+ default: 'minor',
122
+ });
123
+ }
124
+ async confirmPlan(plan) {
125
+ const steps = [
126
+ ...(plan.release ? [messages.getMessage('confirm.release', [plan.release.name, plan.release.tagName])] : []),
127
+ messages.getMessage('confirm.branch', [plan.branch, plan.source, plan.version]),
128
+ ...(plan.defaultBranch ? [messages.getMessage('confirm.default', [plan.branch])] : []),
129
+ ];
130
+ return this.confirm({ message: messages.getMessage('confirm', [steps.map((step) => `- ${step}`).join('\n')]) });
131
+ }
132
+ }
133
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../../../src/commands/simply/project/release/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ # summary
2
+
3
+ Cut the next release branch, with its version bumped in sfdx-project.json.
4
+
5
+ # description
6
+
7
+ Run this from a local clone, on the release branch to cut from, or pass `--source`. The new branch, such as `release/v1.3.0` from `release/v1.2.0`, starts from the remote's copy of the source, never from local commits, and gets one commit that bumps `sfdx-project.json`: `versionNumber` becomes `1.3.0.NEXT` in every package directory on the source's version, and the version inside `versionName` is replaced in place. Then the branch is pushed. A version that already has a branch is refused. A patch on an older line is allowed while newer releases exist, for hotfixes.
8
+
9
+ With `--create-release`, a GitLab or GitHub release for the version being closed out is published first, from the highest `v<version>.<build>` tag that is reachable from the source and on the remote. Fallback tags are skipped. A release that already exists is reported, not recreated. With `--set-default`, the new branch becomes the project's default after the push. Both need a token, from `--vcs-token` or `SIMPLY_VCS_TOKEN`, and a project ID, from `--vcs-project-id`, `SIMPLY_VCS_PROJECT_ID`, or `vcs.projectId` in `.sfdevrc.json`. These are checked before anything changes.
10
+
11
+ Your repository's commit hooks always run. The default commit message is `chore: bump version to {VERSION}`; use `--message` if your rules need something else, such as a ticket number. If a hook rejects the commit, nothing is pushed, and the bump stays staged on the new local branch. Run `git commit` with an accepted message, then run this command again from that branch.
12
+
13
+ The command never force-pushes or pushes tags. Pushing the new branch triggers a normal release-branch build, which creates the new release's first package version.
14
+
15
+ # flags.type.summary
16
+
17
+ Version to bump: major, minor, or patch. Asked for when omitted in a terminal.
18
+
19
+ # flags.source.summary
20
+
21
+ Release branch to cut from. Defaults to the current branch.
22
+
23
+ # flags.package-release-branch-prefix.summary
24
+
25
+ Prefix identifying release branches. Branch names must then be `[v]MAJOR.MINOR[.PATCH]`.
26
+
27
+ # flags.remote.summary
28
+
29
+ Remote holding the release branches.
30
+
31
+ # flags.message.summary
32
+
33
+ Commit message template, with an optional {VERSION} placeholder. Defaults to "chore: bump version to {VERSION}".
34
+
35
+ # flags.create-release.summary
36
+
37
+ Publish a GitLab or GitHub release for the source's version before cutting.
38
+
39
+ # flags.release-tag.summary
40
+
41
+ Tag to publish the release from, instead of the latest build tag. Implies --create-release.
42
+
43
+ # flags.set-default.summary
44
+
45
+ Make the new branch the project's default branch after pushing.
46
+
47
+ # flags.vcs-provider.summary
48
+
49
+ VCS platform. Defaults to SIMPLY_VCS_PROVIDER, then vcs.provider in .sfdevrc.json, then gitlab.
50
+
51
+ # flags.vcs-host.summary
52
+
53
+ VCS hostname, for a self-hosted instance. Defaults to SIMPLY_VCS_HOST, then vcs.host in .sfdevrc.json.
54
+
55
+ # flags.vcs-project-id.summary
56
+
57
+ GitLab project ID or GitHub owner/repo. Defaults to SIMPLY_VCS_PROJECT_ID, then vcs.projectId in .sfdevrc.json.
58
+
59
+ # flags.vcs-token.summary
60
+
61
+ VCS API token, needed only with --create-release, --release-tag, or --set-default.
62
+
63
+ # flags.dry-run.summary
64
+
65
+ Print the plan, including the tag a release would use, without changing anything.
66
+
67
+ # flags.no-prompt.summary
68
+
69
+ Don't ask for confirmation, or for --type.
70
+
71
+ # error.typeRequired
72
+
73
+ Pass --type with major, minor, or patch.
74
+
75
+ # prompt.type
76
+
77
+ Which version do you want to bump?
78
+
79
+ # type.major
80
+
81
+ Breaking changes
82
+
83
+ # type.minor
84
+
85
+ New features
86
+
87
+ # type.patch
88
+
89
+ Fixes for the current release
90
+
91
+ # confirm.release
92
+
93
+ Publish release %s from tag %s.
94
+
95
+ # confirm.branch
96
+
97
+ Create %s from %s, with version %s, and push it. The push starts a build that creates a package version.
98
+
99
+ # confirm.default
100
+
101
+ Make %s the project's default branch.
102
+
103
+ # confirm
104
+
105
+ This will:
106
+ %s
107
+
108
+ Continue?
109
+
110
+ # tableTitle
111
+
112
+ Release branch
113
+
114
+ # examples
115
+
116
+ - Cut the next minor release from the current release branch:
117
+
118
+ <%= config.bin %> <%= command.id %> --type minor
119
+
120
+ - See what would happen, without changing anything:
121
+
122
+ <%= config.bin %> <%= command.id %> --type minor --dry-run
123
+
124
+ - Cut a hotfix from an older release:
125
+
126
+ <%= config.bin %> <%= command.id %> --type patch --source release/v1.2.0
127
+
128
+ - Also publish a release for the current version and make the new branch the default:
129
+
130
+ <%= config.bin %> <%= command.id %> --type minor --create-release --set-default
131
+
132
+ - Use a commit message your repository's rules accept:
133
+
134
+ <%= config.bin %> <%= command.id %> --type minor --message "chore: PROJ-123 bump version to {VERSION}"
@@ -1,5 +1,187 @@
1
1
  {
2
2
  "commands": {
3
+ "simply:project:release:create": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Run this from a local clone, on the release branch to cut from, or pass `--source`. The new branch, such as `release/v1.3.0` from `release/v1.2.0`, starts from the remote's copy of the source, never from local commits, and gets one commit that bumps `sfdx-project.json`: `versionNumber` becomes `1.3.0.NEXT` in every package directory on the source's version, and the version inside `versionName` is replaced in place. Then the branch is pushed. A version that already has a branch is refused. A patch on an older line is allowed while newer releases exist, for hotfixes.\n\nWith `--create-release`, a GitLab or GitHub release for the version being closed out is published first, from the highest `v<version>.<build>` tag that is reachable from the source and on the remote. Fallback tags are skipped. A release that already exists is reported, not recreated. With `--set-default`, the new branch becomes the project's default after the push. Both need a token, from `--vcs-token` or `SIMPLY_VCS_TOKEN`, and a project ID, from `--vcs-project-id`, `SIMPLY_VCS_PROJECT_ID`, or `vcs.projectId` in `.sfdevrc.json`. These are checked before anything changes.\n\nYour repository's commit hooks always run. The default commit message is `chore: bump version to {VERSION}`; use `--message` if your rules need something else, such as a ticket number. If a hook rejects the commit, nothing is pushed, and the bump stays staged on the new local branch. Run `git commit` with an accepted message, then run this command again from that branch.\n\nThe command never force-pushes or pushes tags. Pushing the new branch triggers a normal release-branch build, which creates the new release's first package version.",
7
+ "examples": [
8
+ "Cut the next minor release from the current release branch:\n<%= config.bin %> <%= command.id %> --type minor",
9
+ "See what would happen, without changing anything:\n<%= config.bin %> <%= command.id %> --type minor --dry-run",
10
+ "Cut a hotfix from an older release:\n<%= config.bin %> <%= command.id %> --type patch --source release/v1.2.0",
11
+ "Also publish a release for the current version and make the new branch the default:\n<%= config.bin %> <%= command.id %> --type minor --create-release --set-default",
12
+ "Use a commit message your repository's rules accept:\n<%= config.bin %> <%= command.id %> --type minor --message \"chore: PROJ-123 bump version to {VERSION}\""
13
+ ],
14
+ "flags": {
15
+ "json": {
16
+ "description": "Format output as json.",
17
+ "helpGroup": "GLOBAL",
18
+ "name": "json",
19
+ "allowNo": false,
20
+ "type": "boolean"
21
+ },
22
+ "flags-dir": {
23
+ "helpGroup": "GLOBAL",
24
+ "name": "flags-dir",
25
+ "summary": "Import flag values from a directory.",
26
+ "hasDynamicHelp": false,
27
+ "multiple": false,
28
+ "type": "option"
29
+ },
30
+ "type": {
31
+ "char": "t",
32
+ "name": "type",
33
+ "summary": "Version to bump: major, minor, or patch. Asked for when omitted in a terminal.",
34
+ "hasDynamicHelp": false,
35
+ "multiple": false,
36
+ "options": [
37
+ "major",
38
+ "minor",
39
+ "patch"
40
+ ],
41
+ "type": "option"
42
+ },
43
+ "source": {
44
+ "name": "source",
45
+ "summary": "Release branch to cut from. Defaults to the current branch.",
46
+ "hasDynamicHelp": false,
47
+ "multiple": false,
48
+ "type": "option"
49
+ },
50
+ "package-release-branch-prefix": {
51
+ "name": "package-release-branch-prefix",
52
+ "summary": "Prefix identifying release branches. Branch names must then be `[v]MAJOR.MINOR[.PATCH]`.",
53
+ "default": "release/",
54
+ "hasDynamicHelp": false,
55
+ "multiple": false,
56
+ "type": "option"
57
+ },
58
+ "remote": {
59
+ "name": "remote",
60
+ "summary": "Remote holding the release branches.",
61
+ "default": "origin",
62
+ "hasDynamicHelp": false,
63
+ "multiple": false,
64
+ "type": "option"
65
+ },
66
+ "message": {
67
+ "name": "message",
68
+ "summary": "Commit message template, with an optional {VERSION} placeholder. Defaults to \"chore: bump version to {VERSION}\".",
69
+ "hasDynamicHelp": false,
70
+ "multiple": false,
71
+ "type": "option"
72
+ },
73
+ "create-release": {
74
+ "name": "create-release",
75
+ "summary": "Publish a GitLab or GitHub release for the source's version before cutting.",
76
+ "allowNo": false,
77
+ "type": "boolean"
78
+ },
79
+ "release-tag": {
80
+ "name": "release-tag",
81
+ "summary": "Tag to publish the release from, instead of the latest build tag. Implies --create-release.",
82
+ "hasDynamicHelp": false,
83
+ "multiple": false,
84
+ "type": "option"
85
+ },
86
+ "set-default": {
87
+ "char": "s",
88
+ "name": "set-default",
89
+ "summary": "Make the new branch the project's default branch after pushing.",
90
+ "allowNo": false,
91
+ "type": "boolean"
92
+ },
93
+ "vcs-provider": {
94
+ "name": "vcs-provider",
95
+ "summary": "VCS platform. Defaults to SIMPLY_VCS_PROVIDER, then vcs.provider in .sfdevrc.json, then gitlab.",
96
+ "hasDynamicHelp": false,
97
+ "multiple": false,
98
+ "options": [
99
+ "gitlab",
100
+ "github"
101
+ ],
102
+ "type": "option"
103
+ },
104
+ "vcs-host": {
105
+ "name": "vcs-host",
106
+ "summary": "VCS hostname, for a self-hosted instance. Defaults to SIMPLY_VCS_HOST, then vcs.host in .sfdevrc.json.",
107
+ "hasDynamicHelp": false,
108
+ "multiple": false,
109
+ "type": "option"
110
+ },
111
+ "vcs-project-id": {
112
+ "name": "vcs-project-id",
113
+ "summary": "GitLab project ID or GitHub owner/repo. Defaults to SIMPLY_VCS_PROJECT_ID, then vcs.projectId in .sfdevrc.json.",
114
+ "hasDynamicHelp": false,
115
+ "multiple": false,
116
+ "type": "option"
117
+ },
118
+ "vcs-token": {
119
+ "env": "SIMPLY_VCS_TOKEN",
120
+ "name": "vcs-token",
121
+ "summary": "VCS API token, needed only with --create-release, --release-tag, or --set-default.",
122
+ "hasDynamicHelp": false,
123
+ "multiple": false,
124
+ "type": "option"
125
+ },
126
+ "dry-run": {
127
+ "name": "dry-run",
128
+ "summary": "Print the plan, including the tag a release would use, without changing anything.",
129
+ "allowNo": false,
130
+ "type": "boolean"
131
+ },
132
+ "no-prompt": {
133
+ "name": "no-prompt",
134
+ "summary": "Don't ask for confirmation, or for --type.",
135
+ "allowNo": false,
136
+ "type": "boolean"
137
+ }
138
+ },
139
+ "hasDynamicHelp": false,
140
+ "hiddenAliases": [],
141
+ "id": "simply:project:release:create",
142
+ "pluginAlias": "@simplysf/simply-project",
143
+ "pluginName": "@simplysf/simply-project",
144
+ "pluginType": "core",
145
+ "strict": true,
146
+ "summary": "Cut the next release branch, with its version bumped in sfdx-project.json.",
147
+ "enableJsonFlag": true,
148
+ "isESM": true,
149
+ "relativePath": [
150
+ "lib",
151
+ "commands",
152
+ "simply",
153
+ "project",
154
+ "release",
155
+ "create.js"
156
+ ],
157
+ "aliasPermutations": [],
158
+ "permutations": [
159
+ "simply:project:release:create",
160
+ "project:simply:release:create",
161
+ "project:release:simply:create",
162
+ "project:release:create:simply",
163
+ "simply:release:project:create",
164
+ "release:simply:project:create",
165
+ "release:project:simply:create",
166
+ "release:project:create:simply",
167
+ "simply:release:create:project",
168
+ "release:simply:create:project",
169
+ "release:create:simply:project",
170
+ "release:create:project:simply",
171
+ "simply:project:create:release",
172
+ "project:simply:create:release",
173
+ "project:create:simply:release",
174
+ "project:create:release:simply",
175
+ "simply:create:project:release",
176
+ "create:simply:project:release",
177
+ "create:project:simply:release",
178
+ "create:project:release:simply",
179
+ "simply:create:release:project",
180
+ "create:simply:release:project",
181
+ "create:release:simply:project",
182
+ "create:release:project:simply"
183
+ ]
184
+ },
3
185
  "simply:project:release:roll-forward": {
4
186
  "aliases": [],
5
187
  "args": {},
@@ -221,5 +403,5 @@
221
403
  ]
222
404
  }
223
405
  },
224
- "version": "1.3.1"
406
+ "version": "1.4.0"
225
407
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplysf/simply-project",
3
3
  "description": "Utilities for working with Salesforce projects",
4
- "version": "1.3.1",
4
+ "version": "1.4.0",
5
5
  "author": "@ClayChipps",
6
6
  "homepage": "https://github.com/SimplySF/simply-plugins",
7
7
  "bugs": "https://github.com/SimplySF/simply-plugins/issues",
@@ -51,7 +51,7 @@
51
51
  "description": "Commands for working with Salesforce projects",
52
52
  "subtopics": {
53
53
  "release": {
54
- "description": "Commands for maintaining release branches"
54
+ "description": "Commands for cutting release branches and rolling them forward"
55
55
  },
56
56
  "update": {
57
57
  "description": "Commands for updating Salesforce project settings"
@@ -64,11 +64,13 @@
64
64
  "topicSeparator": " "
65
65
  },
66
66
  "dependencies": {
67
+ "@inquirer/prompts": "^7.10.1",
67
68
  "@oclif/core": "^4.11.2",
68
69
  "@salesforce/core": "^8.30.0",
69
70
  "@salesforce/kit": "^3.2.6",
70
71
  "@salesforce/sf-plugins-core": "^12.2.16",
71
- "@simplysf/simply-project-core": "^0.2.0",
72
+ "@simplysf/simply-core": "^1.8.0",
73
+ "@simplysf/simply-project-core": "^0.3.0",
72
74
  "glob": "^13.0.6"
73
75
  },
74
76
  "devDependencies": {
@@ -207,5 +209,5 @@
207
209
  "output": []
208
210
  }
209
211
  },
210
- "gitHead": "37a20f64434ed8a208f43503c6bbc6e68d25ca0d"
212
+ "gitHead": "743cad9ae6581a38925a6fac023c5820c99e6eab"
211
213
  }