Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c7ac322
feat: firmware compatibility check
JoshuaWellbrock Jun 30, 2025
94cca25
chore: replace firmware_compatibility_check.yml with actions
JoshuaWellbrock Jun 30, 2025
594a661
chore: remove unused import
JoshuaWellbrock Jun 30, 2025
31ac37e
test: fix tests
JoshuaWellbrock Jul 2, 2025
90f91c7
chore: update workflows
JoshuaWellbrock Jul 2, 2025
01f7651
chore: update actions
JoshuaWellbrock Jul 2, 2025
b57c8e3
chore: update actions - fetch tags via REST
JoshuaWellbrock Jul 3, 2025
b84099d
chore: update actions
JoshuaWellbrock Jul 3, 2025
6b55f04
chore: update actions
JoshuaWellbrock Jul 3, 2025
924fa95
chore: update actions
JoshuaWellbrock Jul 3, 2025
c5257f1
chore: update actions
JoshuaWellbrock Jul 3, 2025
9b676e8
chore: update actions
JoshuaWellbrock Jul 3, 2025
0e72a06
chore: update workflows and actions
JoshuaWellbrock Jul 4, 2025
083f693
chore: fix workflow
JoshuaWellbrock Jul 4, 2025
ffe9e97
chore: fix workflow (maximum of 100 tested combinations, latest versi…
JoshuaWellbrock Jul 4, 2025
0992136
chore: update matrix generation in action
JoshuaWellbrock Jul 7, 2025
6a6b3d6
chore: update action
JoshuaWellbrock Jul 7, 2025
6ffa961
chore: update workflow
JoshuaWellbrock Jul 7, 2025
a503988
chore: update actions
JoshuaWellbrock Jul 7, 2025
ebab5d7
chore: add missing trailing comma
Jul 18, 2025
da6a687
Revert "chore: add missing trailing comma"
JoshuaWellbrock Jul 18, 2025
c73546f
chore: only test current SDK Version with three latest firmware version
JoshuaWellbrock Jul 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/actions/fetch-firmware-versions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Fetch Firmware Versions
description: Clones the firmware repo and extracts available tags.
inputs:
token:
description: GitHub token for API access
required: true
outputs:
versions:
description: JSON array of firmware tags
value: ${{ steps.set-output.outputs.versions }}
runs:
using: "composite"
steps:
- name: Fetch firmware tags via REST
id: set-output
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.token }}
run: |
REPO=merckgroup/mtrust-device-sim

# Debug: Check the raw response
echo "Fetching tags from $REPO..."
response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$REPO/tags?per_page=100")

# Debug: Show response structure
echo "Response preview:"
echo "$response" | head -c 200
echo "..."

# Check if response is valid JSON and contains expected data
if echo "$response" | jq -e 'type == "array"' > /dev/null; then
echo "Valid JSON array received"
tags=$(echo "$response" | jq -r '.[].name // empty')
if [ -n "$tags" ]; then
# Filter for major.minor versions only (no patch versions)
# This regex matches versions like v1.0, v2.1, v10.5, etc.
major_minor_tags=$(echo "$tags" | grep -E '^v[0-9]+\.[0-9]+$' || true)

if [ -n "$major_minor_tags" ]; then
# Sort by version and take the 3 latest
latest_3_tags=$(echo "$major_minor_tags" | sort -V | tail -3)

echo "Found major.minor firmware versions:"
echo "$major_minor_tags"
echo ""
echo "Latest 3 major.minor firmware versions:"
echo "$latest_3_tags"

tags_json=$(echo "$latest_3_tags" | jq -R . | jq -s -c .)
echo "versions=$tags_json" >> $GITHUB_OUTPUT
else
echo "No major.minor version tags found"
echo "versions=[]" >> $GITHUB_OUTPUT
fi
else
echo "No tags found in response"
echo "versions=[]" >> $GITHUB_OUTPUT
fi
else
echo "Invalid response or error from GitHub API"
echo "Full response: $response"
echo "versions=[]" >> $GITHUB_OUTPUT
fi

26 changes: 26 additions & 0 deletions .github/actions/fetch-sdk-versions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Fetch SDK Versions
description: Gets the current SDK version from pubspec.yaml.
outputs:
versions:
description: JSON array containing only the current SDK version
value: ${{ steps.set-output.outputs.versions }}
runs:
using: "composite"
steps:
- name: Get current SDK version from pubspec.yaml
id: set-output
shell: bash
run: |
# Read the current version from pubspec.yaml
current_version=$(grep '^version:' pubspec.yaml | awk '{print $2}')

if [ -n "$current_version" ]; then
echo "Current SDK version from pubspec.yaml: $current_version"

# Create JSON array with only the current version
versions_json=$(echo "[\"v$current_version\"]" | jq -c .)
echo "versions=$versions_json" >> $GITHUB_OUTPUT
else
echo "Error: Could not read version from pubspec.yaml"
echo "versions=[]" >> $GITHUB_OUTPUT
fi
64 changes: 64 additions & 0 deletions .github/actions/generate-matrix/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Generate Compatibility Matrix
description: Converts test result artifacts into a firmware-SDK compatibility matrix.
runs:
using: "composite"
steps:
- name: Download all compatibility artifacts
uses: actions/download-artifact@v4
with:
path: all-results

- name: Install dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y jq

- name: Generate SDK to firmware compatibility map
shell: bash
run: |
mkdir -p assets
tmpfile=$(mktemp)

echo '{}' > $tmpfile

# Read package version from pubspec.yaml
package_version=$(grep '^version:' pubspec.yaml | awk '{print $2}')

# Extract and group firmware versions per SDK
find all-results -name compat.json | while read file; do
sdk=$(jq -r .sdk "$file")
fw=$(jq -r .firmware "$file")

# Remove leading 'v' if present
sdk=${sdk#v}
fw=${fw#v}

tmp=$(mktemp)
jq --arg sdk "$sdk" --arg fw "$fw" '
.[$sdk] += [$fw] // {($sdk): [$fw]}
' "$tmpfile" > "$tmp" && mv "$tmp" "$tmpfile"
done

# Convert lists to semver ranges and create final JSON structure
jq --arg version "$package_version" '
{
package_version: $version,
compatibility: (
to_entries |
map({
key: .key,
value: (
.value | sort_by(split(".") | map(tonumber)) |
"\(.[0]) - \(.[-1])"
)
}) | from_entries
)
}
' "$tmpfile" > assets/firmware_compatibility.json

- name: Upload full matrix
uses: actions/upload-artifact@v4
with:
name: compatibility-matrix
path: assets/firmware_compatibility.json
68 changes: 68 additions & 0 deletions .github/actions/test-compatibility/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Test Firmware/SDK Compatibility
description: Runs compatibility tests between a firmware version and an SDK version.
inputs:
firmware_version:
required: true
description: Firmware version tag
sdk_version:
required: true
description: SDK version tag
token:
required: true
description: GitHub token for accessing private repositories
runs:
using: "composite"
steps:
- name: Checkout SDK
uses: actions/checkout@v4
with:
repository: emdgroup/mtrust-sec-kit
ref: ${{ inputs.sdk_version }}
path: sdk

- name: Checkout device sim repo
uses: actions/checkout@v4
with:
repository: merckgroup/mtrust-device-sim
ref: dev
path: mtrust-device-sim
token: ${{ inputs.token }}

- name: Start device sim
id: urp-sim
uses: ./mtrust-device-sim/.github/actions/start-urp-sim
with:
repository: "mtrust-urp-os"
tag: ${{ inputs.firmware_version }}
environment: "d"
token: ''

- name: Default tests for device sim
uses: ./mtrust-device-sim/.github/actions/test-urp-sim

- name: Validate SDK
uses: emdgroup/mtrust-urp/.github/shared_actions/validate-flutter@dev
with:
directory: sdk
is_package: true
api_url: "https://api.dev.mtrust.io"

- name: Mark compatibility as passed
if: success()
shell: bash
run: |
mkdir -p result
echo '{"firmware": "${{ inputs.firmware_version }}", "sdk": "${{ inputs.sdk_version }}"}' > result/compat.json

- name: Upload result
if: success()
uses: actions/upload-artifact@v4
with:
name: compat-${{ inputs.firmware_version }}-${{ inputs.sdk_version }}
path: result/compat.json

- name: Stop device sim
uses: ./mtrust-device-sim/.github/actions/stop-urp-sim
with:
websocket_pid: ${{ steps.urp-sim.outputs.websocket_pid }}
pio_pid: ${{ steps.urp-sim.outputs.pio_pid }}
130 changes: 125 additions & 5 deletions .github/workflows/build_dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,137 @@ jobs:
with:
directory: "."

matrix-generation:
name: Generate Compatibility Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Fetch firmware versions
uses: ./.github/actions/fetch-firmware-versions
id: fetch-firmware-versions
with:
token: ${{secrets.ELEVATED_TOKEN}}

- name: Fetch SDK versions
uses: ./.github/actions/fetch-sdk-versions
id: fetch-sdk-versions

- name: Generate compatibility matrix
id: generate-matrix
run: |
# Parse the JSON arrays and create a matrix
firmware_versions=$(echo '${{ steps.fetch-firmware-versions.outputs.versions }}' | jq -r '.[]')
sdk_versions=$(echo '${{ steps.fetch-sdk-versions.outputs.versions }}' | jq -r '.[]')

echo "Latest 3 major.minor firmware versions:"
echo "$firmware_versions"
echo ""
echo "Current SDK version:"
echo "$sdk_versions"
echo ""

# Create matrix combinations using current SDK version with latest 3 firmware versions
matrix_combinations="[]"
count=0

while IFS= read -r firmware; do
# For each firmware version, use the current SDK version
combination=$(jq -n --arg fw "$firmware" --arg sdk "$sdk_versions" '{firmware: $fw, sdk: $sdk}')

# Add to matrix array
matrix_combinations=$(echo "$matrix_combinations" | jq --argjson combo "$combination" '. += [$combo]')
count=$((count + 1))
done <<< "$firmware_versions"

# Validate JSON before output
if echo "$matrix_combinations" | jq empty 2>/dev/null; then
echo "matrix=$matrix_combinations" >> $GITHUB_OUTPUT
echo "Generated matrix with $count combinations (latest 3 firmware × current SDK version)"
echo "Matrix preview:"
echo "$matrix_combinations" | jq '.[0:3]' # Show first 3 combinations
else
echo "Error: Invalid JSON generated"
echo "Generated content:"
echo "$matrix_combinations"
exit 1
fi

compatibility-tests:
name: Compatibility Tests
needs: matrix-generation
runs-on: ubuntu-latest
strategy:
matrix:
include: ${{ fromJson(needs.matrix-generation.outputs.matrix) }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Test compatibility
uses: ./.github/actions/test-compatibility
with:
token: ${{secrets.ELEVATED_TOKEN}}
firmware_version: ${{ matrix.firmware }}
sdk_version: ${{ matrix.sdk }}

generate-compatibility-matrix:
name: Generate Compatibility Matrix
needs: [version, compatibility-tests]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Generate matrix
uses: ./.github/actions/generate-matrix

- name: Upload compatibility matrix artifact
uses: actions/upload-artifact@v4
with:
name: firmware-compatibility-matrix
path: assets/firmware_compatibility.json

release:
name: Release Package
needs: [version, generate-compatibility-matrix]
runs-on: macos-latest
environment: release
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{secrets.ELEVATED_TOKEN}}

- name: Download compatibility matrix
uses: actions/download-artifact@v4
with:
name: firmware-compatibility-matrix
path: assets/

- name: 📇 Configure git
run: |
git fetch --prune --unshallow
git config --global user.name "GitHub Actions"
git config --global user.email "gh-actions@merckgroup.com"
shell: bash

# We first commit with proper message and add an empty commit to keep the files history clean
- name: Update repo versions
run: |
git add .
git commit -m "chore(release): ${{ steps.get_new_version.outputs.result }}"
git commit --allow-empty -m "chore(release): ${{ steps.get_new_version.outputs.result }} [skip ci]"
git commit -m "chore(release): ${{ needs.version.outputs.version }}"
git commit --allow-empty -m "chore(release): ${{ needs.version.outputs.version }} [skip ci]"
git push origin dev

# For this part it is important to not push a commit with [skip ci] before the tag release
- name: Push tag for pub.dev
run: |
git commit --allow-empty -m "chore(release): ${{ steps.get_new_version.outputs.result }}"
git tag -a v${{ steps.get_new_version.outputs.result }} -m "Pub.dev version ${{ steps.get_new_version.outputs.result }}"
git push origin v${{ steps.get_new_version.outputs.result }}
git commit --allow-empty -m "chore(release): ${{ needs.version.outputs.version }}"
git tag -a v${{ needs.version.outputs.version }} -m "Pub.dev version ${{ needs.version.outputs.version }}"
git push origin v${{ needs.version.outputs.version }}
Loading
Loading