-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Docker container action for OTA releases
Create a Docker container action (cf. https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action) for OTA releases. In this initial version, we support file updates with a locally managed minisign key. Add a test workflow to exercise the action.
- Loading branch information
Showing
4 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: 'Test OTA Release' | ||
|
||
on: | ||
push: | ||
branches: | ||
- 'main' | ||
pull_request: | ||
branches: | ||
- 'main' | ||
|
||
jobs: | ||
test_ota_release: | ||
name: 'Test OTA Release Action' | ||
runs-on: 'ubuntu-latest' | ||
steps: | ||
- name: 'Checkout' | ||
uses: 'actions/checkout@v4' | ||
|
||
- name: 'Create artifacts for test' | ||
run: | | ||
mkdir -p artifacts | ||
hello_time="$(date +'%Y-%m-%dT%H:%M:%S%z')" | ||
echo "${hello_time}: Hello, World!" > artifacts/hello.txt | ||
sleep 4.2 | ||
goodbye_time="$(date +'%Y-%m-%dT%H:%M:%S%z')" | ||
echo "${goodbye_time}: Goodbye, World!" > artifacts/goodbye.txt | ||
- name: 'Test OTA Release' | ||
uses: './' # Use an action in the root directory | ||
with: | ||
release_type: 'file' | ||
persist_dir: '/tmp/persist' | ||
artifacts_dir: 'artifacts' | ||
base_install_path_on_device: '/tmp/ota' | ||
project_access_token: ${{ secrets.TEST_PROJECT_ACCESS_TOKEN }} | ||
signing_key_mangement: 'local' | ||
signing_key: ${{ secrets.TEST_SIGNING_KEY }} | ||
signing_key_password: ${{ secrets.TEST_SIGNING_KEY_PASSWORD }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM alpine:3.10 | ||
|
||
RUN apk add --no-cache bash curl gzip | ||
|
||
COPY entrypoint.sh /entrypoint.sh | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: 'Create OTA Release' | ||
description: 'Creates OTA update releases' | ||
author: 'Ning Shang (Thistle Technologies)' | ||
inputs: | ||
release_type: | ||
description: 'Release type ("file", "zip_archive", or "rootfs")' | ||
required: true | ||
default: 'file' | ||
persist_dir: | ||
description: 'Path to the directory where the device can persist data' | ||
required: true | ||
default: '' | ||
artifacts_dir: | ||
description: 'Path to the directory where OTA update artifacts are stored' | ||
required: false | ||
default: '' | ||
rootfs_img_path: | ||
description: 'Path to the rootfs image file. Required only if release_type is "rootfs"' | ||
required: false | ||
default: '' | ||
zip_archive_path: | ||
description: 'Path to the zip archive file. Required only if release_type is "archive"' | ||
required: false | ||
default: '' | ||
base_install_path_on_device: | ||
description: 'Path to base directory on device file system where OTA update artifacts will be installed. Required if release_type is "file" or "archive"' | ||
required: false | ||
default: '' | ||
project_access_token: | ||
description: 'Project access token can be obtained from the project settings page in Thistle Control Center' | ||
required: true | ||
default: '' | ||
signing_key_mangement: | ||
description: 'Incidates how the signing key is managed ("local" or "remote")' | ||
required: true | ||
default: 'local' | ||
signing_key: | ||
description: 'Minisign signing key in Thistle format. Required only if signing_key_mangement is "local"' | ||
required: false | ||
default: '' | ||
signing_key_password: | ||
description: 'Password for the signing key. Required only if signing_key_mangement is "local" and the signing key is password protected' | ||
required: false | ||
default: '' | ||
runs: | ||
using: 'docker' | ||
image: 'Dockerfile' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Environment variables: | ||
# They are created from an input in a workflow file or a default value by | ||
# GitHub, with the name INPUT_<VARIABLE_NAME>. Cf., | ||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions. | ||
# | ||
# The following environment variables correspond to the input identifiers in | ||
# action.yml. | ||
# | ||
# INPUT_RELEASE_TYPE | ||
# INPUT_PERSIST_DIR | ||
# INPUT_ARTIFACTS_DIR | ||
# INPUT_ROOTFS_IMG_PATH | ||
# INPUT_ZIP_ARCHIVE_PATH | ||
# INPUT_BASE_INSTALL_PATH_ON_DEVICE | ||
# INPUT_PROJECT_ACCESS_TOKEN | ||
# INPUT_SIGNING_KEY_MANAGEMENT | ||
# INPUT_SIGNING_KEY | ||
# INPUT_SIGNING_KEY_PASSWORD | ||
# | ||
|
||
set -euxo pipefail | ||
|
||
SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" | ||
readonly SCRIPT_DIR | ||
TRH_BINARY_PATH="${SCRIPT_DIR}/trh" | ||
readonly TRH_BINARY_PATH | ||
TRH_DOWNLOAD_URL="https://downloads.thistle.tech/embedded-client/1.0.0/trh-1.0.0-x86_64-unknown-linux-musl.gz" | ||
readonly TRH_DOWNLOAD_URL | ||
|
||
# Set environment variables | ||
export THISTLE_KEY="${HOME}/.minisign/minisign.key" | ||
export THISTLE_KEY_PASS="${INPUT_SIGNING_KEY_PASSWORD}" | ||
export THISTLE_TOKEN="${INPUT_PROJECT_ACCESS_TOKEN}" | ||
|
||
download_trh() { | ||
curl -A "curl (ota_release_action)" -L -o /tmp/trh.gz "${TRH_DOWNLOAD_URL}" | ||
gunzip -c /tmp/trh.gz > "${TRH_BINARY_PATH}" | ||
chmod +x "${TRH_BINARY_PATH}" | ||
"${TRH_BINARY_PATH}" --version | ||
} | ||
|
||
file_release() { | ||
# Hack alert: Need to do this to get a manifest template | ||
mkdir -p "$(dirname "${THISTLE_KEY}")" | ||
echo "${INPUT_SIGNING_KEY}" > "${THISTLE_KEY}" | ||
cat "${THISTLE_KEY}" | ||
"${TRH_BINARY_PATH}" init --persist="${INPUT_PERSIST_DIR}" | ||
|
||
local artifacts_dir="${INPUT_ARTIFACTS_DIR:-}" | ||
local base_install_path="${INPUT_BASE_INSTALL_PATH_ON_DEVICE:-}" | ||
[ -z "${artifacts_dir}" ] && { echo "No artifacts directory provided"; exit 1; } | ||
[ -z "${base_install_path}" ] && { echo "No base install path provided"; exit 1; } | ||
|
||
"${TRH_BINARY_PATH}" prepare --target="${artifacts_dir}" --file-base-path="${base_install_path}" | ||
|
||
"${TRH_BINARY_PATH}" release | ||
|
||
echo "done" | ||
} | ||
|
||
rootfs_release() { | ||
echo "Not implemented" | ||
exit 1 | ||
} | ||
|
||
zip_archive_release() { | ||
echo "Not implemented" | ||
exit 1 | ||
} | ||
|
||
do_it() { | ||
|
||
local release_type="${INPUT_RELEASE_TYPE:-}" | ||
[ -z "${release_type}" ] && { echo "No release type provided"; exit 1; } | ||
|
||
download_trh | ||
|
||
case "${INPUT_RELEASE_TYPE}" in | ||
"file") | ||
file_release | ||
;; | ||
"rootfs") | ||
rootfs_release | ||
;; | ||
"zip_archive") | ||
zip_archive_release | ||
;; | ||
*) | ||
echo "Unknown release type: ${INPUT_RELEASE_TYPE}" | ||
exit 1 | ||
;; | ||
esac | ||
} | ||
|
||
do_it |