diff --git a/.github/actions/assert-opendaq-installed/action.yml b/.github/actions/assert-opendaq-installed/action.yml new file mode 100644 index 0000000..125d262 --- /dev/null +++ b/.github/actions/assert-opendaq-installed/action.yml @@ -0,0 +1,44 @@ +name: 'Assert openDAQ Installed' +description: 'Verify that openDAQ package is installed on the system' + +inputs: + enable-32bit: + description: 'Check for 32-bit installation on Windows' + required: false + default: false + +runs: + using: composite + steps: + - name: Verify Installation (Linux) + if: runner.os == 'Linux' + shell: bash + run: | + if ! dpkg-query -W -f='${Status}' opendaq 2>/dev/null | grep -qx "install ok installed"; then + echo "::error::✗ Package not installed or in invalid state" + exit 1 + fi + + - name: Verify Installation (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + if ("${{ inputs.enable-32bit }}" -eq "true") { + $installPath = "C:\Program Files (x86)\openDAQ" + $binPath = "C:\Program Files (x86)\openDAQ\bin" + } else { + $installPath = "C:\Program Files\openDAQ" + $binPath = "C:\Program Files\openDAQ\bin" + } + + # Assert installation directory exists + if (-not (Test-Path $installPath)) { + Write-Host "::error::✗ Installation directory not found: $installPath" + exit 1 + } + + # Assert bin directory is in PATH + if ($env:PATH -notlike "*$binPath*") { + Write-Host "::error::✗ PATH does not contain: $binPath" + exit 1 + } diff --git a/.github/actions/assert-opendaq-version-equals/action.yml b/.github/actions/assert-opendaq-version-equals/action.yml new file mode 100644 index 0000000..165a163 --- /dev/null +++ b/.github/actions/assert-opendaq-version-equals/action.yml @@ -0,0 +1,63 @@ +name: 'Assert openDAQ Version Equals' +description: 'Verify that installed openDAQ version matches expected version' + +inputs: + expected-version: + description: 'Expected version (with v prefix and optional suffix like v3.30.0-rc)' + required: true + enable-32bit: + description: 'Check 32-bit installation on Windows' + required: false + default: false + +runs: + using: composite + steps: + - name: Verify Version (Linux) + if: runner.os == 'Linux' + shell: bash + run: | + ACTUAL_VERSION=$(dpkg-query -W -f='${Version}' opendaq) + EXPECTED_VERSION="${{ inputs.expected-version }}" + EXPECTED_VERSION="${EXPECTED_VERSION#v}" + EXPECTED_VERSION="${EXPECTED_VERSION%%-*}" + + if [[ "$ACTUAL_VERSION" != "$EXPECTED_VERSION"* ]]; then + echo "::error::✗ Version mismatch: expected <$EXPECTED_VERSION> but was <$ACTUAL_VERSION>" + exit 1 + fi + + - name: Verify Version (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + if ("${{ inputs.enable-32bit }}" -eq "true") { + $binDir = "C:\Program Files (x86)\openDAQ\bin" + $dllPath = "$binDir\opendaq-32-3.dll" + } else { + $binDir = "C:\Program Files\openDAQ\bin" + $dllPath = "$binDir\opendaq-64-3.dll" + } + + if (-not (Test-Path $binDir)) { + Write-Host "::error::✗ Directory not found: $binDir" + exit 1 + } + + if (-not (Test-Path $dllPath)) { + Write-Host "::error::✗ DLL not found: $dllPath" + Write-Host "Directory contents:" + Get-ChildItem $binDir | ForEach-Object { Write-Host " $_" } + exit 1 + } + + $actualVersion = (Get-Item $dllPath).VersionInfo.FileVersion + $expectedVersion = "${{ inputs.expected-version }}" -replace '^v', '' -replace '-.*$', '' + + # FileVersion is like 3.31.0.0, compare first 3 components + $actualMajorMinorPatch = ($actualVersion -split '\.')[0..2] -join '.' + + if ($actualMajorMinorPatch -ne $expectedVersion) { + Write-Host "::error::✗ Version mismatch: expected <$expectedVersion> but was <$actualMajorMinorPatch>" + exit 1 + } diff --git a/.github/workflows/README.md b/.github/workflows/README.md deleted file mode 100644 index d642a10..0000000 --- a/.github/workflows/README.md +++ /dev/null @@ -1,46 +0,0 @@ -[![Test All Actions](https://github.com/openDAQ/actions/actions/workflows/test-all-actions.yml/badge.svg)](https://github.com/openDAQ/actions/actions/workflows/test-all-actions.yml) - -# Test All Actions - -This workflow runs automated tests for all openDAQ GitHub Actions in this repository. - ---- - -## 📌 Purpose - -- Ensures that all actions work correctly. -- Runs shared workflows for each action. -- Can be used in pull requests to verify changes before merging. - ---- - -## 🚀 Usage - -This workflow is triggered automatically on: - -- `push` to `main` - -No manual configuration is needed — it automatically runs tests for all actions listed in the matrix. - ---- - -## ⚙️ Matrix - -Currently tested actions (via their **testing workflows**): - -> TODO: add a shared testing workflow for each action here - -- [ ] test-framework-download-artifact -- [ ] test-framework-download-release -- [ ] test-framework-install-package - -You can add new actions to the matrix in `test-all-actions.yml` when new actions are added to the repository. - ---- - -## 🤝 Contributing - -- To add a new action for testing: - 1. Create a shared workflow for the action (e.g., `test-.yml`). - 2. Add the action name to the matrix in `test-all-actions.yml`. - 3. Update this README if needed. diff --git a/.github/workflows/test-all-actions.yml b/.github/workflows/test-all-actions.yml deleted file mode 100644 index 9049212..0000000 --- a/.github/workflows/test-all-actions.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Test All Actions - -on: - push: - branches: - - main - -jobs: - test-actions: - runs-on: ubuntu-latest - strategy: - matrix: - action: [ - framework-download-artifact, - framework-download-release, - framework-install - ] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 diff --git a/.github/workflows/test-install-framework.yml b/.github/workflows/test-install-framework.yml new file mode 100644 index 0000000..3c41492 --- /dev/null +++ b/.github/workflows/test-install-framework.yml @@ -0,0 +1,208 @@ +name: Test Install Framework Action + +on: + pull_request: + paths: + - 'install-framework/**' + - '.github/workflows/test-install-framework.yml' + push: + branches: [ main ] + paths: + - 'install-framework/**' + - '.github/workflows/test-install-framework.yml' + workflow_dispatch: + +jobs: + ubuntu-autodetect: + name: Ubuntu Autodetect (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - ubuntu-22.04 + - ubuntu-22.04-arm + - ubuntu-24.04 + - ubuntu-24.04-arm + - ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework (default version) + id: install + uses: ./install-framework + + - name: Verify Installation + uses: ./.github/actions/assert-opendaq-installed + + ubuntu-versions-explicit: + name: Ubuntu ${{ matrix.version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 1 + matrix: + version: + - v3.30.0 + - v3.29.0-rc + - v3.20.4 + - v3.19.4-rc + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + with: + version: ${{ matrix.version }} + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ matrix.version }} + + ubuntu-versions-aliased: + name: Ubuntu ${{ matrix.version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: + - latest + - latest-stable + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + with: + version: ${{ matrix.version }} + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ steps.install.outputs.version }} + + windows-autodetect: + name: Windows Autodetect + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ steps.install.outputs.version }} + + windows-autodetect-32bit: + name: Windows Autodetect (32-bit) + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + with: + enable-32bit: true + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + with: + enable-32bit: true + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ steps.install.outputs.version }} + enable-32bit: true + + windows-versions-explicit: + name: Windows ${{ matrix.version }} (${{ matrix.enable-32bit && '32-bit' || '64-bit' }}) + runs-on: windows-latest + strategy: + fail-fast: false + max-parallel: 1 + matrix: + version: + - v3.30.0 + - v3.29.0-rc + - v3.20.4 + - v3.19.4-rc + enable-32bit: + - true + - false + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + with: + version: ${{ matrix.version }} + enable-32bit: ${{ matrix.enable-32bit }} + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + with: + enable-32bit: ${{ matrix.enable-32bit }} + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ matrix.version }} + enable-32bit: ${{ matrix.enable-32bit }} + + windows-versions-aliased: + name: Windows ${{ matrix.version }} (${{ matrix.enable-32bit && '32-bit' || '64-bit' }}) + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + version: + - latest + - latest-stable + enable-32bit: + - true + - false + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Framework + id: install + uses: ./install-framework + with: + version: ${{ matrix.version }} + enable-32bit: ${{ matrix.enable-32bit }} + + - name: Verify Framework Installed + uses: ./.github/actions/assert-opendaq-installed + with: + enable-32bit: ${{ matrix.enable-32bit }} + + - name: Verify Framework Version + uses: ./.github/actions/assert-opendaq-version-equals + with: + expected-version: ${{ steps.install.outputs.version }} + enable-32bit: ${{ matrix.enable-32bit }} diff --git a/README.md b/README.md index 81d9260..d2138ec 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Test All Actions](https://github.com/openDAQ/actions/actions/workflows/test-all-actions.yml/badge.svg)](https://github.com/openDAQ/actions/actions/workflows/test-all-actions.yml) # openDAQ/actions A collection of reusable GitHub Actions for working with the [openDAQ Framework](https://github.com/openDAQ). @@ -7,21 +6,15 @@ A collection of reusable GitHub Actions for working with the [openDAQ Framework] ## 📦 Available Actions -> TODO: put an available actions list here: +### [install-framework](./install-framework) -- [ ] framework-download-artifact -- [ ] framework-download-release -- [ ] framework-install-package +[![Test Install Framework Action](https://github.com/openDAQ/actions/actions/workflows/test-install-framework.yml/badge.svg)](https://github.com/openDAQ/actions/actions/workflows/test-install-framework.yml) ---- - -## 🧪 CI / Testing - -We run automated tests for all actions using the **Test All Actions workflow**. +Download and install openDAQ framework packages from GitHub releases. -- Runs automatically on `push` to `main` and on `pull_request` events. -- Ensures that all actions work correctly. -- See [testing workflow details](./.github/workflows/README.md) +```yaml +- uses: openDAQ/actions/install-framework@main +``` --- diff --git a/install-framework/README.md b/install-framework/README.md new file mode 100644 index 0000000..e6cb850 --- /dev/null +++ b/install-framework/README.md @@ -0,0 +1,104 @@ +# Install openDAQ Framework + +[![Test Install Framework Action](https://github.com/openDAQ/actions/actions/workflows/test-install-framework.yml/badge.svg)](https://github.com/openDAQ/actions/actions/workflows/test-install-framework.yml) + +Download and install openDAQ framework packages from GitHub releases. + +## Usage + +```yaml +- uses: openDAQ/actions/install-framework@main + with: + # Framework version to install. + # Supports: 'latest', 'latest-stable', or specific versions like 'v3.30.0' + # Default: latest-stable + version: '' + + # Enable 32-bit version installation (Windows only, ignored on Linux). + # Default: false + enable-32bit: false +``` + +### Outputs + +- `version` - Resolved framework version that was installed (e.g., `v3.30.0`) + +## Examples + +### Basic Usage + +Install latest stable version with automatic platform detection: + +```yaml +- uses: openDAQ/actions/install-framework@main +``` + +### Install Specific Version + +```yaml +- uses: openDAQ/actions/install-framework@main + with: + version: v3.30.0 +``` + +### Install Latest Pre-release + +```yaml +- uses: openDAQ/actions/install-framework@main + with: + version: latest +``` + +### Install 32-bit on Windows + +```yaml +- uses: openDAQ/actions/install-framework@main + with: + enable-32bit: true +``` + +## Scenarios + +### Platform Detection + +The action automatically detects the platform and selects the appropriate package: + +**Linux Runners:** +- Detects architecture from `runner.arch` (X64 → `x86_64`, ARM64 → `arm64`) +- Searches for assets matching pattern: `opendaq-{version}-ubuntu*-{arch}.deb` +- Installs using `sudo dpkg -i` +- Example: `opendaq-3.30.0-ubuntu22.04-x86_64.deb` + +**Windows Runners:** +- Uses `win64` by default, or `win32` when `enable-32bit: true` +- Searches for assets matching pattern: `opendaq-{version}-win{32|64}.exe` +- Installs silently and updates `PATH` (silent installer doesn't update PATH automatically) +- Adds to PATH: `C:\Program Files\openDAQ\bin` (or `Program Files (x86)` for 32-bit) +- Example: `opendaq-3.30.0-win64.exe` + +### Version Resolution + +**`latest`** - Fetches the most recent release (including pre-releases): +```bash +gh release list -R openDAQ/openDAQ --limit 1 --json tagName --jq '.[0].tagName' +``` + +**`latest-stable`** - Fetches the latest stable release (excludes pre-releases): +```bash +gh release view -R openDAQ/openDAQ --json tagName --jq '.tagName' +``` + +**Specific version** - Validates format: `^(v?)([0-9]+)\.([0-9]+)\.([0-9]+)(-(.+))?$` +- Examples: `v3.30.0`, `3.30.0`, `v3.29.0-rc` + +### Installation Process + +1. **Resolve Version** - Determines version from input (`latest`, `latest-stable`, or specific) +2. **Detect Platform** - Identifies OS and architecture, selects package format +3. **Find Asset** - Searches GitHub releases for matching package using pattern +4. **Download** - Retrieves installer, displays SHA256 checksum and file size +5. **Install** - Executes platform-specific installation + +## License + +This action is part of the openDAQ project. See [LICENSE](../LICENSE) for details. diff --git a/install-framework/action.yml b/install-framework/action.yml new file mode 100644 index 0000000..c7f8cb4 --- /dev/null +++ b/install-framework/action.yml @@ -0,0 +1,238 @@ +name: 'Install openDAQ Framework' +description: 'Download and install openDAQ framework from GitHub releases' + +inputs: + version: + description: 'Framework version (latest, latest-stable, or specific version like v3.30.0)' + required: false + default: 'latest-stable' + enable-32bit: + description: 'Enable 32-bit version (only affects Windows, defaults to 64-bit)' + required: false + default: false + +outputs: + version: + description: 'Resolved framework version' + value: ${{ steps.resolve-version.outputs.version }} + +runs: + using: composite + steps: + - name: Resolve Version + id: resolve-version + shell: bash + env: + GITHUB_TOKEN: ${{ github.token }} + OPENDAQ_SDK_VERSION: ${{ inputs.version }} + VERSION_REGEX: '^(v?)([0-9]+)\.([0-9]+)\.([0-9]+)(-(.+))?$' + run: | + OPENDAQ_SDK_VERSION="${OPENDAQ_SDK_VERSION:-latest-stable}" + + if [ "$OPENDAQ_SDK_VERSION" = "latest" ]; then + echo "Resolving latest release..." + OPENDAQ_SDK_VERSION=$(gh release list -R openDAQ/openDAQ --limit 1 --json tagName --jq '.[0].tagName') + + if [ $? -ne 0 ]; then + echo "::error::✗ Failed to fetch latest version tag from GitHub releases" + exit 1 + fi + elif [ "$OPENDAQ_SDK_VERSION" = "latest-stable" ]; then + echo "Resolving latest stable release..." + OPENDAQ_SDK_VERSION=$(gh release view -R openDAQ/openDAQ --json tagName --jq '.tagName') + + if [ $? -ne 0 ]; then + echo "::error::✗ Failed to fetch latest stable version tag from GitHub releases" + exit 1 + fi + fi + + # Validate version format + if ! echo "$OPENDAQ_SDK_VERSION" | grep -qE "$VERSION_REGEX"; then + echo "::error::✗ Invalid version format: $OPENDAQ_SDK_VERSION" + exit 1 + fi + + echo "✓ Resolved version: $OPENDAQ_SDK_VERSION" + echo "version=$OPENDAQ_SDK_VERSION" >> "$GITHUB_OUTPUT" + + - name: Resolve Platform + id: resolve-platform + shell: bash + env: + RUNNER_OS: ${{ runner.os }} + RUNNER_ARCH: ${{ runner.arch }} + OPENDAQ_SDK_ENABLE_32BIT: ${{ inputs.enable-32bit }} + run: | + echo "Resolving platform..." + + case "$RUNNER_ARCH" in + X64) arch="x86_64" ;; + ARM64) arch="arm64" ;; + *) + echo "::error::✗ Unsupported architecture: $RUNNER_ARCH" + exit 1 + ;; + esac + + case "$RUNNER_OS" in + Linux) + OPENDAQ_SDK_PLATFORM="ubuntu*-${arch}" + OPENDAQ_SDK_FILE_EXT="deb" + ;; + Windows) + if [ "$OPENDAQ_SDK_ENABLE_32BIT" = "true" ]; then + OPENDAQ_SDK_PLATFORM="win32" + else + OPENDAQ_SDK_PLATFORM="win64" + fi + OPENDAQ_SDK_FILE_EXT="exe" + ;; + *) + echo "::error::✗ Unsupported OS: $RUNNER_OS" + exit 1 + ;; + esac + + echo "✓ Platform: $OPENDAQ_SDK_PLATFORM" + echo "platform=$OPENDAQ_SDK_PLATFORM" >> $GITHUB_OUTPUT + echo "file-ext=$OPENDAQ_SDK_FILE_EXT" >> $GITHUB_OUTPUT + + - name: Resolve Asset URL + id: resolve-asset + shell: bash + env: + GITHUB_TOKEN: ${{ github.token }} + OPENDAQ_SDK_VERSION: ${{ steps.resolve-version.outputs.version }} + OPENDAQ_SDK_PLATFORM: ${{ steps.resolve-platform.outputs.platform }} + OPENDAQ_SDK_FILE_EXT: ${{ steps.resolve-platform.outputs.file-ext }} + run: | + # Strip version prefix and suffix for pattern matching + ASSET_VERSION="${OPENDAQ_SDK_VERSION#v}" # Remove 'v' prefix + ASSET_VERSION="${ASSET_VERSION%%-*}" # Remove suffix (e.g., -rc) + + # Build wildcard pattern for asset name + ASSET_PATTERN="opendaq-${ASSET_VERSION}-${OPENDAQ_SDK_PLATFORM}.${OPENDAQ_SDK_FILE_EXT}" + + # Convert to regex: escape dots, replace wildcards, add anchors + ASSET_REGEX="^${ASSET_PATTERN//./[.]}$" + ASSET_REGEX="${ASSET_REGEX//\*/.*}" + + # Find all matching assets + ASSETS_VIEW=$(gh release view "$OPENDAQ_SDK_VERSION" \ + -R openDAQ/openDAQ \ + --json assets \ + --jq "[.assets[] | select(.name | test(\"${ASSET_REGEX}\"))]") + + # Check if fetch succeeded + if [ -z "$ASSETS_VIEW" ]; then + echo "::error::✗ Failed to view GitHub release assets by tag \"$OPENDAQ_SDK_VERSION\" matching pattern \"$ASSET_PATTERN\"" + exit 1 + fi + + ASSETS_COUNT=$(echo "$ASSETS_VIEW" | jq 'length') + + if [ "$ASSETS_COUNT" -ne 1 ]; then + echo "::error::✗ Expected a single asset for tag \"$OPENDAQ_SDK_VERSION\" matching pattern \"$ASSET_PATTERN\", but found $ASSETS_COUNT" + if [ "$ASSETS_COUNT" -gt 0 ]; then + echo " Available assets: $(echo "$ASSETS_VIEW" | jq -r '[.[].name] | join(", ")')" + fi + exit 1 + fi + + ASSET_NAME=$(echo "$ASSETS_VIEW" | jq -r '.[0].name') + ASSET_URL=$(echo "$ASSETS_VIEW" | jq -r '.[0].url') + + echo "✓ Resolved asset: \"$ASSET_NAME\" at \"$ASSET_URL\"" + echo "asset-name=$ASSET_NAME" >> "$GITHUB_OUTPUT" + echo "asset-url=$ASSET_URL" >> "$GITHUB_OUTPUT" + + - name: Download Asset + id: download + shell: bash + working-directory: ${{ runner.temp }} + env: + GITHUB_TOKEN: ${{ github.token }} + ASSET_NAME: ${{ steps.resolve-asset.outputs.asset-name }} + ASSET_URL: ${{ steps.resolve-asset.outputs.asset-url }} + run: | + # Check if file already exists + if [ -f "$ASSET_NAME" ]; then + echo "::error::✗ File already exists: $ASSET_NAME" + exit 1 + fi + + echo "Downloading: $ASSET_NAME" + HTTP_CODE=$(curl --fail --location \ + --write-out "%{http_code}" \ + --header "Authorization: token $GITHUB_TOKEN" \ + --output "$ASSET_NAME" \ + "$ASSET_URL" + ) + + if [ $? -ne 0 ]; then + echo "::error::✗ Download failed with HTTP status: $HTTP_CODE" + exit 1 + fi + + echo "✓ Downloaded: \"$ASSET_NAME\"" + echo "filename=$ASSET_NAME" >> $GITHUB_OUTPUT + + - name: Install SDK + shell: bash + working-directory: ${{ runner.temp }} + env: + ASSET_FILENAME: ${{ steps.download.outputs.filename }} + RUNNER_OS: ${{ runner.os }} + OPENDAQ_SDK_ENABLE_32BIT: ${{ inputs.enable-32bit }} + run: | + if [ ! -f "$ASSET_FILENAME" ]; then + echo "::error::✗ Downloaded asset not found: $ASSET_FILENAME" + exit 1 + fi + + # Calculate and display SHA256 for verification + if command -v sha256sum >/dev/null 2>&1; then + ASSET_SHA256=$(sha256sum "$ASSET_FILENAME" | awk '{print $1}') + else + ASSET_SHA256=$(shasum -a 256 "$ASSET_FILENAME" | awk '{print $1}') + fi + + echo "Installing: $ASSET_FILENAME" + echo " SHA256: $ASSET_SHA256" + echo " Size: $(wc -c < "$ASSET_FILENAME") bytes" + + # Install based on file type + case "$ASSET_FILENAME" in + *.deb) + sudo dpkg -i "$ASSET_FILENAME" + if [ $? -ne 0 ]; then + echo "::error::✗ Installation failed" + exit 1 + fi + ;; + *.exe) + powershell.exe -Command " + \$process = Start-Process -FilePath '$ASSET_FILENAME' -ArgumentList '/S' -Wait -NoNewWindow -PassThru; + exit \$process.ExitCode + " + if [ $? -ne 0 ]; then + echo "::error::✗ Installation failed with exit code: $?" + exit 1 + fi + + # Add openDAQ to PATH + if [ "$OPENDAQ_SDK_ENABLE_32BIT" = "true" ]; then + OPENDAQ_BIN_PATH="C:\\Program Files (x86)\\openDAQ\\bin" + else + OPENDAQ_BIN_PATH="C:\\Program Files\\openDAQ\\bin" + fi + echo "$OPENDAQ_BIN_PATH" >> "$GITHUB_PATH" + ;; + *) + echo "::error::✗ Unsupported file type: $ASSET_FILENAME" + exit 1 + ;; + esac + + echo "✓ Installation complete"