@halospv3/hce.shared-config
Version:
Automate commit message quality, changelogs, and CI/CD releases. Exports a semantic-release shareable configuration deserialized from this package's '.releaserc.yml'. Shared resources for .NET projects are also distributed with this package.
142 lines (134 loc) • 6.83 kB
JavaScript
;
const strict = require('node:assert/strict');
const envUtils = require('../envUtils.cjs');
const MSBuildProject = require('./MSBuildProject.cjs');
const dotnetGHPR = require('./dotnetGHPR.cjs');
const dotnetGLPR = require('./dotnetGLPR.cjs');
function formatDotnetPublish(projectsToPublish, publishProperties) {
/* Fun Fact: You can define a property and get the evaluated value in the same command!
```pwsh
dotnet msbuild .\src\HXE.csproj -property:RuntimeIdentifiers="""place;holder""" -getProperty:RuntimeIdentifiers
place;holder
```
enclosing with """ is required in pwsh to prevent the semicolon from breaking the string.
*/
if (!(Array.isArray(projectsToPublish) && projectsToPublish.length > 0)) throw new Error(`Type of projectsToPublish (${typeof projectsToPublish}) is not allowed. Expected a string[] where length > 0.`);
// each may have TargetFramework OR TargetFrameworks (plural)
const evaluatedProjects = projectsToPublish.map(proj => new MSBuildProject.MSBuildProject(proj, publishProperties));
// args appended to "dotnet publish", joined by space
return evaluatedProjects.flatMap(proj => {
const args = [proj.Properties.FullPath];
function appendCustomProperties(publishProperties) {
// convert to dictionary and filter for user-defined properties.
const dictionary = Object.entries(proj.Properties).filter(p => !publishProperties.includes(p[0]));
if (dictionary.length > 0) {
/* format remaining properties as "-p:Property=Value" and append to args */
args.push(...dictionary.map(keyValuePair => `-p:${keyValuePair[0]}=${keyValuePair[1]}`));
}
}
appendCustomProperties(publishProperties);
const cmdPermutations = []; // forEach, run dotnet [...args,...v]
function formatFrameworksAndRuntimes() {
const RIDs = proj.Properties.RuntimeIdentifiers.length > 0 ? proj.Properties.RuntimeIdentifiers.split(';') : [];
const TFMs = proj.Properties.TargetFrameworks.length > 0 ? proj.Properties.TargetFrameworks.split(';') : [];
if (RIDs.length > 0) {
if (TFMs.length > 0) {
for (const RID of RIDs) {
for (const TFM of TFMs) {
cmdPermutations.push(['--runtime', RID, '--framework', TFM]);
}
}
} else {
// assume singular TFM. No need to specify it.
for (const RID of RIDs) {
cmdPermutations.push(['--runtime', RID]);
}
}
} else if (TFMs.length > 0) {
for (const TFM of TFMs) {
cmdPermutations.push(['--framework', TFM]);
}
}
}
formatFrameworksAndRuntimes();
return cmdPermutations.length > 0 ? cmdPermutations.map(permArgs => [...args, ...permArgs]) // string[][]
: [args]; // string[][]
}).map(args => `dotnet publish ${args.join(' ')}`).join(' && ');
}
function formatDotnetPack(projectsToPackAndPush) {
return projectsToPackAndPush === false ? "" : projectsToPackAndPush.map(v => `dotnet pack ${v}`).join(' && ');
}
function formatDotnetNugetSign(dotnetNugetSignArgs) {
switch (dotnetNugetSignArgs.length) {
case 0:
return '';
default:
return `dotnet nuget sign ${dotnetNugetSignArgs.join(' ')}`;
// default: {
// throw new Error("")
// // this needs a rework.
// const packagePaths: string[] = [];
// dotnetNugetSignArgs.forEach((dotnetNugetSignArg, i) => {
// // if current arg doesn't start with '-' and (current arg is first -OR- previous arg also does not start with '-')...
// if (!dotnetNugetSignArg.startsWith("-") && (i === 0 || (i > 0 && !dotnetNugetSignArgs[i - 1].startsWith("-")))) {
// // ...then it's probably a package path.
// packagePaths.push(dotnetNugetSignArg);
// }
// });
// if (packagePaths.length === 0)
// return `dotnet nuget sign ${dotnetNugetSignArgs.join(" ")}`
// else return
// }
}
}
/**
* Build a prepareCmd string from .NET project paths and `dotnet nuget sign` arguments.
*
* 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.
* todo: cleanup, docs
* @export
* @param {string[]} projectsToPublish
* @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/`.
* @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.
*/
function configurePrepareCmd(projectsToPublish, projectsToPackAndPush, dotnetNugetSignArgs = ['./publish']) {
// These are later evaluated with MSBuild, but are passed via --framework and --runtime arguments instead of -p:TargetFramework
const publishProperties = MSBuildProject.MSBuildProjectPreDefinedProperties;
return [formatDotnetPublish(projectsToPublish, publishProperties), formatDotnetPack(projectsToPackAndPush), formatDotnetNugetSign(dotnetNugetSignArgs)].join(' && ');
}
const nugetDefault = {
tokenEnvVar: 'NUGET_TOKEN',
url: 'https://api.nuget.org/v3/index.json'
};
/**
* todo -
* @param nupkgDir
* @param registries
* @param pushToGitHub
* @returns
*/
function configureDotnetNugetPush(nupkgDir = './publish', registries = [nugetDefault], pushToGitHub = true) {
if (registries.some(registry => registry.url.trim() === '')) throw new Error('The URL for one of the provided NuGet registries was empty or whitespace.');
// if user did not specify a GitHub NuGet Registry, try determine default values and add the Source.
if (pushToGitHub && !registries.some(reg => reg.url.startsWith(dotnetGHPR.nugetGitHubUrlBase))) {
const ghPair = dotnetGHPR.getGithubNugetRegistryPair();
if (ghPair) {
registries.push(ghPair);
}
}
if (!registries.some(reg => reg.url.startsWith(dotnetGHPR.nugetGitHubUrlBase))) {
const glPair = dotnetGLPR.getGitlabNugetRegistryPair();
if (glPair) {
registries.push(glPair);
}
}
return registries.map(registry => {
const tokenValue = envUtils.getEnvVarValue(registry.tokenEnvVar);
strict.ok(envUtils.getEnvVarValue('SKIP_TOKEN') === 'true' || tokenValue, `The environment variable ${registry.tokenEnvVar} is undefined!`);
return `dotnet nuget push ${nupkgDir} --source ${registry.url} --token ${tokenValue ?? '**placeholder**'}`;
}).join(' && ');
}
exports.configureDotnetNugetPush = configureDotnetNugetPush;
exports.configurePrepareCmd = configurePrepareCmd;
exports.nugetDefault = nugetDefault;
//# sourceMappingURL=dotnetHelpers.cjs.map