Skip to content

Commit fcca0f0

Browse files
committed
Add github release
1 parent 42726c1 commit fcca0f0

File tree

4 files changed

+90
-8
lines changed

4 files changed

+90
-8
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ env:
2323
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.gradle_enterprise_access_key }}
2424
GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.gradle_enterprise_cache_username }}
2525
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.gradle_enterprise_cache_password }}
26+
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
2627
OPS_GITHUB_ACTIONS_WEBHOOK: ${{ secrets.OPS_GITHUB_ACTIONS_WEBHOOK }}
2728
RELEASE_BUILD: "true"
2829
CI: true

.nuke/build.schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"CleanNugetCache",
3131
"CleanTestResults",
3232
"Compile",
33+
"CreateGithubRelease",
3334
"DownloadTestFixtures",
3435
"GenerateRoslynRecipes",
3536
"GradleAssemble",

Rewrite/.run/Build - Gradle Assemble.run.xml renamed to Rewrite/.run/Build - GradleAssembleAndTest.run.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
<component name="ProjectRunConfigurationManager">
2-
<configuration default="false" name="Build - Gradle Assemble" type="DotNetProject" factoryName=".NET Project" folderName="Build">
2+
<configuration default="false" name="Build - GradleAssembleAndTest" type="DotNetProject" factoryName=".NET Project" folderName="Build">
33
<option name="EXE_PATH" value="$PROJECT_DIR$/../_build/bin/Debug/_build.exe" />
4-
<option name="PROGRAM_PARAMETERS" value="GradleAssemble" />
4+
<option name="PROGRAM_PARAMETERS" value="GradleAssembleAndTest" />
55
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../_build/bin/Debug" />
66
<option name="PASS_PARENT_ENVS" value="1" />
77
<option name="USE_EXTERNAL_CONSOLE" value="0" />
8+
<option name="ENV_FILE_PATHS" value="" />
9+
<option name="REDIRECT_INPUT_PATH" value="" />
10+
<option name="PTY_MODE" value="Auto" />
811
<option name="USE_MONO" value="0" />
912
<option name="RUNTIME_ARGUMENTS" value="" />
13+
<option name="AUTO_ATTACH_CHILDREN" value="0" />
14+
<option name="MIXED_MODE_DEBUG" value="0" />
1015
<option name="PROJECT_PATH" value="$PROJECT_DIR$/../_build/_build.csproj" />
1116
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
1217
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />

_build/Build.cs

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,26 @@
2424
using Microsoft.Extensions.DependencyInjection;
2525
using NuGet.Configuration;
2626
using Nuke.Common.CI.GitHubActions;
27+
using Nuke.Common.Tools.GitVersion;
2728
using Nuke.Common.Tools.PowerShell;
2829
using Nuke.Common.Utilities;
30+
using Octokit;
2931
using Rewrite.Core;
3032
using Rewrite.MSBuild;
3133
using Rewrite.RewriteXml.Tree;
3234
using Serilog;
3335
using Spectre.Console;
3436
using ReflectionMagic;
3537
using static GradleTasks;
38+
using Commit = LibGit2Sharp.Commit;
39+
using Credentials = LibGit2Sharp.Credentials;
40+
using NotFoundException = LibGit2Sharp.NotFoundException;
3641

3742
// ReSharper disable UnusedMember.Local
3843
[HandleHelpRequests(Priority = 20)]
3944
partial class Build : NukeBuild
4045
{
46+
4147
static Build()
4248
{
4349
Environment.SetEnvironmentVariable("NUKE_TELEMETRY_OPTOUT", "true");
@@ -87,13 +93,16 @@ FigletFont LoadFont(string fontName)
8793

8894
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
8995
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
96+
[Parameter("GitHub personal access token with access to the repo")] readonly string GitHubToken;
97+
9098
AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts";
9199
AbsolutePath TestResultsDirectory => ArtifactsDirectory / "test-results";
92100
AbsolutePath TestFixturesDirectory => RootDirectory / "Rewrite" / "tests" / "fixtures";
93101
AbsolutePath TestFixturesFile => TestFixturesDirectory / "fixtures.txt";
94102
[Solution(GenerateProjects = true)] Solution Solution;
95103
[NerdbankGitVersioning] NerdbankGitVersioning Version;
96104
[GitRepositoryExt] LibGit2Sharp.Repository GitRepository;
105+
AbsolutePath DotnetServerFilePath => ArtifactsDirectory / "DotnetServer.zip";
97106

98107
const string TargetFramework = "net9.0";
99108

@@ -205,9 +214,8 @@ IEnumerable<AbsolutePath> GetSubDirectories(params string[] patterns)
205214
var publishDir = Solution.src.Rewrite_Server.Directory / "bin" / "Release" / TargetFramework / "publish";
206215
var extension = IsWin ? ".exe" : "";
207216
Environment.SetEnvironmentVariable("ROSLYN_RECIPE_EXECUTABLE", publishDir);
208-
var zipFilePath = ArtifactsDirectory / "DotnetServer.zip";
209-
zipFilePath.DeleteFile();
210-
publishDir.ZipTo(ArtifactsDirectory / "DotnetServer.zip");
217+
DotnetServerFilePath.DeleteFile();
218+
publishDir.ZipTo(DotnetServerFilePath);
211219
});
212220

213221

@@ -421,7 +429,7 @@ void InjectLogsIntoTrx()
421429
});
422430

423431

424-
Target SetTestOutputFlags => _ => _
432+
Target SignalIfTestcaseOutputExists => _ => _
425433
.Unlisted()
426434
.Description("Sets github actions flags if any java or c# test output files were generated")
427435
.After(Test, GradleAssembleAndTest)
@@ -436,20 +444,21 @@ void InjectLogsIntoTrx()
436444
[Category("CI")]
437445
Target CIBuild => _ => _
438446
.Description("Builds, tests and produces test reports for regular builds on CI")
439-
.DependsOn(Pack, PublishServer, Test, GradleAssembleAndTest, SetTestOutputFlags);
447+
.DependsOn(Pack, PublishServer, Test, GradleAssembleAndTest, GithubRelease, SignalIfTestcaseOutputExists);
440448

441449

442450

443451
[Category("CI")]
444452
Target CIRelease => _ => _
445453
.Description("Creates and publishes release artifacts to maven & nuget")
446-
.DependsOn(Pack, PublishServer, GradlePublish, NugetPush, SetTestOutputFlags);
454+
.DependsOn(Pack, PublishServer, GradlePublish, NugetPush, SignalIfTestcaseOutputExists);
447455

448456
Target CreateGithubRelease => _ => _
449457
.Unlisted()
450458
.DependsOn(PublishServer)
451459
.Executes(() =>
452460
{
461+
453462
});
454463

455464
[Category("Test")]
@@ -533,6 +542,72 @@ GradleSettings ApplyCommonGradleSettings(GradleSettings options) => options
533542

534543
});
535544

545+
Target GithubRelease => _ => _
546+
.Description("Creates a GitHub release (or amends existing)")
547+
.Requires(() => GitHubToken)
548+
.Executes(async () =>
549+
{
550+
await CreateGitHubRelease($"v{Version.SemVer1}");
551+
if (string.Equals(GitRepository.Head.FriendlyName, "main", StringComparison.OrdinalIgnoreCase) && !GitRepository.Info.IsHeadDetached)
552+
{
553+
await CreateGitHubRelease($"latest");
554+
}
555+
});
556+
557+
public async Task CreateGitHubRelease(string releaseName)
558+
{
559+
var client = new GitHubClient(new ProductHeaderValue("OpenRewrite"))
560+
{
561+
Credentials = new Octokit.Credentials(GitHubToken, AuthenticationType.Bearer)
562+
};
563+
var (owner, repoName) = GetGitHubOwnerAndRepo();
564+
565+
Release release;
566+
try
567+
{
568+
release = await client.Repository.Release.Get(owner, repoName, releaseName);
569+
}
570+
catch (Octokit.NotFoundException)
571+
{
572+
var newRelease = new NewRelease(releaseName)
573+
{
574+
Name = releaseName,
575+
Draft = false,
576+
Prerelease = false
577+
};
578+
release = await client.Repository.Release.Create(owner, repoName, newRelease);
579+
}
580+
581+
var existingAsset = release.Assets.FirstOrDefault(x => x.Name == DotnetServerFilePath.Name);
582+
if (existingAsset != null)
583+
{
584+
await client.Repository.Release.DeleteAsset(owner, repoName, existingAsset.Id);
585+
}
586+
587+
var stream = File.OpenRead(DotnetServerFilePath);
588+
var releaseAssetUpload = new ReleaseAssetUpload(DotnetServerFilePath.Name, "application/zip", stream, TimeSpan.FromHours(1));
589+
var releaseAsset = await client.Repository.Release.UploadAsset(release, releaseAssetUpload);
590+
591+
}
592+
public (string Owner, string Repo) GetGitHubOwnerAndRepo()
593+
{
594+
var originRemote = GitRepository.Network.Remotes["origin"];
595+
if (originRemote == null)
596+
throw new Exception("No origin remote");
597+
598+
var url = originRemote.Url;
599+
600+
// Handle SSH and HTTPS GitHub URLs
601+
// Examples:
602+
// - [email protected]:owner/repo.git
603+
// - https://github.com/owner/repo.git
604+
string pattern = @"github\.com[:/](?<owner>[^/]+?)/(?<repo>[^/]+?)(\.git)?$";
605+
var match = System.Text.RegularExpressions.Regex.Match(url, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
606+
if (!match.Success)
607+
throw new Exception("Origin not set to github remote url");
608+
609+
return (match.Groups["owner"].Value, match.Groups["repo"].Value);
610+
}
536611

537612
string[] GetTagsForCurrentCheckout()
538613
{

0 commit comments

Comments
 (0)