Skip to content

Commit

Permalink
Initial version (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
ewingjm authored Dec 12, 2023
1 parent a3fec53 commit eac6865
Show file tree
Hide file tree
Showing 55 changed files with 3,809 additions and 0 deletions.
76 changes: 76 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[*.cs]

# SA1633: File should have header
dotnet_diagnostic.SA1633.severity = none
csharp_indent_labels = one_less_than_current
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent

[*.{cs,vb}]
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
[*.{cs,vb}]
#### Naming styles ####

# Naming rules

dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =

# Naming styles

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.vs/
bin/
obj/
*.feature.cs
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Contributing

Please first discuss the change you wish to make via an issue before making a change.

## Pull requests

A maintainer will merge your pull request once it meets all of the required checks. Please ensure that you:

- Update the automated tests to cover any new or changed functionality
- Update the README.md with details of any new or changed functionality
1 change: 1 addition & 0 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mode: mainline
65 changes: 65 additions & 0 deletions PowerVersion.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33627.172
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F43A5802-1D6B-4D11-BCF9-2B79C0A440F6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{64F47862-C59C-4810-A015-5B024403621E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerVersion.UnitTests", "tests\PowerVersion.UnitTests\PowerVersion.UnitTests.csproj", "{E798E1A6-A902-42AC-8F78-839AB7BF6E0C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerVersion.IntegrationTests", "tests\PowerVersion.IntegrationTests\PowerVersion.IntegrationTests.csproj", "{DEC083A4-57CF-477D-B1FF-7254D36E72D4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerVersion", "src\PowerVersion\PowerVersion.csproj", "{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerVersion.MSBuild", "src\PowerVersion.MSBuild\PowerVersion.MSBuild.csproj", "{5D10EC04-2422-413C-B2AF-2DBD12855F5A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{778D2F1D-CA58-40F3-B80A-5D978BAE4AEB}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerVersion.Specs", "tests\PowerVersion.Specs\PowerVersion.Specs.csproj", "{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E798E1A6-A902-42AC-8F78-839AB7BF6E0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E798E1A6-A902-42AC-8F78-839AB7BF6E0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E798E1A6-A902-42AC-8F78-839AB7BF6E0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E798E1A6-A902-42AC-8F78-839AB7BF6E0C}.Release|Any CPU.Build.0 = Release|Any CPU
{DEC083A4-57CF-477D-B1FF-7254D36E72D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEC083A4-57CF-477D-B1FF-7254D36E72D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEC083A4-57CF-477D-B1FF-7254D36E72D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEC083A4-57CF-477D-B1FF-7254D36E72D4}.Release|Any CPU.Build.0 = Release|Any CPU
{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED}.Release|Any CPU.Build.0 = Release|Any CPU
{5D10EC04-2422-413C-B2AF-2DBD12855F5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D10EC04-2422-413C-B2AF-2DBD12855F5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D10EC04-2422-413C-B2AF-2DBD12855F5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D10EC04-2422-413C-B2AF-2DBD12855F5A}.Release|Any CPU.Build.0 = Release|Any CPU
{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E798E1A6-A902-42AC-8F78-839AB7BF6E0C} = {64F47862-C59C-4810-A015-5B024403621E}
{DEC083A4-57CF-477D-B1FF-7254D36E72D4} = {64F47862-C59C-4810-A015-5B024403621E}
{92F0ABFC-3B8F-4332-9ACB-1E945E70B7ED} = {F43A5802-1D6B-4D11-BCF9-2B79C0A440F6}
{5D10EC04-2422-413C-B2AF-2DBD12855F5A} = {F43A5802-1D6B-4D11-BCF9-2B79C0A440F6}
{A8B2AE5B-2DB9-4749-BF1B-98A27502BECD} = {64F47862-C59C-4810-A015-5B024403621E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E833630E-1042-4790-82BD-8F3BF37C3282}
EndGlobalSection
EndGlobal
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# PowerVersion![](https://raw.githubusercontent.com/ewingjm/power-version/main/docs/images/logo.svg)

Version your Power Apps solutions at build-time automatically with Git.

## Table of contents

- [PowerVersion](#powerversion)
- [Table of contents](#table-of-contents)
- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
- [Version increments](#version-increments)
- [Metadata commits](#metadata-commits)
- [Non-metadata commits](#non-metadata-commits)
- [Version tags](#version-tags)
- [Branch types](#branch-types)
- [Configuration](#configuration)
- [Mainline branches](#mainline-branches)
- [Release branches](#release-branches)
- [Topic branches](#topic-branches)
- [Contributing](#contributing)


## Introduction

Generating [Semantic Versions](https://semver.org/) from Git history is often a sensible approach to versioning artifacts. It is also made incredibly easy thanks to tools such as [GitVersion](https://github.com/GitTools/GitVersion) and [semantic-release](https://github.com/semantic-release/semantic-release).

Power Apps solutions have some unique challenges when applying this approach:

- Multiple solutions often need to be versioned independently within the same repository
- Solution versions do not conform fully to the Semantic Versions specification

**PowerVersion** is designed to address these challenges and provide similar functionality to the tools mentioned above.

## Prerequisites


- You must have a solution project created with the Power App CLI
- Your solution project must exist within a Git repository
- Your Git workflow must be similar to Microsoft's [Release flow](https://learn.microsoft.com/en-us/devops/develop/how-microsoft-develops-devops#microsoft-release-flow)

## Installation

Install the [PowerVersion.MSBuild](https://www.nuget.org/packages/PowerVersion.MSBuild) NuGet package into your solution project (_.cdsproj_).

```shell
dotnet add package PowerVersion.MSBuild
```

## Usage

Simply build the solution project and the outputted solution's version will be set by PowerVersion based on the Git history.

### Version increments

This section describes the different mechanisms in place to increment the solution version for a commit.

The starting version for the calculation is either the version in the _Solution.xml_ (if no [version tag](#version-tags) is found) or the version in the latest version tag. It is recommended to set the version in the _Solution.xml_ to `0.0.0` to ensure that all versioning is handled by PowerVersion - if have an existing solution project, create a version tag to ensure version calculation is started at the correct version.

#### Metadata commits

Metadata commits are commits that make updates under the solution metadata directory. By default, this is the `src` folder in the project created by the Power Apps CLI with `pac solution init`.

These commits will automatically increment the solution version. The kind of increment depends on the commit message title and is based on [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):

- A commit message with an `!` after the Conventional Commits type is a major increment (`refactor!: delete obsolete components`)
- A commit message with a Conventional Commits type of `feat` is a minor increment (`feat: create an application`)
- A commit message containing anything else is a patch increment (`fix: contact form script error`)

#### Non-metadata commits

Non-metadata commits are commits that don't make any changes under the solution metadata directory but _do_ update files that are mapped into the solution at build-time with the Solution Packager. Typically, these will relate to code components such as web resources and plug-in assemblies.

These kinds of commits do **not** automatically increment the solution version as it is not possible to determine which solutions have been updated. You must explicitly bump the solution manually using the following in the commit message body:

> +semver(\<solution-unique-name\>): \<increment\>
- An `<increment>` of `major` or `breaking` is a major increment
- An `<increment>` of `minor` or `feature` is a minor increment
- An `<increment>` of `patch` or `fix` is a patch increment

An explicit version increment of this type will take precedence if the same commit also increments the version as a metadata commit.

#### Version tags

It's possible to override the version calculated for a given commit using a Git tag:

> \<solution-unique-name\>/#.#.#
The version calculation will start at the most recent version tag for the solution (or the first commit if no tags are found). It is recommended to periodically create a version tag to improve the performance of the version calculation.

### Branch types

The version calculation differs based on the branch type.

#### Configuration

There are two MSBuild properties that can be set to configure how the branch type is determined for a given branch.

```xml
<PropertyGroup>
<MainlineBranch>master</MainlineBranch>
<ReleaseBranchPrefix>release/</ReleaseBranchPrefix>
</PropertyGroup>
```

#### Mainline branches

The mainline branch is `master` by default but this is configurable with the `MainlineBranch` MSBuild property.

The version of the mainline branch is calculated by determining the type of increment for each commit and applying each increment in order.

#### Release branches

A release branch is any branch that is prefixed by `release/` by default but this is configurable with the `ReleaseBranchPrefix` MSBuild property.

The version is calculated by taking the mainline version (for the commit the release branch is based on) and setting the revision part of the version to the total number of commits on the release branch that increment the solution version. Only release branches generate a revision version (e.g. `#.#.#.#` rather than `#.#.#`) and this avoids hotfix versions clashing with mainline versions.

#### Topic branches

A topic branch is a branch that is neither the mainline branch nor does it match the release branch prefix.

The version of a feature branch is calculated by taking the mainline version (for the commit the feature branch is based on) and incrementing this by the highest increment found on the feature branch.

## Contributing

Refer to the contributing [guide](./CONTRIBUTING.md).
Binary file added docs/images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions docs/images/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit eac6865

Please sign in to comment.