From 36658164c92ce1504f746e3ac84abce503805cf3 Mon Sep 17 00:00:00 2001 From: RDW Date: Sat, 19 Oct 2024 16:54:13 +0200 Subject: [PATCH] CI: Streamline the autoformat process and format versions After much iteration, this is the simplest solution I could come up with that fulfills all the requirements: * A single clang-format version is used for all platforms * The version can be pinned in one central location * Whichever version is currently used will be tracked by git * Doesn't consume resources excessively thanks to caching * No reliance on third parties, other than the LLVM organization * Uses the same script for both CI runs and local development * No excessive branching/other accidental complexity * Bonus: Approach can also be used to install clang-tidy (later) Downloading a huge release tarball just for the tiny formatter feels like overkill, but it's reasonably fast in the CI. --- .github/autoformat.env | 2 + .github/workflows/autoformat.yml | 71 +++++++++++++++++++++----------- autoformat.sh | 21 ++++------ deps/get-clang-format.sh | 50 ++++++++++++++++++++++ deps/install-clang-format.sh | 27 ------------ 5 files changed, 108 insertions(+), 63 deletions(-) create mode 100755 .github/autoformat.env create mode 100755 deps/get-clang-format.sh delete mode 100755 deps/install-clang-format.sh diff --git a/.github/autoformat.env b/.github/autoformat.env new file mode 100755 index 000000000..504407642 --- /dev/null +++ b/.github/autoformat.env @@ -0,0 +1,2 @@ +EVO_CLANGFORMAT_VERSION=19.1.2 +EVO_STYLUA_VERSION=v0.20.0 \ No newline at end of file diff --git a/.github/workflows/autoformat.yml b/.github/workflows/autoformat.yml index f4d62a0f9..13d2076f3 100644 --- a/.github/workflows/autoformat.yml +++ b/.github/workflows/autoformat.yml @@ -19,15 +19,21 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + include: + - os: ubuntu-latest + stylua: stylua-linux.zip + exe: "" + - os: macos-latest + stylua: stylua-macos.zip + exe: "" + - os: windows-latest + stylua: stylua-win64.zip + exe: ".exe" + defaults: + run: + shell: bash steps: - # MSYS needs to be available before running any git commands - - name: Install clang-format (via MSYS) - if: runner.os == 'Windows' - uses: msys2/setup-msys2@v2 - with: - install: git mingw-w64-x86_64-clang - - name: Disable autocrlf # Messes up everything on Windows since the formatter applies \n run: | git config --global core.autocrlf false @@ -35,25 +41,44 @@ jobs: - name: Check out Git repository uses: actions/checkout@v4 + with: + fetch-depth: 1 + submodules: false + + - name: Set up environment + run: | + set -a + source .github/autoformat.env + cat .github/autoformat.env >> $GITHUB_ENV + echo $(pwd) >> $GITHUB_PATH - - name: Set up StyLua - uses: JohnnyMorganz/stylua-action@v3.0.0 + - name: Cache clang-format binary + id: cache-clang-format + uses: actions/cache@v4 with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --check . --verbose - version: v0.20.0 - - # The preinstalled version is positively antique; replace with the latest and greatest (to match MSYS) - - name: Install clang-format (via APT) - if: runner.os == 'Linux' - run: ./deps/install-clang-format.sh - - - name: Install clang-format (via Homebrew) - if: runner.os == 'macOS' - run: brew install clang-format - + path: clang-format${{ matrix.exe }} + key: clang-format-${{ runner.os }}-${{ env.EVO_CLANGFORMAT_VERSION }} + restore-keys: | + clang-format-${{ runner.os }}-${{ env.EVO_CLANGFORMAT_VERSION }} + + - name: Install clang-format + if: steps.cache-clang-format.outputs.cache-hit != 'true' + run: deps/get-clang-format.sh + + - name: Verify clang-format version + run: which clang-format && clang-format --version + + - name: Install stylua + run: | + curl --location --output ${{ matrix.stylua }} https://github.com/JohnnyMorganz/StyLua/releases/download/${{ env.EVO_STYLUA_VERSION }}/${{ matrix.stylua }} + unzip ${{ matrix.stylua }} + chmod +x stylua + + - name: Verify stylua version + run: which stylua && stylua --version + - name: Run autoformat run: ./autoformat.sh - name: Check for inconsistent formatting - run: git --no-pager diff --exit-code -b . #The -b is for inconsistent newlines, which we ignore (for now) + run: git --no-pager diff --exit-code -b . \ No newline at end of file diff --git a/autoformat.sh b/autoformat.sh index f352cff1e..420a429c6 100755 --- a/autoformat.sh +++ b/autoformat.sh @@ -1,20 +1,15 @@ -# See deps/install-clang-format.sh for the required version (should always match) -REQUIRED_CLANG_FORMAT_VERSION="17" -CLANG_FORMAT="clang-format-$REQUIRED_CLANG_FORMAT_VERSION" - -# The MSYS version may lag behind somewhat, so a fallback option is needed -if ! command -v $CLANG_FORMAT &> /dev/null -then - echo "clang-format-$REQUIRED_CLANG_FORMAT_VERSION not found. Using the default clang-format instead" - echo - CLANG_FORMAT="clang-format" -fi +#!/bin/bash +set -aeuo pipefail +STYLUA="stylua" +CLANG_FORMAT="clang-format" echo "Installed formatters:" echo -echo "* " $(stylua --version) -echo "* " $($CLANG_FORMAT --version) +echo $(which $STYLUA) +echo $($STYLUA --version) +echo $(which $CLANG_FORMAT) +echo $($CLANG_FORMAT --version) echo echo "Formatting Lua sources ..." diff --git a/deps/get-clang-format.sh b/deps/get-clang-format.sh new file mode 100755 index 000000000..1a08b5909 --- /dev/null +++ b/deps/get-clang-format.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -aeuo pipefail +source .github/autoformat.env + +GITHUB_ORGANIZATION="llvm" +GITHUB_REPOSITORY="llvm-project" +REQUIRED_LLVM_VERSION=$EVO_CLANGFORMAT_VERSION # Pinned via ENV file to avoid headaches in CI runs +LLVMORG_SUFFIX="llvmorg-$REQUIRED_LLVM_VERSION" +GITHUB_BASE_URL="https://github.com/$GITHUB_ORGANIZATION/$GITHUB_REPOSITORY/releases/download/$LLVMORG_SUFFIX" + +echo "Downloading clang-format release for version $REQUIRED_LLVM_VERSION" + +PLATFORM=$(uname) +echo "Detected platform: $PLATFORM" + +case $PLATFORM in + MINGW64_NT*|CYGWIN_NT*|MSYS_NT*) + LLVM_ASSET_NAME="LLVM-$REQUIRED_LLVM_VERSION-Windows-X64" + CLANG_FORMAT_EXECUTABLE="clang-format.exe" + ;; + Linux) + LLVM_ASSET_NAME="LLVM-$REQUIRED_LLVM_VERSION-Linux-X64" + CLANG_FORMAT_EXECUTABLE="clang-format" + ;; + Darwin) + LLVM_ASSET_NAME="LLVM-$REQUIRED_LLVM_VERSION-macOS-ARM64" + CLANG_FORMAT_EXECUTABLE="clang-format" + ;; + *) + echo "Unsupported platform: $PLATFORM" + exit 1 + ;; +esac + +LLVM_RELEASE_ASSET="$LLVM_ASSET_NAME.tar.xz" +TARBALL_DOWNLOAD_DIR=$(pwd)/deps +TARBALL_DOWNLOAD_FILE="$TARBALL_DOWNLOAD_DIR/$LLVM_RELEASE_ASSET" + +LLVM_RELEASE_URL="$GITHUB_BASE_URL/$LLVM_RELEASE_ASSET" +echo "Fetching $LLVM_RELEASE_URL ..." +curl --location --output "$TARBALL_DOWNLOAD_FILE" "$LLVM_RELEASE_URL" + +CLANG_FORMAT_PATH="$LLVM_ASSET_NAME/bin/$CLANG_FORMAT_EXECUTABLE" +echo "Unpacking $CLANG_FORMAT_PATH ..." +tar --strip-components=2 -xvf "$TARBALL_DOWNLOAD_FILE" "$CLANG_FORMAT_PATH" + +chmod +x "./$CLANG_FORMAT_EXECUTABLE" + +echo "Cleanup: Removing $TARBALL_DOWNLOAD_FILE ..." +rm $TARBALL_DOWNLOAD_FILE \ No newline at end of file diff --git a/deps/install-clang-format.sh b/deps/install-clang-format.sh deleted file mode 100755 index 607de09b7..000000000 --- a/deps/install-clang-format.sh +++ /dev/null @@ -1,27 +0,0 @@ -set -e - -REQUIRED_CLANG_FORMAT_VERSION="17" -CLANG_FORMAT_DOWNLOAD_URL="https://apt.llvm.org/llvm.sh" - -echo "Downloading LLVM install script from $CLANG_FORMAT_DOWNLOAD_URL" -wget -O llvm.sh $CLANG_FORMAT_DOWNLOAD_URL -chmod +x llvm.sh -echo - -echo "You should inspect the contents of llvm.sh (e.g. via cat llvm.sh)" -echo "Don't blindly run code that was downloaded from the internet" -echo - -echo "The script will now attempt to install clang-format-$REQUIRED_CLANG_FORMAT_VERSION \n" -echo - -# This should prompt the user, giving them time to inspect llvm.sh if so desired (not in CI runs) -sudo ./llvm.sh $REQUIRED_CLANG_FORMAT_VERSION -sudo apt install clang-format-$REQUIRED_CLANG_FORMAT_VERSION -echo - -echo "Cleanup: Removing llvm.sh" -echo -rm -rf llvm.sh - -echo $(clang-format-$REQUIRED_CLANG_FORMAT_VERSION --version) \ No newline at end of file