firmware-module #22
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
name: firmware-module | |
on: | |
schedule: | |
# 02:15 PST / Nightly | |
- cron: '15 10 * * *' | |
workflow_dispatch: | |
inputs: | |
tg_disabled: | |
type: boolean | |
description: 'Disable Telegram notifications' | |
required: false | |
default: false | |
tg_scratch: | |
type: boolean | |
description: 'Use TG scratch channel' | |
required: false | |
default: false | |
graph_enabled: | |
type: boolean | |
description: 'Enable build time graph' | |
required: false | |
default: false | |
teacup_only: | |
type: boolean | |
description: 'Only build Tea Cup profile ' | |
required: false | |
default: false | |
env: | |
TAG_NAME: module | |
UPD_TAG_NAME: module_update | |
TERM: linux | |
BR2_DL_DIR: /tmp/dl | |
TG_TOKEN: ${{secrets.TELEGRAM_TOKEN_BOT_THINGINO}} | |
TG_CHANNEL: ${{secrets.TELEGRAM_CHANNEL_THINGINO_BUILD}} | |
TG_CHANNEL_SCRATCH: ${{secrets.TELEGRAM_CHANNEL_THINGINO_SCRATCH}} | |
TG_OPTIONS: -s | |
jobs: | |
notify-begin: | |
runs-on: ubuntu-24.04 | |
outputs: | |
start_time: ${{ steps.set_output.outputs.time }} | |
tg_disabled: ${{ steps.set_env.outputs.tg_disabled }} | |
steps: | |
- name: Save workflow start time | |
id: set_output | |
run: echo "time=$(date +%s)" >> $GITHUB_OUTPUT | |
- name: Setup Notify Environment | |
run: | | |
echo "TG_DISABLED=${{ github.event.inputs.tg_disabled || 'false' }}" >> $GITHUB_ENV | |
echo "tg_disabled=${{ github.event.inputs.tg_disabled || 'false' }}" >> $GITHUB_OUTPUT | |
- name: Send build start notifcation | |
if: env.TG_DISABLED == 'false' | |
run: | | |
if [[ "${{ github.event.inputs.tg_scratch }}" == 'true' ]]; then | |
TG_CHANNEL=${{ env.TG_CHANNEL_SCRATCH }} | |
fi | |
TG_MSG="Firmware\\-module build started:\nJob: [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n" | |
TG_ICON="\xF0\x9F\x9A\xA6 GitHub Actions" | |
TG_HEADER=$(echo -e ${TG_MSG}${TG_ICON}) | |
HTTP=$(curl ${TG_OPTIONS} -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot${TG_TOKEN}/sendMessage -F parse_mode=MarkdownV2 -F chat_id=${TG_CHANNEL} -F text="${TG_HEADER}" -F disable_web_page_preview=true) | |
echo Telegram response: ${HTTP} | |
generate-matrix: | |
runs-on: ubuntu-24.04 | |
outputs: | |
matrix: ${{ steps.set-matrix.outputs.matrix }} | |
steps: | |
- name: Checkout source | |
uses: actions/checkout@v4 | |
with: | |
ref: "master" | |
fetch-depth: "1" | |
- name: Generate matrix | |
id: set-matrix | |
run: | | |
if [[ "${{ github.event.inputs.teacup_only }}" == 'true' ]]; then | |
CONFIGS=$(find configs/modules/ -type f | grep -v 't23' | sort | awk -F '/' '{print $(NF)}' | sed 's/_defconfig$//' | awk NF | grep 't31zx_imx327_eth') | |
else | |
CONFIGS=$(find configs/modules/ -type f | grep -v 't23' | sort | awk -F '/' '{print $(NF)}' | sed 's/_defconfig$//' | awk NF) | |
fi | |
JSON_MATRIX="{\"thingino-version\": [" | |
for CONFIG in $CONFIGS; do | |
JSON_MATRIX+="\"${CONFIG}\"," | |
done | |
JSON_MATRIX="${JSON_MATRIX%,}]}" | |
echo "Matrix: $JSON_MATRIX" | |
echo "matrix=$JSON_MATRIX" >> $GITHUB_OUTPUT | |
buildroot: | |
name: ${{ matrix.thingino-version }} | |
needs: [generate-matrix, notify-begin] | |
runs-on: ubuntu-24.04 | |
strategy: | |
fail-fast: false | |
matrix: ${{fromJson(needs.generate-matrix.outputs.matrix)}} | |
steps: | |
- name: Checkout source | |
uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
ref: "master" | |
fetch-depth: "1" | |
- name: Setup Environment | |
id: date | |
run: | | |
echo "WEEK_NUMBER=$(date +%U)" >> $GITHUB_ENV | |
echo "CURRENT_YEAR=$(date +%Y)" >> $GITHUB_ENV | |
export GIT_HASH=$(git rev-parse --short ${GITHUB_SHA}) | |
export GIT_BRANCH=${GITHUB_REF_NAME} | |
echo "GIT_HASH=${GIT_HASH}" >> ${GITHUB_ENV} | |
echo "GIT_BRANCH=${GIT_BRANCH}" >> ${GITHUB_ENV} | |
echo "TG_DISABLED=${{ github.event.inputs.tg_disabled || 'false' }}" >> $GITHUB_ENV | |
- name: Setup cache directories | |
run: | | |
mkdir -p /tmp/ccache | |
mkdir -p /tmp/dl | |
ln -s /tmp/ccache ${HOME}/.ccache | |
ln -s /tmp/dl ${HOME}/dl | |
- name: Setup ccache | |
uses: actions/cache@v4 | |
if: always() | |
with: | |
path: /tmp/ccache | |
key: ${{ runner.os }}-ccache-${{ matrix.thingino-version }}-${{ env.CURRENT_YEAR }}-week-${{ env.WEEK_NUMBER }} | |
restore-keys: | | |
${{ runner.os }}-ccache-${{ matrix.thingino-version }}-${{ env.CURRENT_YEAR }}-week- | |
- name: Setup BR2_DL_DIR cache | |
uses: actions/cache@v4 | |
if: always() | |
with: | |
path: /tmp/dl | |
key: ${{ runner.os }}-dl-shared-v1-${{ env.CURRENT_YEAR }}-week-${{ env.WEEK_NUMBER }} | |
restore-keys: | | |
${{ runner.os }}-dl-shared-v1-${{ env.CURRENT_YEAR }}-week- | |
- name: Update APT sources | |
run: | | |
sudo apt-get update | |
- name: Install build dependencies | |
run: | | |
sudo apt-get install -y --no-install-recommends --no-install-suggests build-essential bc bison cpio curl file flex git libncurses-dev make rsync unzip wget whiptail gcc gcc-mipsel-linux-gnu lzop u-boot-tools ca-certificates ccache python3-numpy python3-matplotlib | |
- name: Build firmware | |
run: | | |
BOARD=${{ matrix.thingino-version }} make | |
TIME=$(date -d @${SECONDS} +%M:%S) | |
echo "TIME=${TIME}" >> ${GITHUB_ENV} | |
- name: Generate build graphs | |
if: ${{ github.event.inputs.graph_enabled == 'true' }} | |
run: | | |
BOARD=${{ matrix.thingino-version }} make br-graph-build | |
- name: Prepare full image | |
run: | | |
BOARD=${{ matrix.thingino-version }} make pack_full | |
- name: Prepare update image | |
run: | | |
BOARD=${{ matrix.thingino-version }} make pack_update | |
- name: Set environment for firmware files | |
run: | | |
DYNAMIC_PART="${{ matrix.thingino-version }}" | |
PATTERN="thingino-${DYNAMIC_PART}-*.bin" | |
UPDATE_PATTERN="thingino-${DYNAMIC_PART}-*-update.bin" | |
FULL_FW=$(find ${HOME}/output/${DYNAMIC_PART}*/images/ -name "${PATTERN}" | grep -v -- '-update.bin' | head -n 1) | |
UPDATE_FW=$(find ${HOME}/output/${DYNAMIC_PART}*/images/ -name "${UPDATE_PATTERN}" | grep -- '-update.bin' | head -n 1) | |
echo "FULL_FW: $FULL_FW" | |
echo "UPDATE_FW: $UPDATE_FW" | |
if [[ -n "${FULL_FW}" && -n "${UPDATE_FW}" ]]; then | |
FULL_FW_BASENAME=$(basename "${FULL_FW}" | sed 's/-[0-9]\{12\}\.bin$/.bin/') | |
UPDATE_FW_BASENAME=$(basename "${UPDATE_FW}" | sed -E 's/-[0-9]{12}(-update)?\.bin$/-update.bin/') | |
mv "${FULL_FW}" "${HOME}/output/${DYNAMIC_PART}/images/${FULL_FW_BASENAME}" | |
mv "${UPDATE_FW}" "${HOME}/output/${DYNAMIC_PART}/images/${UPDATE_FW_BASENAME}" | |
echo "FULL_FW=${HOME}/output/${DYNAMIC_PART}/images/${FULL_FW_BASENAME}" >> ${GITHUB_ENV} | |
echo "UPDATE_FW=${HOME}/output/${DYNAMIC_PART}/images/${UPDATE_FW_BASENAME}" >> ${GITHUB_ENV} | |
else | |
echo "Matching .bin files not found." | |
exit 1 | |
fi | |
- name: Upload duration graph as artifact | |
if: ${{ github.event.inputs.graph_enabled == 'true' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.thingino-version }}-build.hist-duration | |
path: | | |
~/output/${{ matrix.thingino-version }}/graphs/build.hist-duration.pdf | |
- name: Upload full firmware as artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: thingino-${{ matrix.thingino-version }}-full-firmware | |
path: | | |
${{ env.FULL_FW }} | |
- name: Upload update firmware as artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: thingino-${{ matrix.thingino-version }}-update-firmware | |
path: | | |
${{ env.UPDATE_FW }} | |
- name: Upload full firmware to release | |
if: github.event_name != 'pull_request' | |
uses: softprops/action-gh-release@master | |
with: | |
tag_name: ${{ env.TAG_NAME }} | |
files: | | |
${{ env.FULL_FW }} | |
- name: Upload update firmware to release | |
if: github.event_name != 'pull_request' | |
uses: softprops/action-gh-release@master | |
with: | |
tag_name: ${{ env.UPD_TAG_NAME }} | |
files: | | |
${{ env.UPDATE_FW }} | |
- name: Send firmware completion notifications with binaries | |
if: ${{ env.TG_DISABLED == 'false' && (env.FULL_FW || env.UPDATE_FW) }} | |
run: | | |
if [[ "${{ github.event.inputs.tg_scratch }}" == 'true' ]]; then | |
TG_CHANNEL=${{ env.TG_CHANNEL_SCRATCH }} | |
fi | |
TG_ESCAPED_TAG_NAME=$(echo "${TAG_NAME}" | sed 's/_/\\_/g') | |
if [ -n "${{ env.FULL_FW }}" ]; then | |
TG_MSG="Commit: [${GIT_HASH}](https://github.com/${GITHUB_REPOSITORY}/commit/${GIT_HASH})\nBranch: [${GIT_BRANCH}](https://github.com/${GITHUB_REPOSITORY}/tree/${GIT_BRANCH})\nTag: [${TG_ESCAPED_TAG_NAME}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${TAG_NAME})\nTime: ${TIME}\nJob: [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n" | |
TG_HEADER=$(echo -e "${TG_MSG}\xE2\x9C\x85 GitHub Actions") | |
HTTP_FULL=$(curl ${TG_OPTIONS} -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot${TG_TOKEN}/sendDocument -F parse_mode=MarkdownV2 -F chat_id=${TG_CHANNEL} -F caption="${TG_HEADER}" -F document=@${FULL_FW} -F disable_web_page_preview=true) | |
echo "Telegram response Full Firmware: $HTTP_FULL" | |
fi | |
TG_ESCAPED_UPD_TAG_NAME=$(echo "${UPD_TAG_NAME}" | sed 's/_/\\_/g') | |
if [ -n "${{ env.UPDATE_FW }}" ]; then | |
TG_MSG="Commit: [${GIT_HASH}](https://github.com/${GITHUB_REPOSITORY}/commit/${GIT_HASH})\nBranch: [${GIT_BRANCH}](https://github.com/${GITHUB_REPOSITORY}/tree/${GIT_BRANCH})\nTag: [${TG_ESCAPED_UPD_TAG_NAME}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/firmware\\_update)\nTime: ${TIME}\nJob: [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n" | |
TG_HEADER=$(echo -e "${TG_MSG}\xE2\x9C\x85 GitHub Actions") | |
HTTP_UPDATE=$(curl ${TG_OPTIONS} -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot${TG_TOKEN}/sendDocument -F parse_mode=MarkdownV2 -F chat_id=${TG_CHANNEL} -F caption="${TG_HEADER}" -F document=@${UPDATE_FW} -F disable_web_page_preview=true) | |
echo "Telegram response Update Firmware: $HTTP_UPDATE" | |
fi | |
- name: Send error notification | |
if: ${{ env.TG_DISABLED == 'false' && failure() }} | |
run: | | |
if [[ "${{ github.event.inputs.tg_scratch }}" == 'true' ]]; then | |
TG_CHANNEL=${{ env.TG_CHANNEL_SCRATCH }} | |
fi | |
TG_ESCAPED_VERSION=$(echo "${{ matrix.thingino-version }}" | sed 's/_/\\_/g') | |
TG_ESCAPED_TAG_NAME=$(echo "${TAG_NAME}" | sed 's/_/\\_/g') | |
TG_WARN="Error: ${TG_ESCAPED_VERSION}\n" | |
TG_MSG="Commit: [${GIT_HASH}](https://github.com/${GITHUB_REPOSITORY}/commit/${GIT_HASH})\nBranch: [${GIT_BRANCH}](https://github.com/${GITHUB_REPOSITORY}/tree/${GIT_BRANCH})\nTag: [${TG_ESCAPED_TAG_NAME}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${TAG_NAME})\nJob: [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n" | |
TG_ICON="\xE2\x9A\xA0 GitHub Actions" | |
TG_HEADER=$(echo -e ${TG_WARN}${TG_MSG}${TG_ICON}) | |
HTTP=$(curl ${TG_OPTIONS} -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot${TG_TOKEN}/sendMessage -F parse_mode=MarkdownV2 -F chat_id=${TG_CHANNEL} -F text="${TG_HEADER}" -F disable_web_page_preview=true) | |
echo Telegram response: ${HTTP} | |
notify-completion: | |
needs: [buildroot, notify-begin] | |
runs-on: ubuntu-24.04 | |
if: always() | |
steps: | |
- name: Setup Environment | |
run: | | |
echo "TG_DISABLED=${{ github.event.inputs.tg_disabled || 'false' }}" >> $GITHUB_ENV | |
- name: Send completion summary | |
if: ${{ env.TG_DISABLED == 'false' }} | |
run: | | |
if [[ "${{ github.event.inputs.tg_scratch }}" == 'true' ]]; then | |
TG_CHANNEL=${{ env.TG_CHANNEL_SCRATCH }} | |
fi | |
START_TIME=${{ needs.notify-begin.outputs.start_time }} | |
END_TIME=$(date -u +%s) | |
ELAPSED=$((END_TIME - START_TIME)) | |
ELAPSED_MIN=$((ELAPSED / 60)) | |
ELAPSED_SEC=$((ELAPSED % 60)) | |
TG_MSG="Firmware\\-module build completed:\nTotal elapsed time: ${ELAPSED_MIN}m ${ELAPSED_SEC}s\nJob: [${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n" | |
TG_ICON="\xF0\x9F\x9A\xA9 GitHub Actions" | |
TG_HEADER=$(echo -e ${TG_MSG}${TG_ICON}) | |
HTTP=$(curl ${TG_OPTIONS} -H "Content-Type: multipart/form-data" -X POST https://api.telegram.org/bot${TG_TOKEN}/sendMessage -F parse_mode=MarkdownV2 -F chat_id=${TG_CHANNEL} -F text="${TG_HEADER}" -F disable_web_page_preview=true) | |
echo Telegram response: ${HTTP} |