Skip to content

Commit

Permalink
Merge pull request #6 from thomaslevesque/modernize-tools
Browse files Browse the repository at this point in the history
Modernize tools
  • Loading branch information
blairconrad authored Feb 4, 2022
2 parents dd95752 + 51e0733 commit b9fab6d
Show file tree
Hide file tree
Showing 7 changed files with 402 additions and 422 deletions.
9 changes: 3 additions & 6 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<PropertyGroup>
<NoWarn>$(NoWarn),SA0001,CA1014</NoWarn>
<NoWarn>$(NoWarn),SA0001,SA1200,SA1516,CA1014,CA1812</NoWarn>
<SimpleExecVersion>6.1.0</SimpleExecVersion>
<NuGetVersion>4.1.0</NuGetVersion>
<OctokitVersion>0.31.0</OctokitVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Remove="Microsoft.CodeAnalysis.FxCopAnalyzers" />
</ItemGroup>

</Project>
253 changes: 120 additions & 133 deletions FakeItEasy.Deploy/Program.cs
Original file line number Diff line number Diff line change
@@ -1,147 +1,134 @@
namespace FakeItEasy.Deploy
using FakeItEasy.Deploy;
using FakeItEasy.Tools;
using Octokit;
using static FakeItEasy.Tools.ReleaseHelpers;
using static SimpleExec.Command;

if (args.Length != 1)
{
Console.WriteLine("Illegal arguments. Usage:");
Console.WriteLine("<program> <artifactsFolder>");
}

string artifactsFolder = args[0];

var releaseName = GetAppVeyorTagName();
if (string.IsNullOrEmpty(releaseName))
{
Console.WriteLine("No Appveyor tag name supplied. Not deploying.");
return;
}

var nugetServerUrl = GetNuGetServerUrl();
var nugetApiKey = GetNuGetApiKey();
var (repoOwner, repoName) = GetRepositoryName();
var gitHubClient = GetAuthenticatedGitHubClient();

Console.WriteLine($"Deploying {releaseName}");
Console.WriteLine($"Looking for GitHub release {releaseName}");

var releases = await gitHubClient.Repository.Release.GetAll(repoOwner, repoName);
var release = releases.FirstOrDefault(r => r.Name == releaseName)
?? throw new Exception($"Can't find release {releaseName}");

const string artifactsPattern = "*.nupkg";

var artifacts = Directory.GetFiles(artifactsFolder, artifactsPattern);
if (!artifacts.Any())
{
throw new Exception("Can't find any artifacts to publish");
}

Console.WriteLine($"Uploading artifacts to GitHub release {releaseName}");
foreach (var file in artifacts)
{
await UploadArtifactToGitHubReleaseAsync(gitHubClient, release, file);
}

Console.WriteLine($"Pushing nupkgs to {nugetServerUrl}");
foreach (var file in artifacts)
{
await UploadPackageToNuGetAsync(file, nugetServerUrl, nugetApiKey);
}

var issueNumbersInCurrentRelease = GetIssueNumbersReferencedFromReleases(new[] { release });
var preReleases = GetPreReleasesContributingToThisRelease(release, releases);
var issueNumbersInPreReleases = GetIssueNumbersReferencedFromReleases(preReleases);
var newIssueNumbers = issueNumbersInCurrentRelease.Except(issueNumbersInPreReleases);

Console.WriteLine($"Adding 'released as part of' notes to {newIssueNumbers.Count()} issues");
var commentText = $"This change has been released as part of [{repoName} {releaseName}](https://github.com/{repoOwner}/{repoName}/releases/tag/{releaseName}).";
await Task.WhenAll(newIssueNumbers.Select(n => gitHubClient.Issue.Comment.Create(repoOwner, repoName, n, commentText)));

Console.WriteLine("Finished deploying");

static IEnumerable<Release> GetPreReleasesContributingToThisRelease(Release release, IReadOnlyList<Release> releases)
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FakeItEasy.Tools;
using Octokit;
using static FakeItEasy.Tools.ReleaseHelpers;
using static SimpleExec.Command;

internal static class Program
if (release.Prerelease)
{
public static async Task Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("Illegal arguments. Usage:");
Console.WriteLine("<program> <artifactsFolder>");
}

string artifactsFolder = args[0];

var releaseName = GetAppVeyorTagName();
if (string.IsNullOrEmpty(releaseName))
{
Console.WriteLine("No Appveyor tag name supplied. Not deploying.");
return;
}

var nugetServerUrl = GetNuGetServerUrl();
var nugetApiKey = GetNuGetApiKey();
var (repoOwner, repoName) = GetRepositoryName();
var gitHubClient = GetAuthenticatedGitHubClient();

Console.WriteLine($"Deploying {releaseName}");
Console.WriteLine($"Looking for GitHub release {releaseName}");

var releases = await gitHubClient.Repository.Release.GetAll(repoOwner, repoName);
var release = releases.FirstOrDefault(r => r.Name == releaseName)
?? throw new Exception($"Can't find release {releaseName}");

const string artifactsPattern = "*.nupkg";

var artifacts = Directory.GetFiles(artifactsFolder, artifactsPattern);
if (!artifacts.Any())
{
throw new Exception("Can't find any artifacts to publish");
}

Console.WriteLine($"Uploading artifacts to GitHub release {releaseName}");
foreach (var file in artifacts)
{
await UploadArtifactToGitHubReleaseAsync(gitHubClient, release, file);
}

Console.WriteLine($"Pushing nupkgs to {nugetServerUrl}");
foreach (var file in artifacts)
{
await UploadPackageToNuGetAsync(file, nugetServerUrl, nugetApiKey);
}

var issueNumbersInCurrentRelease = GetIssueNumbersReferencedFromReleases(new[] { release });
var preReleases = GetPreReleasesContributingToThisRelease(release, releases);
var issueNumbersInPreReleases = GetIssueNumbersReferencedFromReleases(preReleases);
var newIssueNumbers = issueNumbersInCurrentRelease.Except(issueNumbersInPreReleases);

Console.WriteLine($"Adding 'released as part of' notes to {newIssueNumbers.Count()} issues");
var commentText = $"This change has been released as part of [{repoName} {releaseName}](https://github.com/{repoOwner}/{repoName}/releases/tag/{releaseName}).";
await Task.WhenAll(newIssueNumbers.Select(n => gitHubClient.Issue.Comment.Create(repoOwner, repoName, n, commentText)));

Console.WriteLine("Finished deploying");
}

private static IEnumerable<Release> GetPreReleasesContributingToThisRelease(Release release, IReadOnlyList<Release> releases)
{
if (release.Prerelease)
{
return Enumerable.Empty<Release>();
}
return Enumerable.Empty<Release>();
}

string baseName = BaseName(release);
return releases.Where(r => r.Prerelease && BaseName(r) == baseName);
string baseName = BaseName(release);
return releases.Where(r => r.Prerelease && BaseName(r) == baseName);

string BaseName(Release release) => release.Name.Split('-')[0];
}
string BaseName(Release release) => release.Name.Split('-')[0];
}

private static async Task UploadArtifactToGitHubReleaseAsync(GitHubClient client, Release release, string path)
{
var name = Path.GetFileName(path);
Console.WriteLine($"Uploading {name}");
using (var stream = File.OpenRead(path))
{
var upload = new ReleaseAssetUpload
{
FileName = name,
ContentType = "application/octet-stream",
RawData = stream,
Timeout = TimeSpan.FromSeconds(100)
};

var asset = await client.Repository.Release.UploadAsset(release, upload);
Console.WriteLine($"Uploaded {asset.Name}");
}
}

private static async Task UploadPackageToNuGetAsync(string path, string nugetServerUrl, string nugetApiKey)
static async Task UploadArtifactToGitHubReleaseAsync(GitHubClient client, Release release, string path)
{
var name = Path.GetFileName(path);
Console.WriteLine($"Uploading {name}");
using (var stream = File.OpenRead(path))
{
var upload = new ReleaseAssetUpload
{
string name = Path.GetFileName(path);
Console.WriteLine($"Pushing {name}");
await RunAsync(ToolPaths.NuGet, $"push \"{path}\" -ApiKey {nugetApiKey} -Source {nugetServerUrl} -NonInteractive -ForceEnglishOutput", noEcho: true);
Console.WriteLine($"Pushed {name}");
}
FileName = name,
ContentType = "application/octet-stream",
RawData = stream,
Timeout = TimeSpan.FromSeconds(100)
};

var asset = await client.Repository.Release.UploadAsset(release, upload);
Console.WriteLine($"Uploaded {asset.Name}");
}
}

private static (string repoOwner, string repoName) GetRepositoryName()
{
var repoNameWithOwner = GetRequiredEnvironmentVariable("APPVEYOR_REPO_NAME");
var parts = repoNameWithOwner.Split('/');
return (parts[0], parts[1]);
}
static async Task UploadPackageToNuGetAsync(string path, string nugetServerUrl, string nugetApiKey)
{
string name = Path.GetFileName(path);
Console.WriteLine($"Pushing {name}");
await RunAsync(ToolPaths.NuGet, $"push \"{path}\" -ApiKey {nugetApiKey} -Source {nugetServerUrl} -NonInteractive -ForceEnglishOutput", noEcho: true);
Console.WriteLine($"Pushed {name}");
}

private static GitHubClient GetAuthenticatedGitHubClient()
{
var token = GitHubTokenSource.GetAccessToken();
var credentials = new Credentials(token);
return new GitHubClient(new ProductHeaderValue("FakeItEasy-build-scripts")) { Credentials = credentials };
}
static (string repoOwner, string repoName) GetRepositoryName()
{
var repoNameWithOwner = GetRequiredEnvironmentVariable("APPVEYOR_REPO_NAME");
var parts = repoNameWithOwner.Split('/');
return (parts[0], parts[1]);
}

private static string? GetAppVeyorTagName() => Environment.GetEnvironmentVariable("APPVEYOR_REPO_TAG_NAME");
static GitHubClient GetAuthenticatedGitHubClient()
{
var token = GitHubTokenSource.GetAccessToken();
var credentials = new Credentials(token);
return new GitHubClient(new ProductHeaderValue("FakeItEasy-build-scripts")) { Credentials = credentials };
}

private static string GetNuGetServerUrl() => GetRequiredEnvironmentVariable("NUGET_SERVER_URL");
static string? GetAppVeyorTagName() => Environment.GetEnvironmentVariable("APPVEYOR_REPO_TAG_NAME");

private static string GetNuGetApiKey() => GetRequiredEnvironmentVariable("NUGET_API_KEY");
static string GetNuGetServerUrl() => GetRequiredEnvironmentVariable("NUGET_SERVER_URL");

private static string GetRequiredEnvironmentVariable(string key)
{
var environmentValue = Environment.GetEnvironmentVariable(key);
if (string.IsNullOrEmpty(environmentValue))
{
throw new Exception($"Required environment variable {key} is not set. Unable to continue.");
}

return environmentValue;
}
static string GetNuGetApiKey() => GetRequiredEnvironmentVariable("NUGET_API_KEY");

static string GetRequiredEnvironmentVariable(string key)
{
var environmentValue = Environment.GetEnvironmentVariable(key);
if (string.IsNullOrEmpty(environmentValue))
{
throw new Exception($"Required environment variable {key} is not set. Unable to continue.");
}

return environmentValue;
}
Loading

0 comments on commit b9fab6d

Please sign in to comment.