protected override Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var sourcePath = context.ResolvePath(this.SourceDirectory); this.LogInformation($"Finding matching files in {sourcePath}..."); if (!DirectoryEx.Exists(sourcePath)) { this.LogError($"Directory {sourcePath} does not exist."); return(Complete); } var mask = new MaskingContext(this.Includes, this.Excludes); var matches = DirectoryEx.GetFileSystemInfos(sourcePath, mask) .OfType <SlimFileInfo>() .Where(f => f.FullName.EndsWith(".sql", StringComparison.OrdinalIgnoreCase)) .ToList(); if (matches.Count == 0) { this.LogError($"No matching .sql files were found in {sourcePath}."); return(Complete); } var outputFileName = context.ResolvePath(this.OutputFile); DirectoryEx.Create(PathEx.GetDirectoryName(outputFileName)); using (var buffer = new TemporaryStream()) { using (var zip = new ZipArchive(buffer, ZipArchiveMode.Create, true)) { foreach (var f in matches) { var entryName = getEntryName(f.FullName); this.LogDebug($"Adding {entryName}..."); zip.CreateEntryFromFile(f.FullName, entryName, CompressionLevel.Optimal); } } buffer.Position = 0; using (var outputStream = FileEx.Open(outputFileName, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.SequentialScan)) { using (var inedoSqlStream = typeof(BundleSqlScriptsOperation).Assembly.GetManifestResourceStream("Inedo.Extensions.SqlServer.Operations.inedosql.exe")) { inedoSqlStream.CopyTo(outputStream); } buffer.CopyTo(outputStream); } } this.LogInformation($"{outputFileName} created."); return(Complete); string getEntryName(string fullName) => fullName.Substring(0, sourcePath.Length).TrimStart('\\', '/').Replace('\\', '/'); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var projectFullPath = context.ResolvePath(this.ProjectPath); this.LogInformation($"Building {projectFullPath}..."); var buildProperties = string.Join(";", this.MSBuildProperties ?? Enumerable.Empty <string>()); var config = "Configuration=" + this.BuildConfiguration; if (!string.IsNullOrEmpty(this.TargetPlatform)) { config += ";Platform=" + this.TargetPlatform; } if (!string.IsNullOrEmpty(buildProperties)) { config += ";" + buildProperties; } var args = $"\"{projectFullPath}\" \"/p:{config}\""; if (!string.IsNullOrWhiteSpace(this.TargetDirectory)) { args += $" \"/p:OutDir={context.ResolvePath(this.TargetDirectory).TrimEnd('\\')}\\\\\""; } if (!string.IsNullOrWhiteSpace(this.AdditionalArguments)) { args += " " + this.AdditionalArguments; } var workingDir = PathEx.GetDirectoryName(projectFullPath); if (!DirectoryEx.Exists(workingDir)) { throw new DirectoryNotFoundException($"Directory {workingDir} does not exist."); } int result = await this.InvokeMSBuildAsync(context, args, workingDir).ConfigureAwait(false); if (result != 0) { this.LogError($"Build failed (msbuild returned {result})."); } return(null); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { this.LogInformation($"Downloading TFS artifact {this.ArtifactName} with build number \"{this.BuildNumber ?? "latest"}\" from TFS..."); var downloader = new ArtifactDownloader(this, this); using (var artifact = await downloader.DownloadAsync(this.TeamProject, this.BuildNumber, this.BuildDefinition, this.ArtifactName).ConfigureAwait(false)) { string targetDirectory = context.ResolvePath(this.TargetDirectory); if (this.ExtractFilesToTargetDirectory) { this.LogDebug("Extracting artifact files to: " + targetDirectory); AH.ExtractZip(artifact.Content, targetDirectory); } else { string path = PathEx.Combine(targetDirectory, artifact.FileName); this.LogDebug("Saving artifact as zip file to: " + path); using (var file = FileEx.Open(path, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.Asynchronous | FileOptions.SequentialScan)) { await artifact.Content.CopyToAsync(file).ConfigureAwait(false); } } } this.LogInformation("Artifact downloaded."); return(null); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var client = new ProGetClient(this.Server, this.FeedName, this.UserName, this.Password, this, context.CancellationToken); try { this.LogInformation($"Pushing package {this.Name} to ProGet..."); string path = context.ResolvePath(this.FilePath); this.LogDebug("Using package file: " + path); if (!FileEx.Exists(path)) { this.LogError(this.FilePath + " does not exist."); return(null); } if (string.IsNullOrWhiteSpace(this.Name) || string.IsNullOrWhiteSpace(this.Version)) { try { using (var package = new UniversalPackage(path)) { if (string.IsNullOrWhiteSpace(package.Name) || package.Version == null) { this.LogError("Name and Version properties are required unless pushing a package that already has those properties set."); return(null); } } } catch { this.LogError("Name and Version properties are required unless pushing a package that already has those properties set."); return(null); } } using (var file = FileEx.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var data = new ProGetPackagePushData { Title = this.Title, Description = this.Description, Icon = this.Icon, Dependencies = this.Dependencies?.ToArray() }; await client.PushPackageAsync(this.Group, this.Name, this.Version, data, file); } } catch (ProGetException ex) { this.LogError(ex.FullMessage); return(null); } this.LogInformation("Package pushed."); return(null); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var client = new ProGetClient(this.Server, this.FeedName, this.UserName, this.Password, this); try { this.LogInformation($"Pushing package {this.Name} to ProGet..."); string path = context.ResolvePath(this.FilePath); this.LogDebug("Using package file: " + path); if (!FileEx.Exists(path)) { this.LogError(this.FilePath + " does not exist."); return(null); } using (var file = FileEx.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var data = new ProGetPackagePushData { Title = this.Title, Description = this.Description, Icon = this.Icon, Dependencies = this.Dependencies?.ToArray() }; await client.PushPackageAsync(this.Group, this.Name, this.Version, data, file).ConfigureAwait(false); } } catch (ProGetException ex) { this.LogError(ex.FullMessage); return(null); } this.LogInformation("Package pushed."); return(null); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var packagePath = context.ResolvePath(this.PackagePath); this.LogInformation($"Pushing {packagePath} to {this.ServerUrl}..."); if (!FileEx.Exists(packagePath)) { this.LogError(packagePath + " does not exist."); return(null); } var handler = new HttpClientHandler { Proxy = WebRequest.DefaultWebProxy }; if (string.IsNullOrWhiteSpace(this.UserName) || string.IsNullOrEmpty(this.Password)) { this.LogDebug("No credentials specified; sending default credentials."); handler.PreAuthenticate = true; handler.UseDefaultCredentials = true; } using (var client = new HttpClient(handler)) { client.DefaultRequestHeaders.UserAgent.Clear(); client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("BuildMaster", typeof(Operation).Assembly.GetName().Version.ToString())); client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("NuGet-Extension", typeof(PublishPackageOperation).Assembly.GetName().Version.ToString())); if (!string.IsNullOrWhiteSpace(this.ApiKey)) { this.LogDebug("API key is specified; adding X-NuGet-ApiKey request header."); client.DefaultRequestHeaders.Add("X-NuGet-ApiKey", this.ApiKey); } if (!string.IsNullOrWhiteSpace(this.UserName) && !string.IsNullOrEmpty(this.Password)) { this.LogDebug($"Sending basic auth credentials (user={this.UserName})."); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(InedoLib.UTF8Encoding.GetBytes(this.UserName + ":" + this.Password))); } using (var packageStream = FileEx.Open(packagePath, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.SequentialScan | FileOptions.Asynchronous)) using (var contentStream = new StreamContent(packageStream)) using (var formData = new MultipartFormDataContent()) { contentStream.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); formData.Add(contentStream, "package", "package"); using (var response = await client.PutAsync(this.ServerUrl, formData, context.CancellationToken).ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { this.LogInformation("Package pushed!"); } else { this.LogError($"Server responded with {(int)response.StatusCode}: {response.ReasonPhrase}"); this.LogError(await response.Content.ReadAsStringAsync().ConfigureAwait(false)); } } } } return(null); }
protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { var fullPath = context.ResolvePath(this.FileName); this.LogInformation($"Changing \"{fullPath}\" package version to {AH.CoalesceString(this.NewVersion, "remove pre-release label")}..."); var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("n")); try { DirectoryEx.Create(tempPath); UniversalPackageMetadata currentMetadata; using (var upack = new UniversalPackage(fullPath)) { currentMetadata = upack.GetFullMetadata(); await upack.ExtractAllItemsAsync(tempPath, context.CancellationToken); FileEx.Delete(PathEx.Combine(tempPath, "upack.json")); } var newMetadata = currentMetadata.Clone(); if (string.IsNullOrEmpty(this.NewVersion)) { newMetadata.Version = new UniversalPackageVersion(currentMetadata.Version.Major, currentMetadata.Version.Minor, currentMetadata.Version.Patch); } else { newMetadata.Version = UniversalPackageVersion.Parse(this.NewVersion); } if (currentMetadata.Version == newMetadata.Version) { this.LogWarning($"Current package version {currentMetadata.Version} and the new version {newMetadata.Version} are the same; nothing to do."); return(null); } this.LogInformation("New version: " + newMetadata.Version); this.LogDebug("Adding repacking entry..."); newMetadata.RepackageHistory.Add( new RepackageHistoryEntry { Id = new UniversalPackageId(currentMetadata.Group, currentMetadata.Name) + ":" + currentMetadata.Version, Date = DateTimeOffset.Now, Using = SDK.ProductName + "/" + SDK.ProductVersion, Reason = this.Reason } ); using (var builder = new UniversalPackageBuilder(fullPath, newMetadata)) { await builder.AddRawContentsAsync(tempPath, string.Empty, true, c => true, context.CancellationToken); } this.LogInformation("Package version changed."); return(null); } finally { try { this.LogDebug($"Deleting temporary files from {tempPath}..."); DirectoryEx.Clear(tempPath); DirectoryEx.Delete(tempPath); } catch (Exception ex) { this.LogWarning("Unable to delete temporary files: " + ex.Message); } } }
protected override Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context) { if (this.ReadOnly ?? this.Hidden ?? this.System == null) { this.LogWarning("No file attributes have been specified."); return(Complete); } var mask = new MaskingContext(this.Includes, this.Excludes); var sourcePath = context.ResolvePath(this.SourceDirectory); this.LogInformation($"Getting list of files in {sourcePath} matching {mask}..."); var matches = DirectoryEx.GetFileSystemInfos(sourcePath, mask) .OfType <SlimFileInfo>() .ToList(); if (matches.Count == 0) { this.LogWarning("No files match the specified mask."); return(Complete); } FileAttributes attributesToChange = 0; if (this.ReadOnly.HasValue) { attributesToChange |= FileAttributes.ReadOnly; } if (this.Hidden.HasValue) { attributesToChange |= FileAttributes.Hidden; } if (this.System.HasValue) { attributesToChange |= FileAttributes.System; } FileAttributes attributeValues = 0; if (this.ReadOnly.GetValueOrDefault()) { attributeValues |= FileAttributes.ReadOnly; } if (this.Hidden.GetValueOrDefault()) { attributeValues |= FileAttributes.Hidden; } if (this.System.GetValueOrDefault()) { attributeValues |= FileAttributes.System; } if (this.VerboseLogging) { this.LogDebug("Attributes to change: " + attributesToChange); this.LogDebug("Attribute values: " + attributeValues); } this.LogDebug($"Found {matches.Count} matching files."); this.LogInformation("Applying attributes..."); foreach (var file in matches) { context.CancellationToken.ThrowIfCancellationRequested(); var attributes = file.Attributes; if (((attributes & attributesToChange) ^ attributeValues) != 0) { attributes &= ~attributesToChange; attributes |= attributeValues; if (this.VerboseLogging) { this.LogDebug("Changing " + file.FullName + "..."); } FileEx.SetAttributes(file.FullName, attributes); } } this.LogInformation("Attributes applied."); return(Complete); }