@halospv3/hce.shared-config 2.6.4 → 3.0.0-develop.2
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/CHANGELOG.md +356 -101
- package/README.md +100 -87
- package/dotnet/.github/workflows/_unit_test.yml +6 -3
- package/dotnet/.github/workflows/ci.yml +2 -2
- package/dotnet/.github/workflows/dotnet-release.yml +31 -28
- package/dotnet/.github/workflows/sample-dotnet-build.yml +16 -11
- package/dotnet/ExecNupkgDeterministicator.README.md +20 -0
- package/dotnet/ExecNupkgDeterministicator.targets +173 -0
- package/dotnet/GitVersion.yml +3 -1
- package/dotnet/GitVersion6.0.yml +3 -1
- package/dotnet/HCE.Shared.sln +34 -0
- package/dotnet/HCE.Shared.targets +1 -0
- package/dotnet/PublishAll.targets +2 -0
- package/dotnet/SignAfterPack.targets +104 -0
- package/dotnet/samples/HCE.Shared.DeterministicNupkg/Dummy.cs +6 -0
- package/dotnet/samples/HCE.Shared.DeterministicNupkg/HCE.Shared.DeterministicNupkg.csproj +21 -0
- package/dotnet/samples/HCE.Shared.SignAfterPack/Class1.cs +6 -0
- package/dotnet/samples/HCE.Shared.SignAfterPack/HCE.Shared.SignAfterPack.csproj +21 -0
- package/dotnet/samples/HCE.Shared.SignAfterPack/sampleCert.samplepfx +0 -0
- package/dotnet/samples/README.md +7 -0
- package/package.json +72 -73
- package/src/CaseInsensitiveMap.ts +34 -0
- package/src/commitlintConfig.ts +17 -9
- package/src/debug.ts +3 -3
- package/src/dotnet/GithubNugetRegistryInfo.ts +60 -0
- package/src/dotnet/GitlabNugetRegistryInfo.ts +112 -0
- package/src/dotnet/IsNextVersionAlreadyPublished.cli.ts +44 -0
- package/src/dotnet/MSBuildProject.ts +557 -76
- package/src/dotnet/MSBuildProjectProperties.ts +280 -15
- package/src/dotnet/NugetProjectProperties.ts +608 -0
- package/src/dotnet/NugetRegistryInfo.ts +939 -0
- package/src/dotnet/helpers.ts +448 -0
- package/src/eslintConfig.ts +174 -71
- package/src/index.ts +1 -3
- package/src/semantic-release__commit-analyzer.d.ts +44 -38
- package/src/semantic-release__exec.d.ts +15 -0
- package/src/semantic-release__git.d.ts +85 -88
- package/src/semantic-release__github.d.ts +139 -139
- package/src/semanticReleaseConfig.ts +106 -47
- package/src/semanticReleaseConfigDotnet.ts +394 -104
- package/src/setupGitPluginSpec.ts +149 -57
- package/src/tsconfig.json +8 -8
- package/src/utils/Exact.ts +49 -0
- package/src/utils/GracefulRecursion.d.ts +12 -0
- package/src/utils/env.ts +44 -0
- package/src/utils/execAsync.ts +77 -0
- package/src/utils/miscTypes.ts +17 -0
- package/src/utils/reflection/FunctionLike.d.ts +17 -0
- package/src/utils/reflection/GetterDescriptor.d.ts +8 -0
- package/src/utils/reflection/InstancePropertyDescriptorMap.d.ts +32 -0
- package/src/utils/reflection/InstanceTypeOrSelfPropertyDescriptorMap.d.ts +20 -0
- package/src/utils/reflection/OwnGetterDescriptorMap.d.ts +17 -0
- package/src/utils/reflection/OwnKeyOf.d.ts +20 -0
- package/src/utils/reflection/OwnPropertyDescriptorMap.d.ts +82 -0
- package/src/utils/reflection/PropertyDescriptorMap.d.ts +15 -0
- package/src/utils/reflection/filterForGetters.ts +59 -0
- package/src/utils/reflection/getOwnPropertyDescriptors.ts +52 -0
- package/src/utils/reflection/getOwnPropertyDescriptorsRecursively.ts +127 -0
- package/src/utils/reflection/getPrototypeChainOf.ts +85 -0
- package/src/utils/reflection/getPrototypeOf.ts +12 -0
- package/src/utils/reflection/inheritance.ts +262 -0
- package/src/utils/reflection/isConstructor.ts +74 -0
- package/src/utils/reflection/isGetterDescriptor.ts +11 -0
- package/src/utils/reflection/listOwnGetters.ts +80 -0
- package/src/utils/reflection.ts +18 -0
- package/cjs/commitlintConfig-wrapper.mjs +0 -6
- package/cjs/commitlintConfig.cjs +0 -14
- package/cjs/commitlintConfig.cjs.map +0 -1
- package/cjs/commitlintConfig.d.ts +0 -4
- package/cjs/commitlintConfig.d.ts.map +0 -1
- package/cjs/debug.cjs +0 -13
- package/cjs/debug.cjs.map +0 -1
- package/cjs/debug.d.ts +0 -4
- package/cjs/debug.d.ts.map +0 -1
- package/cjs/dotnet/MSBuildProject.cjs +0 -84
- package/cjs/dotnet/MSBuildProject.cjs.map +0 -1
- package/cjs/dotnet/MSBuildProject.d.ts +0 -42
- package/cjs/dotnet/MSBuildProject.d.ts.map +0 -1
- package/cjs/dotnet/MSBuildProjectProperties.cjs +0 -22
- package/cjs/dotnet/MSBuildProjectProperties.cjs.map +0 -1
- package/cjs/dotnet/MSBuildProjectProperties.d.ts +0 -13
- package/cjs/dotnet/MSBuildProjectProperties.d.ts.map +0 -1
- package/cjs/dotnet/createDummyNupkg.cjs +0 -26
- package/cjs/dotnet/createDummyNupkg.cjs.map +0 -1
- package/cjs/dotnet/createDummyNupkg.d.ts +0 -2
- package/cjs/dotnet/createDummyNupkg.d.ts.map +0 -1
- package/cjs/dotnet/dotnetGHPR.cjs +0 -173
- package/cjs/dotnet/dotnetGHPR.cjs.map +0 -1
- package/cjs/dotnet/dotnetGHPR.d.ts +0 -37
- package/cjs/dotnet/dotnetGHPR.d.ts.map +0 -1
- package/cjs/dotnet/dotnetGLPR.cjs +0 -41
- package/cjs/dotnet/dotnetGLPR.cjs.map +0 -1
- package/cjs/dotnet/dotnetGLPR.d.ts +0 -13
- package/cjs/dotnet/dotnetGLPR.d.ts.map +0 -1
- package/cjs/dotnet/dotnetHelpers.cjs +0 -141
- package/cjs/dotnet/dotnetHelpers.cjs.map +0 -1
- package/cjs/dotnet/dotnetHelpers.d.ts +0 -26
- package/cjs/dotnet/dotnetHelpers.d.ts.map +0 -1
- package/cjs/dotnet-wrapper.mjs +0 -6
- package/cjs/dotnet.cjs +0 -15
- package/cjs/dotnet.cjs.map +0 -1
- package/cjs/dotnet.d.ts +0 -7
- package/cjs/dotnet.d.ts.map +0 -1
- package/cjs/envUtils-wrapper.mjs +0 -6
- package/cjs/envUtils.cjs +0 -37
- package/cjs/envUtils.cjs.map +0 -1
- package/cjs/envUtils.d.ts +0 -15
- package/cjs/envUtils.d.ts.map +0 -1
- package/cjs/eslintConfig-wrapper.mjs +0 -6
- package/cjs/eslintConfig.cjs +0 -52
- package/cjs/eslintConfig.cjs.map +0 -1
- package/cjs/eslintConfig.d.ts +0 -3
- package/cjs/eslintConfig.d.ts.map +0 -1
- package/cjs/findStaticConfig-wrapper.mjs +0 -6
- package/cjs/findStaticConfig.cjs +0 -34
- package/cjs/findStaticConfig.cjs.map +0 -1
- package/cjs/findStaticConfig.d.ts +0 -2
- package/cjs/findStaticConfig.d.ts.map +0 -1
- package/cjs/index-wrapper.mjs +0 -6
- package/cjs/index.cjs +0 -10
- package/cjs/index.cjs.map +0 -1
- package/cjs/index.d.ts +0 -5
- package/cjs/index.d.ts.map +0 -1
- package/cjs/semantic-release__commit-analyzer.d.cjs +0 -2
- package/cjs/semantic-release__commit-analyzer.d.cjs.map +0 -1
- package/cjs/semantic-release__git.d.cjs +0 -2
- package/cjs/semantic-release__git.d.cjs.map +0 -1
- package/cjs/semantic-release__github.d.cjs +0 -2
- package/cjs/semantic-release__github.d.cjs.map +0 -1
- package/cjs/semanticReleaseConfig-wrapper.mjs +0 -6
- package/cjs/semanticReleaseConfig.cjs +0 -33
- package/cjs/semanticReleaseConfig.cjs.map +0 -1
- package/cjs/semanticReleaseConfig.d.ts +0 -4
- package/cjs/semanticReleaseConfig.d.ts.map +0 -1
- package/cjs/semanticReleaseConfigDotnet-wrapper.mjs +0 -7
- package/cjs/semanticReleaseConfigDotnet.cjs +0 -112
- package/cjs/semanticReleaseConfigDotnet.cjs.map +0 -1
- package/cjs/semanticReleaseConfigDotnet.d.ts +0 -51
- package/cjs/semanticReleaseConfigDotnet.d.ts.map +0 -1
- package/cjs/setupGitPluginSpec-wrapper.mjs +0 -6
- package/cjs/setupGitPluginSpec.cjs +0 -67
- package/cjs/setupGitPluginSpec.cjs.map +0 -1
- package/cjs/setupGitPluginSpec.d.ts +0 -19
- package/cjs/setupGitPluginSpec.d.ts.map +0 -1
- package/src/dotnet/createDummyNupkg.ts +0 -30
- package/src/dotnet/dotnetGHPR.ts +0 -232
- package/src/dotnet/dotnetGLPR.ts +0 -46
- package/src/dotnet/dotnetHelpers.ts +0 -184
- package/src/dotnet.ts +0 -6
- package/src/envUtils.ts +0 -36
- package/src/findStaticConfig.ts +0 -31
- package/static/.releaserc.yml +0 -35
package/src/dotnet/dotnetGHPR.ts
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { ok } from 'node:assert/strict';
|
|
2
|
-
import { spawnSync, type ExecException, type SpawnSyncReturns } from 'node:child_process';
|
|
3
|
-
import { getEnvVarValue } from '../envUtils.js';
|
|
4
|
-
import { createDummyNupkg } from './createDummyNupkg.js';
|
|
5
|
-
import type { NuGetRegistryInfo } from './dotnetHelpers.js';
|
|
6
|
-
import { isNativeError } from 'node:util/types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param tokenEnvVar The name of the environment variable containing the NUGET token
|
|
10
|
-
* @returns `true` if the token can be used to push nupkg to the given Nuget registry
|
|
11
|
-
* @throws
|
|
12
|
-
* - TypeError: The environment variable ${tokenEnvVar} is undefined!
|
|
13
|
-
* - Error:
|
|
14
|
-
* - The value of the token in ${tokenEnvVar} begins with 'github_pat_' which means it's a Fine-Grained token. At the time of writing, GitHub Fine-Grained tokens cannot push packages. If you believe this is statement is outdated, report the issue at https://github.com/halospv3/hce.shared/issues/new. For more information, see https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry.
|
|
15
|
-
* - The GitHub API response header lacked "x-oauth-scopes". This indicates the token we provided is not a workflow token nor a Personal Access Token (classic) and can never have permission to push packages.
|
|
16
|
-
*/
|
|
17
|
-
export function tokenCanWritePackages(tokenEnvVar: string, url?: string) {
|
|
18
|
-
/* double-check the token exists */
|
|
19
|
-
const info = isTokenDefined(tokenEnvVar);
|
|
20
|
-
ok(info.isDefined)
|
|
21
|
-
|
|
22
|
-
if (url === undefined) {
|
|
23
|
-
console.debug(`tokenCanWritePackages was called without a NuGet Source URL. Defaulting to use ${`${nugetGitHubUrlBase}/\${GITHUB_REPOSITORY_OWNER}/index.json`} where GITHUB_REPOSITORY_OWNER is '${getOwner()}'`)
|
|
24
|
-
url = getNugetGitHubUrl();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (url === undefined || url === '')
|
|
28
|
-
throw new Error('The NuGet source is undefined or empty!')
|
|
29
|
-
|
|
30
|
-
if (info.fallback)
|
|
31
|
-
tokenEnvVar = info.fallback;
|
|
32
|
-
|
|
33
|
-
const tokenValue = getEnvVarValue(tokenEnvVar);
|
|
34
|
-
if (tokenValue === undefined)
|
|
35
|
-
throw new TypeError(`The environment variable ${tokenEnvVar} is undefined!`)
|
|
36
|
-
|
|
37
|
-
if (tokenValue.startsWith('github_pat_'))
|
|
38
|
-
throw new Error(`The value of the token in ${tokenEnvVar} begins with 'github_pat_' which means it's a Fine-Grained token. At the time of writing, GitHub Fine-Grained tokens cannot push packages. If you believe this is statement is outdated, report the issue at https://github.com/halospv3/hce.shared/issues/new. For more information, see https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry.`)
|
|
39
|
-
|
|
40
|
-
const dummyNupkgPath = createDummyNupkg();
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
let pushResult: SpawnSyncReturns<string> | undefined = undefined;
|
|
44
|
-
try {
|
|
45
|
-
pushResult = spawnSync(
|
|
46
|
-
'dotnet',
|
|
47
|
-
[
|
|
48
|
-
'nuget',
|
|
49
|
-
'push',
|
|
50
|
-
dummyNupkgPath,
|
|
51
|
-
'--source',
|
|
52
|
-
url,
|
|
53
|
-
'--api-key',
|
|
54
|
-
tokenValue,
|
|
55
|
-
'--skip-duplicate',
|
|
56
|
-
'--force-english-output'
|
|
57
|
-
],
|
|
58
|
-
{
|
|
59
|
-
stdio: 'pipe',
|
|
60
|
-
encoding: 'utf8',
|
|
61
|
-
shell: process.platform === 'win32' && spawnSync('dotnet.exe', { windowsHide: true }).status === null
|
|
62
|
-
? 'cmd.exe'
|
|
63
|
-
: undefined,
|
|
64
|
-
windowsHide: true,
|
|
65
|
-
},
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
catch (_error) {
|
|
69
|
-
// censor token
|
|
70
|
-
const error = !isNativeError(_error)
|
|
71
|
-
? new Error(`dotnet nuget push failed. \n${String(_error)}`)
|
|
72
|
-
: _error;
|
|
73
|
-
|
|
74
|
-
const tokenPattern = new RegExp(tokenValue, 'g');
|
|
75
|
-
|
|
76
|
-
error.message = error.message.replace(tokenPattern,'***');
|
|
77
|
-
|
|
78
|
-
if (error.stack)
|
|
79
|
-
error.stack = error.stack.replace(tokenPattern, '***');
|
|
80
|
-
if ('cmd' in error && typeof error.cmd === 'string')
|
|
81
|
-
error.cmd = error.cmd.replace(tokenPattern, '***');
|
|
82
|
-
if ('stdout' in error && typeof error.stdout === 'string')
|
|
83
|
-
error.stdout = error.stdout.replace(tokenPattern, '***');
|
|
84
|
-
if ('stderr' in error&& typeof error.stderr === 'string') {
|
|
85
|
-
error.stderr = error.stderr.replace(tokenPattern, '***');
|
|
86
|
-
}
|
|
87
|
-
if ('spawnargs' in error && Array.isArray(error.spawnargs)) {
|
|
88
|
-
error.spawnargs = error.spawnargs.map(arg => {
|
|
89
|
-
return typeof arg === 'string'
|
|
90
|
-
? arg.replace(tokenPattern, '***')
|
|
91
|
-
: arg;
|
|
92
|
-
})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const errNewline = pushResult.stdout.includes('\r\n') ? '\r\n' : pushResult.stdout.includes('\r') ? '\r' : '\n';
|
|
99
|
-
|
|
100
|
-
// if any *lines* start with "error: " or "Error: ", log stderr
|
|
101
|
-
const errorCount = pushResult.stdout.split(errNewline).filter(line => line.trim().startsWith('error: ') || line.trim().startsWith('Error: ')).length;
|
|
102
|
-
if (errorCount > 0)
|
|
103
|
-
console.error(pushResult.stdout);
|
|
104
|
-
|
|
105
|
-
// if any lines start with "warn : ", log stdout
|
|
106
|
-
const warningCount = pushResult.stdout.split(errNewline).filter(line => line.trim().startsWith('warn : ')).length;
|
|
107
|
-
if (warningCount > 0)
|
|
108
|
-
console.warn(pushResult.stdout);
|
|
109
|
-
|
|
110
|
-
const hasAuthError = pushResult.stdout.includes('401 (Unauthorized)');
|
|
111
|
-
|
|
112
|
-
// return true is no lines contain error indicators.
|
|
113
|
-
return errorCount === 0 && hasAuthError === false;
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
const stdout = (err as ExecException).stdout ?? '';
|
|
117
|
-
console.error((err as ExecException).stack + '\n' + stdout.split('Usage: dotnet nuget push')[0]);
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** returns the value of GITHUB_REPOSITORY_OWNER */
|
|
123
|
-
function getOwner(): string | undefined {
|
|
124
|
-
return getEnvVarValue('GITHUB_REPOSITORY_OWNER')
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export const nugetGitHubUrlBase = 'https://nuget.pkg.github.com';
|
|
128
|
-
|
|
129
|
-
/** @deprecated use {@link getNugetGitHubUrl()} instead. */
|
|
130
|
-
export const nugetGitHubUrl: string | undefined = getNugetGitHubUrl();
|
|
131
|
-
|
|
132
|
-
// todo!: refactor to "return string else throw"
|
|
133
|
-
export function getNugetGitHubUrl() {
|
|
134
|
-
const owner = getOwner();
|
|
135
|
-
if (owner)
|
|
136
|
-
return `${nugetGitHubUrlBase}/${owner}/index.json`;
|
|
137
|
-
console.warn('GITHUB_REPOSITORY_OWNER is undefined! Default NuGet source for GitHub is unavailable.');
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* If tokenEnvVar is NOT 'GITHUB_TOKEN', then test if the token is defined and return the boolean.
|
|
143
|
-
* Else If tokenEnvVar is 'GITHUB_TOKEN' and defined, then return true.
|
|
144
|
-
* Else If tokenEnvVar is 'GITHUB_TOKEN' and undefined, then set tokenEnvVar to 'GH_TOKEN', test if GH_TOKEN is defined, and return the boolean.
|
|
145
|
-
* @param tokenEnvVar the name of the environment variable with the token's value. Defaults to 'GITHUB_TOKEN'. If environment variable 'GITHUB_TOKEN' is undefined, falls back to 'GH_TOKEN'.
|
|
146
|
-
* @returns `{isDefined: true}` if the token is defined. Else, if tokenEnvVar is 'GITHUB_TOKEN' (default) and token is defined, returns `true`. Else, if 'GH_TOKEN' is defined, returns `true`. Else, returns `false`
|
|
147
|
-
*/
|
|
148
|
-
export function isTokenDefined(tokenEnvVar = 'GITHUB_TOKEN'): { isDefined: boolean, fallback?: string } {
|
|
149
|
-
let token = getEnvVarValue(tokenEnvVar /* custom or GITHUB_TOKEN */);
|
|
150
|
-
|
|
151
|
-
if (tokenEnvVar !== 'GITHUB_TOKEN')
|
|
152
|
-
return { isDefined: (token !== undefined && token !== 'undefined') };
|
|
153
|
-
|
|
154
|
-
/* GITHUB_TOKEN */
|
|
155
|
-
if (token !== undefined && token !== 'undefined')
|
|
156
|
-
return { isDefined: true };
|
|
157
|
-
|
|
158
|
-
token = getEnvVarValue('GH_TOKEN');
|
|
159
|
-
return {
|
|
160
|
-
isDefined: (token !== undefined && token !== 'undefined'),
|
|
161
|
-
fallback: 'GH_TOKEN'
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Get a {@link NuGetRegistryInfo} for pushing to your GitHub Packages NuGet registry.
|
|
167
|
-
* todo: add support for private, custom GitHub instances. Token is only validated against github.com.
|
|
168
|
-
* @export
|
|
169
|
-
* @param {string | 'GITHUB_TOKEN' | 'GH_TOKEN'} [tokenEnvVar="GITHUB_TOKEN"] The name of environment variable storing the GitHub Packages NuGet registry API key. Defaults to `"GITHUB_TOKEN"`. If GITHUB_TOKEN is undefined, fallback to GH_TOKEN;
|
|
170
|
-
* @param {string} [url=tokenEnvVar] The url of the GitHub Packages NuGet registry. Defaults to return value of {@link getNugetGitHubUrl()}.
|
|
171
|
-
* @returns {(NuGetRegistryInfo | undefined)} a {@link NuGetRegistryInfo} object if {@link tokenEnvVar} and {@link url} are defined. Else, `undefined`.
|
|
172
|
-
* note: `url` defaults to job's repository owner's GitHub registry in GitHub Actions workflow. If GITHUB_REPOSITORY_OWNER is not defined, then an error will be logged and `undefined` will be returned.
|
|
173
|
-
*/
|
|
174
|
-
export function getGithubNugetRegistryPair(
|
|
175
|
-
tokenEnvVar: string | 'GITHUB_TOKEN' | 'GH_TOKEN' = 'GITHUB_TOKEN',
|
|
176
|
-
url: string | undefined = getNugetGitHubUrl(),
|
|
177
|
-
): NuGetRegistryInfo | undefined {
|
|
178
|
-
const errors: Error[] = [];
|
|
179
|
-
const _isTokenDefinedInfo = isTokenDefined(tokenEnvVar);
|
|
180
|
-
let canTokenWritePackages = undefined;
|
|
181
|
-
|
|
182
|
-
if ((url ??= getNugetGitHubUrl()) === undefined) {
|
|
183
|
-
errors.push(
|
|
184
|
-
new Error(
|
|
185
|
-
'The url for the GitHub Packages NuGet registry was undefined.\n' +
|
|
186
|
-
'If running in a GitHub Actions workflow, something is seriously wrong.\n' +
|
|
187
|
-
'If running in a different CI/CD pipeline and you wish to cross-push to GHPR, ensure GITHUB_REPOSITORY_OWNER is set correctly.\n',
|
|
188
|
-
),
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (_isTokenDefinedInfo.isDefined) {
|
|
193
|
-
if (_isTokenDefinedInfo.fallback)
|
|
194
|
-
tokenEnvVar = _isTokenDefinedInfo.fallback;
|
|
195
|
-
try {
|
|
196
|
-
canTokenWritePackages = tokenCanWritePackages(tokenEnvVar, url);
|
|
197
|
-
}
|
|
198
|
-
catch (err) {
|
|
199
|
-
if (err instanceof Error)
|
|
200
|
-
errors.push(err);
|
|
201
|
-
else
|
|
202
|
-
errors.push(new Error(String(err)));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
const errMsg = `The environment variable ${tokenEnvVar} was specified as the source of the token to push a NuGet package to GitHub, but the environment variable does not exist.`
|
|
207
|
-
+ `${_isTokenDefinedInfo.fallback === undefined ? '' : ` The fallback environment variable ${_isTokenDefinedInfo.fallback} is also undefined.`}`;
|
|
208
|
-
errors.push(new Error(errMsg));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (canTokenWritePackages === false) {
|
|
212
|
-
// yes, this is a critical error that should be fixed before Semantic Release can succeed.
|
|
213
|
-
// yes, this is incredibly irritating to deal with in local runs.
|
|
214
|
-
errors.push(
|
|
215
|
-
new Error(
|
|
216
|
-
'The provided GitHub token has insufficient permissions or is a fine-grained permissions token. Only class Personal Access Tokens (classic) or workflow tokens with `repo` or `write:packages` permission can push a package.',
|
|
217
|
-
),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// conditions checked so `url` is certainly defined
|
|
222
|
-
if (_isTokenDefinedInfo.isDefined && url !== undefined && canTokenWritePackages)
|
|
223
|
-
return { tokenEnvVar, url };
|
|
224
|
-
|
|
225
|
-
const aggErr = new Error(`One more more errors occurred when getting GHPR url-token pair. Errors:\n${errors.map(v => v.stack).join('\n')}`);
|
|
226
|
-
|
|
227
|
-
if (getEnvVarValue('SKIP_TOKEN') === 'true' && aggErr.message.length > 0) {
|
|
228
|
-
console.error('WARN: errors were thrown, but SKIP_TOKEN is defined.\n' + aggErr.stack)
|
|
229
|
-
return undefined;
|
|
230
|
-
}
|
|
231
|
-
throw aggErr;
|
|
232
|
-
}
|
package/src/dotnet/dotnetGLPR.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { getEnv, getEnvVarValue } from '../envUtils.js';
|
|
2
|
-
import type { NuGetRegistryInfo } from './dotnetHelpers.js';
|
|
3
|
-
|
|
4
|
-
const { CI_API_V4_URL, CI_PROJECT_ID } = getEnv();
|
|
5
|
-
const nameof = {
|
|
6
|
-
CI_API_V4_URL: 'CI_API_V4_URL',
|
|
7
|
-
CI_PROJECT_ID: 'CI_PROJECT_ID',
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const GitLabTokenEnvVar = 'CI_JOB_TOKEN';
|
|
11
|
-
export const nugetGitLabUrlBase = CI_API_V4_URL;
|
|
12
|
-
export const nugetGitLabUrl: string | undefined =
|
|
13
|
-
CI_API_V4_URL && CI_PROJECT_ID
|
|
14
|
-
? `${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/nuget/index.json`
|
|
15
|
-
: undefined;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Get a {@link NuGetRegistryInfo} for pushing to your GitLab Packages NuGet registry.
|
|
19
|
-
* @export
|
|
20
|
-
* @param {string} [tokenEnvVar=GitLabTokenEnvVar] The name of environment variable storing the GitLab Packages NuGet registry API key. Defaults to {@link GitLabTokenEnvVar}.
|
|
21
|
-
* @param {string} [url=nugetGitLabUrl] The url of the GitLab Packages NuGet registry. Defaults to {@link nugetGitLabUrl}.
|
|
22
|
-
* @returns {(NuGetRegistryInfo | undefined)} a {@link NuGetRegistryInfo} object if {@link tokenEnvVar} and {@link url} are defined. Else, undefined.
|
|
23
|
-
*/
|
|
24
|
-
export function getGitlabNugetRegistryPair(
|
|
25
|
-
tokenEnvVar: string = GitLabTokenEnvVar,
|
|
26
|
-
url: string | undefined = nugetGitLabUrl,
|
|
27
|
-
): NuGetRegistryInfo | undefined {
|
|
28
|
-
// yes, this is stupid. No, I won't change it.
|
|
29
|
-
if (!getEnvVarValue(tokenEnvVar)) {
|
|
30
|
-
console.error(
|
|
31
|
-
new Error(
|
|
32
|
-
`The environment variable ${tokenEnvVar} was specified as the source of the token to push a NuGet package to GitLab, but the environment variable does not exist.`,
|
|
33
|
-
),
|
|
34
|
-
);
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
if (url) {
|
|
38
|
-
return { tokenEnvVar, url };
|
|
39
|
-
}
|
|
40
|
-
console.error(
|
|
41
|
-
new Error(
|
|
42
|
-
`The environment variables ${nameof.CI_API_V4_URL} or ${nameof.CI_PROJECT_ID} do not exist and a custom GitLab Packages NuGet registry URL was not provided.`,
|
|
43
|
-
),
|
|
44
|
-
);
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { ok } from 'node:assert/strict';
|
|
2
|
-
import { getEnvVarValue } from '../envUtils.js';
|
|
3
|
-
import { MSBuildProject, MSBuildProjectPreDefinedProperties } from './MSBuildProject.js';
|
|
4
|
-
import { getGithubNugetRegistryPair, nugetGitHubUrlBase } from './dotnetGHPR.js';
|
|
5
|
-
import { getGitlabNugetRegistryPair } from './dotnetGLPR.js';
|
|
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
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Build a prepareCmd string from .NET project paths and `dotnet nuget sign` arguments.
|
|
113
|
-
*
|
|
114
|
-
* todo: parse Solution files to publish all projects with default Publish parameters (as evaluated by MSBuild). If multi-targeting frameworks and/or runtime, evaluate those properties for Publish permutation matrix.
|
|
115
|
-
* todo: cleanup, docs
|
|
116
|
-
* @export
|
|
117
|
-
* @param {string[]} projectsToPublish
|
|
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/`.
|
|
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.
|
|
120
|
-
*/
|
|
121
|
-
export function configurePrepareCmd(
|
|
122
|
-
projectsToPublish: string[],
|
|
123
|
-
projectsToPackAndPush: string[] | false,
|
|
124
|
-
dotnetNugetSignArgs: string[] = ['./publish'],
|
|
125
|
-
) {
|
|
126
|
-
// These are later evaluated with MSBuild, but are passed via --framework and --runtime arguments instead of -p:TargetFramework
|
|
127
|
-
const publishProperties = MSBuildProjectPreDefinedProperties;
|
|
128
|
-
|
|
129
|
-
return [
|
|
130
|
-
formatDotnetPublish(projectsToPublish, publishProperties),
|
|
131
|
-
formatDotnetPack(projectsToPackAndPush),
|
|
132
|
-
formatDotnetNugetSign(dotnetNugetSignArgs)
|
|
133
|
-
].join(' && ');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export interface NuGetRegistryInfo {
|
|
137
|
-
tokenEnvVar: string;
|
|
138
|
-
url: string;
|
|
139
|
-
user?: string | undefined;
|
|
140
|
-
}
|
|
141
|
-
export const nugetDefault: NuGetRegistryInfo = {
|
|
142
|
-
tokenEnvVar: 'NUGET_TOKEN',
|
|
143
|
-
url: 'https://api.nuget.org/v3/index.json',
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* todo -
|
|
148
|
-
* @param nupkgDir
|
|
149
|
-
* @param registries
|
|
150
|
-
* @param pushToGitHub
|
|
151
|
-
* @returns
|
|
152
|
-
*/
|
|
153
|
-
export function configureDotnetNugetPush(
|
|
154
|
-
nupkgDir = './publish',
|
|
155
|
-
registries: NuGetRegistryInfo[] = [nugetDefault],
|
|
156
|
-
pushToGitHub = true,
|
|
157
|
-
): string {
|
|
158
|
-
if (registries.some((registry) => registry.url.trim() === ''))
|
|
159
|
-
throw new Error('The URL for one of the provided NuGet registries was empty or whitespace.');
|
|
160
|
-
|
|
161
|
-
// if user did not specify a GitHub NuGet Registry, try determine default values and add the Source.
|
|
162
|
-
if (pushToGitHub && !registries.some((reg) => reg.url.startsWith(nugetGitHubUrlBase))) {
|
|
163
|
-
const ghPair: NuGetRegistryInfo | undefined = getGithubNugetRegistryPair();
|
|
164
|
-
if (ghPair) {
|
|
165
|
-
registries.push(ghPair);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (!registries.some((reg) => reg.url.startsWith(nugetGitHubUrlBase))) {
|
|
169
|
-
const glPair = getGitlabNugetRegistryPair();
|
|
170
|
-
if (glPair) {
|
|
171
|
-
registries.push(glPair);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return registries
|
|
176
|
-
.map(
|
|
177
|
-
(registry) => {
|
|
178
|
-
const tokenValue = getEnvVarValue(registry.tokenEnvVar);
|
|
179
|
-
ok(getEnvVarValue('SKIP_TOKEN') === 'true' || tokenValue, `The environment variable ${registry.tokenEnvVar} is undefined!`);
|
|
180
|
-
return `dotnet nuget push ${nupkgDir} --source ${registry.url} --token ${tokenValue ?? '**placeholder**'}`
|
|
181
|
-
}
|
|
182
|
-
)
|
|
183
|
-
.join(' && ');
|
|
184
|
-
}
|
package/src/dotnet.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export * as msbuildProject from "./dotnet/MSBuildProject.js"
|
|
2
|
-
export * as msbuildProjectProperties from "./dotnet/MSBuildProjectProperties.js"
|
|
3
|
-
export * as createDummyNupkg from './dotnet/createDummyNupkg.js'
|
|
4
|
-
export * as dotnetGHPR from "./dotnet/dotnetGHPR.js"
|
|
5
|
-
export * as dotnetGLPR from "./dotnet/dotnetGLPR.js"
|
|
6
|
-
export * as dotnetHelpers from "./dotnet/dotnetHelpers.js"
|
package/src/envUtils.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { config as loadDotenv, type DotenvConfigOptions } from "dotenv";
|
|
2
|
-
import { env } from 'node:process';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Load a .env file from the CWD with the given options (or defaults), returns the new value of process.env
|
|
6
|
-
* @param dotenvOptions
|
|
7
|
-
* @param overrides
|
|
8
|
-
* @returns
|
|
9
|
-
*/
|
|
10
|
-
export function getEnv(dotenvOptions?: DotenvConfigOptions, overrides?: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
|
11
|
-
loadDotenv(dotenvOptions);
|
|
12
|
-
|
|
13
|
-
if (overrides)
|
|
14
|
-
Object.assign(env, overrides);
|
|
15
|
-
|
|
16
|
-
return env;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Get the value from the given env var. If undefined, load .env from CWD and try again or return undefined.
|
|
21
|
-
* @param envVar
|
|
22
|
-
* @returns
|
|
23
|
-
*/
|
|
24
|
-
export function getEnvVarValue(envVar: string): string | undefined {
|
|
25
|
-
let value = env[envVar];
|
|
26
|
-
if (!value) {
|
|
27
|
-
try {
|
|
28
|
-
loadDotenv();
|
|
29
|
-
}
|
|
30
|
-
catch (err) {
|
|
31
|
-
console.error(String(err))
|
|
32
|
-
}
|
|
33
|
-
value = env[envVar];
|
|
34
|
-
}
|
|
35
|
-
return value;
|
|
36
|
-
}
|
package/src/findStaticConfig.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
/// ../static/.releaserc.yml
|
|
6
|
-
export function findStaticConfig(): string {
|
|
7
|
-
const glob = 'static/.releaserc.yml';
|
|
8
|
-
let dirPath = fileURLToPath(path.dirname(import.meta.url));
|
|
9
|
-
let combinedPath = path.join(dirPath, glob);
|
|
10
|
-
|
|
11
|
-
while (!existsSync(combinedPath)) {
|
|
12
|
-
/* file:// + dirname behavior on Windows. 'root' is empty when 'file://' is present.
|
|
13
|
-
* file:///C:/Repos
|
|
14
|
-
* file:///C:
|
|
15
|
-
* file://
|
|
16
|
-
* .
|
|
17
|
-
*/
|
|
18
|
-
// DEBUG.log(dirPath);
|
|
19
|
-
// DEBUG.log(combinedPath.href);
|
|
20
|
-
/** Throw if we reached root. */
|
|
21
|
-
if (path.dirname(dirPath) === '')
|
|
22
|
-
throw new Error(
|
|
23
|
-
`Failed to get full path for HCE.Shared's shared configuration. HCE.Shared recursively searched parent directories for '${glob}' starting from '${path.dirname(
|
|
24
|
-
import.meta.url,
|
|
25
|
-
)}'`,
|
|
26
|
-
);
|
|
27
|
-
dirPath = path.dirname(dirPath);
|
|
28
|
-
combinedPath = path.join(dirPath, glob);
|
|
29
|
-
}
|
|
30
|
-
return combinedPath;
|
|
31
|
-
}
|
package/static/.releaserc.yml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# footer contains links e.g. 3rd-party plugins, little-known features
|
|
2
|
-
|
|
3
|
-
### global vars
|
|
4
|
-
# https://semantic-release.gitbook.io/semantic-release/v/beta/usage/plugins#plugin-options-configuration
|
|
5
|
-
preset: conventionalcommits
|
|
6
|
-
|
|
7
|
-
### main options
|
|
8
|
-
|
|
9
|
-
branches: # https://semantic-release.gitbook.io/semantic-release/v/beta/usage/configuration#branches
|
|
10
|
-
- main
|
|
11
|
-
- name: develop
|
|
12
|
-
channel: develop
|
|
13
|
-
prerelease: true
|
|
14
|
-
plugins: # https://semantic-release.gitbook.io/semantic-release/v/beta/usage/configuration#plugins
|
|
15
|
-
- "@semantic-release/commit-analyzer"
|
|
16
|
-
- "semantic-release-export-data"
|
|
17
|
-
- "@semantic-release/release-notes-generator"
|
|
18
|
-
- "@semantic-release/changelog"
|
|
19
|
-
- - "@semantic-release/git"
|
|
20
|
-
- assets:
|
|
21
|
-
- README.md
|
|
22
|
-
- CHANGELOG.md
|
|
23
|
-
# Arbitrary shell commands - https://github.com/semantic-release/exec
|
|
24
|
-
# hint: set 'prepareCmd' to `dotnet publish`.
|
|
25
|
-
# Because this is sorted after @semantic-release/git, the new Git tag will
|
|
26
|
-
# be visible to dotnet (and GitVersion). Dotnet artifacts will be
|
|
27
|
-
# versioned accordingly.
|
|
28
|
-
# Plugins' Steps: https://github.com/semantic-release/semantic-release/blob/master/docs/extending/plugins-list.md
|
|
29
|
-
- "@semantic-release/exec"
|
|
30
|
-
- - "@semantic-release/github"
|
|
31
|
-
- assets:
|
|
32
|
-
- path: ./publish/*
|
|
33
|
-
## (OPTIONAL) update static Version strings before Git plugin
|
|
34
|
-
# https://github.com/jpoehnelt/semantic-release-replace-plugin
|
|
35
|
-
# https://github.com/droidsolutions/semantic-release-update-file
|