From 37fa1b998742cd5faf81703ebbd539bd9d44fb64 Mon Sep 17 00:00:00 2001 From: Jannik Spiering Date: Wed, 23 Sep 2026 16:02:07 +0200 Subject: [PATCH 1/3] Add CI check for the Windows path length limit (tp#354132) The product installs the gallery below C:\ProgramData\inray\OPC Router 5\config\solution-gallery\\, so up to 83 characters precede every path of this repository. A path over 176 characters cannot be written on Windows and breaks the setup. The check fails for paths over 170 characters; it runs on pull requests, on pushes to main and before the release zip is created. Co-Authored-By: Claude Opus 5.5 --- .github/scripts/check-path-length.sh | 33 +++++++++++++++++++++++++ .github/workflows/check path length.yml | 22 +++++++++++++++++ .github/workflows/create release.yml | 3 +++ CONTRIBUTING.md | 1 + 4 files changed, 59 insertions(+) create mode 100755 .github/scripts/check-path-length.sh create mode 100644 .github/workflows/check path length.yml diff --git a/.github/scripts/check-path-length.sh b/.github/scripts/check-path-length.sh new file mode 100755 index 0000000..08063af --- /dev/null +++ b/.github/scripts/check-path-length.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Fails when a file path in the gallery is too long to be installed on Windows. +# +# The product stores the gallery under +# C:\ProgramData\inray\OPC Router 5\config\solution-gallery\\ +# where is 8 characters (24 in versions before tp#354132), so up to +# 83 characters precede every path of this repository. Windows limits a full +# path to 259 characters (MAX_PATH 260 including the terminating NUL), which +# leaves 176 characters; the default limit keeps a small safety margin. +set -euo pipefail + +export LC_ALL=C.UTF-8 + +limit="${MAX_SOLUTION_PATH_LENGTH:-170}" +failed=0 +longest=0 + +cd "$(git rev-parse --show-toplevel)" + +while IFS= read -r -d '' file; do + rel="${file#./}" + len=${#rel} + if (( len > longest )); then + longest=$len + fi + if (( len > limit )); then + echo "::error file=${rel}::Path is ${len} characters long (limit ${limit}). Shorten the Solution, Flow or parameter names so the Solution can be installed on Windows." + failed=1 + fi +done < <(find . -type f -not -path './.git/*' -not -path './.github/*' -not -path './img/*' -print0) + +echo "Longest path: ${longest} characters (limit ${limit})." +exit $failed diff --git a/.github/workflows/check path length.yml b/.github/workflows/check path length.yml new file mode 100644 index 0000000..2b6665e --- /dev/null +++ b/.github/workflows/check path length.yml @@ -0,0 +1,22 @@ +name: Check path length + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + check-path-length: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check that all paths fit the Windows path length limit + run: bash .github/scripts/check-path-length.sh diff --git a/.github/workflows/create release.yml b/.github/workflows/create release.yml index 6c0be9c..0b90ddb 100644 --- a/.github/workflows/create release.yml +++ b/.github/workflows/create release.yml @@ -20,6 +20,9 @@ jobs: with: ref: main + - name: Check that all paths fit the Windows path length limit + run: bash .github/scripts/check-path-length.sh + - name: Create ZIP without .git and .github run: | zip -r solutions.zip . \ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea945ad..2f21582 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,7 @@ A guide on how to create your own Solutions can be found in the [documentation]( - The **configuration files must be located in a `config` subdirectory**, mirroring the structure used by the products - For reference you can take a look at the Solutions in this Repository - Each Solution must include a `solution.yaml` file +- File paths, counted from the repository root (for example `My Solution/config/versioned/...`), must not exceed **170 characters**; the product installs Solutions below a deep Windows folder, and longer paths cannot be installed. A CI check enforces this limit ### Metadata and Parameter Requirements From 22be354ff2b5b1f91dcdc8f6fa691dd24054cf38 Mon Sep 17 00:00:00 2001 From: Jannik Spiering Date: Wed, 23 Sep 2026 16:47:34 +0200 Subject: [PATCH 2/3] Reword the path length rule in CONTRIBUTING.md Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2f21582..b89fdb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ A guide on how to create your own Solutions can be found in the [documentation]( - The **configuration files must be located in a `config` subdirectory**, mirroring the structure used by the products - For reference you can take a look at the Solutions in this Repository - Each Solution must include a `solution.yaml` file -- File paths, counted from the repository root (for example `My Solution/config/versioned/...`), must not exceed **170 characters**; the product installs Solutions below a deep Windows folder, and longer paths cannot be installed. A CI check enforces this limit +- File paths from the repository root (for example, `My Solution/config/versioned/...`) must be **170 characters or fewer**. Longer paths cannot be installed because Solutions are deployed under a deep Windows directory. CI enforces this limit. ### Metadata and Parameter Requirements From dacc07b4b4aab189fb74b9313ecd6966ff7bd4ec Mon Sep 17 00:00:00 2001 From: Jannik Spiering Date: Fri, 25 Sep 2026 10:06:53 +0200 Subject: [PATCH 3/3] Comment the path length check and split the MAX_PATH sentence Co-Authored-By: Claude Opus 5.5 --- .github/scripts/check-path-length.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/scripts/check-path-length.sh b/.github/scripts/check-path-length.sh index 08063af..cafef96 100755 --- a/.github/scripts/check-path-length.sh +++ b/.github/scripts/check-path-length.sh @@ -5,29 +5,48 @@ # C:\ProgramData\inray\OPC Router 5\config\solution-gallery\\ # where is 8 characters (24 in versions before tp#354132), so up to # 83 characters precede every path of this repository. Windows limits a full -# path to 259 characters (MAX_PATH 260 including the terminating NUL), which -# leaves 176 characters; the default limit keeps a small safety margin. +# path to 259 characters (MAX_PATH 260 including the terminating NUL). That +# leaves 176 characters. The default limit keeps a small safety margin. set -euo pipefail export LC_ALL=C.UTF-8 +# Allow the default safety margin to be adjusted through an environment variable. limit="${MAX_SOLUTION_PATH_LENGTH:-170}" failed=0 longest=0 +# Measure paths from the repository root, regardless of where this script is run. cd "$(git rev-parse --show-toplevel)" +# Read the NUL-delimited paths emitted by find -print0: +# IFS= preserves leading and trailing whitespace. +# -r treats backslashes literally. +# -d '' uses NUL as the delimiter, allowing newlines within filenames. +# Process substitution (< <(...)) keeps the loop in this shell so updates to +# failed and longest remain available after the loop. while IFS= read -r -d '' file; do + # Exclude find's leading ./ from the repository-relative path length. rel="${file#./}" len=${#rel} + if (( len > longest )); then longest=$len fi + if (( len > limit )); then + # Emit a GitHub Actions error annotation, then keep checking the other files. echo "::error file=${rel}::Path is ${len} characters long (limit ${limit}). Shorten the Solution, Flow or parameter names so the Solution can be installed on Windows." failed=1 fi -done < <(find . -type f -not -path './.git/*' -not -path './.github/*' -not -path './img/*' -print0) +done < <( + # Exclude repository metadata, CI configuration, and image assets. + find . -type f \ + -not -path './.git/*' \ + -not -path './.github/*' \ + -not -path './img/*' \ + -print0 +) echo "Longest path: ${longest} characters (limit ${limit})." exit $failed