21 Commits

Author SHA1 Message Date
Artur Stolear
4bda6b5eba renamed gitversion-tool and gitreleasemanager-tool to just tool 2020-02-09 00:30:13 +02:00
Artur Stolear
edd278e744 use the targetDirectory based on repo root
use the targetDirectory based on repo root
2020-02-09 00:28:20 +02:00
Artur Stolear
c7eb02e614 compiled discard action 2020-02-08 21:32:40 +02:00
Artur Stolear
6cbe5073c3 added GRM discard action 2020-02-08 21:32:22 +02:00
Artur Stolear
0e2e93e6aa added GRM create assets 2020-02-08 20:32:41 +02:00
Artur Stolear
274c9b2e99 moved the common settings to a file 2020-02-08 19:20:43 +02:00
Artur Stolear
dab6b01596 moved the gitversion settings to a file 2020-02-08 19:02:57 +02:00
Artur Stolear
b98ee9d8b2 create action for GRM (2)
added azure task definition
2020-02-08 17:38:58 +02:00
Artur Stolear
aba63c943d made gitversion & gitreleasemanager extend dotnet-tool 2020-02-08 15:49:46 +02:00
Artur Stolear
1be05ba386 create action for GRM (2)
check the options settings
2020-02-08 10:57:00 +02:00
Artur Stolear
632a7fdad0 create action for GRM (2) 2020-02-08 10:40:14 +02:00
Artur Stolear
b677d43869 fix github version of isValidInputFile 2020-02-08 10:07:21 +02:00
Artur Stolear
1c5c0557da minor 2020-02-08 09:19:57 +02:00
Artur Stolear
f17101e556 moved tools to separate folders 2020-02-07 22:38:58 +02:00
Artur Stolear
7dee6ba225 split the common.ts into several files 2020-02-07 22:18:48 +02:00
Artur Stolear
237764149f minor 2020-02-03 19:31:31 +02:00
dependabot-preview[bot]
5021e6bca9 Bump @types/node from 13.5.3 to 13.7.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.5.3 to 13.7.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 09:11:34 +01:00
dependabot-preview[bot]
b541d2f286 Bump @types/node from 13.5.2 to 13.5.3
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.5.2 to 13.5.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-31 09:39:39 +02:00
dependabot-preview[bot]
2e93547963 Bump @types/node from 13.5.1 to 13.5.2
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.5.1 to 13.5.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-30 09:33:31 +02:00
dependabot-preview[bot]
22c25b670a Bump @types/uuid from 3.4.6 to 3.4.7
Bumps [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) from 3.4.6 to 3.4.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-29 09:49:31 +02:00
dependabot-preview[bot]
32247c8ed9 Bump @types/node from 13.5.0 to 13.5.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.5.0 to 13.5.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-29 09:49:19 +02:00
44 changed files with 43909 additions and 1959 deletions

File diff suppressed because one or more lines are too long

View File

@@ -20,5 +20,76 @@
"workingDirectory": "."
}
},
"instanceNameFormat": "gitreleasemanager/create"
"instanceNameFormat": "gitreleasemanager/create",
"inputs": [{
"name": "owner",
"type": "string",
"label": "The owner of the repository",
"defaultValue": "",
"required": true,
"helpMarkDown": "The owner of the repository"
}, {
"name": "repository",
"type": "string",
"label": "The name of the repository",
"defaultValue": "",
"required": true,
"helpMarkDown": "The name of the repository"
}, {
"name": "token",
"type": "string",
"label": "The access token to access GitHub with",
"defaultValue": "",
"required": true,
"helpMarkDown": "The access token to access GitHub with"
}, {
"name": "milestone",
"type": "string",
"label": "The milestone to use",
"defaultValue": "",
"required": false,
"helpMarkDown": "The milestone to use"
}, {
"name": "name",
"type": "string",
"label": "The name of the release",
"defaultValue": "",
"required": false,
"helpMarkDown": "The name of the release"
}, {
"name": "inputFilePath",
"type": "string",
"label": "The path to the file to be used as the content of the release notes",
"defaultValue": "",
"required": false,
"helpMarkDown": "The path to the file to be used as the content of the release notes"
}, {
"name": "pre",
"type": "boolean",
"label": "Creates the release as a pre-release",
"defaultValue": "false",
"required": false,
"helpMarkDown": "Creates the release as a pre-release"
}, {
"name": "targetcommitish",
"type": "string",
"label": "The commit to tag. Can be a branch or SHA. Defaults to repository's default branch",
"defaultValue": "",
"required": false,
"helpMarkDown": "The commit to tag. Can be a branch or SHA. Defaults to repository's default branch"
}, {
"name": "targetDirectory",
"type": "string",
"label": "The directory on which GitReleaseManager should be executed. Defaults to current directory",
"defaultValue": "",
"required": false,
"helpMarkDown": "The directory on which GitReleaseManager should be executed. Defaults to current directory"
}, {
"name": "assets",
"type": "multiLine",
"label": "Path(s) to the file(s) to include in the release",
"defaultValue": "",
"required": false,
"helpMarkDown": "Path(s) to the file(s) to include in the release. Separated by newline"
}]
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,46 @@
{
"messages": {
"LIB_UnhandledEx": "Unhandled: %s",
"LIB_FailOnCode": "Failure return code: %d",
"LIB_MkdirFailed": "Unable to create directory '%s'. %s",
"LIB_MkdirFailedFileExists": "Unable to create directory '%s'. Conflicting file exists: '%s'",
"LIB_MkdirFailedInvalidDriveRoot": "Unable to create directory '%s'. Root directory does not exist: '%s'",
"LIB_MkdirFailedInvalidShare": "Unable to create directory '%s'. Unable to verify the directory exists: '%s'. If directory is a file share, please verify the share name is correct, the share is online, and the current process has permission to access the share.",
"LIB_MultilineSecret": "Secrets cannot contain multiple lines",
"LIB_ProcessError": "There was an error when attempting to execute the process '%s'. This may indicate the process failed to start. Error: %s",
"LIB_ProcessExitCode": "The process '%s' failed with exit code %s",
"LIB_ProcessStderr": "The process '%s' failed because one or more lines were written to the STDERR stream",
"LIB_ReturnCode": "Return code: %d",
"LIB_ResourceFileNotExist": "Resource file doesn\\'t exist: %s",
"LIB_ResourceFileAlreadySet": "Resource file has already set to: %s",
"LIB_ResourceFileNotSet": "Resource file haven\\'t set, can\\'t find loc string for key: %s",
"LIB_StdioNotClosed": "The STDIO streams did not close within %s seconds of the exit event from process '%s'. This may indicate a child process inherited the STDIO streams and has not yet exited.",
"LIB_WhichNotFound_Linux": "Unable to locate executable file: '%s'. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.",
"LIB_WhichNotFound_Win": "Unable to locate executable file: '%s'. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.",
"LIB_LocStringNotFound": "Can\\'t find loc string for key: %s",
"LIB_ParameterIsRequired": "%s not supplied",
"LIB_InputRequired": "Input required: %s",
"LIB_InvalidPattern": "Invalid pattern: '%s'",
"LIB_EndpointNotExist": "Endpoint not present: %s",
"LIB_EndpointDataNotExist": "Endpoint data parameter %s not present: %s",
"LIB_EndpointAuthNotExist": "Endpoint auth data not present: %s",
"LIB_InvalidEndpointAuth": "Invalid endpoint auth: %s",
"LIB_InvalidSecureFilesInput": "Invalid secure file input: %s",
"LIB_PathNotFound": "Not found %s: %s",
"LIB_PathHasNullByte": "Path cannot contain null bytes",
"LIB_OperationFailed": "Failed %s: %s",
"LIB_UseFirstGlobMatch": "Multiple workspace matches. using first.",
"LIB_MergeTestResultNotSupported": "Merging test results from multiple files to one test run is not supported on this version of build agent for OSX/Linux, each test result file will be published as a separate test run in VSO/TFS.",
"LIB_PlatformNotSupported": "Platform not supported: %s",
"TOOL_LIB_CachingTool": "Caching tool: %s %s %s",
"_TOOL_LIB_CachingTool.comment": "This informational log message indicates that a tool, that was just downloaded, is being copied into the cache directory. %s %s %s represent the tool name, version information, and processor architecture.",
"TOOL_LIB_Downloading": "Downloading: %s",
"_TOOL_LIB_Downloading.comment": "This information log message indicates that a file is being downloaded. %s represents the URL being downloaded.",
"TOOL_LIB_ExtractingArchive": "Extracting archive",
"_TOOL_LIB_ExtractingArchive.comment": "This informational log message indicates that an archive file is being extracted. For example, a .zip file, .7z file, or .tar.gz file.",
"TOOL_LIB_FoundInCache": "Found tool in cache: %s %s %s",
"_TOOL_LIB_FoundInCache.comment": "This informational log message indicates that the request tool is already cached, and does not need to be downloaded again. %s %s %s represent the tool name, version information, and processor architecture.",
"TOOL_LIB_PrependPath": "Prepending PATH environment variable with directory: %s",
"_TOOL_LIB_PrependPath.comment": "This informational log message indicates that a directory is being prepended to the front of the PATH environment variable. The directories specified by the PATH environment variable are used to resolve the location of command line tools."
}
}

View File

@@ -0,0 +1,60 @@
{
"id": "9ae78b66-6100-4522-8106-b7ae00bbfcdf",
"name": "gitreleasemanager/discard",
"friendlyName": "Discard GitReleaseManager Task",
"description": "Tool for creating and exporting releases for software applications hosted on GitHub",
"author": "GitTools Contributors",
"helpMarkDown": "See the [documentation](https://gittools.github.io/GitReleaseManager/docs/) for help",
"category": "Build",
"demands": [],
"version": {
"Major": "1",
"Minor": "0",
"Patch": "0"
},
"minimumAgentVersion": "2.115.0",
"execution": {
"Node": {
"target": "bundle.js",
"argumentFormat": "",
"workingDirectory": "."
}
},
"instanceNameFormat": "gitreleasemanager/discard",
"inputs": [{
"name": "owner",
"type": "string",
"label": "The owner of the repository",
"defaultValue": "",
"required": true,
"helpMarkDown": "The owner of the repository"
}, {
"name": "repository",
"type": "string",
"label": "The name of the repository",
"defaultValue": "",
"required": true,
"helpMarkDown": "The name of the repository"
}, {
"name": "token",
"type": "string",
"label": "The access token to access GitHub with",
"defaultValue": "",
"required": true,
"helpMarkDown": "The access token to access GitHub with"
}, {
"name": "milestone",
"type": "string",
"label": "The milestone to use",
"defaultValue": "",
"required": true,
"helpMarkDown": "The milestone to use"
}, {
"name": "targetDirectory",
"type": "string",
"label": "The directory on which GitReleaseManager should be executed. Defaults to current directory",
"defaultValue": "",
"required": false,
"helpMarkDown": "The directory on which GitReleaseManager should be executed. Defaults to current directory"
}]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,8 @@
{ "path": "gitversion/setup" },
{ "path": "gitversion/execute" },
{ "path": "gitreleasemanager/setup" },
{ "path": "gitreleasemanager/create" }
{ "path": "gitreleasemanager/create" },
{ "path": "gitreleasemanager/discard" }
],
"categories": [
"Azure Pipelines"
@@ -97,5 +98,14 @@
"properties": {
"name": "gitreleasemanager/create"
}
}, {
"id": "discard-gitreleasemanager-task",
"type": "ms.vss-distributed-task.task",
"targets": [
"ms.vss-distributed-task.tasks"
],
"properties": {
"name": "gitreleasemanager/discard"
}
}]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,4 +6,41 @@ branding:
icon: git-pull-request
runs:
using: node12
main: ../../dist/github/gitreleasemanager/create/bundle.js
main: ../../dist/github/gitreleasemanager/create/bundle.js
inputs:
owner:
description: The owner of the repository
required: true
default: ''
repository:
description: The name of the repository
required: true
default: ''
token:
description: The access token to access GitHub with
required: true
default: ''
milestone:
description: The milestone to use
required: false
default: ''
name:
description: The name of the release
required: false
default: ''
inputFilePath:
description: The path to the file to be used as the content of the release notes
required: false
default: ''
pre:
description: Creates the release as a pre-release
required: false
default: 'false'
targetcommitish:
description: The commit to tag. Can be a branch or SHA. Defaults to repository's default branch
required: false
default: ''
targetDirectory:
description: The directory on which GitReleaseManager should be executed. Defaults to current directory
required: false
default: ''

View File

@@ -0,0 +1,30 @@
name: gitreleasemanager-discard
description: GitHub Action for creating and exporting releases for software applications hosted on GitHub. Discards a release
author: GitTools
branding:
color: gray-dark
icon: git-pull-request
runs:
using: node12
main: ../../dist/github/gitreleasemanager/discard/bundle.js
inputs:
owner:
description: The owner of the repository
required: true
default: ''
repository:
description: The name of the repository
required: true
default: ''
token:
description: The access token to access GitHub with
required: true
default: ''
milestone:
description: The milestone to use
required: true
default: ''
targetDirectory:
description: The directory on which GitReleaseManager should be executed. Defaults to current directory
required: false
default: ''

22
package-lock.json generated
View File

@@ -78,9 +78,9 @@
}
},
"@types/node": {
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz",
"integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==",
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
"integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==",
"dev": true
},
"@types/q": {
@@ -101,19 +101,9 @@
"dev": true
},
"@types/uuid": {
"version": "3.4.6",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.6.tgz",
"integrity": "sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw==",
"requires": {
"@types/node": "*"
},
"dependencies": {
"@types/node": {
"version": "12.12.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.11.tgz",
"integrity": "sha512-O+x6uIpa6oMNTkPuHDa9MhMMehlxLAd5QcOvKRjAFsBVpeFWTOPnXbDvILvFgFFZfQ1xh1EZi1FbXxUix+zpsQ=="
}
}
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.7.tgz",
"integrity": "sha512-C2j2FWgQkF1ru12SjZJyMaTPxs/f6n90+5G5qNakBxKXjTBc/YTSelHh4Pz1HUDwxFXD9WvpQhOGCDC+/Y4mIQ=="
},
"@webassemblyjs/ast": {
"version": "1.8.5",

View File

@@ -35,10 +35,10 @@
"uuid": "^3.4.0"
},
"devDependencies": {
"@types/node": "^13.5.0",
"@types/node": "^13.7.0",
"@types/q": "^1.5.2",
"@types/semver-compare": "^1.0.1",
"@types/uuid": "^3.4.6",
"@types/uuid": "^3.4.7",
"json-update": "^5.3.0",
"reflect-metadata": "^0.1.13",
"replace-in-file-webpack-plugin": "^1.0.6",

View File

@@ -3,7 +3,7 @@ import { injectable } from "inversify";
import * as taskLib from "azure-pipelines-task-lib/task";
import * as toolLib from "azure-pipelines-tool-lib/tool";
import { IBuildAgent, IExecResult } from "../../core/common";
import { IBuildAgent, IExecResult } from "../../core/models";
@injectable()
class BuildAgent implements IBuildAgent {
@@ -77,6 +77,13 @@ class BuildAgent implements IBuildAgent {
return taskLib.getInput(input, required);
}
public getListInput(input: string, required?: boolean): string[] {
return taskLib
.getInput(input, required)
.split("\n")
.filter(x => x !== "");
}
public getBooleanInput(input: string, required?: boolean): boolean {
return taskLib.getBoolInput(input, required);
}

View File

@@ -10,7 +10,7 @@ import * as toolCache from "@actions/tool-cache";
import { injectable } from "inversify";
import { IBuildAgent, IExecResult } from "../../core/common";
import { IBuildAgent, IExecResult } from "../../core/models";
@injectable()
class BuildAgent implements IBuildAgent {
@@ -117,13 +117,24 @@ class BuildAgent implements IBuildAgent {
return core.getInput(input, { required } as core.InputOptions);
}
public getListInput(input: string, required?: boolean): string[] {
return core
.getInput(input, { required } as core.InputOptions)
.split("\n")
.filter(x => x !== "");
}
public getBooleanInput(input: string, required?: boolean): boolean {
const inputValue = this.getInput(input, required);
return (inputValue || "false").toLowerCase() === "true";
}
public isValidInputFile(input: string, file: string): boolean {
const pathValue = path.resolve(this.getInput(input) || "");
return this.filePathSupplied(input) && this.fileExists(file);
}
public filePathSupplied(file: string): boolean {
const pathValue = path.resolve(this.getInput(file) || "");
const repoRoot = this.getSourceDir();
return pathValue !== repoRoot;
}

View File

@@ -1,6 +1,6 @@
import { injectable } from "inversify";
import { IBuildAgent, IExecResult } from "../../core/common";
import { IBuildAgent, IExecResult } from "../../core/models";
@injectable()
class BuildAgent implements IBuildAgent {
@@ -78,6 +78,11 @@ class BuildAgent implements IBuildAgent {
return "getInput";
}
public getListInput(input: string, required?: boolean): string[] {
console.log("getListInput");
return ["getInput"];
}
public getBooleanInput(input: string, required?: boolean): boolean {
console.log("getBooleanInput");
return false;

View File

@@ -1,79 +1,22 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import * as semver from "semver";
import * as http from "typed-rest-client/HttpClient";
import cmp from "semver-compare";
import { inject, injectable } from "inversify";
import { BuildAgent } from "../agent/mock/build-agent";
import { Container } from "inversify";
const container = new Container();
export interface IVersionManager {
isExplicitVersion(versionSpec: string): boolean;
evaluateVersions(versions: string[], versionSpec: string): string;
cleanVersion(version: string): string;
}
export interface IBuildAgent {
agentName: string;
find(toolName: string, versionSpec: string, arch?: string): string;
cacheDir(sourceDir: string, tool: string, version: string, arch?: string): Promise<string>;
createTempDir(): Promise<string>;
debug(message: string): void;
setFailed(message: string, done?: boolean): void;
setSucceeded(message: string, done?: boolean): void;
exportVariable(name: string, val: string): void;
getVariable(name: string): string;
addPath(inputPath: string): void;
which(tool: string, check?: boolean): Promise<string>;
exec(exec: string, args: string[]): Promise<IExecResult>;
getSourceDir(): string;
isValidInputFile(input: string, file: string): boolean;
fileExists(file: string): boolean;
directoryExists(file: string): boolean;
setOutput(name: string, value: string): void;
getInput(input: string, required?: boolean): string;
getBooleanInput(input: string, required?: boolean): boolean;
}
import { TYPES, IExecResult, IBuildAgent } from "./models";
import { IVersionManager } from "./versionManager";
export interface IDotnetTool {
run(args: string[]): Promise<IExecResult>;
disableTelemetry(): void;
toolInstall(toolName: string, versionSpec: string, checkLatest: boolean, includePre: boolean): Promise<string>;
}
export interface IExecResult {
stdout: string;
stderr: string;
code: number;
error: Error;
}
export const TYPES = {
IBuildAgent: Symbol.for("BuildAgent"),
IDotnetTool: Symbol.for("DotnetTool"),
IGitVersionTool: Symbol.for("GitVersionTool"),
IGitReleaseManagerTool: Symbol.for("GitReleaseManagerTool"),
IVersionManager: Symbol.for("VersionManager"),
};
export const SetupOptions = {
includePrerelease: "includePrerelease",
versionSpec: "versionSpec",
};
@injectable()
class DotnetTool implements IDotnetTool {
export class DotnetTool implements IDotnetTool {
private buildAgent: IBuildAgent;
private versionManager: IVersionManager;
protected buildAgent: IBuildAgent;
protected versionManager: IVersionManager;
private httpClient: http.HttpClient;
constructor(
@@ -85,8 +28,13 @@ class DotnetTool implements IDotnetTool {
this.httpClient = new http.HttpClient("dotnet");
}
public run(args: string[]): Promise<IExecResult> {
return this.buildAgent.exec("dotnet", args);
public disableTelemetry(): void {
this.buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
}
public execute(cmd: string, args: string[]): Promise<IExecResult> {
console.log(`Command: ${cmd} ${args.join(' ')}`);
return this.buildAgent.exec(cmd, args);
}
public async toolInstall(toolName: string, versionSpec: string, checkLatest: boolean, includePre: boolean)
@@ -188,7 +136,7 @@ class DotnetTool implements IDotnetTool {
args = args.concat(["--version", version]);
}
const result = await this.run(args);
const result = await this.execute("dotnet", args);
const status = result.code === 0 ? "success" : "failure";
const message = result.code === 0 ? result.stdout : result.stderr;
@@ -200,58 +148,4 @@ class DotnetTool implements IDotnetTool {
return await this.buildAgent.cacheDir(tempDirectory, toolName, version);
}
}
@injectable()
class VersionManager implements IVersionManager {
private buildAgent: IBuildAgent;
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
) {
this.buildAgent = buildAgent;
}
public isExplicitVersion(versionSpec: string): boolean {
const c = semver.clean(versionSpec);
this.buildAgent.debug("isExplicit: " + c);
const valid = semver.valid(c) != null;
this.buildAgent.debug("explicit? " + valid);
return valid;
}
public evaluateVersions(versions: string[], versionSpec: string): string {
let version: string;
this.buildAgent.debug("evaluating " + versions.length + " versions");
versions = versions.sort(cmp);
for (let i = versions.length - 1; i >= 0; i--) {
const potential: string = versions[i];
const satisfied: boolean = semver.satisfies(potential, versionSpec);
if (satisfied) {
version = potential;
break;
}
}
if (version) {
this.buildAgent.debug("matched: " + version);
} else {
this.buildAgent.debug("match not found");
}
return version;
}
public cleanVersion(version: string): string {
this.buildAgent.debug("cleaning: " + version);
return semver.clean(version);
}
}
container.bind<IVersionManager>(TYPES.IVersionManager).to(VersionManager);
container.bind<IBuildAgent>(TYPES.IBuildAgent).to(BuildAgent);
container.bind<IDotnetTool>(TYPES.IDotnetTool).to(DotnetTool);
export { container };
}

View File

@@ -1,23 +0,0 @@
import { IDotnetTool, IBuildAgent, TYPES } from "./common";
import { injectable, inject } from "inversify";
export interface IGitReleaseManagerTool {
install(versionSpec: string, includePrerelease: boolean): Promise<void>;
}
@injectable()
export class GitReleaseManagerTool implements IGitReleaseManagerTool {
private dotnetTool: IDotnetTool;
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
@inject(TYPES.IDotnetTool) dotnetTool: IDotnetTool,
) {
this.dotnetTool = dotnetTool;
}
public async install(versionSpec: string, includePrerelease: boolean): Promise<void> {
await this.dotnetTool.toolInstall("GitReleaseManager.Tool", versionSpec, false, includePrerelease);
}
}

View File

@@ -1,201 +0,0 @@
import { IBuildAgent, IDotnetTool, IExecResult, TYPES } from "./common";
import { injectable, inject } from "inversify";
import path = require("path");
export interface IGitVersionOptions {
targetPath: string;
useConfigFile: boolean;
configFilePath: string;
updateAssemblyInfo: boolean;
updateAssemblyInfoFilename: string;
additionalArguments: string;
srcDir: string;
}
export const RunOptions = {
targetPath: "targetPath",
useConfigFile: "useConfigFile",
configFilePath: "configFilePath",
updateAssemblyInfo: "configFilePath",
updateAssemblyInfoFilename: "configFilePath",
additionalArguments: "additionalArguments",
};
export interface IGitVersion {
Major: number;
Minor: number;
Patch: number;
PreReleaseTag: string;
PreReleaseTagWithDash: string;
PreReleaseLabel: string;
PreReleaseNumber: number;
WeightedPreReleaseNumber: number;
BuildMetaData: number;
BuildMetaDataPadded: string;
FullBuildMetaData: string;
MajorMinorPatch: string;
SemVer: string;
LegacySemVer: string;
LegacySemVerPadded: string;
AssemblySemVer: string;
AssemblySemFileVer: string;
FullSemVer: string;
InformationalVersion: string;
BranchName: string;
Sha: string;
ShortSha: string;
NuGetVersionV2: string;
NuGetVersion: string;
NuGetPreReleaseTagV2: string;
NuGetPreReleaseTag: string;
VersionSourceSha: string;
CommitsSinceVersionSource: number;
CommitsSinceVersionSourcePadded: string;
CommitDate: string;
}
export interface IGitVersionTool {
install(versionSpec: string, includePrerelease: boolean): Promise<void>;
run(options: IGitVersionOptions): Promise<IExecResult>;
writeGitVersionToAgent(gitversion: IGitVersion): void;
getGitVersionOptions(): IGitVersionOptions;
}
@injectable()
export class GitVersionTool implements IGitVersionTool {
private buildAgent: IBuildAgent;
private dotnetTool: IDotnetTool;
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
@inject(TYPES.IDotnetTool) dotnetTool: IDotnetTool,
) {
this.buildAgent = buildAgent;
this.dotnetTool = dotnetTool;
}
public async install(versionSpec: string, includePrerelease: boolean): Promise<void> {
await this.dotnetTool.toolInstall("GitVersion.Tool", versionSpec, false, includePrerelease);
}
public run(options: IGitVersionOptions): Promise<IExecResult> {
const workDir = this.getRepoDir(options.targetPath);
const args = this.getArguments(workDir, options);
return this.buildAgent.exec("dotnet-gitversion", args);
}
private getRepoDir(targetPath: string): string {
let workDir: string;
const srcDir = this.buildAgent.getSourceDir();
if (!targetPath) {
workDir = srcDir;
} else {
if (this.buildAgent.directoryExists(targetPath)) {
workDir = path.join(srcDir, targetPath);
} else {
throw new Error("Directory not found at " + targetPath);
}
}
return workDir.replace(/\\/g, "/");
}
private getArguments(workDir: string, options: IGitVersionOptions): string[] {
const args = [
workDir,
"/output",
"json", // need to use buildserver later
];
const {
useConfigFile,
configFilePath,
updateAssemblyInfo,
updateAssemblyInfoFilename,
additionalArguments,
} = options;
if (useConfigFile) {
if (this.buildAgent.isValidInputFile("configFilePath", configFilePath)) {
args.push("/config", configFilePath);
} else {
throw new Error("GitVersion configuration file not found at " + configFilePath);
}
}
if (updateAssemblyInfo) {
args.push("/updateassemblyinfo");
if (this.buildAgent.isValidInputFile("updateAssemblyInfoFilename", updateAssemblyInfoFilename)) {
args.push(updateAssemblyInfoFilename);
} else {
throw new Error("AssemblyInfoFilename file not found at " + updateAssemblyInfoFilename);
}
}
args.push(additionalArguments);
return args;
}
public getGitVersionOptions(): IGitVersionOptions {
const targetPath = this.buildAgent.getInput(RunOptions.targetPath);
const useConfigFile = this.buildAgent.getBooleanInput(RunOptions.useConfigFile);
const configFilePath = this.buildAgent.getInput(RunOptions.configFilePath);
const updateAssemblyInfo = this.buildAgent.getBooleanInput(RunOptions.updateAssemblyInfo);
const updateAssemblyInfoFilename = this.buildAgent.getInput(RunOptions.updateAssemblyInfoFilename);
const additionalArguments = this.buildAgent.getInput(RunOptions.additionalArguments);
const srcDir = this.buildAgent.getSourceDir().replace(/\\/g, "/");
return {
targetPath,
useConfigFile,
configFilePath,
updateAssemblyInfo,
updateAssemblyInfoFilename,
additionalArguments,
srcDir,
};
}
public writeGitVersionToAgent(gitversion: IGitVersion): void {
this.buildAgent.setOutput("major", gitversion.Major.toString());
this.buildAgent.setOutput("minor", gitversion.Minor.toString());
this.buildAgent.setOutput("patch", gitversion.Patch.toString());
this.buildAgent.setOutput("preReleaseTag", gitversion.PreReleaseTag);
this.buildAgent.setOutput("preReleaseTagWithDash", gitversion.PreReleaseTagWithDash);
this.buildAgent.setOutput("preReleaseLabel", gitversion.PreReleaseLabel);
this.buildAgent.setOutput("preReleaseNumber", gitversion.PreReleaseNumber.toString());
this.buildAgent.setOutput("weightedPreReleaseNumber", gitversion.WeightedPreReleaseNumber.toString());
this.buildAgent.setOutput("buildMetaData", gitversion.BuildMetaData.toString());
this.buildAgent.setOutput("buildMetaDataPadded", gitversion.BuildMetaDataPadded);
this.buildAgent.setOutput("fullBuildMetaData", gitversion.FullBuildMetaData);
this.buildAgent.setOutput("majorMinorPatch", gitversion.MajorMinorPatch);
this.buildAgent.setOutput("semVer", gitversion.SemVer);
this.buildAgent.setOutput("legacySemVer", gitversion.LegacySemVer);
this.buildAgent.setOutput("legacySemVerPadded", gitversion.LegacySemVerPadded);
this.buildAgent.setOutput("assemblySemVer", gitversion.AssemblySemVer);
this.buildAgent.setOutput("assemblySemFileVer", gitversion.AssemblySemFileVer);
this.buildAgent.setOutput("fullSemVer", gitversion.FullSemVer);
this.buildAgent.setOutput("informationalVersion", gitversion.InformationalVersion);
this.buildAgent.setOutput("branchName", gitversion.BranchName);
this.buildAgent.setOutput("sha", gitversion.Sha);
this.buildAgent.setOutput("shortSha", gitversion.ShortSha);
this.buildAgent.setOutput("nuGetVersionV2", gitversion.NuGetVersionV2);
this.buildAgent.setOutput("nuGetVersion", gitversion.NuGetVersion);
this.buildAgent.setOutput("nuGetPreReleaseTagV2", gitversion.NuGetPreReleaseTagV2);
this.buildAgent.setOutput("nuGetPreReleaseTag", gitversion.NuGetPreReleaseTag);
this.buildAgent.setOutput("versionSourceSha", gitversion.VersionSourceSha);
this.buildAgent.setOutput("commitsSinceVersionSource", gitversion.CommitsSinceVersionSource.toString());
this.buildAgent.setOutput("commitsSinceVersionSourcePadded", gitversion.CommitsSinceVersionSourcePadded);
this.buildAgent.setOutput("commitDate", gitversion.CommitDate);
}
}

11
src/core/ioc.ts Normal file
View File

@@ -0,0 +1,11 @@
import { Container } from "inversify";
import { IVersionManager, VersionManager } from "./versionManager";
import { TYPES, IBuildAgent } from "./models";
import { BuildAgent } from "../agent/mock/build-agent";
const container = new Container();
container.bind<IVersionManager>(TYPES.IVersionManager).to(VersionManager);
container.bind<IBuildAgent>(TYPES.IBuildAgent).to(BuildAgent);
export default container;

49
src/core/models.ts Normal file
View File

@@ -0,0 +1,49 @@
export const TYPES = {
IBuildAgent: Symbol.for("BuildAgent"),
IDotnetTool: Symbol.for("DotnetTool"),
IGitVersionTool: Symbol.for("GitVersionTool"),
IGitReleaseManagerTool: Symbol.for("GitReleaseManagerTool"),
IVersionManager: Symbol.for("VersionManager"),
};
export enum SetupFields {
includePrerelease = "includePrerelease",
versionSpec = "versionSpec",
};
export interface ISetupSettings {
[SetupFields.versionSpec]: string;
[SetupFields.includePrerelease]: boolean;
}
export interface IExecResult {
stdout: string;
stderr: string;
code: number;
error: Error;
}
export interface IBuildAgent {
agentName: string;
find(toolName: string, versionSpec: string, arch?: string): string;
cacheDir(sourceDir: string, tool: string, version: string, arch?: string): Promise<string>;
createTempDir(): Promise<string>;
debug(message: string): void;
setFailed(message: string, done?: boolean): void;
setSucceeded(message: string, done?: boolean): void;
exportVariable(name: string, val: string): void;
getVariable(name: string): string;
addPath(inputPath: string): void;
which(tool: string, check?: boolean): Promise<string>;
exec(exec: string, args: string[]): Promise<IExecResult>;
getSourceDir(): string;
isValidInputFile(input: string, file: string): boolean;
fileExists(file: string): boolean;
directoryExists(file: string): boolean;
setOutput(name: string, value: string): void;
getInput(input: string, required?: boolean): string;
getListInput(input: string, required?: boolean): string[];
getBooleanInput(input: string, required?: boolean): boolean;
}

14
src/core/settings.ts Normal file
View File

@@ -0,0 +1,14 @@
import { IBuildAgent, SetupFields, ISetupSettings } from "./models";
export class Settings {
public static getSetupSettings(buildAgent: IBuildAgent): ISetupSettings {
const versionSpec = buildAgent.getInput(SetupFields.versionSpec);
const includePrerelease = buildAgent.getBooleanInput(SetupFields.includePrerelease);
return {
versionSpec,
includePrerelease
}
}
}

View File

@@ -0,0 +1,59 @@
import cmp from "semver-compare";
import * as semver from "semver";
import { injectable, inject } from "inversify";
import { IBuildAgent, TYPES } from "./models";
export interface IVersionManager {
isExplicitVersion(versionSpec: string): boolean;
evaluateVersions(versions: string[], versionSpec: string): string;
cleanVersion(version: string): string;
}
@injectable()
export class VersionManager implements IVersionManager {
private buildAgent: IBuildAgent;
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
) {
this.buildAgent = buildAgent;
}
public isExplicitVersion(versionSpec: string): boolean {
const c = semver.clean(versionSpec);
this.buildAgent.debug("isExplicit: " + c);
const valid = semver.valid(c) != null;
this.buildAgent.debug("explicit? " + valid);
return valid;
}
public evaluateVersions(versions: string[], versionSpec: string): string {
let version: string;
this.buildAgent.debug("evaluating " + versions.length + " versions");
versions = versions.sort(cmp);
for (let i = versions.length - 1; i >= 0; i--) {
const potential: string = versions[i];
const satisfied: boolean = semver.satisfies(potential, versionSpec);
if (satisfied) {
version = potential;
break;
}
}
if (version) {
this.buildAgent.debug("matched: " + version);
} else {
this.buildAgent.debug("match not found");
}
return version;
}
public cleanVersion(version: string): string {
this.buildAgent.debug("cleaning: " + version);
return semver.clean(version);
}
}

View File

@@ -0,0 +1,4 @@
import "reflect-metadata";
import { discard } from "./main";
discard();

View File

@@ -1,5 +1,9 @@
import { container, IBuildAgent, TYPES, SetupOptions } from "../../core/common";
import { IGitReleaseManagerTool, GitReleaseManagerTool } from "../../core/gitreleasemanager";
import { IBuildAgent, TYPES, SetupFields } from "../../core/models";
import { IGitReleaseManagerTool, GitReleaseManagerTool } from "../../tools/gitreleasemanager/tool";
import { Settings as CommonSettings } from "../../core/settings";
import { Settings } from "../../tools/gitreleasemanager/settings";
import container from "../../core/ioc";
container.bind<IGitReleaseManagerTool>(TYPES.IGitReleaseManagerTool).to(GitReleaseManagerTool);
@@ -9,12 +13,11 @@ const buildAgent = container.get<IBuildAgent>(TYPES.IBuildAgent);
export async function setup() {
try {
buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
gitReleaseManagerTool.disableTelemetry();
const versionSpec = buildAgent.getInput(SetupOptions.versionSpec);
const includePrerelease = buildAgent.getBooleanInput(SetupOptions.includePrerelease);
const settings = CommonSettings.getSetupSettings(buildAgent);
await gitReleaseManagerTool.install(versionSpec, includePrerelease);
await gitReleaseManagerTool.install(settings.versionSpec, settings.includePrerelease);
buildAgent.setSucceeded("GitVersionManager installed successfully", true);
} catch (error) {
@@ -25,10 +28,29 @@ export async function setup() {
export async function create() {
try {
buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
gitReleaseManagerTool.disableTelemetry();
const settings = Settings.getCreateSettings(buildAgent);
await gitReleaseManagerTool.create(settings);
buildAgent.setSucceeded("GitVersionManager created release successfully", true);
} catch (error) {
buildAgent.setFailed(error.message, true);
}
}
export async function discard() {
try {
gitReleaseManagerTool.disableTelemetry();
const settings = Settings.getDiscardSettings(buildAgent);
await gitReleaseManagerTool.discard(settings);
buildAgent.setSucceeded("GitVersionManager discarded release successfully", true);
} catch (error) {
buildAgent.setFailed(error.message, true);
}
}

View File

@@ -1,5 +1,10 @@
import { container, IBuildAgent, TYPES, SetupOptions } from "../../core/common";
import { IGitVersionTool, IGitVersionOptions, IGitVersion, GitVersionTool } from "../../core/gitversion";
import { IBuildAgent, TYPES, SetupFields } from "../../core/models";
import { Settings as CommonSettings } from "../../core/settings";
import { Settings } from "../../tools/gitversion/settings";
import { IGitVersionTool, GitVersionTool } from "../../tools/gitversion/tool";
import { GitVersionSettings, GitVersionOutput } from "../../tools/gitversion/models";
import container from "../../core/ioc";
container.bind<IGitVersionTool>(TYPES.IGitVersionTool).to(GitVersionTool);
@@ -9,12 +14,11 @@ const buildAgent = container.get<IBuildAgent>(TYPES.IBuildAgent);
export async function setup() {
try {
buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
gitVersionTool.disableTelemetry();
const versionSpec = buildAgent.getInput(SetupOptions.versionSpec);
const includePrerelease = buildAgent.getBooleanInput(SetupOptions.includePrerelease);
const settings = CommonSettings.getSetupSettings(buildAgent);
await gitVersionTool.install(versionSpec, includePrerelease);
await gitVersionTool.install(settings.versionSpec, settings.includePrerelease);
buildAgent.setSucceeded("GitVersion installed successfully", true);
} catch (error) {
@@ -24,11 +28,14 @@ export async function setup() {
export async function run() {
try {
const inputOptions: IGitVersionOptions = gitVersionTool.getGitVersionOptions();
const result = await gitVersionTool.run(inputOptions);
gitVersionTool.disableTelemetry();
const gitversion = JSON.parse(result.stdout) as IGitVersion;
const settings: GitVersionSettings = Settings.getGitVersionSettings(buildAgent);
const result = await gitVersionTool.run(settings);
const gitversion = JSON.parse(result.stdout) as GitVersionOutput;
gitVersionTool.writeGitVersionToAgent(gitversion);
if (result.code === 0) {

View File

@@ -0,0 +1,41 @@
export enum CommonFields {
repository = "repository",
owner = "owner",
token = "token",
}
export enum CreateFields {
milestone = "milestone",
releaseName = "releaseName",
inputFileName = "inputFileName",
isPreRelease = "isPreRelease",
commit = "commit",
targetDirectory = "targetDirectory",
assets = "assets",
}
export enum DiscardFields {
milestone = "milestone",
targetDirectory = "targetDirectory",
}
export interface GitReleaseManagerSettings {
[CommonFields.repository]: string;
[CommonFields.owner]: string;
[CommonFields.token]: string;
}
export interface GitReleaseManagerCreateSettings extends GitReleaseManagerSettings {
[CreateFields.milestone]: string;
[CreateFields.releaseName]: string;
[CreateFields.inputFileName]: string;
[CreateFields.isPreRelease]: boolean;
[CreateFields.commit]: string;
[CreateFields.targetDirectory]: string;
[CreateFields.assets]?: string[];
}
export interface GitReleaseManagerDiscardSettings extends GitReleaseManagerSettings {
[DiscardFields.milestone]: string;
[DiscardFields.targetDirectory]: string;
}

View File

@@ -0,0 +1,51 @@
import { IBuildAgent } from "../../core/models";
import { GitReleaseManagerSettings, CommonFields, CreateFields, GitReleaseManagerCreateSettings, DiscardFields, GitReleaseManagerDiscardSettings } from "./models";
export class Settings {
public static getCreateSettings(buildAgent: IBuildAgent) : GitReleaseManagerCreateSettings {
const milestone = buildAgent.getInput(CreateFields.milestone);
const releaseName = buildAgent.getInput(CreateFields.releaseName);
const inputFileName = buildAgent.getInput(CreateFields.inputFileName);
const isPreRelease = buildAgent.getBooleanInput(CreateFields.isPreRelease);
const commit = buildAgent.getInput(CreateFields.commit);
const targetDirectory = buildAgent.getInput(CreateFields.targetDirectory);
const assets = buildAgent.getListInput(CreateFields.assets);
const commonSettings = Settings.getCommonSettings(buildAgent);
return {
...commonSettings,
milestone,
releaseName,
inputFileName,
isPreRelease,
commit,
targetDirectory,
assets
}
}
public static getDiscardSettings(buildAgent: IBuildAgent) : GitReleaseManagerDiscardSettings {
const milestone = buildAgent.getInput(DiscardFields.milestone);
const targetDirectory = buildAgent.getInput(CreateFields.targetDirectory);
const commonSettings = Settings.getCommonSettings(buildAgent);
return {
...commonSettings,
milestone,
targetDirectory,
}
}
private static getCommonSettings(buildAgent: IBuildAgent): GitReleaseManagerSettings {
const owner = buildAgent.getInput(CommonFields.owner, true);
const repository = buildAgent.getInput(CommonFields.repository, true);
const token = buildAgent.getInput(CommonFields.token, true);
return {
owner,
repository,
token
};
}
}

View File

@@ -0,0 +1,121 @@
import path = require("path");
import { TYPES, IBuildAgent, IExecResult } from "../../core/models";
import { injectable, inject } from "inversify";
import { DotnetTool, IDotnetTool } from "../../core/dotnet-tool";
import { IVersionManager } from "../../core/versionManager";
import {
GitReleaseManagerSettings,
GitReleaseManagerCreateSettings,
GitReleaseManagerDiscardSettings
} from "./models";
export interface IGitReleaseManagerTool extends IDotnetTool {
install(versionSpec: string, includePrerelease: boolean): Promise<void>;
create(settings: GitReleaseManagerCreateSettings): Promise<IExecResult>;
discard(settings: GitReleaseManagerDiscardSettings): Promise<IExecResult>;
}
@injectable()
export class GitReleaseManagerTool extends DotnetTool implements IGitReleaseManagerTool {
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
@inject(TYPES.IVersionManager) versionManager: IVersionManager
) {
super(buildAgent, versionManager);
}
public async install(versionSpec: string, includePrerelease: boolean): Promise<void> {
await this.toolInstall("GitReleaseManager.Tool", versionSpec, false, includePrerelease);
}
public create(settings: GitReleaseManagerCreateSettings): Promise<IExecResult> {
const args = this.getCreateArguments(settings);
return this.execute("dotnet-gitreleasemanager", args);
}
public discard(settings: GitReleaseManagerDiscardSettings): Promise<IExecResult> {
const args = this.getDiscardArguments(settings);
return this.execute("dotnet-gitreleasemanager", args);
}
getCommonArguments(settings: GitReleaseManagerSettings): string[] {
const args: string[] = [];
args.push("--owner", settings.owner);
args.push("--repository", settings.repository);
args.push("--token", settings.token);
return args;
}
getDiscardArguments(settings: GitReleaseManagerDiscardSettings): string[] {
const args: string[] = ['discard', ...this.getCommonArguments(settings)];
if (settings.milestone) {
args.push("--milestone", settings.milestone);
}
settings.targetDirectory = this.getRepoDir(settings.targetDirectory);
args.push("--targetDirectory", settings.targetDirectory);
return args;
}
getCreateArguments(settings: GitReleaseManagerCreateSettings): string[] {
const args: string[] = ['create', ...this.getCommonArguments(settings)];
if (settings.milestone) {
args.push("--milestone", settings.milestone);
}
if (settings.releaseName) {
args.push("--name", settings.releaseName);
}
if (settings.commit) {
args.push("--targetcommitish", settings.commit);
}
settings.targetDirectory = this.getRepoDir(settings.targetDirectory);
args.push("--targetDirectory", settings.targetDirectory);
if (settings.inputFileName) {
if (this.buildAgent.fileExists(settings.inputFileName)) {
args.push("--inputFilePath", settings.inputFileName);
} else {
throw new Error("GitReleaseManager inputFilePath not found at " + settings.inputFileName);
}
}
if (settings.isPreRelease) {
args.push("--pre");
}
if (settings.assets && settings.assets.length > 0) {
settings.assets = settings.assets.map(asset => {
return path.join(settings.targetDirectory, asset)
})
args.push("--assets", settings.assets.join(","));
}
return args;
}
private getRepoDir(targetPath: string): string {
let workDir: string;
const srcDir = this.buildAgent.getSourceDir();
if (!targetPath) {
workDir = srcDir;
} else {
if (this.buildAgent.directoryExists(targetPath)) {
workDir = path.join(srcDir, targetPath);
} else {
throw new Error("Directory not found at " + targetPath);
}
}
return workDir.replace(/\\/g, "/");
}
}

View File

@@ -0,0 +1,52 @@
export enum ExecuteFields {
targetPath = "targetPath",
useConfigFile = "useConfigFile",
configFilePath = "configFilePath",
updateAssemblyInfo = "updateAssemblyInfo",
updateAssemblyInfoFilename = "updateAssemblyInfoFilename",
additionalArguments = "additionalArguments",
srcDir = "srcDir",
};
export interface GitVersionSettings {
[ExecuteFields.targetPath]: string;
[ExecuteFields.useConfigFile]: boolean;
[ExecuteFields.configFilePath]: string;
[ExecuteFields.updateAssemblyInfo]: boolean;
[ExecuteFields.updateAssemblyInfoFilename]: string;
[ExecuteFields.additionalArguments]: string;
[ExecuteFields.srcDir]: string;
}
export interface GitVersionOutput {
Major: number;
Minor: number;
Patch: number;
PreReleaseTag: string;
PreReleaseTagWithDash: string;
PreReleaseLabel: string;
PreReleaseNumber: number;
WeightedPreReleaseNumber: number;
BuildMetaData: number;
BuildMetaDataPadded: string;
FullBuildMetaData: string;
MajorMinorPatch: string;
SemVer: string;
LegacySemVer: string;
LegacySemVerPadded: string;
AssemblySemVer: string;
AssemblySemFileVer: string;
FullSemVer: string;
InformationalVersion: string;
BranchName: string;
Sha: string;
ShortSha: string;
NuGetVersionV2: string;
NuGetVersion: string;
NuGetPreReleaseTagV2: string;
NuGetPreReleaseTag: string;
VersionSourceSha: string;
CommitsSinceVersionSource: number;
CommitsSinceVersionSourcePadded: string;
CommitDate: string;
}

View File

@@ -0,0 +1,30 @@
import { IBuildAgent } from "../../core/models";
import { GitVersionSettings, ExecuteFields } from "./models";
export class Settings {
public static getGitVersionSettings(buildAgent: IBuildAgent): GitVersionSettings {
const targetPath = buildAgent.getInput(ExecuteFields.targetPath);
const useConfigFile = buildAgent.getBooleanInput(ExecuteFields.useConfigFile);
const configFilePath = buildAgent.getInput(ExecuteFields.configFilePath);
const updateAssemblyInfo = buildAgent.getBooleanInput(ExecuteFields.updateAssemblyInfo);
const updateAssemblyInfoFilename = buildAgent.getInput(ExecuteFields.updateAssemblyInfoFilename);
const additionalArguments = buildAgent.getInput(ExecuteFields.additionalArguments);
const srcDir = buildAgent.getSourceDir().replace(/\\/g, "/");
return {
targetPath,
useConfigFile,
configFilePath,
updateAssemblyInfo,
updateAssemblyInfoFilename,
additionalArguments,
srcDir,
};
}
}

View File

@@ -0,0 +1,120 @@
import path = require("path");
import { injectable, inject } from "inversify";
import { IExecResult, IBuildAgent, TYPES } from "../../core/models";
import { DotnetTool, IDotnetTool } from "../../core/dotnet-tool";
import { GitVersionSettings, GitVersionOutput, ExecuteFields } from "./models";
import { IVersionManager } from "../../core/versionManager";
export interface IGitVersionTool extends IDotnetTool {
install(versionSpec: string, includePrerelease: boolean): Promise<void>;
run(options: GitVersionSettings): Promise<IExecResult>;
writeGitVersionToAgent(gitversion: GitVersionOutput): void;
}
@injectable()
export class GitVersionTool extends DotnetTool implements IGitVersionTool {
constructor(
@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent,
@inject(TYPES.IVersionManager) versionManager: IVersionManager
) {
super(buildAgent, versionManager);
}
public async install(versionSpec: string, includePrerelease: boolean): Promise<void> {
await this.toolInstall("GitVersion.Tool", versionSpec, false, includePrerelease);
}
public run(options: GitVersionSettings): Promise<IExecResult> {
const workDir = this.getRepoDir(options.targetPath);
const args = this.getArguments(workDir, options);
return this.execute("dotnet-gitversion", args);
}
private getRepoDir(targetPath: string): string {
let workDir: string;
const srcDir = this.buildAgent.getSourceDir();
if (!targetPath) {
workDir = srcDir;
} else {
if (this.buildAgent.directoryExists(targetPath)) {
workDir = path.join(srcDir, targetPath);
} else {
throw new Error("Directory not found at " + targetPath);
}
}
return workDir.replace(/\\/g, "/");
}
private getArguments(workDir: string, options: GitVersionSettings): string[] {
const args = [
workDir,
"/output",
"json", // need to use buildserver later
];
const {
useConfigFile,
configFilePath,
updateAssemblyInfo,
updateAssemblyInfoFilename,
additionalArguments,
} = options;
if (useConfigFile) {
if (this.buildAgent.isValidInputFile("configFilePath", configFilePath)) {
args.push("/config", configFilePath);
} else {
throw new Error("GitVersion configuration file not found at " + configFilePath);
}
}
if (updateAssemblyInfo) {
args.push("/updateassemblyinfo");
if (this.buildAgent.isValidInputFile("updateAssemblyInfoFilename", updateAssemblyInfoFilename)) {
args.push(updateAssemblyInfoFilename);
} else {
throw new Error("AssemblyInfoFilename file not found at " + updateAssemblyInfoFilename);
}
}
args.push(additionalArguments);
return args;
}
public writeGitVersionToAgent(gitversion: GitVersionOutput): void {
this.buildAgent.setOutput("major", gitversion.Major.toString());
this.buildAgent.setOutput("minor", gitversion.Minor.toString());
this.buildAgent.setOutput("patch", gitversion.Patch.toString());
this.buildAgent.setOutput("preReleaseTag", gitversion.PreReleaseTag);
this.buildAgent.setOutput("preReleaseTagWithDash", gitversion.PreReleaseTagWithDash);
this.buildAgent.setOutput("preReleaseLabel", gitversion.PreReleaseLabel);
this.buildAgent.setOutput("preReleaseNumber", gitversion.PreReleaseNumber.toString());
this.buildAgent.setOutput("weightedPreReleaseNumber", gitversion.WeightedPreReleaseNumber.toString());
this.buildAgent.setOutput("buildMetaData", gitversion.BuildMetaData.toString());
this.buildAgent.setOutput("buildMetaDataPadded", gitversion.BuildMetaDataPadded);
this.buildAgent.setOutput("fullBuildMetaData", gitversion.FullBuildMetaData);
this.buildAgent.setOutput("majorMinorPatch", gitversion.MajorMinorPatch);
this.buildAgent.setOutput("semVer", gitversion.SemVer);
this.buildAgent.setOutput("legacySemVer", gitversion.LegacySemVer);
this.buildAgent.setOutput("legacySemVerPadded", gitversion.LegacySemVerPadded);
this.buildAgent.setOutput("assemblySemVer", gitversion.AssemblySemVer);
this.buildAgent.setOutput("assemblySemFileVer", gitversion.AssemblySemFileVer);
this.buildAgent.setOutput("fullSemVer", gitversion.FullSemVer);
this.buildAgent.setOutput("informationalVersion", gitversion.InformationalVersion);
this.buildAgent.setOutput("branchName", gitversion.BranchName);
this.buildAgent.setOutput("sha", gitversion.Sha);
this.buildAgent.setOutput("shortSha", gitversion.ShortSha);
this.buildAgent.setOutput("nuGetVersionV2", gitversion.NuGetVersionV2);
this.buildAgent.setOutput("nuGetVersion", gitversion.NuGetVersion);
this.buildAgent.setOutput("nuGetPreReleaseTagV2", gitversion.NuGetPreReleaseTagV2);
this.buildAgent.setOutput("nuGetPreReleaseTag", gitversion.NuGetPreReleaseTag);
this.buildAgent.setOutput("versionSourceSha", gitversion.VersionSourceSha);
this.buildAgent.setOutput("commitsSinceVersionSource", gitversion.CommitsSinceVersionSource.toString());
this.buildAgent.setOutput("commitsSinceVersionSourcePadded", gitversion.CommitsSinceVersionSourcePadded);
this.buildAgent.setOutput("commitDate", gitversion.CommitDate);
}
}

View File

@@ -12,6 +12,7 @@ module.exports = (env) => {
'gitversion/execute': path.resolve(__dirname, 'src/tasks/gitversion/execute.ts'),
'gitreleasemanager/setup': path.resolve(__dirname, 'src/tasks/gitreleasemanager/setup.ts'),
'gitreleasemanager/create': path.resolve(__dirname, 'src/tasks/gitreleasemanager/create.ts'),
'gitreleasemanager/discard': path.resolve(__dirname, 'src/tasks/gitreleasemanager/discard.ts'),
},
target: 'node',
mode: mode,