diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..0978ab1
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,22 @@
+# Description
+
+
+
+# Testing
+
+
+
+# Pull Request Type
+
+Please select the option(s) that are relevant to this PR.
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] Improvement (fixing a typo, updating readme, renaming a variable name, etc)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5846b00..3031d32 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,69 +11,84 @@ jobs:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
+
- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
- dotnet-version: |
- 3.1.x
- 5.x.x
- 6.x.x
- 7.x.x
+ dotnet-version: 7.x.x
+
- name: Set up dotnet tools
run: make install-tools
- - name: Check dotnet Style
+
+ - name: Check style with dotnet-format
run: make lint
- security:
- runs-on: windows-2022
+
+ Security_Code_Scan:
+ runs-on: windows-latest
steps:
- uses: actions/checkout@v3
+
- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
- dotnet-version: |
- 3.1.x
- 5.x.x
- 6.x.x
- 7.x.x
- - name: Set up dotnet tools
- run: make install-tools
+ dotnet-version: 7.x.x
+
+ - name: Set up dotnet tools and dependencies
+ run: make install
+
- name: Run security analysis
run: make scan
- # TODO: In the future, we can collect the output logs by enabling Code Scanning and using the pre-built GitHub Action: https://github.com/marketplace/actions/securitycodescan
- # https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github#uploading-a-code-scanning-analysis-with-github-actions
- coverage:
- if: github.ref == 'refs/heads/master'
- runs-on: windows-2022
+
+ Coverage_Requirements:
+ runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
+
- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
- dotnet-version: |
- 3.1.x
- 5.x.x
- 6.x.x
- 7.x.x
+ dotnet-version: 7.x.x
+
+ - name: Set up dotnet tools and dependencies
+ run: make install
+
+ - name: Check if test suite coverage meets requirements
+ run: make coverage-check
+
+ Upload_Coverage_Report:
+ if: github.ref == 'refs/heads/master'
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v3
+
- name: Set up dotnet tools and dependencies
run: make install
+
- name: Generate coverage report
run: make coverage
+
- name: Upload lcov coverage report to Coveralls
uses: coverallsapp/github-action@master
with:
path-to-lcov: coveragereport/lcov.info
github-token: ${{ secrets.GITHUB_TOKEN }}
+
NET_Tests:
# derived from https://dev.to/felipetofoli/github-actions-for-net-full-framework-build-and-test-299h
runs-on: windows-2022
+ env:
+ EASYPOST_TEST_API_KEY: "123"
+ EASYPOST_PROD_API_KEY: "123"
strategy:
matrix:
- name: [ 'net462', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0' ]
+ name: [ 'net462', 'netstandard2.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0' ]
include:
- name: net462
- # This is really a test of .NET Standard, a bridge between .NET Framework and .NET, targeting .NET Framework 4.6.2
+ framework: net462
+ - name: netstandard2.0
+ # can't run tests on .NET Standard, it's just a bridge between .NET Framework and .NET.
+ # So we'll target .NET Framework 4.6.2
# More notes at the bottom of this file
- # Name chosen so we don't have to change the names of the required tests on GitHub Actions
framework: net462
- name: netcoreapp3.1
framework: netcoreapp3.1
@@ -87,21 +102,21 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
+
- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
+ # .NET 5 is deprecated and removed from GitHub Actions, we need to manually install it
dotnet-version: |
- 3.1.x
5.x.x
- 6.x.x
7.x.x
- # Install MSBuild, used to build the test project
+
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.1.2
- # Install NuGet.exe to restore required NuGet packages
+
- name: Setup Nuget
uses: NuGet/setup-nuget@v1.1.1
- # Load NuGet package cache
+
- name: Load NuGet package cache
uses: actions/cache@v3
with:
@@ -109,61 +124,83 @@ jobs:
key: ${{ runner.os }}-nuget-${{ matrix.framework }}-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-
- # Restore required NuGet packages
+
- name: Restore NuGet Packages
run: make restore
- # Run the framework-specific tests
+
+ # Pull in fixtures submodule
+ - name: Set up dotnet tools and dependencies
+ run: make install
+
+ # Run the unit tests in a specific framework (verify that the library works in that framework)
- name: Run Tests
run: make test-fw fw=${{ matrix.framework }}
- Compatibility_Tests:
+
+ FSharp_Compatibility:
runs-on: windows-2022
- strategy:
- matrix:
- lang: [ 'VB', 'FSharp' ]
- include:
- - lang: VB
- ext: vbproj
- - lang: FSharp
- ext: fsproj
steps:
- uses: actions/checkout@v3
with:
submodules: true
+
- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
- dotnet-version: |
- 3.1.x
- 5.x.x
- 6.x.x
- 7.x.x
- # Set the project name, based on platform version currently selected
- - name: Set up variables
- id: test_project
- run: echo "::set-output name=test_file::EasyVCR.Tests.${{ matrix.lang }}"
- # Install MSBuild, used to build the test project
+ dotnet-version: 7.x.x
+
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.1.2
- # Install NuGet.exe to restore required NuGet packages
+
- name: Setup Nuget
uses: NuGet/setup-nuget@v1.1.1
- # Install Visual Studio's console test application, to execute tests
+
- name: Setup VSTest
uses: darenm/Setup-VSTest@v1.2
- # Load NuGet package cache
- - name: Load NuGet package cache
- uses: actions/cache@v3
+
+ - name: Restore NuGet Packages
+ run: make restore
+
+ # Pull in fixtures submodule
+ - name: Set up dotnet tools and dependencies
+ run: make install
+
+ # Build the test project
+ - name: Build Solution
+ run: msbuild EasyVCR.Tests.FSharp\EasyVCR.Tests.FSharp.fsproj /p:platform="Any CPU" /p:configuration="Debug" /p:outputPath="bin/Test" /p:target="Rebuild" -restore
+
+ Visual_Basic_Compatibility:
+ runs-on: windows-2022
+ steps:
+
+ - uses: actions/checkout@v3
with:
- path: ~/.nuget/packages
- key: ${{ runner.os }}-nuget-${{ matrix.framework }}-${{ hashFiles('**/packages.lock.json') }}
- restore-keys: |
- ${{ runner.os }}-nuget-
- # Restore required NuGet packages
+ submodules: true
+
+ - name: Install .NET SDK
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.x.x
+
+ - name: Setup MSBuild
+ uses: microsoft/setup-msbuild@v1.1.2
+
+ - name: Setup Nuget
+ uses: NuGet/setup-nuget@v1.1.1
+
+ - name: Setup VSTest
+ uses: darenm/Setup-VSTest@v1.2
+
- name: Restore NuGet Packages
run: make restore
+
+ # Pull in fixtures submodule
+ - name: Set up dotnet tools and dependencies
+ run: make install
+
# Build the test project
- name: Build Solution
- run: msbuild ${{ steps.test_project.outputs.test_file }}\${{ steps.test_project.outputs.test_file }}.${{ matrix.ext }} /p:platform="Any CPU" /p:configuration="Debug" /p:outputPath="bin/Test" /p:target="Rebuild" -restore
+ run: msbuild EasyVCR.Tests.VB\EasyVCR.Tests.VB.vbproj /p:platform="Any CPU" /p:configuration="Debug" /p:outputPath="bin/Test" /p:target="Rebuild" -restore
+
# .NET Standard notes:
# - NET Standard 2.0 is compatible with minimum .NET Framework 4.6.1: https://docs.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0
diff --git a/EasyPost.pub b/EasyPost.pub
deleted file mode 100644
index a444a81..0000000
Binary files a/EasyPost.pub and /dev/null differ
diff --git a/EasyPostNETStrongNameSigning.pub b/EasyPostNETStrongNameSigning.pub
new file mode 100644
index 0000000..26cb33c
Binary files /dev/null and b/EasyPostNETStrongNameSigning.pub differ
diff --git a/EasyVCR/EasyVCR.csproj b/EasyVCR/EasyVCR.csproj
index 692ae39..50ff3fb 100644
--- a/EasyVCR/EasyVCR.csproj
+++ b/EasyVCR/EasyVCR.csproj
@@ -43,7 +43,7 @@
true
true
- ..\EasyPost.pub
+ ..\EasyPostNETStrongNameSigning.pub
diff --git a/Makefile b/Makefile
index 6c949a1..d15fc08 100644
--- a/Makefile
+++ b/Makefile
@@ -2,19 +2,23 @@
help:
@cat Makefile | grep '^## ' --color=never | cut -c4- | sed -e "`printf 's/ - /\t- /;'`" | column -s "`printf '\t'`" -t
+## analyze - Run static analysis for the project (check CA rule violations)
+analyze:
+ dotnet build EasyVCR/EasyVCR.csproj -c "Release" -t:Rebuild -restore -p:EnableNETAnalyzers=true -p:CodeAnalysisTreatWarningsAsErrors=true -p:RunAnalyzersDuringBuild=true -p:AnalysisLevel=latest -p:AnalysisMode=Minimum
+
## build - Build the project in Debug mode
build:
- dotnet msbuild -property:Configuration="Debug" -target:Rebuild -restore
+ dotnet build EasyVCR/EasyVCR.csproj -c "Debug" -t:Rebuild -restore -p:EnableNETAnalyzers=false
-## build-test-fw - Build the project for unit testing in Debug mode for a specific framework
+## build-fw - Build the project in Debug mode for a specific framework
# @parameters:
# fw= - The framework to build for.
-build-test-fw:
- dotnet msbuild EasyVCR.Tests/EasyVCR -property:Configuration="Debug" -target:Rebuild -restore -property:TargetFramework=${fw}
+build-fw:
+ dotnet build EasyVCR/EasyVCR.csproj -c "Debug" -t:Rebuild -restore -f ${fw} -p:EnableNETAnalyzers=false
## build-prod - Build the project in Release mode
build-prod:
- dotnet msbuild -property:Configuration="Release" -target:Rebuild -restore
+ dotnet build EasyVCR/EasyVCR.csproj -c "Release" -t:Rebuild -restore -p:EnableNETAnalyzers=false
## clean - Clean the project
clean:
@@ -23,58 +27,54 @@ clean:
## coverage - Generate coverage reports for the project
coverage:
- ./generate_test_reports.sh
+ bash scripts/unix/generate_test_reports.sh
+
+## coverage-check - Check if the coverage is above the minimum threshold
+coverage-check:
+ bash scripts/unix/check_coverage.sh 88
+
+## docs - Generates library documentation
+docs:
+ dotnet tool run docfx docs/docfx.json
## format - Formats the project
format:
- dotnet dotnet-format --no-restore
-
-## install-cert - Install the PFX certificate to your system (Windows only)
-# @parameters:
-# cert= - The certificate to use for signing the built assets.
-# pass= - The password for the certificate.
-install-cert:
- scripts\install_cert.bat ${cert} ${pass}
+ dotnet tool run dotnet-format --no-restore
## install-tools - Install required dotnet tools
install-tools:
dotnet new tool-manifest || exit 0
dotnet tool install --local security-scan --version 5.6.3 || exit 0
dotnet tool install --local dotnet-format || exit 0
+ dotnet tool install --local docfx --version 2.60.2 || exit 0
+
+## install-release-tools - Install required tools for release
+install-release-tools:
+ bash scripts/unix/install_osslsigncode.sh
## install - Install requirements
install: | install-tools
git submodule init
git submodule update
-## lint - Lints the project
+## lint - Lints the solution (EasyVCR + Tests + F#/VB samples) (check IDE and SA rule violations)
lint:
- dotnet dotnet-format --no-restore --check
+ # Lint the source code with dotnet-format
+ dotnet tool run dotnet-format --no-restore --check
+ # Lint the source code by building with the "Linting" configuration (will trigger StyleCop)
+ dotnet build EasyVCR/EasyVCR.csproj -c "Linting" -t:Rebuild -restore -p:EnforceCodeStyleInBuild=true
## lint-scripts - Lint and validate the Batch scripts (Windows only)
lint-scripts:
- scripts\lint_scripts.bat
+ scripts\win\lint_scripts.bat
-## prep-release - Build, sign and package the project for distribution, signing with the provided certificate (Windows only)
+## prep-release - Build, sign and package the project for distribution, signing with the provided certificate
# @parameters:
-# cert= - The certificate to use for signing the built assets.
-# pass= - The password for the certificate.
+# sncert= - The strong-name certificate to use for signing the built assets.
+# cert= - The authenticity certificate to use for signing the built assets.
+# pass= - The password for the authenticity certificate.
prep-release:
- scripts\build_release_nuget.bat EasyVCR ${cert} ${pass} EasyPost Release
-
-## publish-all - Publish all NuGet files to nuget.org.
-# WARNING: Will publish ALL discovered NuGet files.
-# @parameters:
-# key= - The API key for nuget.org
-publish-all:
- scripts\publish_all_nuget.bat ${key}
-
-## publish - Publish a specific NuGet file to nuget.org (Windows only)
-# @parameters:
-# file= - The NuGet file to publish
-# key= - The API key for nuget.org
-publish:
- scripts\publish_nuget.bat ${file} ${key}
+ bash scripts/unix/build_release_nuget.sh EasyVCR ${sncert} ${cert} ${pass} Release
## release - Cuts a release for the project on GitHub (requires GitHub CLI)
# tag = The associated tag title of the release
@@ -85,27 +85,18 @@ release:
restore:
dotnet restore
-## scan - Scan the project for security issues (must run install-scanner first)
-# Makefile cannot access global dotnet tools, so you need to run the below command manually.
+## scan - Scan the solution (EasyVCR + Tests + F#/VB samples) for security issues (must run install-scanner first)
scan:
dotnet tool run security-scan --verbose --no-banner --ignore-msbuild-errors EasyVCR.sln
# "--ignore-msbuild-errors" needed since MSBuild does not like F#: https://github.com/security-code-scan/security-code-scan/issues/235
## setup-win - Install required .NET versions and tools (Windows only)
setup-win:
- scripts\setup.bat
+ scripts\win\setup.bat
## setup-unix - Install required .NET versions and tools (Unix only)
setup-unix:
- bash scripts/setup.sh
-
-## sign - Sign all generated DLLs and NuGet packages with the provided certificate (Windows only)
-# @parameters:
-# cert= - The certificate to use for signing the built assets.
-# pass= - The password for the certificate.
-sign:
- install-cert cert=${cert} pass=${pass}
- scripts\sign_assemblies.bat ${cert} ${pass} EasyPost
+ bash scripts/unix/setup.sh
## test - Test the project
test:
@@ -118,8 +109,4 @@ test-fw:
# Note, running .NET Framework tests on a non-Windows machine may cause issues: https://xunit.net/docs/getting-started/netfx/cmdline
dotnet test EasyVCR.Tests/EasyVCR.Tests.csproj -f ${fw}
-## uninstall-scanner - Uninstall SecurityCodeScan from your system
-uninstall-scanner:
- dotnet tool uninstall security-scan
-
-.PHONY: help build build-test-fw build-prod clean coverage format install-cert install-tools install lint lint-scripts pre-release publish-all publish release restore scan setup-unix setup-win sign test test-fw uninstall-scanner
\ No newline at end of file
+.PHONY: help analyze build build-fw build-prod clean coverage coverage-check docs format install-tools install-release-tools install lint lint-scripts prep-release release restore scan setup-win setup-unix test test-fw
diff --git a/certificate info.txt b/certificate info.txt
deleted file mode 100644
index 203a098..0000000
--- a/certificate info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Build in Release mode (signs with SNK file during build)
-
-Validate with Strong Type tool: https://github.com/brutaldev/StrongNameSigner
-
-Sign each DLL with PFX file: signtool sign /f EasyPost.pfx /p PASSWORD /v /tr http://timestamp.digicert.com?alg=sha256 /td SHA256 /fd SHA256 FILE_PATH
-(https://www.tbs-certificates.co.uk/FAQ/en/550.html)
-
-Check for Digital Signature in File Explorer details
-
-Package into Nuget file
-
-Sign Nuget file with PFX via nuget sign
\ No newline at end of file
diff --git a/generate_test_reports.sh b/generate_test_reports.sh
deleted file mode 100755
index 18d2696..0000000
--- a/generate_test_reports.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# install reportgenerator if not already installed
-dotnet tool install --global dotnet-reportgenerator-globaltool --version 5.1.10 || true # exit 0 will kill the script, not what we want
-
-# check requirements
-set -- dotnet reportgenerator
-for req in "$@"; do
- if ! command -v "$req" >/dev/null 2>&1; then
- echo "$req could not be found"
- exit
- fi
-done
-
-# Generate Cobertura report for each test project
-test_folder="EasyVCR.Tests"
-cd "$test_folder" || exit
-dotnet test --collect:"XPlat Code Coverage"
-
-# Generate HTML and lcov report
-reportgenerator -reports:TestResults/*/coverage.cobertura.xml -targetdir:../coveragereport -reporttypes:Html
-reportgenerator -reports:TestResults/*/coverage.cobertura.xml -targetdir:../coveragereport -reporttypes:lcov
diff --git a/scripts/install_cert.bat b/scripts/install_cert.bat
deleted file mode 100644
index a55f7e1..0000000
--- a/scripts/install_cert.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-:: This script will install a provided PFX certificate to the system.
-
-:: Requirements:
-:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet)
-:: - SnInstallPfx (https://github.com/honzajscz/SnInstallPfx) is installed on the machine and is accessible everywhere (added to PATH)
-
-@ECHO OFF
-
-:: Parse command line arguments
-SET certFile=%1
-SET certPass=%2
-SET containerName=%3
-
-:: Install certificate
-@ECHO:
-@ECHO (Re-)Installing certificate to system...
-sn -d %containerName%
-SnInstallPfx %certFile% %certPass% %containerName% || GOTO :commandFailed
-
-EXIT /B 0
-
-:commandFailed
-@ECHO Command failed.
-GOTO :exitWithError
-
-:exitWithError
-@ECHO Exiting...
-EXIT /B 1
diff --git a/scripts/publish_all_nuget.bat b/scripts/publish_all_nuget.bat
deleted file mode 100644
index 9163a47..0000000
--- a/scripts/publish_all_nuget.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-:: This script will find and publish any NuGet packages to Nuget.org
-
-:: Requirements:
-:: - NuGet is installed on the machine and is accessible everywhere (added to PATH)
-
-@ECHO OFF
-
-:: Parse command line arguments
-SET apiKey=%1
-
-:: Find all NuGet packages
-@ECHO:
-@ECHO Finding NuGet package(s)...
-FOR /R %%F IN (*.nupkg) DO (
- @ECHO Found %%F. Publishing...
- nuget push "%%F" -src https://api.nuget.org/v3/index.json -ApiKey %apiKey%
-)
-
-EXIT /B 0
-
-:commandFailed
-@ECHO Command failed.
-GOTO :exitWithError
-
-:exitWithError
-@ECHO Exiting...
-EXIT /B 1
diff --git a/scripts/unix/build_project.sh b/scripts/unix/build_project.sh
new file mode 100755
index 0000000..cb63f26
--- /dev/null
+++ b/scripts/unix/build_project.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This script will restore and build a .NET project in a specified mode and platform.
+
+# Requirements:
+# - dotnet is installed on the machine and is accessible everywhere (added to PATH)
+
+# Parse command line arguments
+BUILD_MODE=$1
+
+# Restore dependencies and build solution
+echo "Restoring and building project..."
+dotnet msbuild -property:Configuration="$BUILD_MODE" -target:Rebuild -restore || exit 1
diff --git a/scripts/unix/build_release_nuget.sh b/scripts/unix/build_release_nuget.sh
new file mode 100755
index 0000000..33f119c
--- /dev/null
+++ b/scripts/unix/build_release_nuget.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# This script will build a .NET project in Release mode, sign the generated DLLs with a provided PFX certificate,
+# package the DLLs into a NuGet package, and sign the NuGet package with the provided PFX certificate.
+# This script also handles pre-run cleanup (will delete old DLLs and NuGet package files)
+
+# Requirements:
+# - NuGet is installed on the machine and is accessible everywhere (added to PATH)
+# - dotnet is installed on the machine and is accessible everywhere (added to PATH)
+# - osslsigncode (https://github.com/mtrojnar/osslsigncode) is installed on the machine and is accessible everywhere (added to PATH)
+
+# Parse command line arguments
+PROJECT_NAME=$1
+STRONG_NAME_CERT_FILE=$2
+AUTH_CERT_FILE=$3
+AUTH_CERT_PASSWORD=$4
+BUILD_MODE=$5
+
+# Delete old files
+bash scripts/unix/delete_old_assemblies.sh
+
+# Restore dependencies and build solution
+bash scripts/unix/build_project.sh "$BUILD_MODE" || exit 1
+
+# Strong-name sign the DLLs
+bash scripts/unix/strong_name_dlls.sh "$STRONG_NAME_CERT_FILE" || exit 1
+
+# Sign the DLLs for authenticity
+bash scripts/unix/sign_dlls.sh "$AUTH_CERT_FILE" "$AUTH_CERT_PASSWORD" || exit 1
+
+# Package the DLLs into a NuGet package (will fail if DLLs are missing)
+bash scripts/unix/pack_nuget.sh "$PROJECT_NAME" || exit 1
+
+# Sign the NuGet package for authenticity
+bash scripts/unix/sign_nuget.sh "$AUTH_CERT_FILE" "$AUTH_CERT_PASSWORD" || exit 1
+
+# Preset final information
+NUGET_PACKAGE_FILE=$(find lib -name "*.nupkg")
+echo "NuGet file $NUGET_PACKAGE_FILE is ready."
diff --git a/scripts/unix/check_coverage.sh b/scripts/unix/check_coverage.sh
new file mode 100755
index 0000000..39cb0b8
--- /dev/null
+++ b/scripts/unix/check_coverage.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+FRAMEWORK="net7.0"
+
+THRESHOLD=$1
+THRESHOLD_TYPE=line
+
+
+# Navigate to the test folder
+TEST_FOLDER="EasyVCR.Tests"
+cd "$TEST_FOLDER" || exit
+
+# Coverlet as a global tool does not report coverage properly (https://github.com/coverlet-coverage/coverlet/blob/2b8a4565b101ca70c3eaa9b5228c449dd3b81ad1/Documentation/GlobalTool.md)
+# Instead, use the coverlet.msbuild package
+# https://codeburst.io/code-coverage-in-net-core-projects-c3d6536fd7d7
+# This will fail to run on machines without MSBuild installed
+
+# If the coverage is below the threshold, exit with a non-zero exit code
+dotnet test -p:CollectCoverage=true -p:CoverletOutput=TestResults/ -f $FRAMEWORK -p:Threshold="$THRESHOLD" -p:ThresholdType=$THRESHOLD_TYPE
diff --git a/scripts/unix/delete_old_assemblies.sh b/scripts/unix/delete_old_assemblies.sh
new file mode 100755
index 0000000..de420d3
--- /dev/null
+++ b/scripts/unix/delete_old_assemblies.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# This script will delete any DLLs and NuGet packages
+
+# Delete old DLLs
+echo "Cleaning old files..."
+rm -rf lib
+rm -rf "*.nupkg"
diff --git a/scripts/unix/generate_test_reports.sh b/scripts/unix/generate_test_reports.sh
new file mode 100755
index 0000000..6d70eac
--- /dev/null
+++ b/scripts/unix/generate_test_reports.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+FRAMEWORK="net7.0"
+
+# Navigate to the test folder
+TEST_FOLDER="EasyVCR.Tests"
+cd "$TEST_FOLDER" || exit
+
+RESULTS_FOLDER="TestResults"
+
+# Delete old test results
+rm -rf "$RESULTS_FOLDER"
+
+# Generate coverage report
+# https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test#:~:text=To%20collect%20code%20coverage%20on%20any%20platform%20that%20is%20supported%20by%20.NET%20Core%2C
+dotnet test --collect:"XPlat Code Coverage" -f $FRAMEWORK
+
+# install reportgenerator if not already installed
+dotnet tool install --global dotnet-reportgenerator-globaltool --version 5.1.10 || true # exit 0 will kill the script, not what we want
+
+# check reportgenerator is available
+set -- dotnet reportgenerator
+for req in "$@"; do
+ if ! command -v "$req" >/dev/null 2>&1; then
+ echo "$req could not be found"
+ exit
+ fi
+done
+
+COVERAGE_REPORT_FOLDER="../coveragereport"
+
+# Delete old coverage reports
+rm -rf "$COVERAGE_REPORT_FOLDER"
+
+# Generate HTML and lcov report
+reportgenerator -reports:$RESULTS_FOLDER/*/coverage.cobertura.xml -targetdir:$COVERAGE_REPORT_FOLDER -reporttypes:Html
+reportgenerator -reports:$RESULTS_FOLDER/*/coverage.cobertura.xml -targetdir:$COVERAGE_REPORT_FOLDER -reporttypes:lcov
diff --git a/scripts/unix/install_osslsigncode.sh b/scripts/unix/install_osslsigncode.sh
new file mode 100644
index 0000000..f5c6eb3
--- /dev/null
+++ b/scripts/unix/install_osslsigncode.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# This script will install the osslsigncode dependency (https://github.com/mtrojnar/osslsigncode) required to release this project
+
+PATH_STORAGE=/usr/local/bin
+
+# Create a temporary folder
+TEMP_FOLDER="temp"
+mkdir -p "$TEMP_FOLDER"
+cd "$TEMP_FOLDER" || exit
+
+# Download the latest macOS release
+# Courtesy: https://gist.github.com/steinwaywhw/a4cd19cda655b8249d908261a62687f8
+REPO="mtrojnar/osslsigncode"
+curl -s https://api.github.com/repos/$REPO/releases/latest \
+| grep "browser_download_url.*macOS.zip" \
+| cut -d : -f 2,3 \
+| tr -d \" \
+| wget -qi -
+
+# Find the file name of the downloaded file
+ZIP_FILE=$(find . -name "*macOS.zip")
+
+# Unzip the file
+unzip "$ZIP_FILE"
+
+# Find the executable
+OSSLSIGNCODE_EXE=$(find . -name "osslsigncode")
+
+# Make the executable executable
+chmod +x "$OSSLSIGNCODE_EXE"
+
+# Move the executable to the PATH_STORAGE folder
+mv "$OSSLSIGNCODE_EXE" "$PATH_STORAGE"
+
+# Clean up
+cd ..
+rm -rf "$TEMP_FOLDER"
diff --git a/scripts/unix/pack_nuget.sh b/scripts/unix/pack_nuget.sh
new file mode 100755
index 0000000..186efb3
--- /dev/null
+++ b/scripts/unix/pack_nuget.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This script will generate a NuGet package according the the project's .nuspec file.
+
+# Requirements:
+# - NuGet is installed on the machine and is accessible everywhere (added to PATH)
+
+# Parse command line arguments
+PROJECT_NAME=$1
+
+# Generate the NuGet package (will fail if assemblies are missing)
+echo "Generating NuGet package..."
+nuget pack "$PROJECT_NAME.nuspec" || exit 1
diff --git a/scripts/setup.sh b/scripts/unix/setup.sh
similarity index 76%
rename from scripts/setup.sh
rename to scripts/unix/setup.sh
index a93e21c..b6bbf60 100644
--- a/scripts/setup.sh
+++ b/scripts/unix/setup.sh
@@ -3,7 +3,7 @@
# This script is used to download and install the required .NET versions
# .NET versions we want to install
-declare -a NetVersions=("Current" "6.0" "5.0" "3.1")
+declare -a NetVersions=("Current" "7.0" "6.0" "5.0" "3.1")
# Download dotnet-install.sh
echo "Downloading dotnet-install.sh script..."
@@ -12,8 +12,8 @@ curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
# Install each .NET version
echo "Installing .NET versions..."
for version in ${NetVersions[@]}; do
- echo "Installing .NET $version..."
- sudo bash ./dotnet-install.sh -c "$version"
+ echo "Installing .NET $version..."
+ sudo bash ./dotnet-install.sh -c "$version"
done
# Remove dotnet-install.sh
diff --git a/scripts/unix/sign_dlls.sh b/scripts/unix/sign_dlls.sh
new file mode 100755
index 0000000..c4e2f29
--- /dev/null
+++ b/scripts/unix/sign_dlls.sh
@@ -0,0 +1,23 @@
+# Parse command line arguments
+CERT_FILE=$1
+CERT_PASSWORD=$2
+
+# Set variables
+AUTHOR_NAME="EasyPost"
+AUTHOR_URL="http://www.easypost.com"
+TIMESTAMP_SERVER="http://timestamp.digicert.com?alg=sha256"
+FOLDER="lib"
+SUFFIX=".signed"
+FILE_PATTERN="*.dll"
+
+# Sign all DLLs found with our certificate to guarantee authenticity
+echo "Signing DLLs with $CERT_FILE for authenticity..."
+for file in $(find "$FOLDER" -name "$FILE_PATTERN"); do
+ echo "Signing $file..."
+ # Sign the file to a new file with added suffix
+ osslsigncode sign -pkcs12 "$CERT_FILE" -pass "$CERT_PASSWORD" -n "$AUTHOR_NAME" -i "$AUTHOR_URL" -ts "$TIMESTAMP_SERVER" -in "$file" -out "$file$SUFFIX"
+ # Delete original file
+ rm -f "$file"
+ # Rename signed file to original name
+ mv "$file$SUFFIX" "$file"
+done
diff --git a/scripts/unix/sign_nuget.sh b/scripts/unix/sign_nuget.sh
new file mode 100755
index 0000000..b3ea7ff
--- /dev/null
+++ b/scripts/unix/sign_nuget.sh
@@ -0,0 +1,21 @@
+# This script will find and sign any NuGet packages with a provided PFX certificate for authenticity
+
+# Requirements:
+# - NuGet is installed on the machine and is accessible everywhere (added to PATH)
+
+# Parse command line arguments
+CERT_FILE=$1
+CERT_PASSWORD=$2
+
+# Set variables
+TIMESTAMP_SERVER="http://timestamp.digicert.com?alg=sha256"
+FOLDER="."
+FILE_PATTERN="*.nupkg"
+
+# Sign all NuGet packages found with our certificate to guarantee authenticity
+echo "Signing NuGet packages with $CERT_FILE for authenticity..."
+# Should only be one .nupkg file at this point, since we deleted the old ones
+for file in $(find "$FOLDER" -name "$FILE_PATTERN"); do
+ # Sign the file in-place
+ dotnet nuget sign "$file" --timestamper "$TIMESTAMP_SERVER" --certificate-path "$CERT_FILE" --certificate-password "$CERT_PASSWORD"
+done
diff --git a/scripts/unix/strong_name_dlls.sh b/scripts/unix/strong_name_dlls.sh
new file mode 100755
index 0000000..b6920de
--- /dev/null
+++ b/scripts/unix/strong_name_dlls.sh
@@ -0,0 +1,20 @@
+# This script will find and finish strong-naming any DLLs with a provided PFX certificate
+
+# Requirements:
+# - dotnet is installed on the machine and is accessible everywhere (added to PATH)
+# - sn is installed on the machine and is accessible everywhere (added to PATH)
+
+# Parse command line arguments
+CERT_FILE=$1
+
+# Set variables
+FOLDER="lib"
+FILE_PATTERN="*.dll"
+
+# Strong-name all DLLs found in the lib folder
+echo "Strong-naming (finishing delayed signing) DLLs with $CERT_FILE..."
+for file in $(find "$FOLDER" -name "$FILE_PATTERN"); do
+ echo "Strong-naming $file..."
+ # Strong-name the file to a new file with added suffix
+ sn -R "$file" "$CERT_FILE"
+done
diff --git a/scripts/build_project.bat b/scripts/win/build_project.bat
similarity index 100%
rename from scripts/build_project.bat
rename to scripts/win/build_project.bat
diff --git a/scripts/build_release_nuget.bat b/scripts/win/build_release_nuget.bat
similarity index 58%
rename from scripts/build_release_nuget.bat
rename to scripts/win/build_release_nuget.bat
index 6405d40..2ee1f2e 100644
--- a/scripts/build_release_nuget.bat
+++ b/scripts/win/build_release_nuget.bat
@@ -5,34 +5,33 @@
:: Requirements:
:: - NuGet is installed on the machine and is accessible everywhere (added to PATH)
:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet)
-:: - SnInstallPfx (https://github.com/honzajscz/SnInstallPfx) is installed on the machine and is accessible everywhere (added to PATH)
@ECHO OFF
:: Parse command line arguments
SET projectName=%1
-SET certFile=%2
-SET certPass=%3
-SET containerName=%4
+SET strongNameCertFile=%2
+SET authCertFile=%3
+SET authCertPass=%4
SET buildMode=%5
:: Delete old files
-CALL "scripts\delete_old_assemblies.bat"
-
-:: Install certificate (needed to automate signing later on)
-CALL "scripts\install_cert.bat" %certFile% %certPass% %containerName% || GOTO :commandFailed
+CALL "scripts\win\delete_old_assemblies.bat"
:: Restore dependencies and build solution
-CALL "scripts\build_project.bat" %buildMode% || GOTO :commandFailed
+CALL "scripts\win\build_project.bat" %buildMode% || GOTO :commandFailed
+
+:: Strong-name the DLLs
+CALL "scripts\win\strong_name_dlls.bat" %strongNameCertFile% || GOTO :commandFailed
-:: Sign the DLLs
-CALL "scripts\sign_dlls.bat" %certFile% %certPass% %containerName% || GOTO :commandFailed
+:: Sign the DLLs for authenticity
+CALL "scripts\win\sign_dlls.bat" %authCertFile% %authCertPass% || GOTO :commandFailed
:: Package the DLLs in a NuGet package (will fail if DLLs are missing)
-CALL "scripts\pack_nuget.bat" %projectName% || GOTO :commandFailed
+CALL "scripts\win\pack_nuget.bat" %projectName% || GOTO :commandFailed
-:: Sign the NuGet package
-CALL "scripts\sign_nuget.bat" %certFile% %certPass% || GOTO :commandFailed
+:: Sign the NuGet package for authenticity
+CALL "scripts\win\sign_nuget.bat" %authCertFile% %authCertPass% || GOTO :commandFailed
SET nugetFileName=
FOR /R %%F IN (*.nupkg) DO (
SET nugetFileName="%%F"
@@ -51,7 +50,7 @@ GOTO :eof
:usage
@ECHO:
-@ECHO Usage: %0
+@ECHO Usage: %0
GOTO :exitWithError
:commandFailed
diff --git a/scripts/delete_old_assemblies.bat b/scripts/win/delete_old_assemblies.bat
similarity index 100%
rename from scripts/delete_old_assemblies.bat
rename to scripts/win/delete_old_assemblies.bat
diff --git a/scripts/lint_scripts.bat b/scripts/win/lint_scripts.bat
similarity index 100%
rename from scripts/lint_scripts.bat
rename to scripts/win/lint_scripts.bat
diff --git a/scripts/pack_nuget.bat b/scripts/win/pack_nuget.bat
similarity index 90%
rename from scripts/pack_nuget.bat
rename to scripts/win/pack_nuget.bat
index 39aae30..3d77ac2 100644
--- a/scripts/pack_nuget.bat
+++ b/scripts/win/pack_nuget.bat
@@ -5,6 +5,9 @@
@ECHO OFF
+:: Parse command line arguments
+SET projectName=%1
+
:: Generate a NuGet package (will fail if assemblies are missing)
@ECHO:
@ECHO Generating NuGet package...
diff --git a/scripts/publish_nuget.bat b/scripts/win/publish_nuget.bat
similarity index 100%
rename from scripts/publish_nuget.bat
rename to scripts/win/publish_nuget.bat
diff --git a/scripts/setup.bat b/scripts/win/setup.bat
similarity index 97%
rename from scripts/setup.bat
rename to scripts/win/setup.bat
index 13a95e1..310e44f 100644
--- a/scripts/setup.bat
+++ b/scripts/win/setup.bat
@@ -10,7 +10,7 @@
@ECHO OFF
:: .NET Versions we want to install and destination
-SET NetVersions=Current 6.0 5.0 3.1
+SET NetVersions=Current 7.0 6.0 5.0 3.1
SET InstallPath=C:\dotnet
:: Dependency file
diff --git a/scripts/sign_dlls.bat b/scripts/win/sign_dlls.bat
similarity index 63%
rename from scripts/sign_dlls.bat
rename to scripts/win/sign_dlls.bat
index 6e7a152..faaed89 100644
--- a/scripts/sign_dlls.bat
+++ b/scripts/win/sign_dlls.bat
@@ -1,22 +1,19 @@
-:: This script will find and sign any DLLs with a provided PFX certificate
+:: This script will find and sign any DLLs with a provided PFX certificate for authenticity
:: Requirements:
:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet)
+:: - signtool is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64)
@ECHO OFF
:: Parse command line arguments
SET certFile=%1
SET certPass=%2
-SET containerName=%3
-:: Sign all DLLs found in the lib folder
+:: Sign all DLLs found in the lib folder with our certificate to guarantee authenticity
@ECHO:
-@ECHO Signing DLLs with certificate...
+@ECHO Signing DLLs with %certFile% for authenticity...
FOR /R "lib" %%F IN (*.dll) DO (
- REM We need to run the DLLs through both sn.exe and signtool to get complete the signing process
- REM sn erroneously triggers command failed if we put a fallback on this
- sn -Rca "%%F" %containerName%
signtool sign /f %certFile% /p %certPass% /v /tr http://timestamp.digicert.com?alg=sha256 /td SHA256 /fd SHA256 "%%F" || GOTO :commandFailed
)
diff --git a/scripts/sign_nuget.bat b/scripts/win/sign_nuget.bat
similarity index 77%
rename from scripts/sign_nuget.bat
rename to scripts/win/sign_nuget.bat
index 4b109c4..c7190c3 100644
--- a/scripts/sign_nuget.bat
+++ b/scripts/win/sign_nuget.bat
@@ -1,4 +1,4 @@
-:: This script will find and sign any NuGet packages with a provided PFX certificate
+:: This script will find and sign any NuGet packages with a provided PFX certificate for authenticity
:: Requirements:
:: - NuGet is installed on the machine and is accessible everywhere (added to PATH)
@@ -9,9 +9,9 @@
SET certFile=%1
SET certPass=%2
-:: Sign all NuGet packages found
+:: Sign all NuGet packages found with our certificate to guarantee authenticity
@ECHO:
-@ECHO Signing NuGet package with %certFile%...
+@ECHO Signing NuGet package with %certFile% for authenticity...
:: Should only be one .nupkg file at this point, since we deleted the old ones
FOR /R %%F IN (*.nupkg) DO (
nuget sign "%%F" -Timestamper http://timestamp.digicert.com -CertificatePath "%certFile%" -CertificatePassword "%certPass%" || GOTO :commandFailed
diff --git a/scripts/win/strong_name_dlls.bat b/scripts/win/strong_name_dlls.bat
new file mode 100644
index 0000000..4d44c20
--- /dev/null
+++ b/scripts/win/strong_name_dlls.bat
@@ -0,0 +1,28 @@
+:: This script will find and finish strong-naming any DLLs with a provided PFX certificate
+
+:: Requirements:
+:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet)
+:: - sn.exe is installed on the machine and is accessible everywhere (added to PATH)
+
+@ECHO OFF
+
+:: Parse command line arguments
+SET certFile=%1
+
+:: Strong-name all DLLs found in the lib folder
+@ECHO:
+@ECHO Strong-naming (finishing delayed signing) DLLs with %certFile%...
+FOR /R "lib" %%F IN (*.dll) DO (
+ REM sn erroneously triggers command failed if we put a fallback on this
+ sn -Ra "%%F" %certFile%
+)
+
+EXIT /B 0
+
+:commandFailed
+@ECHO Command failed.
+GOTO :exitWithError
+
+:exitWithError
+@ECHO Exiting...
+EXIT /B 1