diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8d8fc8d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: Build + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + compile-tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + environment: ["test_template_engine_8266", "test_template_engine_esp32"] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: python -m pip install --upgrade platformio==6.1.19 + - run: pio test -e ${{ matrix.environment }} --without-uploading --without-testing diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9126114 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,23 @@ +name: Publish release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: python -m pip install --upgrade platformio==6.1.19 + - run: ./scripts/prepare-release.sh "$GITHUB_REF_NAME" + - run: gh release create "$GITHUB_REF_NAME" --generate-notes --title "$GITHUB_REF_NAME" + env: + GH_TOKEN: ${{ github.token }} diff --git a/include/DeviceFrameworkPlaceholderRegistry.h b/include/DeviceFrameworkPlaceholderRegistry.h index af26bcd..52ef90f 100644 --- a/include/DeviceFrameworkPlaceholderRegistry.h +++ b/include/DeviceFrameworkPlaceholderRegistry.h @@ -26,23 +26,13 @@ #define DFTE_RAM_CHUNK_SIZE_DEFAULT 128 #endif -// Use DeviceFramework config defaults at compile-time if available, otherwise use internal defaults -#ifdef DEVICEFRAMEWORK_CONFIG_H - // DeviceFramework is present - use config defaults - // DeviceFrameworkConfig.h must be included before this file to access CONFIG_*_default macros - #ifdef CONFIG_templateProgmemChunkSize_default - #define DFTE_PROGMEM_CHUNK_SIZE CONFIG_templateProgmemChunkSize_default - #else - #define DFTE_PROGMEM_CHUNK_SIZE DFTE_PROGMEM_CHUNK_SIZE_DEFAULT - #endif - #ifdef CONFIG_templateRamChunkSize_default - #define DFTE_RAM_CHUNK_SIZE CONFIG_templateRamChunkSize_default - #else - #define DFTE_RAM_CHUNK_SIZE DFTE_RAM_CHUNK_SIZE_DEFAULT - #endif -#else - // Standalone usage - use internal defaults +// Chunk settings are build-wide DFTE_* flags. They are not inferred from a +// consumer header so library and consumer translation units remain consistent. +#ifndef DFTE_PROGMEM_CHUNK_SIZE #define DFTE_PROGMEM_CHUNK_SIZE DFTE_PROGMEM_CHUNK_SIZE_DEFAULT +#endif + +#ifndef DFTE_RAM_CHUNK_SIZE #define DFTE_RAM_CHUNK_SIZE DFTE_RAM_CHUNK_SIZE_DEFAULT #endif diff --git a/include/DeviceFrameworkTemplateContext.h b/include/DeviceFrameworkTemplateContext.h index e5fb0c4..31ca80c 100644 --- a/include/DeviceFrameworkTemplateContext.h +++ b/include/DeviceFrameworkTemplateContext.h @@ -20,27 +20,13 @@ #define DFTE_PLACEHOLDER_NAME_SIZE_DEFAULT 24 #endif -// Use DeviceFramework config defaults at compile-time if available, otherwise use internal defaults -// Array sizes must be compile-time constants -#ifdef DEVICEFRAMEWORK_CONFIG_H - // DeviceFramework is present - use config defaults for array sizing - // DeviceFrameworkConfig.h must be included before this file to access CONFIG_*_default macros - #ifdef CONFIG_templateStackDepth_default - #define DFTE_MAX_STACK_DEPTH CONFIG_templateStackDepth_default - #else - #define DFTE_MAX_STACK_DEPTH DFTE_MAX_STACK_DEPTH_DEFAULT - #endif - #ifdef CONFIG_templateBufferSize_default - #define DFTE_BUFFER_SIZE CONFIG_templateBufferSize_default - #else - #define DFTE_BUFFER_SIZE DFTE_BUFFER_SIZE_DEFAULT - #endif - // DFTE_PLACEHOLDER_NAME_SIZE is already defined in DeviceFrameworkTemplateTypes.h -#else - // Standalone usage - use internal defaults +// Layout-affecting settings must be supplied through build-wide DFTE_* flags. +#ifndef DFTE_MAX_STACK_DEPTH #define DFTE_MAX_STACK_DEPTH DFTE_MAX_STACK_DEPTH_DEFAULT +#endif + +#ifndef DFTE_BUFFER_SIZE #define DFTE_BUFFER_SIZE DFTE_BUFFER_SIZE_DEFAULT - // DFTE_PLACEHOLDER_NAME_SIZE is already defined in DeviceFrameworkTemplateTypes.h #endif // Forward declaration diff --git a/include/DeviceFrameworkTemplateRenderer.h b/include/DeviceFrameworkTemplateRenderer.h index 6ee8b1b..18acebe 100644 --- a/include/DeviceFrameworkTemplateRenderer.h +++ b/include/DeviceFrameworkTemplateRenderer.h @@ -10,17 +10,8 @@ #define DFTE_MAX_ITERATIONS_DEFAULT 50 #endif -// Use DeviceFramework config defaults at compile-time if available, otherwise use internal defaults -#ifdef DEVICEFRAMEWORK_CONFIG_H - // DeviceFramework is present - use config defaults - // DeviceFrameworkConfig.h must be included before this file to access CONFIG_*_default macros - #ifdef CONFIG_templateMaxIterations_default - #define DFTE_MAX_ITERATIONS CONFIG_templateMaxIterations_default - #else - #define DFTE_MAX_ITERATIONS DFTE_MAX_ITERATIONS_DEFAULT - #endif -#else - // Standalone usage - use internal defaults +// Renderer settings are build-wide DFTE_* flags. +#ifndef DFTE_MAX_ITERATIONS #define DFTE_MAX_ITERATIONS DFTE_MAX_ITERATIONS_DEFAULT #endif diff --git a/include/DeviceFrameworkTemplateTypes.h b/include/DeviceFrameworkTemplateTypes.h index 9e4198a..4eeb5a6 100644 --- a/include/DeviceFrameworkTemplateTypes.h +++ b/include/DeviceFrameworkTemplateTypes.h @@ -9,18 +9,10 @@ #define DFTE_PLACEHOLDER_NAME_SIZE_DEFAULT 24 #endif -// Use DeviceFramework config defaults at compile-time if available, otherwise use internal defaults -// Array sizes must be compile-time constants -#ifdef DEVICEFRAMEWORK_CONFIG_H - // DeviceFramework is present - use config defaults for array sizing - // DeviceFrameworkConfig.h must be included before this file to access CONFIG_*_default macros - #ifdef CONFIG_templatePlaceholderNameSize_default - #define DFTE_PLACEHOLDER_NAME_SIZE CONFIG_templatePlaceholderNameSize_default - #else - #define DFTE_PLACEHOLDER_NAME_SIZE DFTE_PLACEHOLDER_NAME_SIZE_DEFAULT - #endif -#else - // Standalone usage - use internal defaults +// Layout-affecting settings must be passed as build-wide DFTE_* flags so every +// translation unit sees the same object layout. DeviceFramework runtime config is +// intentionally not used for fixed-size storage. +#ifndef DFTE_PLACEHOLDER_NAME_SIZE #define DFTE_PLACEHOLDER_NAME_SIZE DFTE_PLACEHOLDER_NAME_SIZE_DEFAULT #endif diff --git a/library.json b/library.json index 9a42420..cfacc5f 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "DeviceFrameworkTemplateEngine", - "version": "1.0.0", + "version": "1.0.1", "description": "Memory-efficient streaming template engine for ESP8266/ESP32 with chunked rendering support. Designed for embedded web interfaces with PROGMEM template support.", "keywords": [ "template", @@ -24,7 +24,15 @@ ], "license": "MIT", "frameworks": "arduino", - "platforms": ["espressif8266", "espressif32"], - "dependencies": {} + "platforms": [ + "espressif8266", + "espressif32" + ], + "dependencies": {}, + "$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json", + "homepage": "https://github.com/alexhopeoconnor/DFTE", + "repository": { + "type": "git", + "url": "https://github.com/alexhopeoconnor/DFTE.git" + } } - diff --git a/platformio.ini b/platformio.ini index 9b1852d..9798795 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ test_framework = unity test_build_src = yes [env:test_template_engine_esp32] -platform = espressif32@5.3.0 +platform = espressif32@6.13.0 board = nodemcu-32s framework = arduino test_framework = unity diff --git a/scripts/prepare-release.sh b/scripts/prepare-release.sh new file mode 100755 index 0000000..e371f99 --- /dev/null +++ b/scripts/prepare-release.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + echo "Usage: $0 vMAJOR.MINOR.PATCH [--tag]" + exit 2 +} + +tag="${1:-}" +[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || usage +[[ "${2:-}" == "" || "${2:-}" == "--tag" ]] || usage + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +version="${tag#v}" +manifest_version="$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' "$root/library.json" | head -n 1)" + +if [[ "$manifest_version" != "$version" ]]; then + echo "library.json is $manifest_version; expected $version for $tag" >&2 + exit 1 +fi + +if [[ -f "$root/library.properties" ]]; then + properties_version="$(sed -n 's/^version=//p' "$root/library.properties" | head -n 1)" + if [[ "$properties_version" != "$version" ]]; then + echo "library.properties is $properties_version; expected $version for $tag" >&2 + exit 1 + fi +fi + +package_dir="$(mktemp -d)" +trap 'rm -rf "$package_dir"' EXIT +pio pkg pack "$root" --output "$package_dir/package.tar.gz" >/dev/null +echo "Validated PlatformIO package for $tag" + +if [[ "${2:-}" == "--tag" ]]; then + git -C "$root" diff --quiet + git -C "$root" diff --cached --quiet + git -C "$root" tag -a "$tag" -m "Release $tag" + echo "Created $tag. Push the branch and tag; GitHub Actions will publish the release." +fi