From 33ed226b9db709a1a3dc112d2aa3f974218f0b8d Mon Sep 17 00:00:00 2001 From: vidplace7 Date: Sat, 5 Oct 2024 16:28:32 -0400 Subject: [PATCH] entrypoint.py --- .github/workflows/build-container.yml | 56 +++++++++++++++ Containerfile | 23 ++++--- README.md | 8 +-- action.yml | 18 ++--- entrypoint.py | 98 +++++++++++++++++++++++++++ entrypoint.sh | 8 ++- 6 files changed, 185 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/build-container.yml create mode 100755 entrypoint.py diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml new file mode 100644 index 0000000..d0c41e7 --- /dev/null +++ b/.github/workflows/build-container.yml @@ -0,0 +1,56 @@ +name: Build Meshtastic build container +on: + push: + # build and push anytime commits are pushed/merged + branches: + - main + release: + # build and push upon release creation + types: + - created + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build_and_push_latest: + runs-on: ubuntu-24.04 + name: Build and push upon merge + permissions: + contents: read + packages: write + id-token: write + attestations: write + + steps: + - uses: actions/checkout@v4 + + - uses: docker/setup-qemu-action@v3 + + - uses: docker/setup-buildx-action@v3 + + - name: Docker Login GHCR + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64,linux/arm64 + # platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Containerfile b/Containerfile index 367116d..d3efe9c 100644 --- a/Containerfile +++ b/Containerfile @@ -1,20 +1,20 @@ FROM python:3.12-bookworm ENV PIP_ROOT_USER_ACTION=ignore -# Add build scripts 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" +# 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 && \ + # 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 @@ -27,5 +27,8 @@ RUN python -m pip install --upgrade pip && \ # Upgrade PlatformIO RUN pio upgrade -COPY entrypoint.sh /entrypoint.sh -ENTRYPOINT [ "/entrypoint.sh" ] +# COPY entrypoint.sh /entrypoint.sh +# ENTRYPOINT [ "/entrypoint.sh" ] + +COPY entrypoint.py /entrypoint.py +ENTRYPOINT [ "/entrypoint.py" ] \ No newline at end of file diff --git a/README.md b/README.md index 253fa60..4c1d230 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ ```yaml uses: vidplace7/build-meshtastic@main with: - board: - github_token: - build-script-path: - arch: + arch: nrf52840 + board: xiao_ble + build-script-path: bin/build-nrf52.sh ``` ## Inputs @@ -22,7 +21,6 @@ with: | `remove-debug-flags` | False | `""` | | | `ota-firmware-source` | False | `""` | | | `ota-firmware-target` | False | `""` | | -| `artifact-paths` | False | `""` | | | `include-web-ui` | False | `"false"` | | diff --git a/action.yml b/action.yml index 75302c8..368ee15 100644 --- a/action.yml +++ b/action.yml @@ -35,12 +35,12 @@ outputs: runs: using: docker - image: Dockerfile - 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 }} + 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 }} diff --git a/entrypoint.py b/entrypoint.py new file mode 100755 index 0000000..1d58efc --- /dev/null +++ b/entrypoint.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import requests +import tarfile +import sys + +inputs = { + 'arch': os.getenv('INPUT_ARCH'), + 'board': os.getenv('INPUT_BOARD'), + 'build-script-path': os.path(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)) +} + +env = { + 'GITHUB_ACTIONS': bool(os.getenv('GITHUB_ACTIONS')), + 'XDG_CACHE_HOME': os.path(os.getenv('XDG_CACHE_HOME')) +} + +def gh_latest_release(owner, repo): + r = requests.get(f"https://api.github.com/repos/{owner}/{repo}/releases/latest") + r_j = r.json() + if r.status_code == 200: + return r_j + else: + raise Exception(f"Failed to fetch latest release from {owner}/{repo}") + +def download_file(url, dest): + print(f"Downloading {url} to {dest}") + r = requests.get(url, stream=True) + with open(dest, 'wb') as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + +def extract_tar(tar_file, extract_to, remove_src=False): + print(f"Extracting {tar_file} to {extract_to}") + with tarfile.open(tar_file, 'r') as tar: + tar.extractall(extract_to) + if remove_src == True: + print(f"..Cleaning up {tar_file}") + os.remove(tar_file) + +# ============== + +# 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: + mt_web = gh_latest_release('meshtastic', 'web') + for asset in mt_web['assets']: + if asset['name'] == 'build.tar': + # Download build.tar + download_file(asset['browser_download_url'], 'build.tar') + # Extract build.tar + 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']: + os.system(f"sed -i /DDEBUG_HEAP/d {flag}") + +# Run the Build +r_build = subprocess.run([inputs['build-script-path'], inputs['board']], check=True) + +# Pull OTA firmware +if inputs['ota-firmware-source'] != '' and inputs['ota-firmware-target'] != '': + ota_fw = gh_latest_release('meshtastic', 'firmware-ota') + for asset in ota_fw['assets']: + if asset['name'] == inputs['ota-firmware-source']: + # Download firmware.bin + download_file(asset['browser_download_url'], inputs['ota-firmware-target']) + +# When running in GitHub Actions +if env['GITHUB_ACTIONS']: + # Hack! - Add checked-out firmware/bin to the python module path + cwd_bin = os.path.join(os.getcwd(), 'bin') + sys.path.append(cwd_bin) + from readprops import readProps # type: ignore + # /Hack! + + # Get release version string + verObj = readProps("version.properties") + version_str = verObj['long'] + # Write version string to GitHub Actions output + with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: + print(f'version={version_str}', file=fh) + + # Fix cache permissions + os.system(f'chmod -R 777 {env['XDG_CACHE_HOME']}') diff --git a/entrypoint.sh b/entrypoint.sh index 3162de2..a719cb8 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,4 +1,5 @@ #!/bin/bash +git config --system --add safe.directory /github/workspace # Web UI if [ "$INCLUDE_WEB_UI" = "true" ]; then @@ -22,10 +23,13 @@ $BUILD_SCRIPT_PATH $BOARD # Pull OTA firmware if [ "$OTA_FIRMWARE_SOURCE" != "" ] && [ "$OTA_FIRMWARE_TARGET" != "" ]; then - dra download --select $OTA_FIRMWARE_SOURCE --output $OTA_FIRMWARE_TARGET + dra download --select $OTA_FIRMWARE_SOURCE meshtastic/firmware-ota --output $OTA_FIRMWARE_TARGET fi -# Get release version string when running in GitHub Actions +# 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