From 91d7135562ec65a25b7f6be0d9303f531698e9cf Mon Sep 17 00:00:00 2001 From: Krzysztof Moch Date: Sat, 2 Dec 2023 15:58:43 +0100 Subject: [PATCH] chore: enhance CI tests (#3344) * chore: add swift linter * chore: add clang linters * chore: add kotlin linter * chore(ci): update workflows * chore(ci): clean workflows --- .github/actions/setup-node/action.yml | 2 +- .github/workflows/check-android.yml | 34 ++++++++++++++++++ .github/workflows/check-clang.yml | 31 ++++++++++++++++ .github/workflows/check-ios.yml | 41 +++++++++++++++++++++ .github/workflows/check-js.yml | 2 +- android/.editorconfig | 14 ++++++++ ios/.clang-format | 25 +++++++++++++ ios/.swiftformat | 13 +++++++ ios/.swiftlint.yml | 51 +++++++++++++++++++++++++++ package.json | 5 ++- scripts/bootstrap.js | 26 ++++++++++++++ scripts/clang-format.sh | 9 +++++ scripts/kotlin-lint.sh | 7 ++++ scripts/swift-format.sh | 7 ++++ scripts/swift-lint.sh | 7 ++++ 15 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/check-android.yml create mode 100644 .github/workflows/check-clang.yml create mode 100644 .github/workflows/check-ios.yml create mode 100644 android/.editorconfig create mode 100644 ios/.clang-format create mode 100644 ios/.swiftformat create mode 100644 ios/.swiftlint.yml create mode 100644 scripts/bootstrap.js create mode 100755 scripts/clang-format.sh create mode 100755 scripts/kotlin-lint.sh create mode 100755 scripts/swift-format.sh create mode 100755 scripts/swift-lint.sh diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index 4627f212..e131e408 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -31,4 +31,4 @@ runs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install --immutable --ignore-scripts shell: bash - + \ No newline at end of file diff --git a/.github/workflows/check-android.yml b/.github/workflows/check-android.yml new file mode 100644 index 00000000..b5e4e165 --- /dev/null +++ b/.github/workflows/check-android.yml @@ -0,0 +1,34 @@ +name: Check Android + +on: + push: + branches: + - master + paths: + - '.github/workflows/check-android.yml' + - 'android/**' + pull_request: + paths: + - '.github/workflows/check-android.yml' + - 'android/**' + +jobs: + Kotlin-Lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: | + curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.0.0/ktlint && chmod a+x ktlint && sudo mv ktlint /usr/local/bin/ + - name: run ktlint + working-directory: ./android/ + run: | + ktlint --reporter=checkstyle,output=build/ktlint-report.xml --relative --editorconfig=./.editorconfig + continue-on-error: true + - uses: yutailang0119/action-ktlint@v3 + with: + report-path: ./android/build/*.xml + continue-on-error: false + - uses: actions/upload-artifact@v3 + with: + name: ktlint-report + path: ./android/build/*.xml diff --git a/.github/workflows/check-clang.yml b/.github/workflows/check-clang.yml new file mode 100644 index 00000000..86433c94 --- /dev/null +++ b/.github/workflows/check-clang.yml @@ -0,0 +1,31 @@ +name: Check CLang + +on: + push: + branches: + - master + paths: + - '.github/workflows/check-clang.yml' + - 'ios/**' + pull_request: + branches: + - master + paths: + - '.github/workflows/check-clang.yml' + - 'ios/**' + +jobs: + CLang-Format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install clang-format + run: sudo apt-get install clang-format + - name: Check ios clang formatting + run: | + find ios -type f \( -name "*.h" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" \) -print0 | while read -d $'\0' file; do + clang-format -style=file:./ios/.clang-format -i "$file" + done + shell: bash + - name: Check for changes + run: git diff --exit-code HEAD diff --git a/.github/workflows/check-ios.yml b/.github/workflows/check-ios.yml new file mode 100644 index 00000000..621522de --- /dev/null +++ b/.github/workflows/check-ios.yml @@ -0,0 +1,41 @@ +name: Check iOS + +on: + push: + branches: + - master + paths: + - '.github/workflows/check-ios.yml' + - 'ios/**' + pull_request: + paths: + - '.github/workflows/check-ios.yml' + - 'ios/**' + +jobs: + Swift-Lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Lint with SwiftLint + uses: norio-nomura/action-swiftlint@master + with: + args: --strict + env: + WORKING_DIRECTORY: ios + Swift-Format: + runs-on: macOS-latest + defaults: + run: + working-directory: ./ios + steps: + - uses: actions/checkout@v4 + + - name: Install SwiftFormat + run: brew install swiftformat + + - name: Format Swift code + run: swiftformat --verbose . + + - name: Verify formatted code is unchanged + run: git diff --exit-code HEAD diff --git a/.github/workflows/check-js.yml b/.github/workflows/check-js.yml index 77839789..c9f7bd3d 100644 --- a/.github/workflows/check-js.yml +++ b/.github/workflows/check-js.yml @@ -59,4 +59,4 @@ jobs: run: yarn lint --fix - name: Verify no files have changed after auto-fix - run: git diff --exit-code HEAD \ No newline at end of file + run: git diff --exit-code HEAD diff --git a/android/.editorconfig b/android/.editorconfig new file mode 100644 index 00000000..30514ea4 --- /dev/null +++ b/android/.editorconfig @@ -0,0 +1,14 @@ +[*.{kt,kts}] +indent_style=space +indent_size=2 +continuation_indent_size=4 +insert_final_newline=true +max_line_length=160 +ktlint_code_style=android_studio +ktlint_standard=enabled +ktlint_experimental=enabled +ktlint_standard_filename=disabled # dont require PascalCase filenames +ktlint_standard_no-wildcard-imports=disabled # allow .* imports +ktlint_function_signature_body_expression_wrapping=multiline +ij_kotlin_allow_trailing_comma_on_call_site=false +ij_kotlin_allow_trailing_comma=false \ No newline at end of file diff --git a/ios/.clang-format b/ios/.clang-format new file mode 100644 index 00000000..3988e8df --- /dev/null +++ b/ios/.clang-format @@ -0,0 +1,25 @@ +# Config for clang-format version 16 + +# standard +BasedOnStyle: llvm +Standard: c++14 + +# Indentation +IndentWidth: 2 +ColumnLimit: 140 + +# Includes +SortIncludes: true +SortUsingDeclarations: true + +# Pointer and reference alignment +PointerAlignment: Left +ReferenceAlignment: Left +ReflowComments: true + +# Line breaking options +BreakBeforeBraces: Attach +BreakConstructorInitializers: BeforeColon +AllowShortFunctionsOnASingleLine: Empty +IndentCaseLabels: true +NamespaceIndentation: Inner \ No newline at end of file diff --git a/ios/.swiftformat b/ios/.swiftformat new file mode 100644 index 00000000..0bdcb6b7 --- /dev/null +++ b/ios/.swiftformat @@ -0,0 +1,13 @@ +--allman false +--indent 2 +--exclude Pods,Generated + +--disable andOperator +--disable redundantReturn +--disable wrapMultilineStatementBraces +--disable organizeDeclarations +--disable redundantSelf + +--enable markTypes + +--enable isEmpty \ No newline at end of file diff --git a/ios/.swiftlint.yml b/ios/.swiftlint.yml new file mode 100644 index 00000000..7d51a163 --- /dev/null +++ b/ios/.swiftlint.yml @@ -0,0 +1,51 @@ +disabled_rules: + - identifier_name + - trailing_comma + - todo + - type_body_length + - file_length + - cyclomatic_complexity + - function_body_length +opt_in_rules: + - contains_over_filter_count + - contains_over_filter_is_empty + - contains_over_first_not_nil + - contains_over_range_nil_comparison + - empty_collection_literal + - empty_count + - empty_string + - first_where + - flatmap_over_map_reduce + - last_where + - reduce_boolean + - reduce_into + - yoda_condition + - vertical_whitespace_opening_braces + - vertical_whitespace_closing_braces + - vertical_parameter_alignment_on_call + - untyped_error_in_catch + - unowned_variable_capture + - unavailable_function + - switch_case_on_newline + - static_operator + - strict_fileprivate + - sorted_imports + - sorted_first_last + - required_enum_case + - redundant_type_annotation + - redundant_nil_coalescing + - attributes + - convenience_type +analyzer_rules: + - explicit_self + - unused_declaration + - unused_import + +excluded: # paths to ignore during linting. Takes precedence over `included`. + - Pods + +# Adjust rule numbers +line_length: 160 + +# reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging) +reporter: "xcode" \ No newline at end of file diff --git a/package.json b/package.json index c30d8c6e..4b1d6193 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@types/react": "~18.0.0", "@types/react-native": "0.72.3", "@typescript-eslint/eslint-plugin": "^6.7.4", + "@jamesacarr/eslint-formatter-github-actions": "^0.2.0", "eslint": "^8.19.0", "eslint-plugin-jest": "^27.4.2", "jest": "^29.7.0", @@ -45,7 +46,9 @@ "xbasic": "yarn --cwd examples/basic", "docs": "yarn --cwd docs build", "release": "release-it", - "test": "echo no test available" + "test": "echo no test available", + "check-ios": "scripts/swift-format.sh && scripts/swift-lint.sh && scripts/clang-format.sh", + "check-android": "scripts/kotlin-lint.sh" }, "files": [ "android", diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js new file mode 100644 index 00000000..2375956d --- /dev/null +++ b/scripts/bootstrap.js @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const path = require('path'); +const child_process = require('child_process'); + +const root = path.resolve(__dirname, '..'); +const args = process.argv.slice(2); +const options = { + cwd: process.cwd(), + env: process.env, + stdio: 'inherit', + encoding: 'utf-8', +}; + +let result; + +if (process.cwd() !== root || args.length) { + // We're not in the root of the project, or additional arguments were passed + // In this case, forward the command to `yarn` + result = child_process.spawnSync('yarn', args, options); +} else { + // If `yarn` is run without arguments, perform bootstrap + result = child_process.spawnSync('yarn', ['bootstrap'], options); +} + +process.exitCode = result.status; diff --git a/scripts/clang-format.sh b/scripts/clang-format.sh new file mode 100755 index 00000000..ef5913d6 --- /dev/null +++ b/scripts/clang-format.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if which clang-format >/dev/null; then + find ios -type f \( -name "*.h" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" \) -print0 | while read -d $'\0' file; do + clang-format -style=file:./ios/.clang-format -i "$file" + done +else + echo "[ERROR]: clang-format is not installed - Install with 'brew install clang-format' (or manually from https://clang.llvm.org/docs/ClangFormat.html)" +fi \ No newline at end of file diff --git a/scripts/kotlin-lint.sh b/scripts/kotlin-lint.sh new file mode 100755 index 00000000..bf4bde48 --- /dev/null +++ b/scripts/kotlin-lint.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if which ktlint >/dev/null; then + cd android && ktlint --color --relative --editorconfig=./.editorconfig -F ./**/*.kt* +else + echo "[ERROR]: KTLint is not installed - Install with 'brew install ktlint' (or manually from https://github.com/pinterest/ktlint)" +fi \ No newline at end of file diff --git a/scripts/swift-format.sh b/scripts/swift-format.sh new file mode 100755 index 00000000..43ad0d62 --- /dev/null +++ b/scripts/swift-format.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if which swiftformat >/dev/null; then + cd ios && swiftformat --quiet . +else + echo "[ERROR]: SwiftFormat is not installed -Install with 'brew install swiftformat' (or manually from https://github.com/nicklockwood/SwiftFormat)" +fi \ No newline at end of file diff --git a/scripts/swift-lint.sh b/scripts/swift-lint.sh new file mode 100755 index 00000000..ea07239b --- /dev/null +++ b/scripts/swift-lint.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if which swiftlint >/dev/null; then + cd ios && swiftlint --quiet --fix && swiftlint --quiet +else + echo "[ERROR]: SwiftLint is not installed - Install with 'brew install swiftlint' (or manually from https://github.com/realm/SwiftLint)" +fi \ No newline at end of file