diff --git a/Laerdal.Dfu.Bindings.iOS.sln b/Laerdal.Dfu.Bindings.iOS.sln index 74fab34..d9391af 100644 --- a/Laerdal.Dfu.Bindings.iOS.sln +++ b/Laerdal.Dfu.Bindings.iOS.sln @@ -12,9 +12,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Misc", "_Misc", "{DB8D9BFF .github\workflows\github-actions.yml = .github\workflows\github-actions.yml Laerdal.Scripts\Laerdal.SetupBuildEnvironment.sh = Laerdal.Scripts\Laerdal.SetupBuildEnvironment.sh Laerdal.Scripts\Laerdal.CreateNewReleaseInGithub.sh = Laerdal.Scripts\Laerdal.CreateNewReleaseInGithub.sh - Laerdal.Scripts\Laerdal.Changelog.sh = Laerdal.Scripts\Laerdal.Changelog.sh Laerdal.Scripts\Laerdal.Builder.targets = Laerdal.Scripts\Laerdal.Builder.targets .gitignore = .gitignore + Laerdal.Scripts\Laerdal.GenerateSignAndUploadSbom.sh = Laerdal.Scripts\Laerdal.GenerateSignAndUploadSbom.sh EndProjectSection EndProject Global diff --git a/Laerdal.Scripts/Laerdal.Changelog.sh b/Laerdal.Scripts/Laerdal.Changelog.sh deleted file mode 100644 index 49e40ae..0000000 --- a/Laerdal.Scripts/Laerdal.Changelog.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/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 index f073f71..ffd8950 100644 --- a/Laerdal.Scripts/Laerdal.CreateNewReleaseInGithub.sh +++ b/Laerdal.Scripts/Laerdal.CreateNewReleaseInGithub.sh @@ -1,281 +1,135 @@ #!/bin/bash -# set -x +declare VERBOSE=0 +declare TAG_VERSION="" -declare project_name="" -declare project_version="" - -declare parent_project_name="" -declare parent_project_version="" - -declare csproj_file_path="" -declare csproj_classifier="" -declare output_directory_path="" -declare output_sbom_file_name="" -declare sbom_signing_key_file_path="" - -declare dependency_tracker_url="" -declare dependency_tracker_api_key_file_path="" +declare GIT_BRANCH="" +declare GITHUB_ACCESS_TOKEN="" +declare GITHUB_REPOSITORY_PATH="" function parse_arguments() { - while [[ $# -gt 0 ]]; do - case $1 in - - --project-name) - project_name="$2" - shift - ;; - - --project-version) - project_version="$2" - shift - ;; - - --parent-project-name) - parent_project_name="$2" - shift - ;; - - --parent-project-version) - parent_project_version="$2" - shift - ;; - - --csproj-file-path) - csproj_file_path="$2" - shift - ;; - - --csproj-classifier) - csproj_classifier="$2" - shift - ;; - - --output-directory-path) - output_directory_path="$2" - shift - ;; - - --output-sbom-file-name) - output_sbom_file_name="$2" - shift - ;; - - --sbom-signing-key-file-path) - sbom_signing_key_file_path="$2" - shift - ;; - - --dependency-tracker-url) - dependency_tracker_url="$2" - shift - ;; - - --dependency-tracker-api-key-file-path) - dependency_tracker_api_key_file_path="$2" + case $1 in + -v | --log) + VERBOSE=1 + # shift dont shift no need for this one + ;; + + -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 - ;; - - *) - echo "Unknown option: $1" - usage - exit 1 - ;; - esac - - shift - done - - if [[ -z ${project_name} ]]; then - echo "Specifying --project-name is mandatory!" - usage - exit 1 - fi + done - if [[ -z ${project_version} ]]; then - echo "Specifying --project-version is mandatory!" + if [[ -z $GIT_BRANCH ]]; then + echo "Missing git-branch." usage exit 1 fi - # if [[ -z ${parent_project_name} ]]; then this is optional - # ... - - # if [[ -z ${parent_project_version} ]]; then this is optional - # ... - - # if [[ -n ${parent_project_name} && -z ${parent_project_version} ]]; then # nah better not to enforce this - # echo "Specifying --parent-project-version is mandatory when --parent-project-name has been used!" - # usage - # exit 1 - # fi - - if [[ -z ${csproj_file_path} ]]; then - echo "Specifying --csproj-file-path is mandatory!" + if [[ -z $GITHUB_REPOSITORY_PATH ]]; then + echo "Missing github-repository." usage exit 1 fi - if [[ -z ${csproj_classifier} ]]; then - echo "Specifying --csproj-classifier is mandatory!" + if [[ -z $GITHUB_ACCESS_TOKEN ]]; then + echo "Missing github-access-token." usage exit 1 fi - if [[ -z ${output_directory_path} ]]; then - echo "Specifying --output-directory-path is mandatory!" - usage - exit 1 - fi + validate_tag_format "$TAG_VERSION" +} - if [[ -z ${output_sbom_file_name} ]]; then - echo "Specifying --output-sbom-file-name is mandatory!" - usage - exit 1 - fi - - if [[ -z ${sbom_signing_key_file_path} ]]; then - echo "Specifying --sbom-signing-key-file-path is mandatory!" - usage - exit 1 - fi - - if [[ -z ${dependency_tracker_url} ]]; then - echo "Specifying --dependency-tracker-url is mandatory!" - usage - exit 1 - fi +function validate_tag_format() { + local -r tag="$1" + local -r pattern='^[0-9]+\.[0-9]+(\.[0-9]+)?$' - if [[ -z ${dependency_tracker_api_key_file_path} ]]; then - echo "Specifying --dependency-tracker-api-key-file-path is mandatory!" - usage - exit 1 + 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} --project-name --project-version [--parent-project-name --parent-project-version ] --csproj-file-path --csproj-file-path --output-directory-path --output-sbom-file-name --sbom-signing-key-file-path --dependency-tracker-url --dependency-tracker-api-key-file-path " + echo "Usage: $script_name [--verbose|-v] [--repository-path|-r]= [--git-branch|-b]= [--access-token|-a]= [--tag-version|-t]=" } -function install_tools() { +function create_release_on_github() { + # https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release - echo - echo "** Installing CycloneDX as a dotnet tool:" - dotnet tool \ - install \ - --global CycloneDX - declare exitCode=$? - if [ $exitCode != 0 ]; then - echo "##vso[task.logissue type=error]Something went wrong with the CycloneDX tool for dotnet." - exit 10 - fi + 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" - echo - echo "** CycloneDX:" - which dotnet-CycloneDX && dotnet-CycloneDX --version - declare exitCode=$? - if [ $exitCode != 0 ]; then - echo "##vso[task.logissue type=error]Something's wrong with 'dotnet-CycloneDX'." - exit 12 - fi + 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" - # we need to install the CycloneDX tool too in order to sign the artifacts - curl --output cyclonedx --url https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.26.0/cyclonedx-osx-arm64 \ - && chmod +x cyclonedx - declare exitCode=$? - if [ $exitCode != 0 ]; then - echo "##vso[task.logissue type=error]Failed to install 'cyclonedx'." - exit 13 + 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 -} - -function generate_sign_and_upload_sbom() { - # set -x - - # GENERATE SBOM we intentionally disable package restore because the packages are already restored at this point - dotnet-CycloneDX "${csproj_file_path}" \ - --exclude-dev \ - --disable-package-restore \ - --include-project-references \ - \ - --output "${output_directory_path}" \ - --set-type "${csproj_classifier}" \ - --set-version "${project_version}" \ - \ - --filename "${output_sbom_file_name}" - declare exitCode=$? - if [ ${exitCode} != 0 ]; then - echo "##vso[task.logissue type=error]Failed to generate the SBOM!" - exit 20 + gh auth login --with-token <<<"$GITHUB_ACCESS_TOKEN" + local -r gh_auth_login_exit_code=$? + if [[ $gh_auth_login_exit_code -ne 0 ]]; then + exit_with_error "GitHub CLI exited with code '$gh_auth_login_exit_code' upon attempting to login using a github access token!" fi - - - # SIGN SBOM todo figure out why this doesnt actually sign anything on windows even though on macos it works as intended - declare -r bom_file_path="${output_directory_path}/${output_sbom_file_name}" - ./cyclonedx sign bom \ - "${bom_file_path}" \ - --key-file "${sbom_signing_key_file_path}" - declare exitCode=$? - if [ ${exitCode} != 0 ]; then - echo "##vso[task.logissue type=error]Singing the SBOM failed!" - exit 30 + gh release create "$eventual_tag_name" \ + --title "$eventual_singleline_summary" \ + --target "$GIT_BRANCH" \ + --generate-notes + local -r gh_create_release_exit_code=$? + if [[ $gh_create_release_exit_code -ne 0 ]]; then + exit_with_error "GitHub CLI exited with code '$gh_create_release_exit_code' upon attempting to create a new release!" fi - # echo -e "\n\n" - # tail "${bom_file_path}" - # echo -e "\n\n" - +} - # UPLOAD SBOM - declare optional_parent_project_name_parameter="" - if [[ -n ${parent_project_name} ]]; then - optional_parent_project_name_parameter="--form parentName=${parent_project_name}" - fi - - declare optional_parent_project_version_parameter="" - if [[ -n ${parent_project_version} ]]; then - optional_parent_project_version_parameter="--form parentVersion=${parent_project_version}" +function log() { + if [[ $VERBOSE -ne 0 ]]; then + echo -e "$*" fi +} - declare -r http_response_code=$( \ - curl "${dependency_tracker_url}" \ - --location \ - --request "POST" \ - \ - --header "Content-Type: multipart/form-data" \ - --header "X-API-Key: $(cat "${dependency_tracker_api_key_file_path}")" \ - \ - --form "bom=@${bom_file_path}" \ - --form "autoCreate=true" \ - \ - --form "projectName=${project_name}" \ - --form "projectVersion=${project_version}" \ - \ - ${optional_parent_project_name_parameter} \ - ${optional_parent_project_version_parameter} \ - \ - -w "%{http_code}" \ - ) - declare exitCode=$? - set +x - - echo "** Curl sbom-uploading HTTP Response Code: ${http_response_code}" - - if [ ${exitCode} != 0 ]; then - echo "##vso[task.logissue type=error]SBOM Uploading failed!" - exit 40 - fi +function exit_with_error() { + echo "Error: $1" + exit 1 } function main() { parse_arguments "$@" - install_tools - generate_sign_and_upload_sbom + create_release_on_github } main "$@"