diff --git a/.github/dependabot.yml b/.github/dependabot.yml old mode 100644 new mode 100755 index 0bccaf4..241a688 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,7 @@ updates: directory: "/" schedule: interval: "daily" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml old mode 100644 new mode 100755 index 3665dec..96eaeae --- a/.github/workflows/build-container.yml +++ b/.github/workflows/build-container.yml @@ -48,7 +48,6 @@ jobs: uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64 - # platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..c8c1362 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.venv +firmware +.firmware diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100755 index 0000000..b19a8fc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File with Arguments", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "args": [ + "${command:pickArgs}", + "--arch", "nrf52840", + "--board", "xiao_ble", + "--build_script_path", "bin/build-nrf52.sh", + ] + } + ] +} \ No newline at end of file diff --git a/Containerfile b/Containerfile old mode 100644 new mode 100755 index d3efe9c..2030006 --- a/Containerfile +++ b/Containerfile @@ -1,25 +1,17 @@ FROM python:3.12-bookworm ENV PIP_ROOT_USER_ACTION=ignore -# Add build scripts (firmware/bin) to PATH -# RUN git clone --no-checkout --depth 1 https://github.com/meshtastic/firmware.git /meshtastic && \ -# git -C /meshtastic config core.sparseCheckout true && \ -# echo "bin/*" > /meshtastic/.git/info/sparse-checkout && \ -# git -C /meshtastic checkout master -# ENV PATH="/meshtastic/bin:$PATH" - # Install build dependencies RUN apt update && apt install -y \ build-essential \ cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev && \ - # Install DRA (GitHub Releases downloader) - # wget 'https://github.com/devmatteini/dra/releases/download/0.6.2/dra_0.6.2-1_amd64.deb' && \ - # dpkg --install dra_0.6.2-1_amd64.deb && rm dra_0.6.2-1_amd64.deb && \ apt clean && rm -rf /var/lib/apt/lists/* # Install Python dependencies +COPY requirements.txt . RUN python -m pip install --upgrade pip && \ pip install -U --no-build-isolation --no-cache-dir "setuptools<72" && \ + pip install -U --no-build-isolation -r requirements.txt && \ pip install -U platformio adafruit-nrfutil --no-build-isolation && \ pip install -U poetry --no-build-isolation && \ pip install -U meshtastic --pre --no-build-isolation @@ -27,8 +19,6 @@ RUN python -m pip install --upgrade pip && \ # Upgrade PlatformIO RUN pio upgrade -# COPY entrypoint.sh /entrypoint.sh -# ENTRYPOINT [ "/entrypoint.sh" ] - COPY entrypoint.py /entrypoint.py -ENTRYPOINT [ "/entrypoint.py" ] \ No newline at end of file +ENTRYPOINT [ "/entrypoint.py" ] +CMD [ "master" ] \ No newline at end of file diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 4c1d230..cf2b227 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ```yaml uses: vidplace7/build-meshtastic@main with: + git-ref: master arch: nrf52840 board: xiao_ble build-script-path: bin/build-nrf52.sh @@ -13,15 +14,16 @@ with: ## Inputs -| Name | Required | Default | Description | -| --------------------- | -------- | --------- | ----------- | -| `arch` | True | `esp32` | | -| `board` | True | _None_ | | -| `build-script-path` | True | _None_ | | -| `remove-debug-flags` | False | `""` | | -| `ota-firmware-source` | False | `""` | | -| `ota-firmware-target` | False | `""` | | -| `include-web-ui` | False | `"false"` | | +| Name | Required | Default | Description | +| --------------------- | -------- | --------- | --------------------------------------------------------------- | +| `git-ref` | True | `master` | The git ref (tag/branch) of the meshtastic firmware to checkout | +| `arch` | True | `esp32` | | +| `board` | True | _None_ | | +| `build-script-path` | True | _None_ | | +| `remove-debug-flags` | False | `""` | | +| `ota-firmware-source` | False | `""` | | +| `ota-firmware-target` | False | `""` | | +| `include-web-ui` | False | `"false"` | | ## Outputs diff --git a/action.yml b/action.yml old mode 100644 new mode 100755 index 368ee15..0d3a0ea --- a/action.yml +++ b/action.yml @@ -2,6 +2,10 @@ name: Setup Build Variant Composite Action description: Variant build actions for Meshtastic Platform IO steps inputs: + git-ref: + description: The git ref (tag/branch) of the meshtastic firmware to checkout + required: true + default: "master" arch: description: Processor arch name required: true @@ -36,11 +40,11 @@ outputs: runs: using: docker image: docker://ghcr.io/vidplace7/build-meshtastic:main - # env: - # ARCH: ${{ inputs.arch }} - # BOARD: ${{ inputs.board }} - # BUILD_SCRIPT_PATH: ${{ inputs.build-script-path }} - # REMOVE_DEBUG_FLAGS: ${{ inputs.remove-debug-flags }} - # OTA_FIRMWARE_SOURCE: ${{ inputs.ota-firmware-source }} - # OTA_FIRMWARE_TARGET: ${{ inputs.ota-firmware-target }} - # INCLUDE_WEB_UI: ${{ inputs.include-web-ui }} + args: + - ${{ inputs.git-ref }} + - --arch + - ${{ inputs.arch }} + - --board + - ${{ inputs.board }} + - --build_script_path + - ${{ inputs.build-script-path }} diff --git a/entrypoint.py b/entrypoint.py index c2de9a9..6b349a1 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -5,20 +5,45 @@ import requests import tarfile import sys - -inputs = { - 'arch': os.getenv('INPUT_ARCH'), - 'board': os.getenv('INPUT_BOARD'), - 'build-script-path': os.path.normpath(os.getenv('INPUT_BUILD-SCRIPT-PATH')), - 'remove-debug-flags': str(os.getenv('INPUT_REMOVE-DEBUG-FLAGS', '')).split(), - 'ota-firmware-source': os.getenv('INPUT_OTA-FIRMWARE-SOURCE', ''), - 'ota-firmware-target': os.getenv('INPUT_OTA-FIRMWARE-TARGET', ''), - 'include-web-ui': bool(os.getenv('INPUT_INCLUDE-WEB-UI', False)) -} +import shutil +import argparse + +from git import Repo + +# Parse arguments +# Handle CLI and GitHub Actions inputs +parser = argparse.ArgumentParser(description="") +parser.add_argument('git_ref', type=str, + default="master", + help='The tag or branch to clone from the repository.') +parser.add_argument('--git_dir', type=str, required=False, + # Use the GITHUB_WORKSPACE environment variable when running in GitHub Actions + # Otherwise, use the 'firmware' directory (local testing) + default=os.getenv('GITHUB_WORKSPACE', 'firmware'), + help='The directory to clone the meshtastic repository to.') +parser.add_argument('--arch', type=str, required=True, + help='The architecture to build for.') +parser.add_argument('--board', type=str, required=True, + help='The board to build for.') +parser.add_argument('--build_script_path', type=str, required=True, + help='The path to the build script.') +parser.add_argument('--remove_debug_flags', type=list, required=False, + default=str(os.getenv('INPUT_REMOVE-DEBUG-FLAGS', '')).split(), + help='The debug flags to remove from the build.') +parser.add_argument('--ota_firmware_source', type=str, required=False, + default=os.getenv('INPUT_OTA-FIRMWARE-SOURCE', ''), + help='The source path to download the OTA firmware.') +parser.add_argument('--ota_firmware_target', type=str, required=False, + default=os.getenv('INPUT_OTA-FIRMWARE-TARGET', ''), + help='The target path to save the OTA firmware.') +parser.add_argument('--include_web_ui', type=bool, required=False, + default=bool(os.getenv('INPUT_INCLUDE-WEB-UI', False)), + help='Whether to include the web UI in the build.') +args = parser.parse_args() env = { 'GITHUB_ACTIONS': bool(os.getenv('GITHUB_ACTIONS')), - 'XDG_CACHE_HOME': os.path.normpath(os.getenv('XDG_CACHE_HOME')) + 'XDG_CACHE_HOME': os.path.normpath(os.getenv('XDG_CACHE_HOME', '')) } def gh_latest_release(owner, repo): @@ -51,15 +76,27 @@ def extract_tar(tar_file, extract_to, remove_src=False): # ============== -# Fix cache permissions -if os.path.exists(env['XDG_CACHE_HOME']): - os.system(f'chmod -R 777 {env['XDG_CACHE_HOME']}') +# Clone the Meshtastic repo +if env['GITHUB_ACTIONS'] == False: + if os.path.exists(args.git_dir): + shutil.rmtree(args.git_dir) +gh_repo = "meshtastic/firmware" +print(f"Cloning {gh_repo} {args.git_ref} to {args.git_dir}/") +meshtastic_repo = Repo.clone_from("https://github.com/meshtastic/firmware.git", ".firmware", single_branch=True, branch=args.git_ref, recursive=True) +shutil.copytree(".firmware", args.git_dir, dirs_exist_ok=True) +shutil.rmtree(".firmware") +print(f"..Cloned {gh_repo} {args.git_ref} to {args.git_dir}/") -# Workaround for the "safe.directory" issue -os.system("git config --system --add safe.directory /github/workspace") +if env['GITHUB_ACTIONS']: + # Fix cache permissions + if os.path.exists(env['XDG_CACHE_HOME']): + os.system(f'chmod -R 777 {env['XDG_CACHE_HOME']}') + + # Workaround for the "safe.directory" issue + os.system("git config --system --add safe.directory /github/workspace") # Web UI -if inputs['include-web-ui'] == True: +if args.include_web_ui == True: mt_web = gh_latest_release('meshtastic', 'web') for asset in mt_web['assets']: if asset['name'] == 'build.tar': @@ -69,26 +106,34 @@ def extract_tar(tar_file, extract_to, remove_src=False): extract_tar('build.tar','data/static', remove_src=True) # Remove debug flags for release -if len(inputs['remove-debug-flags']) > 0: - for flag in inputs['remove-debug-flags']: +if len(args.remove_debug_flags) > 0: + for flag in args.remove_debug_flags: os.system(f"sed -i /DDEBUG_HEAP/d {flag}") +# Apply custom changes (if any) +if os.path.exists('.custom'): + shutil.copytree(".custom/firmware", args.git_dir, dirs_exist_ok=True) + shutil.rmtree('.custom') + # Run the Build -sys.stdout.flush() -r_build = subprocess.run([inputs['build-script-path'], inputs['board']], check=True) +sys.stdout.flush() # Fix subprocess output buffering issue +build_abspath = os.path.abspath(os.path.join(args.git_dir, args.build_script_path)) +r_build = subprocess.run( + [build_abspath, args.board], + cwd=args.git_dir, check=True) # Pull OTA firmware -if inputs['ota-firmware-source'] != '' and inputs['ota-firmware-target'] != '': +if args.ota_firmware_source != '' and args.ota_firmware_target != '': ota_fw = gh_latest_release('meshtastic', 'firmware-ota') for asset in ota_fw['assets']: - if asset['name'] == inputs['ota-firmware-source']: + if asset['name'] == args.ota_firmware_source: # Download firmware.bin - download_file(asset['browser_download_url'], inputs['ota-firmware-target']) + download_file(asset['browser_download_url'], args.ota_firmware_target) # When running in GitHub Actions if env['GITHUB_ACTIONS']: # Hack! - Add checked-out firmware/bin to the python module path - sys.path.append(os.path.abspath('bin')) + sys.path.append(os.path.join(args.git_dir, 'bin')) from readprops import readProps # type: ignore # /Hack! diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100755 index a719cb8..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -git config --system --add safe.directory /github/workspace - -# Web UI -if [ "$INCLUDE_WEB_UI" = "true" ]; then - # Pull web ui - dra download --select build.tar meshtastic/web --output /tmp/webui.tar - - # Unpack web ui - tar -xf /tmp/webui.tar -C data/static - rm /tmp/webui.tar -fi - -# Remove debug flags for release -if [ "$REMOVE_DEBUG_FLAGS" != "" ]; then - for INI_FILE in $REMOVE_DEBUG_FLAGS; do - sed -i '/DDEBUG_HEAP/d' ${INI_FILE} - done -fi - -# Run the Build -$BUILD_SCRIPT_PATH $BOARD - -# Pull OTA firmware -if [ "$OTA_FIRMWARE_SOURCE" != "" ] && [ "$OTA_FIRMWARE_TARGET" != "" ]; then - dra download --select $OTA_FIRMWARE_SOURCE meshtastic/firmware-ota --output $OTA_FIRMWARE_TARGET -fi - -# When running in GitHub Actions -if [ "$GITHUB_ACTIONS" = "true" ]; then - # Get release version string - echo "version=$(buildinfo.py long)" > $GITHUB_OUTPUT - # Set cache permissions - chmod -R 777 $PLATFORMIO_CACHE_DIR -fi diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000..fef41ca --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests +GitPython +platformio