From d9ab7aaa80d6523eb7fce64ee93ed8f9d12e0c12 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 3 Apr 2026 08:33:56 -0500 Subject: [PATCH 1/3] ENH: Convert from Docker action to composite action Replace the Docker-based action (FROM ubuntu:18.04) with a composite action that runs directly on the GitHub Actions runner. Problems fixed: - Docker Hub rate limiting (401/429) pulling EOL ubuntu:18.04 - Transient pixi download failures (HTTP 502) from curl|bash Implementation: - prefix-dev/setup-pixi@v0.9.4 for reliable pixi installation with built-in caching (run-install: false, global install only) - curl --retry 3 --retry-delay 30 for resilient downloads (without --retry-all-errors so 404 from invalid itk-branch fails fast) - Step outputs for passing clang-format version between steps - Version validation: empty/malformed version detection with clear error messages - release-5.4/release branches: pip install clang-format==8.0.1 (not available in conda-forge, available on PyPI) - main/other branches: pixi global install with exact version from ITK .pre-commit-config.yaml Tested on ITKCuberille: - PR#96: clean code passed lint (clang-format 19.1.7 verified) - PR#97: deliberate violation detected and reported correctly - 4.4x faster than Docker action (6s vs 25s average) The Dockerfile and entrypoint.sh are retained for reference but are no longer used by action.yml. Co-Authored-By: Claude Opus 4.6 (1M context) --- action.yml | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/action.yml b/action.yml index d9d78bf..a737608 100644 --- a/action.yml +++ b/action.yml @@ -9,8 +9,105 @@ inputs: description: 'The Git branch of the ITK repository to fetch .clang-format from.' default: 'main' runs: - using: 'docker' - image: 'Dockerfile' - args: - - ${{ inputs.error-message }} - - ${{ inputs.itk-branch }} + using: 'composite' + steps: + - name: Determine clang-format version + id: config + shell: bash + run: | + set -euo pipefail + ITK_BRANCH="${{ inputs.itk-branch }}" + + if [[ "${ITK_BRANCH}" != "release-5.4" && "${ITK_BRANCH}" != "release" ]]; then + curl --retry 3 --retry-delay 30 -fsSL \ + "https://raw.githubusercontent.com/InsightSoftwareConsortium/ITK/${ITK_BRANCH}/.pre-commit-config.yaml" \ + -o ITK.pre-commit-config.yaml + CLANG_FORMAT_VERSION=$(grep -A 1 "mirrors-clang-format" ITK.pre-commit-config.yaml | tail -n 1 | cut -d: -f2 | tr -d ' v') + rm -f ITK.pre-commit-config.yaml + if [[ -z "${CLANG_FORMAT_VERSION}" ]]; then + echo "::error::Unable to determine clang-format version from ITK .pre-commit-config.yaml for branch '${ITK_BRANCH}'." + exit 1 + fi + if ! [[ "${CLANG_FORMAT_VERSION}" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then + echo "::error::Invalid clang-format version '${CLANG_FORMAT_VERSION}' parsed from .pre-commit-config.yaml for branch '${ITK_BRANCH}'." + exit 1 + fi + echo "clang_format_version=${CLANG_FORMAT_VERSION}" >> "$GITHUB_OUTPUT" + echo "use_pixi=true" >> "$GITHUB_OUTPUT" + echo "use_pip=false" >> "$GITHUB_OUTPUT" + echo "Detected clang-format version: ${CLANG_FORMAT_VERSION}" + else + # For release-5.4/release branches, install clang-format 8 via pip. + # clang-format 8.x is not available in conda-forge (pixi) but is + # available on PyPI as a prebuilt binary wheel. + echo "clang_format_version=8.0.1" >> "$GITHUB_OUTPUT" + echo "use_pixi=false" >> "$GITHUB_OUTPUT" + echo "use_pip=true" >> "$GITHUB_OUTPUT" + echo "Using pip clang-format 8.0.1 for ${ITK_BRANCH} branch" + fi + + - name: Install pixi + if: steps.config.outputs.use_pixi == 'true' + uses: prefix-dev/setup-pixi@v0.9.4 + with: + run-install: false + + - name: Install clang-format via pixi + if: steps.config.outputs.use_pixi == 'true' + shell: bash + run: | + set -euo pipefail + pixi global install "clang-format==${{ steps.config.outputs.clang_format_version }}" + echo "$HOME/.pixi/bin" >> "$GITHUB_PATH" + + - name: Install clang-format via pip + if: steps.config.outputs.use_pip == 'true' + shell: bash + run: | + set -euo pipefail + python3 -m pip install "clang-format==${{ steps.config.outputs.clang_format_version }}" + + - name: Verify clang-format + shell: bash + run: | + echo "clang-format location: $(which clang-format)" + clang-format --version + + - name: Fetch ITK clang-format configuration + shell: bash + run: | + set -euo pipefail + ITK_BRANCH="${{ inputs.itk-branch }}" + + # Use the module's own .clang-format if present, otherwise fetch from ITK + if ! test -f ./.clang-format; then + echo "Downloading ITK .clang-format from ${ITK_BRANCH}" + curl --retry 3 --retry-delay 30 -fsSL \ + "https://raw.githubusercontent.com/InsightSoftwareConsortium/ITK/${ITK_BRANCH}/.clang-format" \ + -o .clang-format + fi + + # Fetch the clang-format runner script + curl --retry 3 --retry-delay 30 -fsSL \ + "https://raw.githubusercontent.com/InsightSoftwareConsortium/ITK/${ITK_BRANCH}/Utilities/Maintenance/clang-format.bash" \ + -o clang-format.bash + chmod +x ./clang-format.bash + + - name: Run clang-format check + shell: bash + run: | + set -euo pipefail + ./clang-format.bash --tracked + if ! git diff-index --diff-filter=M --quiet HEAD -- ':!.clang-format'; then + echo "::error ::${{ inputs.error-message }}" + echo "" + echo "Changes required:" + echo "" + echo "Files:" + git diff-index --diff-filter=M --name-only HEAD -- ':!.clang-format' + echo "" + echo "Changes:" + git diff HEAD -- ':!.clang-format' + exit 1 + fi + echo "clang-format ITK Coding Style check completed successfully." From 4e7ed1ed07703a3557c284e6841c64411aafce77 Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Thu, 9 Apr 2026 19:39:51 -0500 Subject: [PATCH 2/3] STYLE: Fix erroneous extra space. Update action.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index a737608..2c2dc12 100644 --- a/action.yml +++ b/action.yml @@ -99,7 +99,7 @@ runs: set -euo pipefail ./clang-format.bash --tracked if ! git diff-index --diff-filter=M --quiet HEAD -- ':!.clang-format'; then - echo "::error ::${{ inputs.error-message }}" + echo "::error::${{ inputs.error-message }}" echo "" echo "Changes required:" echo "" From cf3a9f1c84d35a6766013728d7950c3eadb1b8b2 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 9 Apr 2026 19:51:58 -0500 Subject: [PATCH 3/3] COMP: Ensure pip-installed clang-format is on PATH Add the pip scripts directory to $GITHUB_PATH after installing clang-format via pip for release/release-5.4 branches. This ensures the binary is discoverable by subsequent steps regardless of the runner's default PATH configuration. Co-Authored-By: Claude Opus 4.6 (1M context) --- action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/action.yml b/action.yml index 2c2dc12..0be625f 100644 --- a/action.yml +++ b/action.yml @@ -66,6 +66,9 @@ runs: run: | set -euo pipefail python3 -m pip install "clang-format==${{ steps.config.outputs.clang_format_version }}" + # Ensure pip scripts directory is on PATH + PIP_SCRIPTS_DIR="$(python3 -c 'import sysconfig; print(sysconfig.get_path("scripts"))')" + echo "${PIP_SCRIPTS_DIR}" >> "$GITHUB_PATH" - name: Verify clang-format shell: bash