UNPKG

@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
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