From 42efc9206ef027fc6b482e1c224dcd6cde6c1971 Mon Sep 17 00:00:00 2001 From: gretel Date: Tue, 3 Dec 2024 04:09:48 +0100 Subject: [PATCH] initial fork --- .github/workflows/package.yml | 114 +++++++++++++ .github/workflows/test.yml | 41 ----- Dockerfile | 13 +- README.md | 156 ++++++++++------- action.yml | 59 ------- entrypoint.sh | 310 ++++++++++++++++------------------ 6 files changed, 368 insertions(+), 325 deletions(-) create mode 100644 .github/workflows/package.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 action.yml diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000..1ca4393 --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,114 @@ +name: Build RNS Packages for OpenWrt + +on: + push: + branches: + - '*' + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + pull_request: + branches: + - '*' + workflow_dispatch: + +permissions: + contents: write + packages: write # needed for cache operations + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +env: + V: '' + PRIVATE_KEY: ${{ secrets.SIGNING_KEY }} + EXTRA_FEEDS: >- + src-git|reticulum|https://github.com/gretel/feed-reticulum.git + PACKAGES: | + python3-light python3-cryptography python3-pyserial rns lxmf +jobs: + build: + name: ${{ matrix.arch }}-${{ matrix.release }} + runs-on: ubuntu-latest + environment: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || 'development' }} + strategy: + fail-fast: false + matrix: + release: + - master + arch: + - aarch64_cortex-a53 # Modern 64-bit ARM (MT7981, newer RPis) + - arm_arm1176jzf-s_vfp # RPi Zero 1 + - mips_24kc # Common in budget routers + - x86_64 # Generic "PC" + + steps: + - uses: actions/checkout@v4 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup Buildx + uses: docker/setup-buildx-action@v3 + # with: + # buildkitd-flags: --debug + + - name: Build SDK container + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_SUMMARY: false + with: + tags: sdk + context: . + push: false + load: true + build-args: | + CONTAINER=ghcr.io/openwrt/sdk + ARCH=${{ matrix.arch }}-${{ matrix.release }} + cache-from: | + type=gha,scope=${{ matrix.arch }}-${{ matrix.release }} + cache-to: | + type=gha,mode=max,scope=${{ matrix.arch }}-${{ matrix.release }} + + - name: Prepare artifacts directory + run: | + mkdir -p artifacts + sudo chown -R 1000:1000 artifacts + shell: bash + + - name: Build packages + run: | + docker run --rm \ + --env EXTRA_FEEDS \ + --env IGNORE_ERRORS \ + --env INDEX \ + --env KEY_BUILD \ + --env NO_DEFAULT_FEEDS \ + --env PACKAGES \ + --env PRIVATE_KEY \ + --env V \ + -v ${{ github.workspace }}/artifacts:/artifacts \ + sdk + + - name: Debug output locations + if: always() + run: | + find ${{ github.workspace }}/artifacts/bin | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/" + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arch }}-${{ matrix.release }}-packages + path: artifacts/bin/**/*.*pk + retention-days: 7 + compression-level: 0 + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: | + artifacts/bin/**/*.*pk + draft: true + generate_release_notes: true + prerelease: ${{ contains(github.ref, '-') }} + fail_on_unmatched_files: true \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 90a85fd..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Test - -on: - pull_request: - -jobs: - build: - name: Test ${{ matrix.arch }}-${{ matrix.release }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - release: - - master - - 23.05.2 - - 23.05.0 - - 22.03.2 - arch: - - arm_cortex-a15_neon-vfpv4 - - mips_24kc - - x86_64 - - steps: - - uses: actions/checkout@v3 - - - name: Add test directories - run: mkdir artifacts feed - - - name: Build - uses: ./ - env: - ARCH: ${{ matrix.arch }}-${{ matrix.release }} - ARTIFACTS_DIR: ${{ github.workspace }}/artifacts - FEED_DIR: ${{ github.workspace }}/feed - PACKAGES: vim privoxy - - - name: Verify packages saved - run: find artifacts/bin/packages/${{ matrix.arch }}/packages/ -maxdepth 1 -name '*.ipk' -type f | grep . - - - name: Verify logs saved - run: find artifacts/logs/package/feeds/packages/ -mindepth 2 -maxdepth 2 -name compile.txt -type f | grep . diff --git a/Dockerfile b/Dockerfile index 096e792..853e93b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ ARG CONTAINER=ghcr.io/openwrt/sdk -ARG ARCH=mips_24kc -FROM $CONTAINER:$ARCH +ARG ARCH=x86_64 -LABEL "com.github.actions.name"="OpenWrt SDK" +FROM ${CONTAINER}:${ARCH} -ADD entrypoint.sh / +LABEL "com.github.actions.name"="OpenWrt Packager" +LABEL "repository"="https://github.com/gretel/openwrt-packager" +LABEL "maintainer"="gretel" -ENTRYPOINT ["/entrypoint.sh"] +COPY entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index aeb6afb..c21415e 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,110 @@ -# OpenWrt GitHub Action SDK +# OpenWrt Reticulum Package Builder 📡 -GitHub CI action to build packages via SDK using official OpenWrt SDK Docker -containers. This is primary used to test build OpenWrt repositories but can -also be used for downstream projects maintaining their own package -repositories. +GitHub workflow for cross-compiling [Reticulum Network Stack (RNS)](https://github.com/markqvist/Reticulum) packages for OpenWrt. Based on [openwrt/gh-action-sdk](https://github.com/openwrt/gh-action-sdk). -## Example usage +> **Note**: This is an experimental project currently under active development. The build process and package structure are still being refined and may change significantly. Not recommended for production use yet! -The following YAML code can be used to build all packages of a repository and -store created `ipk` files as artifacts. +## Overview 📖 + +This repository provides GitHub Actions workflows for building OpenWrt packages defined in the [feed-reticulum](https://github.com/gretel/feed-reticulum) repository. While the feed contains the package definitions (Makefiles, patches, and configurations), this workflow handles the automated cross-compilation process. + +### Repository Relationship +- **feed-reticulum**: Contains OpenWrt package definitions for RNS +- **This repository**: Provides automation to build those packages for different architectures + +## Features ✨ + +- Cross-compiles RNS packages for OpenWrt targets +- Uses official OpenWrt SDK containers +- Build artifact collection and release management +- Package signing support + +## How it Works 🔄 + +1. The workflow fetches the official OpenWrt SDK container for each target architecture +2. It adds our custom feed (`feed-reticulum`) to the SDK +3. The packages (`rns` and `lxmf`) are then built using the SDK +4. Built packages are collected and published as artifacts + +## Supported Platforms 🎯 + +This workflow builds `rns` and `lxmf` packages for: + +| Architecture | Example Devices | +|--------------|----------------| +| `aarch64_cortex-a53` | GL.iNet MT3000 (Beryl AX), Raspberry Pi 4/Zero 2, MediaTek MT7981/MT7622 | +| `arm_arm1176jzf-s_vfp` | Raspberry Pi Zero (1st gen) | +| `mips_24kc` | GL.iNet AR750S (Slate), GL.iNet AR300M, Most Atheros AR71xx/AR72xx/AR93xx | +| `x86_64` | Generic x86_64 devices, Virtual Machines | + +## Usage 🚀 + +Create a workflow file (e.g. `.github/workflows/build.yml`): ```yaml -name: Test Build +name: Build OpenWrt Packages on: + push: + branches: [ main ] + tags: ["[0-9]+.[0-9]+.[0-9]+*"] pull_request: - branches: - - main + workflow_dispatch: + +env: + PACKAGES: rns lxmf + EXTRA_FEEDS: >- + src-git|reticulum|https://github.com/gretel/feed-reticulum.git jobs: build: - name: ${{ matrix.arch }} build - runs-on: ubuntu-latest - strategy: - matrix: - arch: - - x86_64 - - mips_24kc - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Build - uses: openwrt/gh-action-sdk@main - env: - ARCH: ${{ matrix.arch }} - - - name: Store packages - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.arch}}-packages - path: bin/packages/${{ matrix.arch }}/packages/*.ipk + # ... rest of workflow configuration ``` -## Environmental variables - -The action reads a few env variables: - -* `ARCH` determines the used OpenWrt SDK Docker container. - E.g. `x86_64` or `x86_64-22.03.2`. -* `ARTIFACTS_DIR` determines where built packages and build logs are saved. - Defaults to the default working directory (`GITHUB_WORKSPACE`). -* `BUILD_LOG` stores build logs in `./logs`. -* `CONTAINER` can set other SDK containers than `openwrt/sdk`. -* `EXTRA_FEEDS` are added to the `feeds.conf`, where `|` are replaced by white - spaces. -* `FEED_DIR` used in the created `feeds.conf` for the current repo. Defaults to - the default working directory (`GITHUB_WORKSPACE`). -* `FEEDNAME` used in the created `feeds.conf` for the current repo. Defaults to - `action`. -* `IGNORE_ERRORS` can ignore failing packages builds. -* `INDEX` makes the action build the package index. Default is 0. Set to 1 to enable. -* `KEY_BUILD` can be a private Signify/`usign` key to sign the packages (ipk) feed. -* `PRIVATE_KEY` can be a private key to sign the packages (apk) feed. -* `NO_DEFAULT_FEEDS` disable adding the default SDK feeds -* `NO_REFRESH_CHECK` disable check if patches need a refresh. -* `NO_SHFMT_CHECK` disable check if init files are formated -* `PACKAGES` (Optional) specify the list of packages (space separated) to be built -* `V` changes the build verbosity level. +## Configuration ⚙️ + +### Environment Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `PACKAGES` | Space-separated list (`rns lxmf`) | Required | +| `EXTRA_FEEDS` | Feed URL (`src-git\|reticulum\|url`) | Required | +| `V` | Build verbosity ('', 's', 'sc') | '' | +| `PRIVATE_KEY` | Package signing key | Repository Secret | +| `INDEX` | Generate package index (0/1) | 0 | + +## Artifacts 📦 + +The workflow produces: +- Built packages (`.ipk` format) +- Build logs (if enabled) +- Package index (if enabled) + +All artifacts are: +- Collected from `/artifacts` directory +- Uploaded to GitHub Actions artifacts +- Published to GitHub Releases for tagged commits + +## Requirements 📋 + +- GitHub Actions runner with Docker support +- OpenWrt-compatible package source code +- Valid package Makefiles in feed +- Package signing key (optional) + +## Development Setup 🛠️ + +For local development and testing, refer to the [feed-reticulum](https://github.com/gretel/feed-reticulum) repository, which contains detailed instructions for: +- Setting up the OpenWrt build environment +- Installing required dependencies +- Building packages locally +- Configuration and usage guides + +## Credits 🙏 + +- Mark Qvist - Creator of [Reticulum Network Stack](https://github.com/markqvist/Reticulum) +- OpenWrt team - [SDK action](https://github.com/openwrt/gh-action-sdk) + +## License ⚖️ + +MIT \ No newline at end of file diff --git a/action.yml b/action.yml deleted file mode 100644 index b3d2a20..0000000 --- a/action.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: "OpenWrt SDK" -description: "Build OpenWrt packages via the SDK" -author: aparcar -runs: - using: 'composite' - steps: - - run: | - echo "artifacts_dir=${ARTIFACTS_DIR:-$GITHUB_WORKSPACE}" >> "$GITHUB_OUTPUT" - echo "feed_dir=${FEED_DIR:-$GITHUB_WORKSPACE}" >> "$GITHUB_OUTPUT" - shell: bash - id: inputs - - run: sudo chown -R 1000:1000 ${{ steps.inputs.outputs.artifacts_dir }} ${{ steps.inputs.outputs.feed_dir }} - shell: bash - - - name: Set up Docker QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build Docker container image - uses: docker/build-push-action@v6 - env: - DOCKER_BUILD_SUMMARY: false - with: - push: false - tags: sdk - context: ${{ github.action_path }} - build-args: | - CONTAINER - ARCH - cache-to: type=gha,mode=max,scope=${{ env.CONTAINER }}-${{ env.ARCH }} - cache-from: type=gha,scope=${{ env.CONTAINER }}-${{ env.ARCH }} - load: true - - - run: | - docker run --rm \ - --env BUILD_LOG \ - --env EXTRA_FEEDS \ - --env FEEDNAME \ - --env IGNORE_ERRORS \ - --env KEY_BUILD \ - --env PRIVATE_KEY \ - --env NO_DEFAULT_FEEDS \ - --env NO_REFRESH_CHECK \ - --env NO_SHFMT_CHECK \ - --env PACKAGES \ - --env INDEX \ - --env V \ - -v ${{ steps.inputs.outputs.artifacts_dir }}:/artifacts \ - -v ${{ steps.inputs.outputs.feed_dir }}:/feed \ - sdk - shell: bash - - run: sudo chown -R --reference=${{ steps.inputs.outputs.artifacts_dir }}/.. ${{ steps.inputs.outputs.artifacts_dir }} - shell: bash - if: always() - - run: sudo chown -R --reference=${{ steps.inputs.outputs.feed_dir }}/.. ${{ steps.inputs.outputs.feed_dir }} - shell: bash - if: always() diff --git a/entrypoint.sh b/entrypoint.sh index 91ffa4a..0ca2cf7 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,200 +1,188 @@ #!/bin/bash -set -ef +set -euo pipefail -GROUP= +# Logging functions +log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${*}" >&2; } +log_error() { log "ERROR: ${*}"; } +log_info() { log "INFO: ${*}"; } +log_debug() { [[ "${V:-}" =~ ^(sc|s)$ ]] && log "DEBUG: ${*}"; } +# Stack to track nested groups +declare -a GROUP_STACK=() + +# GitHub Actions group helpers with stacking support group() { - endgroup - echo "::group:: $1" - GROUP=1 + if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then + echo "::group::${1}" + fi + GROUP_STACK+=("${1}") + log "BEGIN: ${1}" } endgroup() { - if [ -n "$GROUP" ]; then - echo "::endgroup::" - fi - GROUP= + if [[ ${#GROUP_STACK[@]} -gt 0 ]]; then + if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then + echo "::endgroup::" + fi + log "END: ${GROUP_STACK[-1]}" + unset 'GROUP_STACK[${#GROUP_STACK[@]}-1]' + fi } -trap 'endgroup' ERR +cleanup() { + local exit_code=$? + while [[ ${#GROUP_STACK[@]} -gt 0 ]]; do + if [[ ${exit_code} -ne 0 ]]; then + log_error "Failed during: ${GROUP_STACK[-1]}" + fi + endgroup + done + exit "${exit_code}" +} -# snapshot containers don't ship with the SDK to save bandwidth -# run setup.sh to download and extract the SDK -[ ! -f setup.sh ] || bash setup.sh +trap cleanup EXIT FEEDNAME="${FEEDNAME:-action}" -BUILD_LOG="${BUILD_LOG:-1}" +ALL_CUSTOM_FEEDS="${FEEDNAME} " -if [ -n "$KEY_BUILD" ]; then - echo "$KEY_BUILD" > key-build - CONFIG_SIGNED_PACKAGES="y" +if [[ -f setup.sh ]]; then + log_info "Executing setup script" + bash setup.sh fi -if [ -n "$PRIVATE_KEY" ]; then - echo "$PRIVATE_KEY" > private-key.pem - CONFIG_SIGNED_PACKAGES="y" +if [[ -n "${KEY_BUILD:-}" ]]; then + log_info "Installing build signing key" + echo "${KEY_BUILD}" >key-build + CONFIG_SIGNED_PACKAGES="y" fi -if [ -z "$NO_DEFAULT_FEEDS" ]; then - sed \ - -e 's,https://git.openwrt.org/feed/,https://github.com/openwrt/,' \ - -e 's,https://git.openwrt.org/openwrt/,https://github.com/openwrt/,' \ - -e 's,https://git.openwrt.org/project/,https://github.com/openwrt/,' \ - feeds.conf.default > feeds.conf +if [[ -n "${PRIVATE_KEY:-}" ]]; then + log_info "Installing private signing key" + echo "${PRIVATE_KEY}" >private-key.pem + CONFIG_SIGNED_PACKAGES="y" fi -echo "src-link $FEEDNAME /feed/" >> feeds.conf +if [[ -z "${NO_DEFAULT_FEEDS:-}" ]]; then + log_info "Configuring default feeds" + sed -e 's,https://git.openwrt.org/\(feed\|openwrt\|project\)/,https://github.com/openwrt/,' \ + feeds.conf.default >feeds.conf +fi -ALL_CUSTOM_FEEDS="$FEEDNAME " -#shellcheck disable=SC2153 -for EXTRA_FEED in $EXTRA_FEEDS; do - echo "$EXTRA_FEED" | tr '|' ' ' >> feeds.conf - ALL_CUSTOM_FEEDS+="$(echo "$EXTRA_FEED" | cut -d'|' -f2) " -done +echo "src-link ${FEEDNAME} /feed/" >>feeds.conf + +if [[ -n "${EXTRA_FEEDS:-}" ]]; then + log_info "Adding additional feeds" + while read -r feed; do + echo "${feed}" | tr '|' ' ' >>feeds.conf + ALL_CUSTOM_FEEDS+="$(echo "${feed}" | cut -d'|' -f2) " + done <<<"${EXTRA_FEEDS}" +fi -group "feeds.conf" +group "Feed Configuration" +log_info "Active feed configuration" cat feeds.conf endgroup -group "feeds update -a" +group "Feed Update" +log_info "Updating feed repositories" ./scripts/feeds update -a endgroup -group "make defconfig" +group "Default Configuration" +log_info "Generating build configuration" make defconfig endgroup -if [ -z "$PACKAGES" ]; then - # compile all packages in feed - for FEED in $ALL_CUSTOM_FEEDS; do - group "feeds install -p $FEED -f -a" - ./scripts/feeds install -p "$FEED" -f -a - endgroup - done - - RET=0 - - make \ - BUILD_LOG="$BUILD_LOG" \ - CONFIG_SIGNED_PACKAGES="$CONFIG_SIGNED_PACKAGES" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - CONFIG_AUTOREMOVE=y \ - V="$V" \ - -j "$(nproc)" || RET=$? +build_package() { + local pkg="${1}" + local feed + + for feed in ${ALL_CUSTOM_FEEDS}; do + log_info "Installing ${pkg} from feed ${feed}" + if ! ./scripts/feeds install -p "${feed}" -f "${pkg}"; then + log_error "Installation failed for ${pkg} from ${feed}" + return 1 + fi + done + + log_info "Downloading ${pkg}" + if ! make "package/${pkg}/download" V=s; then + log_error "Download failed for ${pkg}" + return 1 + fi + + log_info "Verifying ${pkg}" + if ! make "package/${pkg}/check" V=s; then + log_error "Verification failed for ${pkg}" + return 1 + fi + + log_info "Compiling ${pkg}" + if ! make "package/${pkg}/compile" \ + CONFIG_AUTOREMOVE=y \ + NO_DEPS=1 \ + V="${V:-}" \ + -j "$(nproc)"; then + log_error "Compilation failed for ${pkg}" + return 1 + fi + + return 0 +} + +if [[ -z "${PACKAGES:-}" ]]; then + group "Full Build" + + for feed in ${ALL_CUSTOM_FEEDS}; do + group "Installing ${feed}" + log_info "Installing all packages from ${feed}" + if ! ./scripts/feeds install -p "${feed}" -d m -f -a; then + log_error "Feed installation failed: ${feed}" + exit 1 + fi + endgroup + done + + group "Build" + log_info "Starting build" + if ! make \ + CONFIG_AUTOREMOVE=y \ + NO_DEPS=1 \ + V="${V:-}" \ + -j "$(nproc)"; then + log_error "Build failed" + exit 1 + fi + endgroup + + endgroup else - # compile specific packages with checks - for PKG in $PACKAGES; do - for FEED in $ALL_CUSTOM_FEEDS; do - group "feeds install -p $FEED -f $PKG" - ./scripts/feeds install -p "$FEED" -f "$PKG" - endgroup - done - - group "make package/$PKG/download" - make \ - BUILD_LOG="$BUILD_LOG" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - "package/$PKG/download" V=s - endgroup - - group "make package/$PKG/check" - make \ - BUILD_LOG="$BUILD_LOG" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - "package/$PKG/check" V=s 2>&1 | \ - tee logtmp - endgroup - - RET=${PIPESTATUS[0]} - - if [ "$RET" -ne 0 ]; then - echo_red "=> Package check failed: $RET)" - exit "$RET" - fi - - badhash_msg="HASH does not match " - badhash_msg+="|HASH uses deprecated hash," - badhash_msg+="|HASH is missing," - if grep -qE "$badhash_msg" logtmp; then - echo "Package HASH check failed" - exit 1 - fi - - PATCHES_DIR=$(find /feed -path "*/$PKG/patches") - if [ -d "$PATCHES_DIR" ] && [ -z "$NO_REFRESH_CHECK" ]; then - group "make package/$PKG/refresh" - make \ - BUILD_LOG="$BUILD_LOG" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - "package/$PKG/refresh" V=s - endgroup - - if ! git -C "$PATCHES_DIR" diff --quiet -- .; then - echo "Dirty patches detected, please refresh and review the diff" - git -C "$PATCHES_DIR" checkout -- . - exit 1 - fi - - group "make package/$PKG/clean" - make \ - BUILD_LOG="$BUILD_LOG" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - "package/$PKG/clean" V=s - endgroup - fi - - FILES_DIR=$(find /feed -path "*/$PKG/files") - if [ -d "$FILES_DIR" ] && [ -z "$NO_SHFMT_CHECK" ]; then - find "$FILES_DIR" -name "*.init" -exec shfmt -w -sr -s '{}' \; - if ! git -C "$FILES_DIR" diff --quiet -- .; then - echo "init script must be formatted. Please run through shfmt -w -sr -s" - git -C "$FILES_DIR" checkout -- . - exit 1 - fi - fi - - done - - make \ - -f .config \ - -f tmp/.packagedeps \ - -f <(echo "\$(info \$(sort \$(package-y) \$(package-m)))"; echo -en "a:\n\t@:") \ - | tr ' ' '\n' > enabled-package-subdirs.txt - - RET=0 - - for PKG in $PACKAGES; do - if ! grep -m1 -qE "(^|/)$PKG$" enabled-package-subdirs.txt; then - echo "::warning file=$PKG::Skipping $PKG due to unsupported architecture" - continue - fi - - make \ - BUILD_LOG="$BUILD_LOG" \ - IGNORE_ERRORS="$IGNORE_ERRORS" \ - CONFIG_AUTOREMOVE=y \ - V="$V" \ - -j "$(nproc)" \ - "package/$PKG/compile" || { - RET=$? - break - } - done + group "Package Build" + for pkg in ${PACKAGES}; do + group "Building ${pkg}" + if ! build_package "${pkg}"; then + log_error "Package build failed: ${pkg}" + exit 1 + fi + endgroup + done + endgroup fi -if [ "$INDEX" = '1' ];then - group "make package/index" - make package/index - endgroup +if [[ "${INDEX:-0}" == "1" ]]; then + group "Index Generation" + log_info "Generating package index" + if ! make package/index; then + log_error "Index generation failed" + exit 1 + fi + endgroup fi if [ -d bin/ ]; then - mv bin/ /artifacts/ -fi - -if [ -d logs/ ]; then - mv logs/ /artifacts/ + mv -v bin /artifacts/ fi -exit "$RET" +log_info "Build completed" +exit 0 \ No newline at end of file