-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/build release #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5728bc4
Add automatic builds that contain examples on release
malcolm-sparkfun 5de809f
Add unmount of immutable directory and persistent tracking so expandi…
malcolm-sparkfun 0885da7
update names for frozen examples
malcolm-sparkfun fa2d97a
pedantic fixes
malcolm-sparkfun fe4cc0d
Use built in extraction of freezefs to simplify build script
malcolm-sparkfun 95c72eb
Update content of PERSISTENT_FILE_FOR_UNPACK
sfe-SparkFro 4fc3bbe
Update build.sh
sfe-SparkFro 65cb21a
Merge branch 'features_for_launch' into feature/build_release
sfe-SparkFro c37d7b3
Change release workflow to rename firmware file
sfe-SparkFro b6b5958
build.sh: only copy frozen directory if different
sfe-SparkFro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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,23 @@ | ||
name: Build and Deploy Firmware Release | ||
|
||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
with: | ||
submodules: true | ||
- name: Build Firmware | ||
run: source build.sh && build_micropython_opencv | ||
- name: Upload Release Assets | ||
uses: shogo82148/actions-upload-release-asset@v1 | ||
with: | ||
asset_path: "micropython/ports/rp2/build-SPARKFUN_XRP_CONTROLLER-LARGE_BINARY/firmware.uf2" | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
upload_url: ${{ github.event.release.upload_url }} | ||
|
This file contains hidden or 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,198 @@ | ||
if which nproc > /dev/null; then | ||
MAKEOPTS="-j$(nproc)" | ||
else | ||
MAKEOPTS="-j$(sysctl -n hw.ncpu)" | ||
fi | ||
|
||
# TODO: Could also make these opts into the build_micropython_opencv function if we care... | ||
FROZEN_MODULES_DIR="$(dirname "$0")/frozen_modules" | ||
FROZEN_EXAMPLES_ARCHIVE_SCRIPT="frozen_examples.py" | ||
FROZEN_EXAMPLES_UNPACKED_DIR="micropython-opencv-examples" | ||
PERSISTENT_FILE_FOR_UNPACK="/keep_opencv_example_changes" | ||
malcolm-sparkfun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Uses freezefs to create a frozen filesystem archive for the provided directory. | ||
# See https://github.com/bixb922/freezefs for more details on freezefs | ||
# Options: | ||
# $1: The directory to freeze | ||
# $2: The name that you want the frozen directory to have once unpacked on the board | ||
# $3: The output file name for the frozen archive .py file | ||
function create_frozen_fs { | ||
local DIR_TO_FREEZE=$1 | ||
local DIR_NAME_ON_BOARD=$2 | ||
local OUTPUT_FILE=$3 | ||
|
||
echo "Creating frozen filesystem for directory: $DIR_TO_FREEZE" | ||
echo "The frozen directory will be named: $DIR_NAME_ON_BOARD" | ||
echo "The output file will be: $OUTPUT_FILE" | ||
|
||
cp -r $DIR_TO_FREEZE $DIR_NAME_ON_BOARD | ||
|
||
python -m freezefs $DIR_NAME_ON_BOARD $OUTPUT_FILE | ||
sfe-SparkFro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
# Options: | ||
# $1: The directory to add to the manifest | ||
# $2: The port (e.g. rp2) | ||
# $3: The board (e.g. SPARKFUN_XRP_CONTROLLER) | ||
# $4: The mpconfigboard file name (e.g. mpconfigboard.cmake or mpconfigboard.m) Default: mpconfigboard.cmake | ||
function add_to_manifest { | ||
local DIR=$1 | ||
local PORT=$2 | ||
local BOARD=$3 | ||
local MPCONFIG_FILE="${4:-mpconfigboard.cmake}" | ||
|
||
# Add the directory to the manifest file | ||
echo "Adding $DIR to the manifest for $PORT on $BOARD using $MPCONFIG_FILE" | ||
local BOARD_DIR="micropython/ports/${PORT}/boards/${BOARD}" | ||
|
||
# Create manifest.py if it doesn't exist | ||
if [ ! -f ${BOARD_DIR}/manifest.py ]; then | ||
echo "include(\"\$(PORT_DIR)/boards/manifest.py\")" > ${BOARD_DIR}/manifest.py | ||
|
||
# also add the necessary frozen manifest line to mpconfigboard.cmake: set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) | ||
# We will use the optional MPCONFIG_FILE argument to determine if we should add this line | ||
|
||
if [ -n "$MPCONFIG_FILE" ]; then | ||
if [[ $MPCONFIG_FILE == *.mk ]]; then | ||
# e.g. for TEENSY which uses mpconfigboard.mk instead of mpconfigboard.cmake | ||
echo "Adding frozen manifest line to mpconfigboard.mk for $BOARD" | ||
printf "\nFROZEN_MANIFEST ?= \$(BOARD_DIR)/manifest.py" >> ${BOARD_DIR}/$MPCONFIG_FILE | ||
elif [[ $MPCONFIG_FILE == *.cmake ]]; then | ||
echo "Adding frozen manifest line to mpconfigboard.cmake for $BOARD" | ||
malcolm-sparkfun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
printf "\nset(MICROPY_FROZEN_MANIFEST \"\${MICROPY_BOARD_DIR}/manifest.py\")" >> ${BOARD_DIR}/$MPCONFIG_FILE | ||
fi | ||
fi | ||
fi | ||
|
||
# Add the freeze line to the manifest.py for the board | ||
echo "Adding freeze line to manifest.py for $BOARD" | ||
printf "\nfreeze(\"${DIR}\")" >> ${BOARD_DIR}/manifest.py | ||
malcolm-sparkfun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Helpful for debugging during the build process, but can be removed if we'd rather not see this output... | ||
echo "Manifest.py for $BOARD:" | ||
cat ${BOARD_DIR}/manifest.py | ||
} | ||
|
||
# Adds the frozen data filesystem to the boot.py file for the given port | ||
malcolm-sparkfun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Options: | ||
# $1: Port name | ||
# $2: Frozen data file path | ||
# $3: Copy Source: If copying imported frozen data to a mutable location, this is the directory name of the source (optional) | ||
# $4: Copy Destination: If copying imported frozen data to a mutable location, this is the directory name of the destination (optional) | ||
# $5: Add destination to sys.path? If true, the destination directory will be added to sys.path in _boot.py (optional) | ||
# NOTE: By providing the source and destination, the frozen data filesystem will be copied to a mutable location on the board | ||
# If they are not provided, the frozen data filesystem will still be accessible, but will be read-only. | ||
function add_frozen_data_to_boot_for_port { | ||
local TARGET_PORT_NAME=$1 | ||
local FROZEN_DATA_FILE=$2 | ||
local SOURCE_DIR=$3 | ||
local DESTINATION_DIR=$4 | ||
local ADD_TO_SYSPATH=${5:-false} | ||
|
||
# Remove the ".py" extension from the frozen data file | ||
local FROZEN_DATA_BASENAME=$(basename $FROZEN_DATA_FILE .py) | ||
|
||
# Check if the _boot.py file exists in the port's modules directory and error out if it does not | ||
if [ ! -f micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py ]; then | ||
echo "Error: _boot.py file not found in ports/${TARGET_PORT_NAME}/modules/" | ||
exit 1 | ||
fi | ||
|
||
# Add the frozen data filesystem to the _boot.py file | ||
local BOOT_FILE="micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py" | ||
|
||
# Create our "persistent file for unpack" that will be used to check if the frozen data filesystem has already been unpacked | ||
# If it has not been unpacked, we will import the frozen data filesystem | ||
echo "Adding frozen data filesystem to ${BOOT_FILE}" | ||
echo "import os" >> ${BOOT_FILE} | ||
echo "try:" >> ${BOOT_FILE} | ||
echo " os.stat('${PERSISTENT_FILE_FOR_UNPACK}')" >> ${BOOT_FILE} | ||
echo "except OSError:" >> ${BOOT_FILE} | ||
echo " import ${FROZEN_DATA_BASENAME}" >> ${BOOT_FILE} | ||
echo " with open('${PERSISTENT_FILE_FOR_UNPACK}', 'w') as f:" >> ${BOOT_FILE} | ||
echo " f.write('Hi! Delete this file to restore the ${FROZEN_EXAMPLES_UNPACKED_DIR} to its default state. WARNING: This will override ALL of your changes to that directory.')" >> ${BOOT_FILE} | ||
|
||
# Now, copy the unpacked frozen data filesystem to a mutable location if the source and destination are provided | ||
# Simple recursive function to copy the directory tree (since i.e. shutil.copytree is not available on MicroPython) | ||
if [ -n "$SOURCE_DIR" ] && [ -n "$DESTINATION_DIR" ]; then | ||
echo "Copying frozen data from ${SOURCE_DIR} to ${DESTINATION_DIR} in _boot.py" | ||
local BOOT_FILE="micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py" | ||
echo " def copytree(src, dst):" >> ${BOOT_FILE} | ||
echo " try:" >> ${BOOT_FILE} | ||
echo " os.mkdir(dst)" >> ${BOOT_FILE} | ||
echo " except OSError:" >> ${BOOT_FILE} | ||
echo " pass" >> ${BOOT_FILE} | ||
echo " for entry in os.ilistdir(src):" >> ${BOOT_FILE} | ||
echo " fname, typecode, _, _ = entry" >> ${BOOT_FILE} | ||
echo " src_path = src + '/' + fname" >> ${BOOT_FILE} | ||
echo " dst_path = dst + '/' + fname" >> ${BOOT_FILE} | ||
echo " if typecode == 0x4000:" >> ${BOOT_FILE} # typecode == 0x4000 means directory | ||
echo " copytree(src_path, dst_path)" >> ${BOOT_FILE} | ||
echo " else:" >> ${BOOT_FILE} | ||
echo " with open(src_path, 'rb') as fsrc:" >> ${BOOT_FILE} | ||
echo " with open(dst_path, 'wb') as fdst:" >> ${BOOT_FILE} | ||
echo " fdst.write(fsrc.read())" >> ${BOOT_FILE} | ||
echo " copytree('${SOURCE_DIR}', '${DESTINATION_DIR}')" >> ${BOOT_FILE} | ||
# Finally, unmount the source directory if it is mounted | ||
echo " try:" >> ${BOOT_FILE} | ||
echo " os.umount('/${SOURCE_DIR}')" >> ${BOOT_FILE} | ||
echo " except Exception as e:" >> ${BOOT_FILE} | ||
echo " print('umount failed:', e)" >> ${BOOT_FILE} | ||
fi | ||
sfe-SparkFro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# If the ADD_TO_SYSPATH flag is true, add the destination directory to sys.path | ||
if [ "$ADD_TO_SYSPATH" = true ]; then | ||
echo "Adding ${DESTINATION_DIR} to sys.path in _boot.py" | ||
echo "import sys" >> ${BOOT_FILE} | ||
echo "sys.path.append('/${DESTINATION_DIR}')" >> ${BOOT_FILE} | ||
fi | ||
|
||
# Helpful for debugging during the build process, but can be removed if we'd rather not see this output... | ||
echo "Content of _boot.py after adding frozen data filesystem:" | ||
cat micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py | ||
} | ||
|
||
# Installs necessary dependencies and builds OpenCV and the firmware | ||
# Also freezes the examples directory in a filesystem archive on the board | ||
function build_micropython_opencv { | ||
# Install necessary packages (Could move into an install_dependencies.sh if we want this to be more explicit/modular) | ||
sudo apt-get update | ||
sudo apt install cmake python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib | ||
# Install necessary python packages (could also move this to a requirements.txt file) | ||
pip install freezefs | ||
|
||
# Create a directory for frozen modules, we can add arbitrary .py files to this directory in the future. | ||
# For now it will just contain the archived examples script. | ||
mkdir "$FROZEN_MODULES_DIR" | ||
|
||
# Create our frozen filesystem archive for the examples directory | ||
# Note the "." to make the read-only version of the examples directory hidden in IDEs like Thonny | ||
create_frozen_fs "examples" ".$FROZEN_EXAMPLES_UNPACKED_DIR" "$FROZEN_MODULES_DIR/$FROZEN_EXAMPLES_ARCHIVE_SCRIPT" | ||
|
||
# Add necessary content to the manifest file to freeze the modules in the provided directory | ||
add_to_manifest "$FROZEN_MODULES_DIR" "rp2" "SPARKFUN_XRP_CONTROLLER" "mpconfigvariant_LARGE_BINARY.cmake" | ||
|
||
# Add necessary content to the boot.py file to unpack the frozen data filesystem on boot | ||
# Provide the source and destination directories to copy the frozen data filesystem to a mutable (and non-hidden) location | ||
# Provide "true" as the last argument to add the destination directory to sys.path (since our examples directory contains modules that we want to be importable...) | ||
add_frozen_data_to_boot_for_port "rp2" "$FROZEN_EXAMPLES_ARCHIVE_SCRIPT" ".$FROZEN_EXAMPLES_UNPACKED_DIR" "$FROZEN_EXAMPLES_UNPACKED_DIR" true | ||
|
||
# Set Pico SDK path to $GITHUB_WORKSPACE/micropython/lib/pico-sdk if $GITHUB_WORKSPACE is set, otherwise use the current directory | ||
if [ -n "$GITHUB_WORKSPACE" ]; then | ||
export PICO_SDK_PATH="$GITHUB_WORKSPACE/micropython/lib/pico-sdk" | ||
else | ||
export PICO_SDK_PATH=$(dirname "$0")/micropython/lib/pico-sdk | ||
fi | ||
|
||
# Build MPY Cross compiler | ||
make -C micropython/mpy-cross | ||
|
||
# Update necessary MicroPython submodules | ||
make -C micropython/ports/rp2 BOARD=SPARKFUN_XRP_CONTROLLER submodules | ||
|
||
# Build OpenCV | ||
make -C src/opencv PLATFORM=rp2350 --no-print-directory ${MAKEOPTS} | ||
|
||
# Build firmware | ||
make BOARD=SPARKFUN_XRP_CONTROLLER ${MAKEOPTS} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.