Files
factorio-clusterio/.github/workflows/ci-changes.yml
T
Arvids Godjuks c4f48b6c12 Correct developer guidance and skip heavy CI for documentation changes (#1090)
Add a minimal AGENTS.md, update documentation and optimize the CI runs to not run actions for which there are no changes present
2026-10-16 22:30:05 +03:00

127 lines
5.7 KiB
YAML

name: Classify CI changes
on:
workflow_call:
outputs:
build_and_test:
description: Run the test and coverage matrix, compatibility tests, and mod build.
value: ${{ jobs.changes.outputs.build_and_test }}
js_lint:
description: Run the JavaScript/TypeScript linter.
value: ${{ jobs.changes.outputs.js_lint }}
lua_lint:
description: Run the Lua linter.
value: ${{ jobs.changes.outputs.lua_lint }}
jobs:
changes:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
build_and_test: ${{ steps.syntax.outputs.build_and_test || steps.paths.outputs.code }}
js_lint: ${{ steps.lint.outputs.js_lint }}
lua_lint: ${{ steps.lint.outputs.lua_lint }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: dorny/paths-filter@v4
id: paths
with:
token: ''
base: ${{ github.event.pull_request.base.sha || github.event.before }}
ref: ${{ github.sha }}
list-files: json
predicate-quantifier: every
filters: |
# Files requiring validation beyond documentation checks.
code:
- '**'
- '!**/*.md'
- '!docs/**/*.{png,jpg,svg,gif}'
# Sources and configuration owned by each linter.
# Workflow scripts and shared build configuration run both linters.
js:
- '**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'
- '!.github/**'
- '!**/{webpack,babel,rollup,vite,jest}.config.*'
lua:
- '{*.lua,**/*.lua,.emmyrc.json}'
- '!.github/**'
# Modified JS/TS source eligible for the comment-only shortcut.
# TypeScript type changes still count as substantive changes.
syntax:
- modified: '**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'
# Source fixtures and templates always receive full validation.
- '!test/file/**'
- '!packages/create/templates/**'
- '!.github/**'
- '!**/{eslint,webpack,babel,rollup,vite,jest}.config.*'
- name: Select linters
id: lint
env:
CODE_FILES: ${{ steps.paths.outputs.code_files }}
JS_FILES: ${{ steps.paths.outputs.js_files }}
LUA_FILES: ${{ steps.paths.outputs.lua_files }}
run: |
# Unclassified non-documentation files can affect either language.
jq -nr --argjson code "$CODE_FILES" --argjson js "$JS_FILES" --argjson lua "$LUA_FILES" '
($code - $js - $lua | length > 0) as $shared |
"js_lint=\($shared or ($js | length > 0))",
"lua_lint=\($shared or ($lua | length > 0))"
' >> "$GITHUB_OUTPUT"
- name: Install Difftastic
if: steps.paths.outputs.syntax == 'true'
env:
DIFFT_VERSION: 0.71.0
DIFFT_SHA256: 61aea5394a53c56f144637cf39b3a0c0dafa27769731745e5851ff276e6478da
run: |
mkdir -p "$RUNNER_TEMP/difftastic"
curl -fsSL "https://github.com/Wilfred/difftastic/releases/download/$DIFFT_VERSION/difft-$DIFFT_VERSION-x86_64-unknown-linux-gnu.tar.gz" -o "$RUNNER_TEMP/difftastic.tar.gz"
echo "$DIFFT_SHA256 $RUNNER_TEMP/difftastic.tar.gz" | sha256sum -c
tar -xzf "$RUNNER_TEMP/difftastic.tar.gz" -C "$RUNNER_TEMP/difftastic"
echo "$RUNNER_TEMP/difftastic" >> "$GITHUB_PATH"
- name: Check for substantive changes
id: syntax
if: steps.paths.outputs.code == 'true'
env:
CODE_FILES: ${{ steps.paths.outputs.code_files }}
SYNTAX_FILES: ${{ steps.paths.outputs.syntax_files }}
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.sha }}
run: |
# Skip only when every non-documentation file is an ordinary source edit.
echo 'build_and_test=true' >> "$GITHUB_OUTPUT"
# A new branch has no previous commit; keep full validation on its first push.
if [[ "$BASE" == 0000000000000000000000000000000000000000 ]]; then
exit 0
fi
if ! jq -en --argjson code "$CODE_FILES" --argjson syntax "$SYNTAX_FILES" \
'$code - $syntax | length == 0' > /dev/null; then
exit 0
fi
git cat-file -e "$BASE^{commit}"
jq -j '.[] | ., "\u0000"' <<< "$SYNTAX_FILES" > "$RUNNER_TEMP/syntax-files"
while IFS= read -r -d '' file; do
# Mode changes and symlinks are substantive even when text is identical.
[[ -z "$(git diff --summary --no-renames "$BASE" "$HEAD_SHA" -- "$file")" ]] || exit 0
git ls-tree "$HEAD_SHA" -- "$file" | grep -qE '^100(644|755) blob ' || exit 0
before="$RUNNER_TEMP/before.${file##*.}"
after="$RUNNER_TEMP/after.${file##*.}"
git show "$BASE:$file" > "$before"
git show "$HEAD_SHA:$file" > "$after"
# Difftastic ignores ALL comments; retain compiler/bundler/coverage directives.
if grep -Eq '@ts-|@jsx|@internal|<reference\b|<amd-|sourceMappingURL|sourceURL|webpack|vite|[#@]__|/\*!|(istanbul|c8|v8)[[:space:]]+ignore' "$before" "$after"; then
exit 0
fi
case "$file" in
*.js|*.cjs|*.mjs|*.jsx)
# JavaScript JSDoc can contain type information.
if grep -Fq '/**' "$before" "$after"; then exit 0; fi ;;
esac
if ! difft --ignore-comments --check-only --exit-code "$before" "$after"; then
exit 0
fi
done < "$RUNNER_TEMP/syntax-files"
echo 'build_and_test=false' >> "$GITHUB_OUTPUT"