Skip to content

Port AKV, MST, and AAS extension packs with zero-copy adaptation #1108

Port AKV, MST, and AAS extension packs with zero-copy adaptation

Port AKV, MST, and AAS extension packs with zero-copy adaptation #1108

Workflow file for this run

#### Build, Test, and Publish ####
# This is the main workflow for the CoseSignTool project. It handles the following events:
# - Pull requests: When a user submits a pull request, or pushes a commit to an existing pull request, this workflow
# - generates a changelog and commits it to the working branch, and then
# - builds and tests the code.
# - Pushes to the main branch: When a user pushes a commit to the main branch, this workflow
# - creates a semantically versioned tag,
# - creates a release with the new tag, and then
# - triggers the release portion of the workflow.
# - Releases: When a user creates a release, or a release is created in response to a push event, this workflow
# - builds, publishes, and zips the outputs, and then
# - uploads the zipped assets to the release.
name: Build, Test, and Publish
on:
pull_request:
branches: [ "**" ] # Trigger on all branches for pull requests.
push:
branches: [ "main" ] # Trigger on pushes to the main branch.
release:
types: [ created ] # Trigger on new releases.
workflow_dispatch: # Allow manual triggering from the Actions tab.
jobs:
#### CHANGE DETECTION ####
# Determine which paths changed so downstream jobs only run when relevant.
detect-changes:
name: detect-changes
runs-on: ubuntu-latest
outputs:
native: ${{ steps.filter.outputs.native }}
dotnet: ${{ steps.filter.outputs.dotnet }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check changed paths
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
native:
- 'native/**'
dotnet:
- '**/*.cs'
- '**/*.csproj'
- '**/*.sln'
- '*.props'
- '*.targets'
- 'Directory.Build.props'
- 'Directory.Packages.props'
- 'Nuget.config'
- 'global.json'
#### PULL REQUEST EVENTS ####
# Build and test the code.
build:
name: dotnet-build
needs: [ detect-changes ]
if: ${{ needs.detect-changes.outputs.dotnet == 'true' }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: windows-latest
dir_command: gci -Recurse
- os: ubuntu-latest
dir_command: ls -a -R
- os: macos-latest
runtime_id: osx-x64
dir_command: ls -a -R
- os: macos-latest
runtime_id: osx-arm64
dir_command: ls -a -R
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.0.x
# Show dotnet info for debugging architecture issues
- name: Show .NET info
run: dotnet --info
# Use the Dotnet Test command to load dependencies, build, and test the code.
# We have to run the test projects individually so CoseSignTool.Tests can run under arm64 on the Mac runner.
- name: Build and Test debug
id: build-test
run: |
dotnet build --configuration Debug CoseSignTool.sln
dotnet test --no-restore CoseSign1.Tests/CoseSign1.Tests.csproj
dotnet test --no-restore CoseSign1.Certificates.Tests/CoseSign1.Certificates.Tests.csproj
dotnet test --no-restore CoseSign1.Certificates.AzureArtifactSigning.Tests/CoseSign1.Certificates.AzureArtifactSigning.Tests.csproj
dotnet test --no-restore CoseSign1.Headers.Tests/CoseSign1.Headers.Tests.csproj
dotnet test --no-restore CoseIndirectSignature.Tests/CoseIndirectSignature.Tests.csproj
dotnet test --no-restore CoseSign1.Transparent.Tests/CoseSign1.Transparent.Tests.csproj
dotnet test --no-restore CoseSign1.Transparent.MST.Tests/CoseSign1.Transparent.MST.Tests.csproj
dotnet test --no-restore CoseHandler.Tests/CoseHandler.Tests.csproj
dotnet test --no-restore CoseSignTool.Tests/CoseSignTool.Tests.csproj
dotnet test --no-restore CoseSignTool.Abstractions.Tests/CoseSignTool.Abstractions.Tests.csproj
dotnet test --no-restore CoseSignTool.MST.Plugin.Tests/CoseSignTool.MST.Plugin.Tests.csproj
dotnet test --no-restore CoseSignTool.IndirectSignature.Plugin.Tests/CoseSignTool.IndirectSignature.Plugin.Tests.csproj
# Build Release to catch issues the internal ADO pipeline would hit (e.g. netstandard2.0 API surface differences).
- name: Build Release
run: dotnet build --configuration Release CoseSignTool.sln
# List the contents of the working directory to make sure all the artifacts are there.
- name: List working directory
run: ${{ matrix.dir_command }}
# ── Native Rust: lint, build, test, coverage ─────────────────────────
native-rust:
name: native-rust
needs: [ detect-changes ]
if: ${{ needs.detect-changes.outputs.native == 'true' }}
runs-on: windows-latest
env:
VCPKG_ROOT: C:\vcpkg
OPENSSL_DIR: C:\vcpkg\installed\x64-windows
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache vcpkg packages
uses: actions/cache@v4
with:
path: C:\vcpkg\installed
key: vcpkg-openssl-x64-windows-v1
- name: Install OpenSSL via vcpkg
shell: pwsh
run: |
if (Test-Path "$env:VCPKG_ROOT\installed\x64-windows\lib\libssl.lib") {
Write-Host "OpenSSL already cached" -ForegroundColor Green
} else {
& "$env:VCPKG_ROOT\vcpkg" install openssl:x64-windows
}
- name: Setup Rust (stable)
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
workspaces: native/rust -> target
- name: Rust format check
shell: pwsh
working-directory: native/rust
run: |
# Per-package to avoid Windows OS error 206 (command line too long)
$members = (cargo metadata --no-deps --format-version 1 | ConvertFrom-Json).packages.name
foreach ($pkg in $members) {
cargo fmt -p $pkg -- --check
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
# FFI crates with test=false exclude test files from cargo fmt.
# Check them directly with rustfmt.
Get-ChildItem -Path . -Filter '*.rs' -Recurse |
Where-Object { $_.FullName -match 'ffi[\\/]tests[\\/]' } |
ForEach-Object {
rustfmt --check $_.FullName
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
- name: Rust clippy
shell: pwsh
working-directory: native/rust
run: |
$env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH"
cargo clippy --workspace -- -D warnings
- name: Setup Rust (nightly, for coverage)
uses: dtolnay/rust-toolchain@nightly
with:
components: llvm-tools-preview
- name: Cache cargo-llvm-cov
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-llvm-cov*
key: cargo-llvm-cov-${{ runner.os }}
- name: Install cargo-llvm-cov
shell: pwsh
run: |
if (Get-Command cargo-llvm-cov -ErrorAction SilentlyContinue) {
Write-Host "cargo-llvm-cov already cached" -ForegroundColor Green
} else {
cargo install cargo-llvm-cov --locked
}
- name: Build Rust workspace
shell: pwsh
working-directory: native/rust
run: |
$env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH"
cargo build --workspace --exclude cose-openssl
- name: Test Rust workspace
shell: pwsh
working-directory: native/rust
run: |
$env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH"
cargo test --workspace --exclude cose-openssl
- name: Rust coverage (90% line gate)
shell: pwsh
working-directory: native/rust
run: |
$env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH"
pwsh -NoProfile -File collect-coverage.ps1 -NoHtml
# ── Native C/C++: build, test, coverage (ASAN) ────────────────────
native-c-cpp:
name: native-c-cpp
needs: [ detect-changes ]
if: ${{ needs.detect-changes.outputs.native == 'true' }}
runs-on: windows-latest
env:
VCPKG_ROOT: C:\vcpkg
OPENSSL_DIR: C:\vcpkg\installed\x64-windows
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache vcpkg packages
uses: actions/cache@v4
with:
path: C:\vcpkg\installed
key: vcpkg-openssl-x64-windows-v1
- name: Install OpenSSL via vcpkg
shell: pwsh
run: |
if (Test-Path "$env:VCPKG_ROOT\installed\x64-windows\lib\libssl.lib") {
Write-Host "OpenSSL already cached" -ForegroundColor Green
} else {
& "$env:VCPKG_ROOT\vcpkg" install openssl:x64-windows
}
- name: Setup Rust (stable)
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust (nightly, for coverage)
uses: dtolnay/rust-toolchain@nightly
with:
components: llvm-tools-preview
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
workspaces: native/rust -> target
- name: Install OpenCppCoverage
shell: pwsh
run: |
choco install opencppcoverage -y --no-progress
- name: Native ASAN coverage (Rust + C + C++, 90% gate)
shell: pwsh
run: |
$env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH"
./native/collect-coverage-asan.ps1 -Configuration Debug -MinimumLineCoveragePercent 90
# Generate and commit a changelog on every push to main.
# On pull requests this job passes without committing because:
# - Fork PRs cannot receive pushes via GITHUB_TOKEN (GitHub security boundary).
# - The changelog is auto-generated from merged PRs, so it only needs to be
# up-to-date on main, not in every PR branch.
# Commits made with GITHUB_TOKEN do not trigger new workflow runs, so there is
# no risk of an infinite loop.
create_changelog:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
#### PUSH TO MAIN — generate, commit, and push the changelog ####
- name: Checkout main
if: ${{ github.event_name == 'push' }}
uses: actions/checkout@v4
with:
ref: main
- name: Configure git
if: ${{ github.event_name == 'push' }}
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Generate changelog
if: ${{ github.event_name == 'push' }}
uses: tj-actions/github-changelog-generator@v1.19
with:
output: CHANGELOG.md
token: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changelog
if: ${{ github.event_name == 'push' }}
run: |
git add CHANGELOG.md
if git diff-index --quiet HEAD; then
echo "No changelog changes to commit."
else
git commit -m "Update changelog"
git push
fi
#### PULL REQUEST — nothing to commit; just pass ####
- name: Skip changelog commit for PRs
if: ${{ github.event_name == 'pull_request' }}
run: echo "Changelog will be updated automatically when this PR is merged to main."
#### OTHER EVENTS — nothing to do ####
- name: No-op for other events
if: ${{ github.event_name != 'push' && github.event_name != 'pull_request' }}
run: echo "Changelog is already up to date."
#### PUSH EVENTS ####
# Create a semantically versioned release.
# A prerelease is created for every push to the main branch.
# Official releases are created manually on GitHub.
create_release:
name: Create Release
if: ${{ (github.event_name == 'push' && needs.detect-changes.outputs.dotnet == 'true') || github.event_name == 'release' }}
needs: [ detect-changes, create_changelog ] # Ensure changelog is committed before tagging.
runs-on: ubuntu-latest
permissions:
actions: write
contents: write
deployments: write
packages: write
pull-requests: write
security-events: write
statuses: write
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
tag_name: ${{ steps.output_tag_name.outputs.tag_name }}
steps:
# Checkout the main branch and fetch tags.
- name: Checkout code
if: ${{ github.event_name == 'push' }}
uses: actions/checkout@v3
# Checkout the main branch so we can see the correct tag set.
- name: Fetch and checkout main
if: ${{ github.event_name == 'push' }}
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git fetch
git checkout main
# Create a semantically versioned tag that increments the last release.
# If the last release is a pre-release, increment the pre-release number, so v1.2.3-pre4 becomes v1.2.3-pre5.
# If the last release is an official release, create a new pre-release, so v1.2.3 becomes v1.2.3-pre1.
- name: Increment pre-release tag
if: ${{ github.event_name == 'push' }}
id: new-tag # Output: ${{ steps.new-tag.outputs.newtag }}
run: |
CURRENT_TAG=$(git tag | sort --version-sort | tail -n1)
echo "Current tag is $CURRENT_TAG"
if [[ $CURRENT_TAG =~ ^v([0-9]+\.[0-9]+\.[0-9]+)(-pre([0-9]+))?$ ]]; then
BASE_VERSION=${BASH_REMATCH[1]}
PRE_VERSION=${BASH_REMATCH[3]}
if [ -z "$PRE_VERSION" ]; then
NEW_TAG="v$BASE_VERSION-pre1"
else
NEW_TAG="v$BASE_VERSION-pre$((PRE_VERSION + 1))"
fi
echo "New tag is $NEW_TAG"
echo "Let's make sure this tag doesn't already exist..."
tries=0
maxTries=5
while true; do
echo "This is try $tries"
RESPONSE=$(curl -sl https://api.github.com/repos/microsoft/CoseSignTool/releases/tags/$NEW_TAG)
if [ "$(echo "$RESPONSE" | jq -r '.message')" == "Not Found" ]; then
echo "Tag not found. We're good to go."
break
else
if [ $tries -ge $maxTries ]; then
echo "Max tries reached. Exiting."
exit 1
fi
echo "Oops! That tag already exists!"
NEW_TAG="${NEW_TAG%-*}-pre$(( ${NEW_TAG##*-pre} + 1 ))" # Increment the prerelease number.
echo "Let's try $NEW_TAG"
tries=$((tries+1))
fi
done
echo "::set-output name=newtag::$NEW_TAG"
else
echo "Invalid tag format"
exit 1
fi
# Create the release. This should generate a release event, which will trigger the release_assets job.
- name: Create Release
if: ${{ github.event_name == 'push' }}
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Get the tag name and release name from the previous step.
tag_name: ${{ steps.new-tag.outputs.newtag }}
release_name: Release ${{ steps.new-tag.outputs.newtag }}
# Generate release text from changelog.
body_path: ./CHANGELOG.md
# Always use prerelease for automated releases. Official releases are created manually.
prerelease: true
# Output the semver tag if it's a push event, or the most recent tag if it's a release event.
- name: Output tag name
id: output_tag_name
run: |
if [ "${{ github.event_name }}" == "push" ]; then
echo "::set-output name=tag_name::${{ steps.new-tag.outputs.newtag }}"
echo "Generated semver tag is ${{ steps.new-tag.outputs.newtag }}."
else
echo "::set-output name=tag_name::${{ github.event.release.tag_name }}"
echo "Current release tag is ${{ github.event.release.tag_name }}."
fi
#### RELEASE EVENTS ####
# Build, publish, and zip the outputs, and then upload them to the release.
# We include the push event and the dependency on create_release to support automatic releases, because
# automatic release creation does not trigger the release event.
release_assets:
name: release-assets
if: ${{ github.event_name == 'release' || (github.event_name == 'push' && needs.detect-changes.outputs.dotnet == 'true') }}
needs: [ detect-changes, create_release ]
runs-on: ${{ matrix.os }}
permissions:
actions: write
contents: write
deployments: write
packages: write
pull-requests: write
security-events: write
statuses: write
strategy:
matrix:
include:
- os: windows-latest
runtime_id: win-x64
dir_command: gci -Recurse
zip_command_debug: Compress-Archive -Path ./debug/ -DestinationPath CoseSignTool-Windows-debug.zip
zip_command_release: Compress-Archive -Path ./release/ -DestinationPath CoseSignTool-Windows-release.zip
- os: ubuntu-latest
runtime_id: linux-x64
dir_command: ls -a -R
zip_command_debug: zip -r CoseSignTool-Linux-debug.zip ./debug/
zip_command_release: zip -r CoseSignTool-Linux-release.zip ./release/
- os: macos-latest
runtime_id: osx-x64
dir_command: ls -a -R
zip_command_debug: zip -r CoseSignTool-MacOS-x64-debug.zip ./debug/
zip_command_release: zip -r CoseSignTool-MacOS-x64-release.zip ./release/
- os: macos-latest
runtime_id: osx-arm64
dir_command: ls -a -R
zip_command_debug: zip -r CoseSignTool-MacOS-arm64-debug.zip ./debug/
zip_command_release: zip -r CoseSignTool-MacOS-arm64-release.zip ./release/
steps:
# Checkout the branch.
- name: Checkout code again
uses: actions/checkout@v3
# Restore all projects including plugins.
# Plugin projects are not direct ProjectReferences of CoseSignTool — they are discovered
# by glob in the BuildPlugins MSBuild target. Because of this, `dotnet publish` only
# restores CoseSignTool and its transitive project references, leaving plugin projects
# without a project.assets.json. Restoring the full solution up front ensures plugins
# are restored before the BuildPlugins target tries to compile them.
- name: Restore all projects
run: dotnet restore CoseSignTool.sln --runtime ${{ matrix.runtime_id }}
# Build and publish the binaries to ./published.
# Plugins are automatically built and deployed via BuildPlugins and DeployAllPlugins targets (enabled by default)
# PublishSingleFile=true creates a single self-contained executable with plugins bundled inside
- name: Publish outputs
run: |
VERSION=${{ needs.create_release.outputs.tag_name }}
# Remove the 'v' prefix from VERSION for VersionNgt property
VERSION_WITHOUT_V=$(echo "$VERSION" | sed 's/^v//')
RUNTIME_ID=${{ matrix.runtime_id }}
echo "Publishing single-file self-contained executable for runtime: $RUNTIME_ID"
echo "Plugins will be bundled inside the executable"
dotnet publish --no-restore --configuration Debug --self-contained true --runtime $RUNTIME_ID --output published/debug --property:FileVersion=$VERSION --property:VersionNgt=$VERSION_WITHOUT_V --property:PublishSingleFile=true CoseSignTool/CoseSignTool.csproj
dotnet publish --no-restore --configuration Release --self-contained true --runtime $RUNTIME_ID --output published/release --property:FileVersion=$VERSION --property:VersionNgt=$VERSION_WITHOUT_V --property:PublishSingleFile=true CoseSignTool/CoseSignTool.csproj
# PublishSingleFile=true bundles everything into a single executable:
# - The .NET runtime (self-contained)
# - All plugins (bundled and extracted on first run)
# - No separate plugins folder needed - everything is in the exe
shell: bash
# Verify the single-file executable was created correctly
# With PublishSingleFile=true and IncludeAllContentForSelfExtract=true, plugins are bundled INSIDE the exe
- name: Verify single-file executable
run: |
Write-Host "Verifying single-file self-contained executable..."
Write-Host ""
# Check debug output
Write-Host "=== Debug build ==="
$debugExe = Get-ChildItem "published/debug/CoseSignTool*" -File | Where-Object { $_.Extension -eq '.exe' -or $_.Extension -eq '' } | Select-Object -First 1
if ($debugExe) {
$sizeMB = [math]::Round($debugExe.Length / 1MB, 2)
Write-Host "✅ Found: $($debugExe.Name) ($sizeMB MB)"
# Plugins are bundled inside, so exe should be > 40MB (contains runtime + plugins)
if ($sizeMB -gt 40) {
Write-Host "✅ Size indicates plugins are bundled (expected for single-file with plugins)"
} else {
Write-Host "⚠️ Size seems small - plugins may not be bundled correctly"
}
} else {
Write-Host "❌ CoseSignTool executable not found in debug output!"
exit 1
}
# Check that plugins folder does NOT exist (should be bundled in exe)
if (Test-Path "published/debug/plugins") {
Write-Host "⚠️ Plugins folder exists - it should be cleaned up for single-file publish"
} else {
Write-Host "✅ No external plugins folder (correctly bundled in exe)"
}
Write-Host ""
Write-Host "=== Release build ==="
$releaseExe = Get-ChildItem "published/release/CoseSignTool*" -File | Where-Object { $_.Extension -eq '.exe' -or $_.Extension -eq '' } | Select-Object -First 1
if ($releaseExe) {
$sizeMB = [math]::Round($releaseExe.Length / 1MB, 2)
Write-Host "✅ Found: $($releaseExe.Name) ($sizeMB MB)"
if ($sizeMB -gt 40) {
Write-Host "✅ Size indicates plugins are bundled"
} else {
Write-Host "⚠️ Size seems small - plugins may not be bundled correctly"
}
} else {
Write-Host "❌ CoseSignTool executable not found in release output!"
exit 1
}
if (Test-Path "published/release/plugins") {
Write-Host "⚠️ Plugins folder exists - it should be cleaned up for single-file publish"
} else {
Write-Host "✅ No external plugins folder (correctly bundled in exe)"
}
Write-Host ""
Write-Host "Single-file verification complete. Plugins are bundled inside the executable."
Write-Host "On first run, the exe will extract to a temp directory including the plugins folder."
shell: pwsh
# List the contents of the published directory to make sure all the artifacts are there.
- name: List published directory
run: ${{ matrix.dir_command }}
working-directory: ./published
# Verify that the file versions on the exe match the release version
- name: Check File Version
run: |
# With single-file publish, we have CoseSignTool.exe (Windows) or CoseSignTool (Unix)
$file = Get-Item "CoseSignTool*" -ErrorAction SilentlyContinue | Where-Object { $_.Extension -eq '.exe' -or $_.Extension -eq '' }
if ($file) {
$version = $file.VersionInfo.FileVersion
Write-Output "File Version is $version"
} else {
Write-Output "Warning: Could not find CoseSignTool executable"
}
shell: pwsh
working-directory: ./published/debug
# Create NuGet packages for library projects (commented out for now)
- name: Create NuGet packages
run: |
echo "📦 Creating NuGet packages for library projects..."
VERSION=${{ needs.create_release.outputs.tag_name }}
# Remove the 'v' prefix from VERSION for VersionNgt property
VERSION_WITHOUT_V=$(echo "$VERSION" | sed 's/^v//')
# Define library projects that should be packaged (excluding plugins and test projects)
LIBRARY_PROJECTS=(
"CoseHandler/CoseHandler.csproj"
"CoseIndirectSignature/CoseIndirectSignature.csproj"
"CoseSign1/CoseSign1.csproj"
"CoseSign1.Abstractions/CoseSign1.Abstractions.csproj"
"CoseSign1.Certificates/CoseSign1.Certificates.csproj"
"CoseSign1.Headers/CoseSign1.Headers.csproj"
"CoseSign1.Transparent/CoseSign1.Transparent.csproj"
"CoseSign1.Transparent.MST/CoseSign1.Transparent.MST.csproj"
"CoseSignTool.Abstractions/CoseSignTool.Abstractions.csproj"
)
# Create packages directory
mkdir -p published/packages
# Pack each library project
for project in "${LIBRARY_PROJECTS[@]}"; do
if [ -f "$project" ]; then
project_name=$(basename "${project%.*}")
echo "📦 Creating package for $project_name..."
dotnet pack "$project" \
--configuration Release \
--property:FileVersion=$VERSION \
--property:PackageVersion=$VERSION_WITHOUT_V \
--property:VersionNgt=$VERSION_WITHOUT_V \
--output published/packages \
--verbosity minimal
if [ $? -eq 0 ]; then
echo "✅ Successfully created package for $project_name"
else
echo "❌ Failed to create package for $project_name"
fi
else
echo "⚠️ Project file not found: $project"
fi
done
# List created packages
echo ""
echo "📋 Created NuGet packages:"
if [ -d "published/packages" ]; then
ls -la published/packages/*.nupkg | while read -r line; do
echo " 📦 $(echo "$line" | awk '{print $9}')"
done
else
echo "❌ No packages directory found"
fi
echo "🎯 NuGet package creation completed."
shell: bash
# Copy the docs, license, and markdown files to the release folders.
- name: Copy docs to release folders
run: |
mkdir -p published/debug/docs
cp -r docs/* published/debug/docs/
mkdir -p published/release/docs
cp -r docs/* published/release/docs/
cp -r LICENSE published/debug/
cp -r LICENSE published/release/
cp -r *.md published/debug/
cp -r *.md published/release/
# Create zip files for release.
- name: Create zip files for the release
run: |
${{ matrix.zip_command_debug }}
${{ matrix.zip_command_release }}
working-directory: ./published
# List the contents of the published directory to make sure all the artifacts are there.
- name: List published directory
run: ${{ matrix.dir_command }}
working-directory: ./published
# Upload the zipped assets to the release.
- name: Upload binary archives
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./published/CoseSignTool-*.zip
file_glob: true
overwrite: true
tag: ${{ needs.create_release.outputs.tag_name }}
# Commented out until we decide to support publishing of nuget packages.
# Upload the NuGet packages to the release (commented out for now)
# - name: Upload NuGet packages
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: ./published/packages/*.nupkg
# file_glob: true
# overwrite: true
# tag: ${{ needs.create_release.outputs.tag_name }}