Skip to content

Commit

Permalink
Add simple unreleased version logic
Browse files Browse the repository at this point in the history
- Simply take the latest version, increment patch, add -alpha.
- Handle changelogs with no releases.
- Hanlde changelogs with no releases nor unreleased
- Add targets from ionide#5 which conditionally use the unreleased version in packaging
  • Loading branch information
tboby committed Oct 26, 2024
1 parent 9cdc26d commit d186da3
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 66 deletions.
45 changes: 25 additions & 20 deletions src/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ type ParseChangeLogs() =

[<Output>]
member val UnreleasedChangelog: ITaskItem = null with get, set

[<Output>]
member val UnreleasedReleaseNotes: string = null with get, set
member val UnreleasedReleaseNotes: string = null with get, set

[<Output>]
member val CurrentReleaseChangelog: ITaskItem = null with get, set
Expand Down Expand Up @@ -131,48 +131,53 @@ type ParseChangeLogs() =
Error()

member this.ReadUnreleasedSection(changelog: Changelog) =
match changelog.SectionUnreleased with
| null -> Ok()
| unreleased ->
match changelog.SectionUnreleased, changelog.SectionUnreleased.MarkdownTitle with
| null, _
| _, "" -> Ok()
| unreleased, _ ->
this.UnreleasedChangelog <- unreleased.ToTaskItem()
this.UnreleasedReleaseNotes <- unreleased.SubSectionCollection.ToMarkdown()
Ok()
member this.UpdateUnreleasedVersion(latestVersion : SemVersion) =

member this.UpdateUnreleasedVersion(latestVersion: SemVersion) =
match this.UnreleasedChangelog with
| null -> ()
| _ ->
let newUnreleased = latestVersion.WithPrereleaseParsedFrom "alpha" |> _.WithPatch(latestVersion.Patch + 1)
let newUnreleased =
latestVersion.WithPrereleaseParsedFrom "alpha"
|> _.WithPatch(latestVersion.Patch + 1)

this.UnreleasedChangelog.ItemSpec <- newUnreleased.ToString()

member this.ProcessReleases(changelog: Changelog) =
let releases =
changelog.SectionCollection.Unwrapped()
|> Seq.sortByDescending _.version
|> Seq.toArray

let latestRelease = releases |> (fun x -> x[0])
|> Seq.toList

let mapped =
releases
|> Array.map (fun x ->
|> List.map (fun x ->
let taskItem = TaskItem(x.version.ToString())
taskItem.SetMetadata("Date", x.date.ToString("yyyy-MM-dd"))

for (key, value) in x.collection.ToTaskItemMetadata() do
taskItem.SetMetadata(key, value)

taskItem :> ITaskItem
(x, taskItem :> ITaskItem)
)

this.CurrentReleaseChangelog <- mapped[0]
this.AllReleasedChangelogs <- mapped
this.LatestReleaseNotes <- latestRelease.collection.ToMarkdown()

this.UpdateUnreleasedVersion(latestRelease.version)

match mapped with
| (latestRelease, latestTaskItem) :: _ ->
this.CurrentReleaseChangelog <- latestTaskItem
this.AllReleasedChangelogs <- mapped |> List.map snd |> Array.ofList
this.LatestReleaseNotes <- latestRelease.collection.ToMarkdown()
this.UpdateUnreleasedVersion(latestRelease.version)
| _ ->
this.AllReleasedChangelogs <- [||]
this.UpdateUnreleasedVersion(SemVersion(0, 0, 0))

Ok()


/// <summary>
/// Helper method to log an error with the given log data.
Expand Down
15 changes: 13 additions & 2 deletions src/build/Core.targets
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Target Name="GetChangelogVersion" Condition="'$(ChangelogFile)' != '' and Exists('$(ChangelogFile)')" DependsOnTargets="ValidateChangelog" Inputs="$(ChangelogFile)" Outputs="UnreleasedChangelog;CurrentReleaseChangelog;AllReleasedChangelogslLatestReleaseNotes">
<Ionide.KeepAChangelog.Tasks.ParseChangeLogs ChangelogFile="$(ChangelogFile)">
<Output TaskParameter="UnreleasedChangelog" ItemName="UnreleasedChangelog"/>
<Output TaskParameter="UnreleasedReleaseNotes" ItemName="UnreleasedReleaseNotes"/>
<Output TaskParameter="CurrentReleaseChangelog" ItemName="CurrentReleaseChangelog"/>
<Output TaskParameter="AllReleasedChangelogs" ItemName="AllReleasedChangelogs"/>
<Output TaskParameter="LatestReleaseNotes" ItemName="LatestReleaseNotes"/>
Expand All @@ -26,15 +27,25 @@

<Target Name="SetVersionFromChangelog" DependsOnTargets="GetChangelogVersion">
<PropertyGroup Condition="'@(CurrentReleaseChangelog)' != ''">
<!-- Set the version to the version of the latest release -->
<Version>%(CurrentReleaseChangelog.Identity)</Version>
<PackageVersion>%(CurrentReleaseChangelog.Identity)</PackageVersion>
<PackageReleaseNotes>@(LatestReleaseNotes)</PackageReleaseNotes>
<_ReleaseDate>%(CurrentReleaseChangelog.Date)</_ReleaseDate>
</PropertyGroup>

<PropertyGroup Condition="'@(UnreleasedChangelog)' != '' and '$(GenerateVersionForUnreleasedChanges)' == 'true'">
<!-- Set the version to the derived version of the unreleased changelog -->
<Version>%(UnreleasedChangelog.Identity)</Version>
<PackageVersion>%(UnreleasedChangelog.Identity)</PackageVersion>
<PackageReleaseNotes>@(UnreleasedReleaseNotes)</PackageReleaseNotes>
<_ReleaseDate>%(UnreleasedChangelog.Date)</_ReleaseDate>
</PropertyGroup>

<ItemGroup Condition="'@(CurrentReleaseChangelog)' != '' and '$(GenerateAssemblyInfo)' == 'true'">
<ItemGroup Condition="'@(_ReleaseDate)' != '' and '$(GenerateAssemblyInfo)' == 'true'">
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute" Condition="'$(GenerateRepositoryUrlAttribute)' == 'true' and ('$(RepositoryUrl)' != '' or '$(PublishRepositoryUrl)' == 'true')">
<_Parameter1>BuildDate</_Parameter1>
<_Parameter2>%(CurrentReleaseChangelog.Date)</_Parameter2>
<_Parameter2>%(_ReleaseDate)</_Parameter2>
</AssemblyAttribute>
</ItemGroup>
</Target>
Expand Down
6 changes: 6 additions & 0 deletions src/build/Ionide.KeepAChangelog.Tasks.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- If set, the assembly/package version and release notes will be set from Unreleased changes, if any are present -->
<GenerateVersionForUnreleasedChanges Condition="'$(GenerateVersionForUnreleasedChanges)' == ''">true</GenerateVersionForUnreleasedChanges>
</PropertyGroup>
</Project>
1 change: 1 addition & 0 deletions tests/Ionide.KeepAChangelog.Tasks.Test.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

<ItemGroup>
<Content Include="changelogs\*.md" />
<None Include="fixtures\*"/>
</ItemGroup>

</Project>
84 changes: 66 additions & 18 deletions tests/UnitTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ type UnitTests() =
myTask.BuildEngine <- this.context.BuildEngine.Object

let success = myTask.Execute()
%success.Should().BeTrue "Should have successfully parsed the changelog data"
%success.Should().BeTrue("Should have successfully parsed the changelog data")
%myTask.AllReleasedChangelogs.Length.Should().Be(9, "Should have 9 versions")

%myTask.CurrentReleaseChangelog.ItemSpec
Expand All @@ -112,45 +112,93 @@ type UnitTests() =
|> Seq.cast
|> _.Should().Contain("Date", "Should have date metadata"))

%myTask.UnreleasedChangelog.ItemSpec
.Should()
.Be("0.1.9-alpha", "Should have the alpha prefix from a patch release")

%(myTask.UnreleasedChangelog.MetadataNames
|> Seq.cast
|> _.Should().Contain("Removed", "Should have removed metadata"))

[<TestMethod>]
member this.``task produces expected markdown``() =
let myTask = ParseChangeLogs(ChangelogFile = Workspace.changelogs.``CHANGELOG.md``)
let myTask =
ParseChangeLogs(ChangelogFile = Workspace.changelogs.``CHANGELOG_detailed.md``)

myTask.BuildEngine <- this.context.BuildEngine.Object

let success = myTask.Execute()
%success.Should().BeTrue "Should have successfully parsed the changelog data"
%success.Should().BeTrue("Should have successfully parsed the changelog data")

%myTask.LatestReleaseNotes
.Should()
.BeLineEndingEquivalent(
"""### Added
- Created the package
### Changed
"""### Changed
- Changed something in the package
- Updated the target framework"""
- Minor packaging fix for non-Core MSBuild versions"""
)

%myTask.UnreleasedReleaseNotes
.Should()
.BeLineEndingEquivalent(
"""### Removed
- A test removal line
- And another removal""")
- And another removal"""
)

[<TestMethod>]
member this.``task produces correct versions``() =
member this.``task correctly processes a changelog with no unreleased``() =
let myTask = ParseChangeLogs(ChangelogFile = Workspace.changelogs.``CHANGELOG.md``)

myTask.BuildEngine <- this.context.BuildEngine.Object

let success = myTask.Execute()
%success.Should().BeTrue "Should have successfully parsed the changelog data"
%success.Should().BeTrue("Should have successfully parsed the changelog data")

%myTask.CurrentReleaseChangelog.ItemSpec
.Should()
.Be("0.1.0", "It is the latest release")

%myTask.LatestReleaseNotes.Should().NotBeNull().And.NotBeEmpty()

%myTask.AllReleasedChangelogs
.Should()
.HaveLength(1, "There is only a single release section")

%myTask.CurrentReleaseChangelog.ItemSpec.Should().Be("0.1.0")
%myTask.UnreleasedChangelog.ItemSpec.Should().Be("0.1.1-alpha")


%myTask.UnreleasedChangelog.Should().BeNull("There is no unreleased section")
%myTask.UnreleasedReleaseNotes.Should().BeNull("There is no unreleased section")

[<TestMethod>]
member this.``task correctly processes a changelog with only unreleased``() =
let myTask =
ParseChangeLogs(ChangelogFile = Workspace.changelogs.``CHANGELOG_unreleased.md``)

myTask.BuildEngine <- this.context.BuildEngine.Object

let success = myTask.Execute()
%success.Should().BeTrue("Should have successfully parsed the changelog data")
%myTask.CurrentReleaseChangelog.Should().BeNull("There are no released sections")
%myTask.LatestReleaseNotes.Should().BeNull("There are no released sections")
%myTask.AllReleasedChangelogs.Should().BeEmpty("There are no released sections")

%myTask.UnreleasedChangelog.ItemSpec
.Should()
.Be("0.0.1-alpha", "There is no previous version, so it starts from 0.0.0")

%myTask.UnreleasedReleaseNotes.Should().NotBeNull().And.NotBeEmpty()

[<TestMethod>]
member this.``task correctly processes a changelog with only introduction``() =
let myTask =
ParseChangeLogs(ChangelogFile = Workspace.changelogs.``CHANGELOG_empty.md``)

myTask.BuildEngine <- this.context.BuildEngine.Object

let success = myTask.Execute()
%success.Should().BeTrue("Should have successfully parsed the changelog data")
%myTask.CurrentReleaseChangelog.Should().BeNull("There are no released sections")
%myTask.LatestReleaseNotes.Should().BeNull("There are no released sections")
%myTask.AllReleasedChangelogs.Should().BeEmpty("There are no released sections")
%myTask.UnreleasedChangelog.Should().BeNull("There is no unreleased section")
%myTask.UnreleasedReleaseNotes.Should().BeNull("There is no unreleased section")
7 changes: 0 additions & 7 deletions tests/changelogs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
# Changelog

## [Unreleased]

### Removed

- A test removal line
- And another removal

## [0.1.0] - 2022-01-13

### Added
Expand Down
7 changes: 7 additions & 0 deletions tests/changelogs/CHANGELOG_detailed.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [Unreleased]

### Removed

- A test removal line
- And another removal

## [0.1.8] - 2022-03-31

### Changed
Expand Down
3 changes: 3 additions & 0 deletions tests/changelogs/CHANGELOG_empty.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Changelog

Some notes in the header but no sections
10 changes: 0 additions & 10 deletions tests/changelogs/CHANGELOG_unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,3 @@
- A test removal line
- And another removal

## [0.1.0] - 2022-01-13

### Added

- Created the package

### Changed

- Changed something in the package
- Updated the target framework
7 changes: 0 additions & 7 deletions tests/fixtures/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
# Changelog

## [Unreleased]

### Removed

- A test removal line
- And another removal

## [0.1.0] - 2022-01-13

### Added
Expand Down
2 changes: 0 additions & 2 deletions tests/fixtures/CHANGELOG_KeepAChangelog.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Changelog

## [Unreleased]

## [0.1.0] - 2022-01-13

### Added
Expand Down
19 changes: 19 additions & 0 deletions tests/fixtures/CHANGELOG_unreleased.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

## [Unreleased]

### Removed

- A test removal line
- And another removal

## [0.1.0] - 2022-01-13

### Added

- Created the package

### Changed

- Changed something in the package
- Updated the target framework
20 changes: 20 additions & 0 deletions tests/fixtures/WorksForUnreleased.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<ChangelogFile>CHANGELOG_unreleased.md</ChangelogFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DotNet.ReproducibleBuilds.Isolated" Version="1.2.25"/>
<PackageReference Include="Ionide.KeepAChangelog.Tasks" Version="[0.0.1-test-WorksForRelativePathWithKeepAChangelog]" >
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

</Project>

0 comments on commit d186da3

Please sign in to comment.