Skip to content

Commit 673e933

Browse files
committed
Initial Commit
0 parents  commit 673e933

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2009
-0
lines changed

.gitattributes

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Auto detect text files and perform CRLF normalization
2+
* text=auto eol=crlf
3+
4+
# Standard to msysgit
5+
*.doc diff=astextplain
6+
*.DOC diff=astextplain
7+
*.docx diff=astextplain
8+
*.DOCX diff=astextplain
9+
*.dot diff=astextplain
10+
*.DOT diff=astextplain
11+
*.pdf diff=astextplain
12+
*.PDF diff=astextplain
13+
*.rtf diff=astextplain
14+
*.RTF diff=astextplain
15+
16+
*.exe -text -diff
17+
*.jpg -text -diff
18+
*.png -text -diff
19+
*.gif -text -diff
20+
*.dll -text -diff
21+
*.pdb -text -diff
22+
*.pptx -text -diff
23+
*.xap -text -diff
24+
*.ico -text -diff
25+
*.ttf -text -diff
26+
*.otf -text -diff
27+
28+
*.cs text diff=csharp
29+
*.config text diff=csharp
30+
*.xml text diff=csharp
31+
*.vb text
32+
*.c text
33+
*.cpp text
34+
*.cxx text
35+
*.h text
36+
*.hxx text
37+
*.py text
38+
*.rb text
39+
*.java text
40+
*.html text
41+
*.htm text
42+
*.css text
43+
*.scss text
44+
*.sass text
45+
*.less text
46+
*.js text
47+
*.lisp text
48+
*.clj text
49+
*.sql text
50+
*.php text
51+
*.lua text
52+
*.m text
53+
*.asm text
54+
*.erl text
55+
*.fs text
56+
*.fsx text
57+
*.hs text
58+
59+
*.psm1 text
60+
*.ps1 text
61+
*.txt text eol=crlf
62+
*.bat text eol=crlf
63+
64+
# Custom for Visual Studio
65+
*.csproj merge=union
66+
*.vbproj merge=union
67+
*.fsproj merge=union
68+
*.dbproj merge=union
69+
*.sln text eol=crlf merge=union
70+
*.suo -text -diff
71+
*.snk -text -diff
72+
*.cub -text -diff
73+
*.wixlib -text -diff
74+
75+
76+
*.approved.* binary

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
nugets
2+
build32
3+
binaries
4+
obj
5+
bin
6+
*.vshost.*
7+
.nu
8+
_ReSharper.*
9+
_UpgradeReport.*
10+
*.csproj.user
11+
*.resharper.user
12+
*.resharper
13+
*.suo
14+
*.cache
15+
*~
16+
*.swp
17+
*.user
18+
TestResults
19+
TestResult.xml
20+
results
21+
CommonAssemblyInfo.cs
22+
lib/sqlite/System.Data.SQLite.dll
23+
*.orig
24+
Samples/DataBus/storage
25+
packages
26+
PrecompiledWeb
27+
core-only
28+
Release
29+
Artifacts
30+
LogFiles
31+
csx
32+
*.ncrunchproject
33+
*.ncrunchsolution
34+
_NCrunch_NServiceBus/*
35+
logs
36+
run-git.cmd
37+
src/Chocolatey/Build/*
38+
App_Packages

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2013 Particular Software
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
this software and associated documentation files (the "Software"), to deal in
7+
the Software without restriction, including without limitation the rights to
8+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ReleaseNotesCompiler
2+
====================
3+
4+
In order to improve the quality for our release notes we'll generate them based on the relevant github issues.
5+
6+
### Conventions
7+
8+
* All closed issues for a milestone will be included
9+
* All issues must have one of the following tags `Bug`, `Feature`, `Internal refactoring`, `Improvement`. Where `Internal refactoring` will be included in a milestone but excluded from the release notes.
10+
* For now the text is taken from the name of the issue
11+
* Milestones are named {major.minor.patch}
12+
* Version is picked up from the build number (GFV) and that info is used to find the milestone
13+
* We'll generate release notes as markdown for display on the website
14+
* by default only the first 30 line of an issue description is included in the release noted. If you want to control exactly how many lines are included then use a `--` to add a horizontal rule. Then only the contents above that horizontal rule will be included.
15+
16+
### Plans
17+
18+
* The build server will compile the release notes either for each commit or daily
19+
* Build will fail if release notes can't be generated
20+
* No milestone found is considered a exception
21+
* Want to be able to output in a manner compatible with http://www.semanticreleasenotes.org/
22+
* We'll generate release notes as X for inclusion in our nugets
23+
* For each milestone a corresponding GitHub release will be created with the same name and set to tag master with the same tag when published
24+
25+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
3+
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
4+
<id>GitHubReleaseNotes</id>
5+
<title>Generates release notes</title>
6+
<version>$version$</version>
7+
<authors>NServiceBus Ltd</authors>
8+
<owners>Particular et al</owners>
9+
<projectUrl>https://github.com/Particular/GitHubReleaseNotes</projectUrl>
10+
<description>Create release notes in markdown given a GH milestone</description>
11+
<tags>github release nptes</tags>
12+
</metadata>
13+
<files>
14+
<file src="..\..\src\App\bin\release\*.exe" target="tools" />
15+
</files>
16+
</package>

src/.nuget/packages.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="NuGet.CommandLine" version="2.8.2" />
4+
</packages>

src/App/AssemblyInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using System.Reflection;
2+
3+
[assembly: AssemblyCompany("Particular")]

src/App/FodyWeavers.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Weavers>
3+
<Costura/>
4+
</Weavers>

src/App/Program.cs

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
namespace ReleaseNotesCompiler.CLI
2+
{
3+
using System;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
using CommandLine;
8+
using CommandLine.Text;
9+
using Octokit;
10+
using FileMode = System.IO.FileMode;
11+
12+
abstract class CommonSubOptions
13+
{
14+
[Option('u', "username", HelpText = "The username to access GitHub with.", Required = true)]
15+
public string Username { get; set; }
16+
17+
[Option('p', "password", HelpText = "The password to access GitHub with.", Required = true)]
18+
public string Password { get; set; }
19+
20+
[Option('o', "owner", HelpText = "The owner of the repository.", Required = true)]
21+
public string RepositoryOwner { get; set; }
22+
23+
[Option('r', "repository", HelpText = "The name of the repository.", Required = true)]
24+
public string RepositoryName { get; set; }
25+
26+
[Option('m', "milestone", HelpText = "The milestone to use.", Required = true)]
27+
public string Milestone { get; set; }
28+
29+
public GitHubClient CreateGitHubClient()
30+
{
31+
var creds = new Credentials(Username, Password);
32+
var github = new GitHubClient(new ProductHeaderValue("ReleaseNotesCompiler")) { Credentials = creds };
33+
34+
return github;
35+
}
36+
}
37+
38+
class CreateSubOptions : CommonSubOptions
39+
{
40+
[Option('a', "asset", HelpText = "Path to the file to include in the release.", Required = false)]
41+
public string AssetPath { get; set; }
42+
43+
[Option('t', "targetcommitish", HelpText = "The commit to tag. Can be a branch or SHA. Defaults to repo's default branch.", Required = false)]
44+
public string TargetCommitish { get; set; }
45+
}
46+
47+
class PublishSubOptions : CommonSubOptions
48+
{
49+
}
50+
51+
class Options
52+
{
53+
[VerbOption("create", HelpText = "Creates a draft release notes from a milestone.")]
54+
public CreateSubOptions CreateVerb { get; set; }
55+
56+
[VerbOption("publish", HelpText = "Publishes the release notes and closes the milestone.")]
57+
public PublishSubOptions PublishVerb { get; set; }
58+
59+
[HelpVerbOption]
60+
public string DoHelpForVerb(string verbName)
61+
{
62+
return HelpText.AutoBuild(this, verbName);
63+
}
64+
}
65+
66+
class Program
67+
{
68+
static int Main(string[] args)
69+
{
70+
var options = new Options();
71+
72+
var result = 1;
73+
74+
if (!Parser.Default.ParseArgumentsStrict(args, options, (verb, subOptions) =>
75+
{
76+
if (verb == "create")
77+
{
78+
result = CreateReleaseAsync((CreateSubOptions)subOptions).Result;
79+
}
80+
81+
if (verb == "publish")
82+
{
83+
result = PublishReleaseAsync((PublishSubOptions)subOptions).Result;
84+
}
85+
}))
86+
{
87+
return 1;
88+
}
89+
90+
return result;
91+
}
92+
93+
static async Task<int> CreateReleaseAsync(CreateSubOptions options)
94+
{
95+
try
96+
{
97+
var github = options.CreateGitHubClient();
98+
99+
await CreateRelease(github, options.RepositoryOwner, options.RepositoryName, options.Milestone, options.TargetCommitish, options.AssetPath);
100+
101+
return 0;
102+
}
103+
catch (Exception ex)
104+
{
105+
Console.WriteLine(ex);
106+
107+
return 1;
108+
}
109+
}
110+
111+
static async Task<int> PublishReleaseAsync(PublishSubOptions options)
112+
{
113+
try
114+
{
115+
var github = options.CreateGitHubClient();
116+
117+
await CloseMilestone(github, options.RepositoryOwner, options.RepositoryName, options.Milestone);
118+
119+
await PublishRelease(github, options.RepositoryOwner, options.RepositoryName, options.Milestone);
120+
121+
return 0;
122+
}
123+
catch (Exception ex)
124+
{
125+
Console.WriteLine(ex);
126+
127+
return 1;
128+
}
129+
}
130+
131+
private static async Task CreateRelease(GitHubClient github, string owner, string repository, string milestone, string targetCommitish, string asset)
132+
{
133+
var releaseNotesBuilder = new ReleaseNotesBuilder(new DefaultGitHubClient(github, owner, repository), owner, repository, milestone);
134+
135+
var result = await releaseNotesBuilder.BuildReleaseNotes();
136+
137+
var releaseUpdate = new ReleaseUpdate(milestone)
138+
{
139+
Draft = true,
140+
Body = result,
141+
Name = milestone
142+
};
143+
if (!string.IsNullOrEmpty(targetCommitish))
144+
releaseUpdate.TargetCommitish = targetCommitish;
145+
146+
var release = await github.Release.Create(owner, repository, releaseUpdate);
147+
148+
if (File.Exists(asset))
149+
{
150+
var upload = new ReleaseAssetUpload { FileName = Path.GetFileName(asset), ContentType = "application/octet-stream", RawData = File.Open(asset, FileMode.Open) };
151+
152+
await github.Release.UploadAsset(release, upload);
153+
}
154+
}
155+
156+
private static async Task CloseMilestone(GitHubClient github, string owner, string repository, string milestoneTitle)
157+
{
158+
var milestoneClient = github.Issue.Milestone;
159+
var openMilestones = await milestoneClient.GetForRepository(owner, repository, new MilestoneRequest { State = ItemState.Open });
160+
var milestone = openMilestones.FirstOrDefault(m => m.Title == milestoneTitle);
161+
if (milestone == null)
162+
return;
163+
164+
await milestoneClient.Update(owner, repository, milestone.Number, new MilestoneUpdate { State = ItemState.Closed });
165+
}
166+
167+
private static async Task PublishRelease(GitHubClient github, string owner, string repository, string milestone)
168+
{
169+
var releases = await github.Release.GetAll(owner, repository);
170+
var release = releases.FirstOrDefault(r => r.Name == milestone);
171+
if (release == null)
172+
return;
173+
174+
var releaseUpdate = new ReleaseUpdate(milestone)
175+
{
176+
Draft = false
177+
};
178+
179+
await github.Release.Edit(owner, repository, release.Id, releaseUpdate);
180+
}
181+
}
182+
}

0 commit comments

Comments
 (0)