@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.
384 lines • 21.6 kB
TypeScript
import type { NugetProjectProperties } from './NugetProjectProperties.js';
import { config as configDotenv } from '@dotenvx/dotenvx';
import { type Type } from 'arktype';
import { MSBuildEvaluationOutput, MSBuildProject } from './MSBuildProject.js';
import type { Default } from 'arktype/internal/attributes.ts';
/**
* Read the contents of $GITHUB_OUTPUT (if its value is a file path) or $TEMP/GITHUB_OUTPUT.
* If the file doesn't exist, it is created.
* @returns If successful, a promised object with a parsed key.
*/
export declare function getGithubOutput(): Promise<ReturnType<typeof configDotenv>['parsed']>;
/**
* Read the contents of $GITHUB_OUTPUT (if its value is a file path) or $TEMP/GITHUB_OUTPUT.
* If the file doesn't exist, it is created.
* @returns An object with a parsed key if successful.
*/
export declare function getGithubOutputSync(): NonNullable<ReturnType<typeof configDotenv>['parsed']>;
export declare class NugetRegistryInfo {
private _canPushPackagesToSource;
private readonly _project;
private readonly _resolvedEnvVariable;
private readonly _source;
static readonly DefaultTokenEnvVars: readonly ['NUGET_TOKEN'];
/**
* Convert a URL string to a filesystem folder name.
*
* Intended usage: modify the output path of `dotnet pack` based on the NuGet
* Source the package should be pushed to. This is extra work is usually
* unnecessary and you'd typically push the same file to multiple sources.
* This is for the edge-case scenario of creating multiple nupkgs and signing
* each one with a different certificate corresponding to a given NuGet
* Source. This is only useful if the Sources have different certificates
* registered for a given package/user/organization.
* @param source The URL of the NuGet Source
* @returns A string suitable for a local filesystem folder name, formatted as
* `${hostname}_${pathname.replace('/', '_')}`.
*/
static GetDirNameForSource(source: string): string;
/**
* Creates an instance of NugetRegistryInfo.\
* This class enables the ability to push a given {@link project}'s
* package(s) to the {@link source} of a given NuGet Source's API endpoint with
* a user-defined API key. This API key, herein referred to as a "token", is
* derived from the {@link tokenEnvVars} array. This array is iterated through
* until one of the items is discovered to be an existing environment variable
* (or is defined in a file named '.env' in the current working directory for
* LOCAL TESTING ONLY! Do NOT `git add` your private keys!).
* \
* WARNING:
* - The token value is stored privately within this class, but it is plain text.
* - This private key may be copied to command line strings stored in Semantic
* Release's config object for later use by `@semantic-release/exec`.
* - Other EcmaScript modules can access the environment variable(s) and steal
* your key. Be aware of malicious dependencies!
* @param opts The input type of {@link NRIOpts.from}
* @param opts.project The project whose package(s) will be
* pushed.\
* - Its {@link NugetProjectProperties#PackageId} will be read.\
* - Its {@link NugetProjectProperties#PackageVersion} will be overridden via CLI args when creating a dummy package. The real package's
* `PackageVersion` will *not* be overridden.
* @param [opts.tokenEnvVars] The environment variables
* whose values are tokens with permission to push a package to the NuGet
* package registry. The array is iterated through until one token is found.
* If none of the environment variables are defined, this constructor will
* throw an {@link Error}.
* @param [opts.source] A NuGet package registry's API endpoint URL or name. Default: 'https://api.nuget.org/v3/index.json'
*/
constructor(opts: typeof NRIOpts['inferIn']);
get project(): MSBuildProject;
/**
* This is not useful without it being executed as part of a Semantic Release
* plugin. Deferring this to @semantic-release/exec's prepareCmd is possible,
* but impractical. You'd need to configure prepareCmd to invoke something
* like `node customScriptFile.mjs`. It's not worth the hassle.
* @returns `true` if the token can be used to push nupkg to the given Nuget registry
* @throws {TypeError | Error | import('../utils/execAsync.js').ChildProcessSpawnException }
* - {@link Error} | {@link module:utils/execAsync:ChildProcessSpawnException ChildProcessSpawnException}
* - The token is invalid, of the wrong token type, or lacks permission to push packages
* - The URL does not exist or a connection could not be established
* - The command line string is malformed.
* @deprecated Call during the `verifyConditions` step of Semantic Release! Additionally, {@link GetIsNextVersionAlreadyPublishedCommand}'s return value should be assigned to `prepareCmd` to prevent package version collision errors.
*/
get canPushPackagesToSource(): Promise<true>;
/**
* The first environment variable found to have a defined value. Set by
* {@link _GetTokenEnvVariables} in the constructor.
* @returns The first environment variable found to have a defined value.
*/
get resolvedEnvVariable(): string | undefined;
get source(): string;
/**
* Get the API token from {@link NugetRegistryInfo#resolvedEnvVariable}
* @param resolvedEnvVariable The name of the environment variable(s) whose
* value is a NuGet API key. Typically, the value of
* {@link NugetRegistryInfo#resolvedEnvVariable}.
* @returns The value of the first defined environment variable.
* @throws {Error} when none of the provided environment variables are defined.
*/
private static _GetTokenValue;
/**
* The type for options and arguments of `dotnet pack`. See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-pack.
*
* {@link NRI.PackPackagesOptionsType.t.propertyOverrides `propertyOverrides`}
* is a wrapper for MSBuild's `-property:<n>=<v>` properties override arg.
*/
static readonly PackPackagesOptionsType: Type<{
propertyOverrides?: Record<string, string> | undefined;
artifactsPath?: string | undefined;
configuration?: 'Release' | 'Debug' | undefined;
disableBuildServers?: boolean | undefined;
force?: boolean | undefined;
includeSource?: boolean | undefined;
includeSymbols?: boolean | undefined;
interactive?: boolean | undefined;
noBuild?: boolean | undefined;
noLogo?: boolean | undefined;
noRestore?: boolean | undefined;
output?: string | undefined;
runtime?: string | undefined;
serviceable?: boolean | undefined;
terminalLogger?: 'auto' | 'on' | 'off' | undefined;
useCurrentRuntime?: boolean | undefined;
verbosity?: 'quiet' | 'minimal' | 'normal' | 'detailed' | 'diagnostic' | undefined;
versionSuffix?: string | undefined;
'-GetItem'?: readonly string[] | string[] | undefined;
}>;
static readonly PackDummyPackagesOptionsType: Type<{
propertyOverrides?: Record<string, string> | undefined;
artifactsPath?: string | undefined;
configuration?: 'Release' | 'Debug' | undefined;
disableBuildServers?: boolean | undefined;
force?: boolean | undefined;
includeSource?: boolean | undefined;
includeSymbols?: boolean | undefined;
interactive?: boolean | undefined;
noBuild?: boolean | undefined;
noLogo?: boolean | undefined;
noRestore?: boolean | undefined;
runtime?: string | undefined;
serviceable?: boolean | undefined;
terminalLogger?: 'auto' | 'on' | 'off' | undefined;
useCurrentRuntime?: boolean | undefined;
verbosity?: 'quiet' | 'minimal' | 'normal' | 'detailed' | 'diagnostic' | undefined;
versionSuffix?: string | undefined;
'-GetItem'?: readonly string[] | string[] | undefined;
}>;
/**
* Get a `dotnet pack` command line string, outputting the package(s) to a
* path determined by this method's parameters.
* When pushing the package(s), you only need to supply the main .nupkg's path
* or its directory to the dotnet CLI—by default, it will also push the
* symbols package, if present.
* @param opts Options passed to
* `dotnet pack`, excluding the required `<PROJECT | SOLUTION>` argument. The
* {@link PackPackagesOptionsType.t.output} path is modified according to the
* {@link usePerSourceSubfolder} and {@link usePerPackageIdSubfolder}
* arguments.
* @param usePerSourceSubfolder If true, the path of the package output will
* include a subfolder named after the NuGet Source.
* @param usePerPackageIdSubfolder If true, the path of the package output
* will include a subfolder named after the NuGet package's ID.
* @returns `dotnet pack "${this.project.Properties.MSBuildProjectFullPath}"
* -o "${outDir}"` where outDir may be `${cwd()}/publish/${NugetRegistryInfo.GetNameForURL(this.source)}/${this._project.Properties.PackageId}`
*/
GetPackCommand(opts: typeof NRI.PackPackagesOptionsType.inferIn, usePerSourceSubfolder?: boolean, usePerPackageIdSubfolder?: boolean): string;
/**
* !Not ready for use! Remove private modifier and commit as `feat(dotnet)` when ready for release!
* Blocking Issue: convert all dotnet-related functionality to a Semantic Release plugin!
* The current {@link SemanticReleaseConfigDotnet} leverages
* `@semantic-release/exec` to invoke dotnet commands. This is fine for
* relatively short command lines, but chaining commands with ' && ' results
* in quickly-growing complexity.
* NuGet packages should be created during the `prepare` step, but complex
* configuration of `dotnet pack` via command lines intended to be invoked by
* `@semantic-release/exec` is impractical.
* @param opts `dotnet pack` options. See `dotnet pack -h`,
* https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-pack, and
* {@link PackPackagesOptionsType}.
* {@link opts['-GetItem']} will _always_ have '_OutputPackItems'.
* @param [usePerSourceSubfolder] If `true`, modify the output path to
* include a subfolder bearing a path-safe encoding of the NuGet Source that
* will receive the nupkg.
* @param [usePerPackageIdSubfolder] If `true`, modify the output path
* to include a subfolder named after the the PackageId.
* @returns a string[] containing the full file paths of all new packages i.e.
* .nupkg, .symbols.nupkg, .snupkg
*/
private _PackPackages;
/**
* Create a dummy package for the current {@link project} by executing a
* command line like \``dotnet pack ${this.project.Properties.MSBuildProjectFullPath} -p:Version=0.0.1-DUMMY -output ${getDummiesDir(this._project)}/${GetNameForURL(this.source)}`\`
* @param opts Options passed to
* `dotnet pack`, excluding the required `<PROJECT | SOLUTION>` argument.
* - The `output` field is ignored and overwritten. It is replaced with
* ${{@link getDummiesDir}({@link project})}/${{@link GetDirNameForSource}({@link source})}
* - The `output` path will be affixed with a folder named after this
* {@link NugetRegistryInfo#source}, but will not include a subfolder for the
* {@link NugetRegistryInfo#project NugetRegistryInfo.project}.{@link MSBuildProject#Properties Properties}.{@link MSBuildProject#Properties#PackageId PackageId}.
* @returns the full paths of all nupkg, symbols.nupkg, and snupkg files
* created by the Pack target, as extracted from the dotnet process's STDOUT.
* If mixed with other nupkgs, filter for the {@link NugetProjectProperties#PackageId}
*/
PackDummyPackage(opts: typeof NRI.PackDummyPackagesOptionsType.inferIn): Promise<string[]>;
/**
* Also includes required argument 'ROOT': the directory in which packages
* should be present and ready to be pushed the default or specified Source.
* The ROOT may also include wildcards e.g. `*.nupkg`, `**\\*.nupkg`
* See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push
*
* Specific to this API:
* If you want to use this API's default root value (\`${cwd()}/publish`), assign an empty string.
*/
static readonly PushPackagesOptionsType: Type<{
root: string;
apiKey?: string | undefined;
configFile?: string | undefined;
disableBuffering?: boolean | undefined;
forceEnglishOutput?: boolean | undefined;
interactive?: boolean | undefined;
noServiceEndpoint?: boolean | undefined;
noSymbols?: boolean | undefined;
skipDuplicate?: boolean | undefined;
source?: string | undefined;
symbolApiKey?: string | undefined;
symbolSource?: string | undefined;
timeout?: number | undefined;
}>;
/**
* {@link NRI.PushPackagesOptionsType} sans {@link NRI.PushPackagesOptionsType.t.root}.
* The result of {@link getDummiesDir} is used, instead.
*/
static readonly PushDummyPackagesOptionsType: Type<{
apiKey?: string | undefined;
configFile?: string | undefined;
disableBuffering?: boolean | undefined;
forceEnglishOutput?: boolean | undefined;
interactive?: boolean | undefined;
noServiceEndpoint?: boolean | undefined;
noSymbols?: boolean | undefined;
source?: string | undefined;
symbolApiKey?: string | undefined;
symbolSource?: string | undefined;
timeout?: number | undefined;
skipDuplicate: Default<true, true>;
}>;
/**
* Create a `dotnet nuget push` command line from the given options and
* optional boolean parameters.
* @param opts See {@link PushPackagesOptionsType}
* @param usePerSourceSubfolder If `true`, the NuGet Source name or URL is formatted
* to a folder name and appended to the ROOT as a subfolder. Do not use
* wildcards in ROOT with this set to `true`!
* @param usePerPackageIdSubfolder If `true`, the
* {@link project}'s {@link NugetProjectProperties#PackageId}
* is appended to the ROOT as a subfolder. Do not use wildcards in
* ROOT with this set to `true`!
* @returns A `dotnet nuget push` command line formatted with the
* appropriate arguments.
*/
GetPushCommand(opts: typeof NRI.PushPackagesOptionsType.inferIn, usePerSourceSubfolder?: boolean, usePerPackageIdSubfolder?: boolean): string;
/**
* Immediately push packages. The input path may be modified according to the
* {@link usePerSourceSubfolder} and {@link usePerPackageIdSubfolder}
* arguments.
* @param opts The `dotnet nuget push` command line options, including the
* ROOT argument, the directory containing local nuget packages ready to be
* pushed.
* @param usePerSourceSubfolder If `true`, the NuGet Source name or URL is formatted
* to a folder name and appended to the ROOT as a subfolder. Do not use
* wildcards in ROOT with this set to `true`!
* @param usePerPackageIdSubfolder If `true`, the current {@link project}'s
* PackageId is appended to the ROOT as a subfolder. Do not use wildcards in
* ROOT with this set to `true`!
*/
private _PushPackages;
/**
*
* Get a `dotnet nuget push` command for pushing one or more nupkg/snupkg
* files created by {@link GetPackCommand} or {@link _PackPackages}.\
* Like {@link PackDummyPackage}, the output/ROOT path will include a
* folder named after this NRI instance's {@link NugetRegistryInfo#source},
* but will not include a subfolder for the
* {@link NugetRegistryInfo#project NugetRegistryInfo.project}.{@link MSBuildProject#Properties Properties}.{@link MSBuildProject#Properties#PackageId PackageId}
* @example
* ```ts
* const packAndPushDummyCmd = [
* nri.GetPackCommand(
* NugetRegistryInfo.PackPackagesOptionsType.from({ root: '' }),
* false,
* false,
* ),
* nri.GetPushDummyPackageCommand(pushOpts, false, false),
* ].join(' && ')
* ```
* @param opts options for `dotnet nuget push`. The following
* fields are overwritten:
* - root: getDummiesDir(this.project)
* - skipDuplicates: true
* @returns a `dotnet nuget push` command to push a dummy package
* (created by executing {@link PackDummyPackage}) to {@link source}
*/
GetPushDummyCommand(opts: typeof NRI.PushDummyPackagesOptionsType.inferIn): string;
/**
* Call {@link GetPushDummyCommand} and immediately execute it.
* @throws {Error} when the process exits with an error code indicating
* failure i.e. the command line is invalid, the process fails to start,
* the push fails, et cetera.
* @param opts the ROOT arg and options for `dotnet nuget push`. The following
* fields are overwritten:
* - root: getDummiesDir(this.project)
* - skipDuplicates: true
* @returns The return type of {@link execAsync} i.e. a {@link Promise} resolving to `{ stdout: string; stderr: string }`.
*/
private _PushDummyPackages;
private static readonly _NugetSearchReturnTypes;
private static readonly _ParseNugetSearchReturn;
/**
* !WARNING: this method requires the Nuget Source to be configured via `dotnet nuget add source` or `dotnet nuget update source`. `NUGET_TOKEN` works, but it may be vulnerable to supply chain attacks.\
* Call during the `prepare` step of a Semantic Release run.\
* Determine if the `nextVersion` generated during the `analyze` Semantic
* Release step was already published to the NuGet {@link source}.
* @param source The name or URI of the NuGet Source to search. If this API
* endpoint does not support searches, the operation will fail. If this API
* endpoint requires authentication (e.g. GitHub), it must be configured via
* `dotnet nuget add source` or `dotnet nuget update source` before calling
* this method.
* @param packageId The ID of the NuGet package to search for.
* @param nextVersion The nextVersion value generated by semantic-release's hidden ["Create Git tag" step](https://semantic-release.gitbook.io/semantic-release#:~:text=the%20last%20release.-,Create%20Git%20tag,-Create%20a%20Git).
* @returns A promised boolean.
* If the promise resolves to `true`, the semantic release run should be
* cancelled immediately.
* Otherwise, the release should proceed.
* @todo utilize in custom plugin inserted at the beginning of `prepare`
*/
static IsNextVersionAlreadyPublished(source: string, packageId: string, nextVersion: string): Promise<boolean>;
/**
* !WARNING: GITHUB_OUTPUT must be the full path to an environment file.
* The plugin "semantic-release-output-variables" next-release-version
*
* !WARNING: NuGet Source API Key mus tbe configured via `dotnet nuget add source` or `dotnet nuget update source`.
* Some Sources (e.g. GitHub) require authentication for package searches.
*
* # Authenticating NuGet Package Searches
*
* ## GitHub NuGet Registry authentication
* - {@link https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry#authenticating-in-a-github-actions-workflow Authenticating in a GitHub Actions workflow}
* - {@link https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry#authenticating-with-a-personal-access-token Authenticating with a personal access token}.
* ## For GitLab NuGet Registry authentication, see
* - {@link https://docs.gitlab.com/ee/user/packages/nuget_repository/#add-a-source-with-the-net-cli Add a source with the .NET CLI}
* @returns a string containing a Node.JS command line invoking {@link ./IsNextVersionAlreadyPublished.cli.ts}
* @see {@link ./IsNextVersionAlreadyPublished.cli.ts}, {@link ./IsNextVersionAlreadyPublished.cli.js}
*/
GetIsNextVersionAlreadyPublishedCommand(): string;
}
declare const NRI: typeof NugetRegistryInfo;
/**
* The base type for {@link NRIOpts} and related types. Extend this type while
* overriding member types via {@link NRIOptsBase.merge}
*/
export declare const NRIOptsBase: Type<{
project: MSBuildProject | {
readonly Items: Readonly<Required<MSBuildEvaluationOutput>['Items']>;
readonly Properties: Readonly<NugetProjectProperties>;
readonly Targets: readonly string[];
readonly TargetResults: Required<MSBuildEvaluationOutput>['TargetResults'][];
};
source: string;
tokenEnvVars: readonly string[];
}>;
/**
* The type of the parameter for {@link NugetRegistryInfo}'s constructor.
*/
export declare const NRIOpts: Type<{
project: MSBuildProject | {
readonly Items: Readonly<Required<MSBuildEvaluationOutput>['Items']>;
readonly Properties: Readonly<NugetProjectProperties>;
readonly Targets: readonly string[];
readonly TargetResults: Required<MSBuildEvaluationOutput>['TargetResults'][];
};
tokenEnvVars: Default<readonly string[], readonly ['NUGET_TOKEN']>;
source: Default<string, string>;
}>;
export {};
//# sourceMappingURL=NugetRegistryInfo.d.ts.map