@halospv3/hce.shared-config 2.3.1 → 2.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.
Files changed (42) hide show
  1. package/README.md +159 -77
  2. package/cjs/debug.cjs +13 -0
  3. package/cjs/debug.cjs.map +1 -0
  4. package/cjs/debug.d.ts +4 -0
  5. package/cjs/debug.d.ts.map +1 -0
  6. package/cjs/dotnet/dotnetHelpers.cjs +83 -87
  7. package/cjs/dotnet/dotnetHelpers.cjs.map +1 -1
  8. package/cjs/dotnet/dotnetHelpers.d.ts +3 -3
  9. package/cjs/dotnet/dotnetHelpers.d.ts.map +1 -1
  10. package/cjs/eslintConfig.cjs +7 -3
  11. package/cjs/eslintConfig.cjs.map +1 -1
  12. package/cjs/eslintConfig.d.ts.map +1 -1
  13. package/cjs/semantic-release__github.d.cjs +2 -0
  14. package/cjs/semantic-release__github.d.cjs.map +1 -0
  15. package/cjs/semanticReleaseConfig.cjs +27 -10
  16. package/cjs/semanticReleaseConfig.cjs.map +1 -1
  17. package/cjs/semanticReleaseConfig.d.ts +1 -1
  18. package/cjs/semanticReleaseConfig.d.ts.map +1 -1
  19. package/cjs/semanticReleaseConfigDotnet-wrapper.mjs +2 -1
  20. package/cjs/semanticReleaseConfigDotnet.cjs +54 -18
  21. package/cjs/semanticReleaseConfigDotnet.cjs.map +1 -1
  22. package/cjs/semanticReleaseConfigDotnet.d.ts +24 -3
  23. package/cjs/semanticReleaseConfigDotnet.d.ts.map +1 -1
  24. package/cjs/setupGitPluginSpec.cjs +2 -1
  25. package/cjs/setupGitPluginSpec.cjs.map +1 -1
  26. package/cjs/setupGitPluginSpec.d.ts +1 -0
  27. package/cjs/setupGitPluginSpec.d.ts.map +1 -1
  28. package/dotnet/.github/workflows/_unit_test.yml +0 -2
  29. package/dotnet/.github/workflows/ci.yml +2 -2
  30. package/dotnet/.github/workflows/dotnet-release.yml +9 -23
  31. package/dotnet/.github/workflows/sample-dotnet-build.yml +5 -3
  32. package/dotnet/HCE.Shared.CI.props +1 -1
  33. package/dotnet/HCE.Shared.props +4 -2
  34. package/package.json +3 -3
  35. package/src/debug.ts +9 -0
  36. package/src/dotnet/dotnetHelpers.ts +113 -111
  37. package/src/eslintConfig.ts +5 -1
  38. package/src/semantic-release__git.d.ts +24 -0
  39. package/src/semantic-release__github.d.ts +145 -0
  40. package/src/semanticReleaseConfig.ts +46 -8
  41. package/src/semanticReleaseConfigDotnet.ts +70 -20
  42. package/src/setupGitPluginSpec.ts +2 -1
@@ -3,6 +3,111 @@ import { getGithubNugetRegistryPair, nugetGitHubUrlBase } from './dotnetGHPR.js'
3
3
  import { getGitlabNugetRegistryPair } from './dotnetGLPR.js';
4
4
  import { MSBuildProject, MSBuildProjectPreDefinedProperties } from './MSBuildProject.js';
5
5
 
6
+
7
+ function formatDotnetPublish(projectsToPublish: string[], publishProperties: string[]): string {
8
+ /* Fun Fact: You can define a property and get the evaluated value in the same command!
9
+ ```pwsh
10
+ dotnet msbuild .\src\HXE.csproj -property:RuntimeIdentifiers="""place;holder""" -getProperty:RuntimeIdentifiers
11
+ place;holder
12
+ ```
13
+ enclosing with """ is required in pwsh to prevent the semicolon from breaking the string.
14
+ */
15
+ if (!(Array.isArray(projectsToPublish) && projectsToPublish.length > 0))
16
+ throw new Error(`Type of projectsToPublish (${typeof projectsToPublish}) is not allowed. Expected a string[] where length > 0.`);
17
+
18
+ // each may have TargetFramework OR TargetFrameworks (plural)
19
+ const evaluatedProjects: MSBuildProject[] = projectsToPublish.map(
20
+ (proj) => new MSBuildProject(proj, publishProperties),
21
+ );
22
+ // args appended to "dotnet publish", joined by space
23
+
24
+ return evaluatedProjects.flatMap(proj => {
25
+ const args: string[] = [proj.Properties.FullPath];
26
+
27
+ function appendCustomProperties(publishProperties: string[]) {
28
+ // convert to dictionary and filter for user-defined properties.
29
+ const dictionary = Object.entries(proj.Properties).filter(
30
+ (p) => !publishProperties.includes(p[0]),
31
+ );
32
+ if (dictionary.length > 0) {
33
+ /* format remaining properties as "-p:Property=Value" and append to args */
34
+ args.push(
35
+ ...dictionary.map((keyValuePair) => `-p:${keyValuePair[0]}=${keyValuePair[1]}`),
36
+ );
37
+ }
38
+ }
39
+ appendCustomProperties(publishProperties);
40
+
41
+ const cmdPermutations: string[][] = []; // forEach, run dotnet [...args,...v]
42
+
43
+ function formatFrameworksAndRuntimes() {
44
+ const RIDs: string[] =
45
+ proj.Properties.RuntimeIdentifiers.length > 0
46
+ ? proj.Properties.RuntimeIdentifiers.split(';')
47
+ : [];
48
+ const TFMs: string[] =
49
+ proj.Properties.TargetFrameworks.length > 0
50
+ ? proj.Properties.TargetFrameworks.split(';')
51
+ : [];
52
+ if (RIDs.length > 0) {
53
+ if (TFMs.length > 0) {
54
+ for (const RID of RIDs) {
55
+ for (const TFM of TFMs) {
56
+ cmdPermutations.push(['--runtime', RID, '--framework', TFM]);
57
+ }
58
+ }
59
+ } else {
60
+ // assume singular TFM. No need to specify it.
61
+ for (const RID of RIDs) {
62
+ cmdPermutations.push(['--runtime', RID]);
63
+ }
64
+ }
65
+ } else if (TFMs.length > 0) {
66
+ for (const TFM of TFMs) {
67
+ cmdPermutations.push(['--framework', TFM]);
68
+ }
69
+ }
70
+ }
71
+ formatFrameworksAndRuntimes();
72
+
73
+ return cmdPermutations.length > 0
74
+ ? cmdPermutations.map((permArgs) => [...args, ...permArgs]) // string[][]
75
+ : [args]; // string[][]
76
+ }).map((args) => `dotnet publish ${args.join(' ')}`).join(' && ');
77
+ }
78
+
79
+ function formatDotnetPack(projectsToPackAndPush: string[] | false): string {
80
+ return projectsToPackAndPush === false
81
+ ? ""
82
+ : projectsToPackAndPush
83
+ .map(v => `dotnet pack ${v}`)
84
+ .join(' && ');
85
+ }
86
+
87
+ function formatDotnetNugetSign(dotnetNugetSignArgs: string[]): string {
88
+ switch (dotnetNugetSignArgs.length) {
89
+ case 0:
90
+ return '';
91
+ default:
92
+ return `dotnet nuget sign ${dotnetNugetSignArgs.join(' ')}`;
93
+ // default: {
94
+ // throw new Error("")
95
+ // // this needs a rework.
96
+ // const packagePaths: string[] = [];
97
+ // dotnetNugetSignArgs.forEach((dotnetNugetSignArg, i) => {
98
+ // // if current arg doesn't start with '-' and (current arg is first -OR- previous arg also does not start with '-')...
99
+ // if (!dotnetNugetSignArg.startsWith("-") && (i === 0 || (i > 0 && !dotnetNugetSignArgs[i - 1].startsWith("-")))) {
100
+ // // ...then it's probably a package path.
101
+ // packagePaths.push(dotnetNugetSignArg);
102
+ // }
103
+ // });
104
+ // if (packagePaths.length === 0)
105
+ // return `dotnet nuget sign ${dotnetNugetSignArgs.join(" ")}`
106
+ // else return
107
+ // }
108
+ }
109
+ }
110
+
6
111
  /**
7
112
  * Build a prepareCmd string from .NET project paths and `dotnet nuget sign` arguments.
8
113
  *
@@ -10,125 +115,22 @@ import { MSBuildProject, MSBuildProjectPreDefinedProperties } from './MSBuildPro
10
115
  * todo: cleanup, docs
11
116
  * @export
12
117
  * @param {string[]} projectsToPublish
13
- * @param {string[]} projectsToPackAndPush Relative and/or full file paths of projects to pass to `dotnet pack`. By default, these will be output to `./publish/`.
118
+ * @param {string[]|false} projectsToPackAndPush Relative and/or full file paths of projects to pass to `dotnet pack`. By default, these will be output to `./publish/`.
14
119
  * @param {string[]} dotnetNugetSignArgs Arguments appended to `dotnet nuget sign`. You can also append '&&' if you want to start a new command or if you want to sign different sets of packages with different keys.
15
120
  */
16
121
  export function configurePrepareCmd(
17
122
  projectsToPublish: string[],
18
- projectsToPackAndPush: string[],
123
+ projectsToPackAndPush: string[] | false,
19
124
  dotnetNugetSignArgs: string[] = ['./publish'],
20
125
  ) {
21
126
  // These are later evaluated with MSBuild, but are passed via --framework and --runtime arguments instead of -p:TargetFramework
22
127
  const publishProperties = MSBuildProjectPreDefinedProperties;
23
128
 
24
- function formatDotnetPublish(): string {
25
- /* Fun Fact: You can define a property and get the evaluated value in the same command!
26
- ```pwsh
27
- dotnet msbuild .\src\HXE.csproj -property:RuntimeIdentifiers="""place;holder""" -getProperty:RuntimeIdentifiers
28
- place;holder
29
- ```
30
- enclosing with """ is required in pwsh to prevent the semicolon from breaking the string.
31
- */
32
- let dotnetPublishArgs: string[][];
33
- if (Array.isArray(projectsToPublish) && projectsToPublish.length > 0) {
34
- // each may have TargetFramework OR TargetFrameworks (plural)
35
- const evaluatedProjects: MSBuildProject[] = projectsToPublish.map(
36
- (proj) => new MSBuildProject(proj, publishProperties),
37
- );
38
- // args appended to "dotnet publish", joined by space
39
- dotnetPublishArgs = evaluatedProjects.flatMap((proj) => {
40
- const args: string[] = [proj.Properties.FullPath];
41
-
42
- function appendCustomProperties() {
43
- // convert to dictionary and filter for user-defined properties.
44
- const dictionary = Object.entries(proj.Properties).filter(
45
- (p) => !publishProperties.includes(p[0]),
46
- );
47
- if (dictionary.length > 0) {
48
- /* format remaining properties as "-p:Property=Value" and append to args */
49
- args.push(
50
- ...dictionary.map((keyValuePair) => `-p:${keyValuePair[0]}=${keyValuePair[1]}`),
51
- );
52
- }
53
- }
54
- appendCustomProperties();
55
-
56
- const cmdPermutations: string[][] = []; // forEach, run dotnet [...args,...v]
57
-
58
- function formatFrameworksAndRuntimes() {
59
- const RIDs: string[] =
60
- proj.Properties.RuntimeIdentifiers.length > 0
61
- ? proj.Properties.RuntimeIdentifiers.split(';')
62
- : [];
63
- const TFMs: string[] =
64
- proj.Properties.TargetFrameworks.length > 0
65
- ? proj.Properties.TargetFrameworks.split(';')
66
- : [];
67
- if (RIDs.length > 0) {
68
- if (TFMs.length > 0) {
69
- for (const RID of RIDs) {
70
- for (const TFM of TFMs) {
71
- cmdPermutations.push(['--runtime', RID, '--framework', TFM]);
72
- }
73
- }
74
- } else {
75
- // assume singular TFM. No need to specify it.
76
- for (const RID of RIDs) {
77
- cmdPermutations.push(['--runtime', RID]);
78
- }
79
- }
80
- } else if (TFMs.length > 0) {
81
- for (const TFM of TFMs) {
82
- cmdPermutations.push(['--framework', TFM]);
83
- }
84
- }
85
- }
86
- formatFrameworksAndRuntimes();
87
-
88
- return cmdPermutations.length > 0
89
- ? cmdPermutations.map((permArgs) => [...args, ...permArgs]) // string[][]
90
- : [args]; // string[][]
91
- }); // string[][][] -> string[][]
92
- } else
93
- throw new Error(
94
- `Type of projectsToPublish (${typeof projectsToPublish}) is not allowed. Expected a string[] where length > 0.`,
95
- );
96
-
97
- return dotnetPublishArgs.map((args) => `dotnet publish ${args.join(' ')}`).join(' && ');
98
- }
99
-
100
- function formatDotnetPack(): string {
101
- return projectsToPackAndPush.map((v) => `dotnet pack ${v}`).join(' && ');
102
- }
103
-
104
- function formatDotnetNugetSign(): string {
105
- switch (dotnetNugetSignArgs.length) {
106
- case 0:
107
- return '';
108
- default:
109
- return `dotnet nuget sign ${dotnetNugetSignArgs.join(' ')}`;
110
- // default: {
111
- // throw new Error("")
112
- // // this needs a rework.
113
- // const packagePaths: string[] = [];
114
- // dotnetNugetSignArgs.forEach((dotnetNugetSignArg, i) => {
115
- // // if current arg doesn't start with '-' and (current arg is first -OR- previous arg also does not start with '-')...
116
- // if (!dotnetNugetSignArg.startsWith("-") && (i === 0 || (i > 0 && !dotnetNugetSignArgs[i - 1].startsWith("-")))) {
117
- // // ...then it's probably a package path.
118
- // packagePaths.push(dotnetNugetSignArg);
119
- // }
120
- // });
121
- // if (packagePaths.length === 0)
122
- // return `dotnet nuget sign ${dotnetNugetSignArgs.join(" ")}`
123
- // else return
124
- // }
125
- }
126
- }
127
-
128
- const dotnetPublish = formatDotnetPublish();
129
- const dotnetPack = formatDotnetPack();
130
- const dotnetNugetSign = formatDotnetNugetSign();
131
- return [dotnetPublish, dotnetPack, dotnetNugetSign].join(' && ');
129
+ return [
130
+ formatDotnetPublish(projectsToPublish, publishProperties),
131
+ formatDotnetPack(projectsToPackAndPush),
132
+ formatDotnetNugetSign(dotnetNugetSignArgs)
133
+ ].join(' && ');
132
134
  }
133
135
 
134
136
  export interface NuGetRegistryInfo {
@@ -142,7 +144,7 @@ export const nugetDefault: NuGetRegistryInfo = {
142
144
  };
143
145
 
144
146
  /**
145
- * todo
147
+ * todo -
146
148
  * @param nupkgDir
147
149
  * @param registries
148
150
  * @param pushToGitHub
@@ -2,8 +2,12 @@ import jsonc from "eslint-plugin-jsonc";
2
2
  import tseslint from "typescript-eslint";
3
3
  import { type TSESLint } from "@typescript-eslint/utils";
4
4
  import eslint from "@eslint/js";
5
- import globals from "globals" with {type: "json"};
5
+ import { createRequire } from "module";
6
6
 
7
+ // CJS compatibility; it started transpiling to a top-level await after upgrading from packemon 4.0.1 to 4.1.0
8
+ const require = createRequire(import.meta.url);
9
+ const globals = require("globals") as typeof import("globals", {with: {type: "json"}});
10
+ console.log(globals)
7
11
  // https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config
8
12
  // https://www.google.com/search?q=javascript+recurse+through+object+and+remove+undefined+properties
9
13
 
@@ -1,4 +1,6 @@
1
+ /** @see 'file://./../node_modules/@semantic-release/git/index.js' */
1
2
  declare module '@semantic-release/git' {
3
+ import type { Options as SemanticReleaseOptions } from "semantic-release";
2
4
  export type MicromatchGlob = string;
3
5
  export interface AssetObject {
4
6
  path: MicromatchGlob;
@@ -64,4 +66,26 @@ declare module '@semantic-release/git' {
64
66
  */
65
67
  message?: string;
66
68
  }
69
+
70
+ function verifyConditions(
71
+ pluginConfig: Options,
72
+ context: {
73
+ options: {
74
+ prepare: unknown
75
+ }
76
+ }
77
+ ): void;
78
+ async function prepare(
79
+ pluginConfig: Options,
80
+ context: {
81
+ env,
82
+ cwd: string,
83
+ branch: { name: string },
84
+ options: SemanticReleaseOptions,
85
+ lastRelease,
86
+ nextRelease: { version, notes, gitTag },
87
+ logger: { log(_0: string, _1: unknown | number): void },
88
+ }
89
+ ): Promise<void>;
90
+ export { verifyConditions, prepare }
67
91
  }
@@ -0,0 +1,145 @@
1
+ declare module "@semantic-release/github" {
2
+ /**
3
+ * @see https://github.com/semantic-release/github#configuration
4
+ */
5
+ export interface Env extends NodeJS.ProcessEnv {
6
+ /**
7
+ * __Required__. The token used to authenticate with GitHub.
8
+ */
9
+ GITHUB_TOKEN?: string,
10
+ /**
11
+ * {@inheritDoc GitHubEnv.GITHUB_TOKEN}
12
+ */
13
+ GH_TOKEN?: string,
14
+
15
+ /**
16
+ * The GitHub server endpoint.
17
+ */
18
+ GITHUB_URL?: string,
19
+ /**
20
+ * {@inheritDoc GitHubEnv.GITHUB_URL}
21
+ */
22
+ GH_URL?: string,
23
+
24
+ /**
25
+ * The GitHub API prefix, relative to {@link Env.GITHUB_URL GITHUB_URL}.
26
+ */
27
+ GITHUB_PREFIX?: string,
28
+ /** {@inheritDoc GitHubEnv.GITHUB_PREFIX} */
29
+ GH_PREFIX?: string,
30
+
31
+ /**
32
+ * The GitHub API endpoint. Note that this overwrites {@link Env.GITHUB_PREFIX GITHUB_PREFIX}.
33
+ */
34
+ GITHUB_API_URL?: string
35
+ }
36
+
37
+ /** https://github.com/isaacs/node-glob#glob-primer */
38
+ type Glob = string;
39
+
40
+ /** @see https://github.com/semantic-release/github#assets */
41
+ interface Asset {
42
+ /** __Required__. A {@link https://github.com/isaacs/node-glob#glob-primer glob} to identify the files to upload. */
43
+ path: Glob,
44
+ /**
45
+ * The name of the downloadable file on the GitHub release.
46
+ * @defaultValue File name extracted from the {@link Asset.path path}.
47
+ */
48
+ name?: string,
49
+ /** Short description of the file displayed on the GitHub release. */
50
+ label?: string
51
+ }
52
+
53
+ /** @see https://github.com/semantic-release/github#configuration */
54
+ export interface Options {
55
+ /**
56
+ * The GitHub server endpoint.
57
+ * @defaultValue {@link Env.GH_URL GH_URL} or {@link Env.GITHUB_URL GITHUB_URL} environment variables.
58
+ */
59
+ githubUrl?: string,
60
+ /**
61
+ * The GitHub API prefix, relative to `githubUrl`.
62
+ * @defaultValue {@link Env.GH_PREFIX GH_PREFIX} or {@link Env.GITHUB_PREFIX GITHUB_PREFIX} environment variables
63
+ */
64
+ githubApiPathPrefix?: string,
65
+ /**
66
+ * The GitHub API endpoint.
67
+ * Note that this overwrites {@link Options.githubApiPathPrefix githubApiPathPrefix}.
68
+ */
69
+ githubApiUrl?: string,
70
+ /**
71
+ * The proxy to use to access the GitHub API.
72
+ * Set to `false` to disable usage of proxy.
73
+ * See {@link https://github.com/semantic-release/github#proxy proxy}.
74
+ */
75
+ proxy?: string | false,
76
+ /**
77
+ * An array of files to upload to the release.
78
+ * See {@link https://github.com/semantic-release/github#assets assets}.
79
+ */
80
+ assets?: Glob | (Asset | Glob)[],
81
+ /**
82
+ * The comment to add to each issue and pull request resolved by the release.
83
+ * Set to `false` to disable commenting on issues and pull requests.
84
+ * See {@link https://github.com/semantic-release/github?tab=readme-ov-file#successcomment successComment}.
85
+ * @defaultValue `:tada: This issue has been resolved in version ${nextRelease.version} :tada:\n\nThe release is available on [GitHub release](<github_release_url>)`
86
+ */
87
+ successComment?: string | false,
88
+ /**
89
+ * The content of the issue created when a release fails.
90
+ * Set to `false` to disable opening an issue when a release fails.
91
+ * See {@link https://github.com/semantic-release/github?tab=readme-ov-file#failcomment failComment}.
92
+ * @defaultValue Friendly message with links to semantic-release documentation and support, with the list of errors that caused the release to fail.
93
+ */
94
+ failComment?: string | false,
95
+ /**
96
+ * The title of the issue created when a release fails.
97
+ * Set to `false` to disable opening an issue when a release fails.
98
+ * @defaultValue `The automated release is failing 🚨`
99
+ */
100
+ failTitle?: string | false,
101
+ /**
102
+ * The {@link https://help.github.com/articles/about-labels labels} to add to the issue created when a release fails.
103
+ * Set to `false` to not add any label.
104
+ * @default ['semantic-release']
105
+ */
106
+ labels?: string[] | false,
107
+ /**
108
+ * The {@link https://help.github.com/articles/assigning-issues-and-pull-requests-to-other-github-users assignees} to add to the issue created when a release fails.
109
+ */
110
+ assignees?: unknown,
111
+ /**
112
+ * The {@link https://help.github.com/articles/about-labels labels} to add to each issue and pull request resolved by the release.
113
+ * Set to `false` to not add any label.
114
+ * See {@link https://github.com/semantic-release/github#releasedlabels releasedLabels}.
115
+ * @default [ 'released<%= nextRelease.channel ? \` on @\${nextRelease.channel}\` : "" %>' ]
116
+ */
117
+ releasedLabels?: string[],
118
+ /**
119
+ * Will add release links to the GitHub Release. Can be `false`, `"bottom"` or `"top"`. See {@link https://github.com/semantic-release/github#addReleases addReleases}.
120
+ * @default false
121
+ */
122
+ addReleases?: false | "bottom" | "top",
123
+ /**
124
+ * A boolean indicating if a GitHub Draft Release should be created instead of publishing an actual GitHub Release.
125
+ * @default false
126
+ */
127
+ draftRelease?: boolean,
128
+ /**
129
+ * A {@link https://lodash.com/docs#template Lodash template} to customize the github release's name
130
+ * @default '<%= nextverison.name %>'
131
+ */
132
+ releaseNameTemplate?: string,
133
+ /**
134
+ * A {@link https://lodash.com/docs#template Lodash template} to customize the github release's body
135
+ * @default '<%= nextverison.notes %>'
136
+ */
137
+ releaseBodyTemplate?: string,
138
+ /**
139
+ * The category name in which to create a linked discussion to the release.
140
+ * Set to `false` to disable creating discussion for a release.
141
+ * @default false
142
+ */
143
+ discussionCategoryName?: string | false
144
+ }
145
+ }
@@ -1,15 +1,53 @@
1
- import { readFileSync } from 'node:fs';
2
- import jsYaml from 'js-yaml';
3
1
  import type { Options, PluginSpec } from 'semantic-release';
4
- import { findStaticConfig } from './findStaticConfig.js';
2
+ import type { Options as GitOptions } from '@semantic-release/git'
3
+ import type { Options as GithubOptions } from '@semantic-release/github'
4
+ import { DefaultOptions } from './setupGitPluginSpec.js';
5
5
 
6
- export const defaultPlugins = [
7
- '@semantic-release/commit-analyzer' as PluginSpec,
6
+ export const defaultPlugins: readonly PluginSpec[] = [
7
+ '@semantic-release/commit-analyzer',
8
8
  '@semantic-release/release-notes-generator',
9
9
  '@semantic-release/npm',
10
10
  '@semantic-release/github',
11
11
  ];
12
12
 
13
- export const baseConfig: Options = jsYaml.load(
14
- readFileSync(findStaticConfig(), { encoding: 'utf8' }),
15
- ) as Options;
13
+ export const baseConfig = {
14
+ /** @see https://semantic-release.gitbook.io/semantic-release/usage/plugins#plugin-options-configuration */
15
+ preset: 'conventionalcommits',
16
+ branches: [
17
+ 'main',
18
+ {
19
+ name: 'develop',
20
+ channel: 'develop',
21
+ prerelease: true
22
+ }
23
+ ],
24
+ plugins: [
25
+ "@semantic-release/commit-analyzer",
26
+ "semantic-release-export-data",
27
+ "@semantic-release/release-notes-generator",
28
+ "@semantic-release/changelog",
29
+ [
30
+ "@semantic-release/git",
31
+ DefaultOptions
32
+ ] as PluginSpec<GitOptions>,
33
+ // Arbitrary shell commands - https://github.com/semantic-release/exec
34
+ // hint: set 'prepareCmd' to`dotnet publish`.
35
+ // Because this is sorted after @semantic-release / git, the new Git tag will
36
+ // be visible to dotnet(and GitVersion).Dotnet artifacts will be
37
+ // versioned accordingly.
38
+ // Plugins' Steps: https://github.com/semantic-release/semantic-release/blob/master/docs/extending/plugins-list.md
39
+ "@semantic-release/exec",
40
+ [
41
+ "@semantic-release/github",
42
+ {
43
+ assets: [{
44
+ path: './publish/*'
45
+ }]
46
+ }
47
+ ] as PluginSpec<GithubOptions>
48
+ ]
49
+ } as Options;
50
+
51
+ /// (OPTIONAL) update static Version strings before Git plugin
52
+ // https://github.com/jpoehnelt/semantic-release-replace-plugin
53
+ // https://github.com/droidsolutions/semantic-release-update-file
@@ -11,11 +11,11 @@
11
11
  *
12
12
  */
13
13
 
14
- import { log } from 'node:console';
15
14
  import type { Options, PluginSpec } from 'semantic-release';
16
15
  import { configureDotnetNugetPush, configurePrepareCmd } from './dotnet/dotnetHelpers.js';
17
16
  import { baseConfig, defaultPlugins } from './semanticReleaseConfig.js';
18
17
  import { setupGitPluginSpec } from './setupGitPluginSpec.js';
18
+ import debug from './debug.js'
19
19
 
20
20
  /**
21
21
  * TODO: options/params for inserts/edits. NOT ready for production. Currently, this can only add Git plugin's options if undefined or one or more is missing.
@@ -28,24 +28,29 @@ import { setupGitPluginSpec } from './setupGitPluginSpec.js';
28
28
  * @returns a modified copy of {@link config}
29
29
  */
30
30
  export function insertAndEditPlugins(config: Options): Options {
31
- const newConfig = config;
32
31
  // const insertAndEditCommands = [];
33
- newConfig.plugins = [...(config.plugins ?? defaultPlugins)];
32
+ config.plugins = [...(config.plugins ?? defaultPlugins)];
34
33
 
35
- newConfig.plugins = setupGitPluginSpec(newConfig.plugins as PluginSpec[]);
34
+ config.plugins = setupGitPluginSpec(config.plugins as PluginSpec[]);
36
35
 
37
- return newConfig;
36
+ return config;
38
37
  }
39
38
 
39
+ /**
40
+ * Currently, only configures `@semantic-release/exec` with `prepareCmd: configurePrepareCmd(projectsToPublish, projectsToPackAndPush)` and `publishCmd: configureDotnetNugetPush()`
41
+ * @param config
42
+ * @param projectsToPublish
43
+ * @param projectsToPackAndPush
44
+ * @returns config with the specified plugins and plugin options.
45
+ */
40
46
  export function appendPlugins(
41
47
  config: Options,
42
48
  projectsToPublish: string[],
43
- projectsToPackAndPush: string[],
44
- ) {
45
- const newConfig = config;
46
- if (newConfig.plugins === undefined)
49
+ projectsToPackAndPush: string[] | false,
50
+ ): Options {
51
+ if (config.plugins === undefined)
47
52
  throw new Error('Plugins array was undefined when it should be an array!');
48
- (newConfig.plugins as PluginSpec[]).push(
53
+ (config.plugins as PluginSpec[]).push(
49
54
  // APPEND this array of [pluginName, pluginConfig] to plugins
50
55
  // https://github.com/semantic-release/exec#usage
51
56
  [
@@ -57,22 +62,67 @@ export function appendPlugins(
57
62
  },
58
63
  ],
59
64
  );
60
- return newConfig;
65
+ return config;
61
66
  }
62
67
 
63
68
  /**
64
- * @type {import("semantic-release").Options}
69
+ * Configures {@link baseConfig} with `@semantic-release/exec` to `dotnet` publish, pack, and push.
70
+ * @param projectsToPublish An array of dotnet projects' relative paths. If
71
+ * empty or unspecified, tries getting projects' semi-colon-separated relative
72
+ * paths from the `PROJECTS_TO_PUBLISH` environment variable. If configured as
73
+ * recommended, the projects' publish outputs will be zipped to '$PWD/publish'
74
+ * for use in the `publish` semantic-release step (typically, GitHub release).
75
+ * @param projectsToPackAndPush An array of dotnet projects' relative paths. If
76
+ * false, `dotnet pack` and `dotnet nuget push` will be left out of the exec
77
+ * commands. If empty or unspecified, tries getting projects'
78
+ * semi-colon-separated relative paths from the `PROJECTS_TO_PACK_AND_PUSH`
79
+ * environment variable. If configured as recommended, `dotnet pack` will output
80
+ * the nupkg/snupk files to `$PWD/publish` where they will be globbed by `dotnet
81
+ * nuget push`.
82
+ * @returns a semantic-release Options object, based on `@halospv3/hce.shared-config` (our base config), with the `@semantic-release/exec` plugin configured to `dotnet publish`, `pack`, and `push` the specified projects.
65
83
  */
66
- export function getConfig(projectsToPublish: string[], projectsToPackAndPush: string[]) {
67
- if (process.argv.includes('--debug') || process.argv.includes('--verbose')) {
68
- log(`hce.shared-config:\n${JSON.stringify(baseConfig, null, 2)}`);
84
+ export function getConfig(projectsToPublish: string[] = [], projectsToPackAndPush: string[] | false = []): Options {
85
+ if (debug.enabled) {
86
+ debug('hce.shared-config:\n%o', baseConfig);
87
+ }
88
+
89
+ const errors: Error[] = [];
90
+
91
+ if (projectsToPublish.length === 0) {
92
+ const _ = process.env["PROJECTS_TO_PUBLISH"];
93
+ if (_ === undefined)
94
+ errors.push(new Error("projectsToPublish.length must be > 0 or PROJECTS_TO_PUBLISH must be defined and contain at least one path."));
95
+ else
96
+ projectsToPublish = _.split(';');
69
97
  }
70
98
 
71
- let newConfig = { ...baseConfig };
72
- newConfig = insertAndEditPlugins(newConfig);
73
- newConfig = appendPlugins(newConfig, projectsToPublish, projectsToPackAndPush);
99
+ if (projectsToPackAndPush && projectsToPackAndPush.length) {
100
+ const _ = process.env["PROJECTS_TO_PACK_AND_PUSH"]
101
+ if (_ === undefined)
102
+ errors.push(new Error("projectsToPackAndPush.length must be > 0 or PROJECTS_TO_PACK_AND_PUSH must be defined and contain at least one path."));
103
+ else
104
+ projectsToPackAndPush = _.split(';');
105
+ }
74
106
 
75
- if (process.argv.includes('--debug') || process.argv.includes('--verbose')) {
76
- log(`modified plugins array:\n${JSON.stringify(newConfig.plugins, null, 2)}`);
107
+ if (errors.length > 0) {
108
+ throw new Error(
109
+ [
110
+ "getConfig cannot continue. One or more errors occurred.",
111
+ ...(errors.map(v => v.message))
112
+ ].join('\n')
113
+ )
77
114
  }
115
+
116
+ let config = { ...baseConfig };
117
+ config = insertAndEditPlugins(config);
118
+ if (projectsToPublish)
119
+ config = appendPlugins(config, projectsToPublish, projectsToPackAndPush);
120
+
121
+ if (debug.enabled) {
122
+ debug('modified plugins array:\n%o', config.plugins);
123
+ }
124
+
125
+ return config;
78
126
  }
127
+
128
+ export default getConfig;
@@ -2,8 +2,9 @@ import type { PluginSpec } from 'semantic-release';
2
2
  import type { AssetEntry, Options as GitOptions } from '@semantic-release/git';
3
3
 
4
4
  export const GitPluginId = '@semantic-release/git';
5
+ /** As specified at https://github.com/semantic-release/git#options */
5
6
  export const DefaultOptions = {
6
- assets: ['CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json'],
7
+ assets: ['README.md', 'CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json'],
7
8
  // eslint-disable-next-line no-template-curly-in-string
8
9
  message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
9
10
  } satisfies GitOptions;