diff --git a/Laerdal.Dfu.sln b/Laerdal.Dfu.sln index 5cfac61..1dbf783 100644 --- a/Laerdal.Dfu.sln +++ b/Laerdal.Dfu.sln @@ -8,7 +8,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Misc", "_Misc", "{37EBD209 LICENSE = LICENSE azure-pipelines.yaml = azure-pipelines.yaml Laerdal.Scripts\Laerdal.Version.sh = Laerdal.Scripts\Laerdal.Version.sh - Laerdal.Build.targets = Laerdal.Build.targets + Laerdal.Scripts\Laerdal.Build.targets = Laerdal.Scripts\Laerdal.Build.targets + Laerdal.Scripts\Laerdal.Changelog.sh = Laerdal.Scripts\Laerdal.Changelog.sh + Laerdal.Scripts\Laerdal.CreateNewReleaseInGithub.sh = Laerdal.Scripts\Laerdal.CreateNewReleaseInGithub.sh + Laerdal.Scripts\Laerdal.SetupBuildEnvironment.sh = Laerdal.Scripts\Laerdal.SetupBuildEnvironment.sh EndProjectSection EndProject Global diff --git a/Laerdal.Build.targets b/Laerdal.Scripts/Laerdal.Build.targets similarity index 95% rename from Laerdal.Build.targets rename to Laerdal.Scripts/Laerdal.Build.targets index d1da623..4e68d46 100644 --- a/Laerdal.Build.targets +++ b/Laerdal.Scripts/Laerdal.Build.targets @@ -19,12 +19,12 @@ High - $([System.IO.Path]::Combine($(MSBuildThisFileDirectory), `Output/`)) + $([System.IO.Path]::Combine($(MSBuildThisFileDirectory), `..`, `Output`)) $(BUILD_ARTIFACTSTAGINGDIRECTORY) - $([System.IO.Path]::Combine($(MSBuildThisFileDirectory), `Laerdal.Dfu/Laerdal.Dfu.csproj`)) + $([System.IO.Path]::Combine($(MSBuildThisFileDirectory), `..`, `Laerdal.Dfu`, `Laerdal.Dfu.csproj`)) - $([System.IO.Path]::Combine($(MSBuildThisFileDirectory), `Laerdal.Scripts/`)) + $(MSBuildThisFileDirectory) diff --git a/Laerdal.Scripts/Laerdal.Changelog.sh b/Laerdal.Scripts/Laerdal.Changelog.sh new file mode 100644 index 0000000..49e40ae --- /dev/null +++ b/Laerdal.Scripts/Laerdal.Changelog.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +usage(){ + echo "usage: ./Laerdal.Changelog.sh [-nv | --new-version X.Y.Z] [-o | --output version.txt] [-h | --help]" + echo "parameters:" + echo " -nv | --new-version [version] New major.minor.patch version (default is 0.0.0)" + echo " -o | --output [filename] Name of the output file" + echo " -h | --help Prints this message" + echo " -v | --verbose Verbose mode" +} + +function log () { + if [[ $verbose -eq 1 ]]; then + echo "$@" + fi +} + +filename="CHANGELOG.md" + +while [ "$1" != "" ]; do + case $1 in + -nv | --new-version ) shift + newversion="$1" + ;; + -o | --output ) shift + filename="$1" + ;; + -h | --help ) usage + exit + ;; + -v | --verbose ) verbose=1 + ;; + * ) echo + echo "### Wrong parameter: $1 ###" + echo + usage + exit 1 + esac + shift +done + + +if [ ! -z "$newversion" ]; then + if [[ "$newversion" =~ .*"-".* ]]; then + log "New version contains a dash, skipping changelog generation" + else + currenthash=$(git show --format=%h --no-patch) + echo "$currenthash $newversion" > tags.txt + log "New version: $newversion" + fi +else + echo "" > tags.txt +fi + +# Get all tags on develop and Filter out tags that are not in the format "HASH 1.2.3" +git tag --format='%(objectname:short) %(refname:short)' --sort=-version:refname --merged | grep -o '[a-z0-9]* [a-z0-9]*[.][a-z0-9]*[.][a-z0-9]*$' >> tags.txt + +# Create changelog file +echo "# CHANGELOG" > "$filename" +echo "" >> "$filename" +log "Created changelog file: $filename" + + +# Loop through all tags and create changelog +lastline='' +while read line; do + if [ -z "$lastline" ]; then + lastline=$line + else + # Split the line into hash and version + lasthash=`echo $lastline | cut -d' ' -f1` + lastversion=`echo $lastline | cut -d' ' -f2` + hash=`echo $line | cut -d' ' -f1` + + echo "## **$lastversion**" >> "$filename" + log "Added version: $lastversion" + # Get the commit message and author of the tag + git log -n 1 --pretty=tformat:"%b" $lasthash >> "$filename" + + echo "" >> "$filename" + + # Get all commits between the current tag and the previous tag + git log $hash..$lasthash --pretty=format:"- %s [%cn]" --no-merges >> "$filename" + + echo "" >> "$filename" + echo "" >> "$filename" + + # Get the commit message and author of the tag + git log -n 1 --pretty=tformat:"> by _%cn_ on _%cd_" --date=format:'%Y-%m-%d %H:%M:%S' $lasthash >> "$filename" + + echo "" >> "$filename" + echo "---" >> "$filename" + echo "" >> "$filename" + lastline=$line + fi +done < tags.txt + +rm -r -f tags.txt + +log "Done" + +exit 0 \ No newline at end of file diff --git a/Laerdal.Scripts/Laerdal.CreateNewReleaseInGithub.sh b/Laerdal.Scripts/Laerdal.CreateNewReleaseInGithub.sh new file mode 100644 index 0000000..cf1ce63 --- /dev/null +++ b/Laerdal.Scripts/Laerdal.CreateNewReleaseInGithub.sh @@ -0,0 +1,167 @@ +#!/bin/bash + +declare VERBOSE=0 +declare TAG_VERSION="" + +declare GIT_BRANCH="" +declare GITHUB_ACCESS_TOKEN="" +declare GITHUB_REPOSITORY_PATH="" + +function parse_arguments() { + while [[ $# -gt 0 ]]; do + case $1 in + + -v | --log) + VERBOSE=1 + shift + ;; + + -r | --repository-path) + GITHUB_REPOSITORY_PATH="$2" + shift + ;; + + -t | --tag-version) + TAG_VERSION="$2" + shift + ;; + + -b | --git-branch) + GIT_BRANCH="$2" + shift + ;; + + -a | --access-token) + GITHUB_ACCESS_TOKEN="$2" + shift + ;; + + *) + echo "Unknown option: $1" + usage + exit 1 + ;; + + esac + shift + done + + if [[ -z $GIT_BRANCH ]]; then + echo "Missing git-branch." + usage + exit 1 + fi + + if [[ -z $GITHUB_REPOSITORY_PATH ]]; then + echo "Missing github-repository." + usage + exit 1 + fi + + if [[ -z $GITHUB_ACCESS_TOKEN ]]; then + echo "Missing github-access-token." + usage + exit 1 + fi + + validate_tag_format "$TAG_VERSION" +} + +function validate_tag_format() { + local -r tag="$1" + local -r pattern='^[0-9]+\.[0-9]+(\.[0-9]+)?$' + + if ! [[ $tag =~ $pattern ]]; then + exit_with_error "Tag format is invalid: '$tag'" + fi +} + +function usage() { + local -r script_name=$(basename "$0") + + echo "Usage: $script_name [--verbose|-v] [--repository-path|-r]= [--git-branch|-b]= [--access-token|-a]= [--tag-version|-t]=" +} + +function create_release_on_github() { + # https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release + + local eventual_tag_name="" + local eventual_singleline_summary="" + if [[ $GIT_BRANCH == "refs/heads/main" || $GIT_BRANCH == "refs/heads/master" ]]; then + eventual_tag_name="v$TAG_VERSION" # builds targeting main have this simple and straightforward tag name + eventual_singleline_summary="Release $eventual_tag_name" + + elif [[ $GIT_BRANCH == "refs/heads/develop" ]]; then # all builds that target develop are beta builds + eventual_tag_name="v$TAG_VERSION-beta" + eventual_singleline_summary="Beta $eventual_tag_name" + + else # all other builds that dont target main are alpha builds should rarely happen in practice but just in case + eventual_tag_name="v$TAG_VERSION-alpha" + eventual_singleline_summary="Alpha $eventual_tag_name" + fi + + local -r payload=$( + cat </dev/null 2>&1 # its vital to do this silently otherwise the +git fetch origin "$develop_branch:$develop_branch" >/dev/null 2>&1 # output of this entire script will be malformed + if [ "$branch_name" == "$develop_branch" ]; then develop_master_point=`git rev-list $branch_prefix$master_branch --merges --before=\`git show -s --format=%ct $commit\` --first-parent --max-count=1` - if [ -z $develop_master_point ]; then - # has never been merged, + if [ -z $develop_master_point ]; then # has never been merged develop_master_point=`git merge-base $branch_prefix$master_branch $commit --fork-point` fi log "develop_master_point=$develop_master_point" + elif [ "$branch_name" != "$master_branch" ]; then head_develop_point=`git rev-list $branch_prefix$develop_branch --merges --before=\`git show -s --format=%ct $commit\` --first-parent --max-count=1` - if [ -z $head_develop_point ]; then - # has never been merged, - head_develop_point=`git merge-base $branch_prefix$develop_branch $commit --fork-point` + if [ -z $head_develop_point ]; then # has never been merged + head_develop_point=$(git merge-base $branch_prefix$develop_branch $commit --fork-point) fi + log "head_develop_point=$head_develop_point" develop_master_point=`git rev-list $branch_prefix$master_branch --merges --before=\`git show -s --format=%ct $head_develop_point\` --first-parent --max-count=1` - if [ -z $develop_master_point ]; then - # has never been merged, + if [ -z $develop_master_point ]; then # has never been merged develop_master_point=`git merge-base $branch_prefix$master_branch $head_develop_point --fork-point` fi log "develop_master_point=$develop_master_point" @@ -161,12 +166,15 @@ fi # Minor if [ "$minor_override" != "true" ]; then if [ "$branch_name" == "$master_branch" ]; then - minor=`git rev-list $first_commit..$commit --count --first-parent --ancestry-path` + minor=$( git rev-list "$first_commit..$commit" --count --first-parent --ancestry-path ) + elif [ "$branch_name" == "$develop_branch" ]; then - minor=`git rev-list $first_commit..$develop_master_point --count --first-parent --ancestry-path` + minor=$( git rev-list "$first_commit..$develop_master_point" --count --first-parent --ancestry-path ) + else - minor=`git rev-list $first_commit..$develop_master_point --count --first-parent --ancestry-path` + minor=$( git rev-list "$first_commit..$develop_master_point" --count --first-parent --ancestry-path ) fi + else log "Minor version override: $minor" fi @@ -175,11 +183,33 @@ fi if [ "$patch_override" != "true" ]; then if [ "$branch_name" == "$master_branch" ]; then patch=0 + elif [ "$branch_name" == "$develop_branch" ]; then - patch=`git rev-list $first_commit..$commit --count --first-parent --ancestry-path --not \`git rev-list $first_commit..$commit --before=\\\`git show -s --format=%ct $develop_master_point --first-parent --ancestry-path\\\`\`` + declare -r before=$( git show -s --format=%ct "$develop_master_point" --first-parent --ancestry-path ) + declare -r not=$( git rev-list "$first_commit..$commit" --before=$before | head -n 750 ) # its vital to trim the number of parameters to around 750 otherwise we will get an error below + + patch=$( \ + git \ + rev-list \ + "$first_commit..$commit" \ + --count \ + --first-parent \ + --ancestry-path \ + --not $not ) # do not doublequote $not as this will break the script + else - patch=`git rev-list $first_commit..$head_develop_point --count --first-parent --ancestry-path --not \`git rev-list $first_commit..$head_develop_point --before=\\\`git show -s --format=%ct $develop_master_point --first-parent --ancestry-path\\\`\`` + declare -r before=$( git show -s --format=%ct "$develop_master_point" --first-parent --ancestry-path ) + declare -r not=$( git rev-list "$first_commit..$head_develop_point" --before="$before" | head -n 750 ) # its vital to trim the number of parameters to around 750 otherwise we will get an error below + + patch=$( \ + git rev-list \ + "$first_commit..$head_develop_point" \ + --count \ + --first-parent \ + --ancestry-path \ + --not $not ) # do not doublequote $not as this will break the script fi + else log "Patch version override: $patch" fi diff --git a/azure-pipelines.yaml b/azure-pipelines.yaml index 958524f..236dec0 100644 --- a/azure-pipelines.yaml +++ b/azure-pipelines.yaml @@ -17,19 +17,19 @@ steps: fetchDepth: 0 persistCredentials: true - - task: DotNetCoreCLI@2 - displayName: 'dotnet workload install' + - task: Bash@3 + displayName: 'Setup Build Environment' inputs: - custom: 'workload' - command: 'custom' - arguments: 'install maui ios android' + filePath: 'Laerdal.Scripts/Laerdal.SetupBuildEnvironment.sh' + arguments: ' "https://pkgs.dev.azure.com/LaerdalMedical/_packaging/LaerdalNuGet/nuget/v3/index.json" "$(Laerdal.NugetFeed.Username)" "$(Laerdal.NugetFeed.AccessToken)" "$(Build.ArtifactStagingDirectory)" ' + targetType: 'filePath' - task: DotNetCoreCLI@2 - displayName: dotnet build + displayName: 'dotnet build' inputs: - projects: '$(Build.SourcesDirectory)/Laerdal.Build.targets' + projects: '$(Build.SourcesDirectory)/Laerdal.Scripts/Laerdal.Build.targets' arguments: '--verbosity detailed' configuration: 'Release' - - publish: $(Build.ArtifactStagingDirectory) - artifact: output + - publish: '$(Build.ArtifactStagingDirectory)' + artifact: 'output'