Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
73 changes: 64 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,78 @@ on:
branches: [ master ]
workflow_dispatch:

permissions:
contents: read

jobs:
check:
name: Lint and Typecheck
runs-on: ubuntu-24.04
build:
name: Check and Build
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v6
with:
submodules: true

- name: Cache cargo
uses: actions/cache@v5
with:
path: ~/.cargo
key: cargo-stylua-${{ runner.os }}

- name: Install tools
run: make install-tools

- name: Run checks
run: make check

- name: Set version
env:
EVENT: ${{ github.event_name }}
PR: ${{ github.event.pull_request.number }}
# On pull_request, github.sha is GitHub's temporary merge commit.
SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
version="${SHA::7}"
if [ "$EVENT" = pull_request ]; then
zip_name="expresslrs-lua-pr${PR}-${version}"
elif [ "$GITHUB_REF" = refs/heads/master ]; then
zip_name=expresslrs-lua-nightly
else
zip_name="expresslrs-lua-${GITHUB_REF_NAME//\//-}-${version}"
fi
echo "VERSION=$version" >> "$GITHUB_ENV"
echo "ZIP_NAME=$zip_name" >> "$GITHUB_ENV"

- name: Build
run: make build VERSION="$VERSION" ZIP_NAME="$ZIP_NAME"

- uses: actions/upload-artifact@v4
with:
name: ${{ env.ZIP_NAME }}
path: dist/*.zip
if-no-files-found: error

nightly:
name: Publish Nightly
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-26.04
permissions:
contents: write
concurrency:
group: nightly
cancel-in-progress: true
steps:
- uses: actions/download-artifact@v4
with:
name: expresslrs-lua-nightly
path: dist

- name: Publish release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release delete nightly --repo "$GITHUB_REPOSITORY" --cleanup-tag --yes || true
gh release create nightly dist/*.zip \
--repo "$GITHUB_REPOSITORY" \
--target "$GITHUB_SHA" \
--title "Nightly (development build)" \
--prerelease \
--latest=false \
--notes "**Development build, not a stable release.** Built automatically from the latest \`master\` commit ($GITHUB_SHA). It may contain unfinished or untested changes; for normal use, install the [latest release](https://github.com/$GITHUB_REPOSITORY/releases/latest).

The tools show version \`${GITHUB_SHA::7}\`. To install, extract the zip onto the SD card root."
60 changes: 60 additions & 0 deletions .github/workflows/pr-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: PR Build Comment

# Runs in the base repository's context so it can comment on fork PRs.
# It never checks out or runs PR code.
on:
workflow_run:
workflows: [ CI ]
types: [ completed ]

permissions:
actions: read
pull-requests: write

jobs:
comment:
if: github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-26.04
steps:
- name: Post build comment
env:
GH_TOKEN: ${{ github.token }}
SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.event.workflow_run.id }}
RUN_URL: ${{ github.event.workflow_run.html_url }}
CONCLUSION: ${{ github.event.workflow_run.conclusion }}
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
run: |
marker='<!-- expresslrs-lua-build -->'

pr=$(gh pr list --repo "$GITHUB_REPOSITORY" --state open --limit 200 \
--json number,headRefOid --jq ".[] | select(.headRefOid == \"$SHA\") | .number" | head -n 1)
if [ -z "$pr" ]; then
echo "No open PR for $SHA"
exit 0
fi

if [ "$CONCLUSION" = success ]; then
artifact=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/artifacts" \
--jq '.artifacts[] | select(.name | startswith("expresslrs-lua-")) | "\(.id) \(.name)"' | head -n 1)
read -r artifact_id artifact_name <<< "$artifact"
body="$marker
### Test build for ${SHA::7}

- Download: [$artifact_name.zip](https://github.com/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/artifacts/$artifact_id) (requires a GitHub login; extract it, then extract the inner zip onto the SD card root). The tools show version \`${SHA::7}\`.
- Or install from source with: \`edgetx-cli pkg install $HEAD_REPO@$HEAD_BRANCH\` (shows version \`dev\`)"
else
body="$marker
### Build failed for ${SHA::7}

See the [CI run]($RUN_URL)."
fi

comment_id=$(gh api --paginate "repos/$GITHUB_REPOSITORY/issues/$pr/comments" \
--jq ".[] | select(.body | startswith(\"$marker\")) | .id" | head -n 1)
if [ -n "$comment_id" ]; then
gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/comments/$comment_id" -f body="$body" > /dev/null
else
gh pr comment "$pr" --repo "$GITHUB_REPOSITORY" --body "$body"
fi
51 changes: 51 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Release

on:
push:
tags: [ 'v[0-9]*' ]

permissions:
contents: write

jobs:
release:
name: Build and Release
runs-on: ubuntu-26.04
steps:
- name: Check tag
run: |
# No pre-release suffixes: "1.1.0-rc.1" does not fit the B&W EXIT labels.
if ! [[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::Release tags must be vMAJOR.MINOR.PATCH, got $GITHUB_REF_NAME"
exit 1
fi

- uses: actions/checkout@v6
with:
submodules: true
fetch-depth: 0

- name: Install tools
run: make install-tools

- name: Run checks
run: make check

- name: Build
run: make build VERSION="${GITHUB_REF_NAME#v}" ZIP_NAME="expresslrs-lua-$GITHUB_REF_NAME"

- name: Publish release
env:
GH_TOKEN: ${{ github.token }}
run: |
# Without an explicit start tag GitHub may diff against the nightly prerelease.
args=()
if prev=$(git describe --tags --abbrev=0 --match 'v[0-9]*' "$GITHUB_REF_NAME^" 2>/dev/null); then
args+=(--notes-start-tag "$prev")
fi
gh release create "$GITHUB_REF_NAME" dist/*.zip \
--repo "$GITHUB_REPOSITORY" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--latest \
"${args[@]}"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ src/SCRIPTS/TOOLS/ExpressLRSBind/history.txt
bin/
.claude/plans/
TODO.md
dist/
2 changes: 1 addition & 1 deletion .luarc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"bit32": "disable"
},
"workspace.library": ["edgetx-lua-stdlib"],
"workspace.ignoreDir": ["bin", "edgetx-lua-stdlib", "legacy"],
"workspace.ignoreDir": ["bin", "dist", "edgetx-lua-stdlib", "legacy"],
"workspace.checkThirdParty": false,
"diagnostics.disable": ["lowercase-global"]
}
52 changes: 44 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,46 +1,82 @@
SRC_DIR := src
DIST_DIR := dist
STAGE_DIR := $(DIST_DIR)/sdcard
# Shown in the tools: at most 8 characters fit the B&W EXIT labels.
VERSION ?= $(or $(shell git rev-parse HEAD 2>/dev/null | cut -c1-7),dev)
ZIP_NAME ?= expresslrs-lua-$(VERSION)

STYLUA_VERSION := 2.3.1
STYLUA := bin/stylua
STYLUA_URL := https://github.com/JohnnyMorganz/StyLua/releases/download/v$(STYLUA_VERSION)/stylua-linux-x86_64.zip

LUALS_VERSION := 3.17.1
LUALS_DIR := bin/lua-language-server
LUALS := $(LUALS_DIR)/bin/lua-language-server
LUALS_URL := https://github.com/LuaLS/lua-language-server/releases/download/$(LUALS_VERSION)/lua-language-server-$(LUALS_VERSION)-linux-x64.tar.gz

.PHONY: help install-tools install-stylua install-luals format format-check typecheck check sync push
LUAC_VERSION := 1.0.0
LUAC_DIR := bin/edgetx-luac
LUAC := $(LUAC_DIR)/edgetx-luac
LUAC_URL := https://github.com/EdgeTX/edgetx-luac-action/releases/download/v$(LUAC_VERSION)/edgetx-luac-v$(LUAC_VERSION)-linux-x64.tar.gz

.PHONY: help install-tools install-stylua install-luals install-luac format format-check typecheck check build sync push

help:
@echo "Usage: make <target>"
@echo ""
@echo " install-tools Install stylua and lua-language-server"
@echo " install-stylua Install stylua (via cargo)"
@echo " install-tools Install stylua, lua-language-server and edgetx-luac"
@echo " install-stylua Install stylua"
@echo " install-luals Install lua-language-server"
@echo " install-luac Install the EdgeTX Lua compiler"
@echo " format Format Lua files with stylua"
@echo " format-check Check formatting without modifying files"
@echo " typecheck Run lua-language-server type checking"
@echo " check Run format-check and typecheck"
@echo " build Build an SD card zip with compiled bytecode (VERSION=, ZIP_NAME=)"
@echo " sync Sync source files to EdgeTX simulator SD card"
@echo " push Install package to EdgeTX radio and eject"

install-stylua:
@command -v cargo >/dev/null 2>&1 || { echo "cargo is required (install Rust: https://rustup.rs)"; exit 1; }
cargo install stylua --features lua53
mkdir -p bin
curl -fSL -o bin/stylua.zip $(STYLUA_URL)
unzip -o -q bin/stylua.zip -d bin
rm bin/stylua.zip
chmod +x $(STYLUA)

install-luals:
mkdir -p $(LUALS_DIR)
curl -fSL $(LUALS_URL) | tar xz -C $(LUALS_DIR)

install-tools: install-stylua install-luals
install-luac:
mkdir -p $(LUAC_DIR)
curl -fSL $(LUAC_URL) | tar xz -C $(LUAC_DIR)

install-tools: install-stylua install-luals install-luac

format:
stylua $(SRC_DIR)
$(STYLUA) $(SRC_DIR)

format-check:
stylua --check $(SRC_DIR)
$(STYLUA) --check $(SRC_DIR)

typecheck:
$(LUALS) --check .

check: format-check typecheck

# Keep in sync with the dev libraries and excludes in edgetx.yml.
build:
rm -rf $(DIST_DIR)
mkdir -p $(STAGE_DIR)
cp -r $(SRC_DIR)/SCRIPTS $(SRC_DIR)/WIDGETS $(STAGE_DIR)/
rm -rf $(STAGE_DIR)/SCRIPTS/CRSFSimulator
rm -f $(STAGE_DIR)/SCRIPTS/TOOLS/ExpressLRSBind/history.txt $(STAGE_DIR)/WIDGETS/ELRSVTXAdmin/presets.txt
find $(STAGE_DIR) -name '*.luac' -delete
printf 'return "%s"\n' '$(VERSION)' > $(STAGE_DIR)/SCRIPTS/ELRS/version.lua
find $(STAGE_DIR) -name '*.lua' | while read -r f; do $(LUAC) -s -o "$${f}c" "$$f" || exit 1; done
cd $(STAGE_DIR) && zip -q -r ../$(ZIP_NAME).zip SCRIPTS WIDGETS
@echo "Built $(DIST_DIR)/$(ZIP_NAME).zip (version $(VERSION))"

sync:
edgetx-cli dev sync ../edgetx-sdcard

Expand Down
7 changes: 7 additions & 0 deletions src/SCRIPTS/ELRS/version.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---------------------------------------------------------------------------
-- Package Version --
-- "dev" in the source tree; release builds write the semver version --
-- (or a short commit hash) here. --
---------------------------------------------------------------------------

return "dev"
3 changes: 2 additions & 1 deletion src/SCRIPTS/TOOLS/ExpressLRS/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
---- # Unified tool for BW and color LCD radios (EdgeTX 2.11.6+/2.12.1+) #
---- #########################################################################

local VERSION = "r3"
local useLvgl = (lvgl ~= nil)

---@diagnostic disable-next-line: need-check-nil
local loader = loadScript("/SCRIPTS/ELRS/loader.lua")()

local VERSION = loader("/SCRIPTS/ELRS/version.lua")

local crsf = loader("/SCRIPTS/ELRS/crsf.lua")
local params = loader("/SCRIPTS/ELRS/crsf_params.lua", crsf)
local CRSFSession = loader("/SCRIPTS/ELRS/crsf_session.lua", crsf, params)
Expand Down
3 changes: 2 additions & 1 deletion src/SCRIPTS/TOOLS/ExpressLRSBind/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- #########################################################################

local VERSION = "r1"
local useLvgl = (lvgl ~= nil)

---@diagnostic disable-next-line: need-check-nil
local loader = loadScript("/SCRIPTS/ELRS/loader.lua")()

local VERSION = loader("/SCRIPTS/ELRS/version.lua")

local crsf = loader("/SCRIPTS/ELRS/crsf.lua")
local msp = loader("/SCRIPTS/ELRS/msp.lua", crsf)
local defer = loader("/SCRIPTS/ELRS/defer.lua")
Expand Down
Loading