Thistle Technologies provides a software solution to over-the-air (OTA) updates for embedded devices. This action creates an OTA update release, and publishes it to Thistle's backend platform, to update devices running the Thistle Update Client (TUC).
To use this action, one needs to create an account in the Thistle Control
Center, and obtain the API token ("Project Access
Token"). In case a locally managed OTA update signing key is used, one needs run
the trh keygen
(requiring
TRH
v1.1.0 or above) command to create a password-protected
Minisign private key. For remote signing
(with Thistle-managed Cloud KMS-backed keys, supported in version 1.4.0 and
above), the keygen step isn't needed.
An example workflow for file update is as follows. Confidential information, such as the aforementioned project access token, private signing key, and signing key password are saved as GitHub repository secrets.
name: 'OTA Release'
on:
push:
tags:
# Trigger release by tagging
- 'release-v*'
jobs:
ota_release:
name: 'OTA Release'
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout source'
uses: 'actions/checkout@v4'
- name: 'Create artifacts for OTA release'
run: |
...
[build artifacts from source]
[run tests on artifacts]
...
rm -rf artifacts
mkdir -p artifacts
...
[copy built artifacts to directory artifacts/]
...
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'file'
artifacts_dir: 'artifacts'
persist_dir_on_device: '/ota/persist'
base_install_path_on_device: '/ota/bin'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'local'
signing_key: ${{ secrets.SIGNING_KEY }}
signing_key_password: ${{ secrets.SIGNING_KEY_PASSWORD }}
For rootfs update, configure the "OTA Release" step as
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'rootfs'
rootfs_img_path: '/path/to/rootfs.img'
persist_dir_on_device: '/ota/persist'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'local'
signing_key: ${{ secrets.SIGNING_KEY }}
signing_key_password: ${{ secrets.SIGNING_KEY_PASSWORD }}
For zip archive update, configure the "OTA Release" step as
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'zip_archive'
zip_archive_dir: '/path/to/uncompressed_artifacts_dir'
persist_dir_on_device: '/ota/persist'
base_install_path_on_device: '/ota/bin'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'local'
signing_key: ${{ secrets.SIGNING_KEY }}
signing_key_password: ${{ secrets.SIGNING_KEY_PASSWORD }}
For file update, an example workflow is as follows.
name: 'OTA Release'
on:
push:
tags:
# Trigger release by tagging
- 'release-v*'
jobs:
ota_release:
name: 'OTA Release'
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout source'
uses: 'actions/checkout@v4'
- name: 'Create artifacts for OTA release'
run: |
...
[build artifacts from source]
[run tests on artifacts]
...
rm -rf artifacts
mkdir -p artifacts
...
[copy built artifacts to directory artifacts/]
...
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'file'
artifacts_dir: 'artifacts'
persist_dir_on_device: '/ota/persist'
base_install_path_on_device: '/ota/bin'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'remote'
For rootfs update, configure the "OTA Release" step as
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'rootfs'
rootfs_img_path: '/path/to/rootfs.img'
persist_dir_on_device: '/ota/persist'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'remote'
For zip archive update, configure the "OTA Release" step as
- name: 'OTA Release'
uses: 'thistletech/ota-release-action@v1'
with:
release_name: 'OPTIONAL RELEASE NAME'
release_type: 'zip_archive'
zip_archive_dir: '/path/to/uncompressed_artifacts_dir'
persist_dir_on_device: '/ota/persist'
base_install_path_on_device: '/ota/bin'
project_access_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
signing_key_management: 'remote'
INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
---|---|---|---|---|
artifacts_dir | string | false | Path to the directory where OTA update artifacts are stored |
|
backend_url | string | false | URL of the backend server that runs the OTA update service. If not provided, the Thistle service will be used |
|
base_install_path_on_device | string | false | Path to base directory on device file system where OTA update artifacts will be installed. Required if release_type is "file" or "zip_archive" |
|
persist_dir_on_device | string | true | Path to the directory where the device can persist data |
|
project_access_token | string | true | Project access token can be obtained from the project settings page in Thistle Control Center |
|
release_name | string | false | Display name of the release. If not provided or empty, the unique manifest ID will be used |
|
release_type | string | true | "file" |
Release type ("file", "zip_archive", or "rootfs") |
rootfs_img_path | string | false | Path to the rootfs image file. Required only if release_type is "rootfs" |
|
signing_key | string | false | Minisign signing key in Thistle format. Required only if signing_key_management is "local" |
|
signing_key_management | string | true | "local" |
Indicates how the signing key is managed ("local" or "remote") |
signing_key_password | string | false | Password for the signing key. Required only if signing_key_management is "local" and the signing key is password protected |
|
zip_archive_dir | string | false | Path to the directory whose content will be zipped before releasing. Required only if release_type is "zip_archive" |