blob: 199dfcbe8240df0055e3e49b83dedf4d69767e63 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: _common
on:
workflow_call:
inputs:
skip_pr_title:
type: boolean
required: false
default: false
description: "Skip PR title check (for push events)"
permissions:
contents: read
pull-requests: read
jobs:
rust-versions:
name: Check Rust versions sync
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- uses: actions/checkout@v4
- name: Check Rust versions are synchronized
run: |
# Use the sync-rust-version.sh script in check mode
if ! bash scripts/sync-rust-version.sh --check; then
echo ""
echo "โŒ Rust versions are not synchronized!"
echo ""
echo "To fix this issue, run:"
echo " ./scripts/sync-rust-version.sh --fix"
echo ""
echo "This script will automatically update all Dockerfiles to match rust-toolchain.toml"
exit 1
fi
pr-title:
name: Check PR Title
if: github.event_name == 'pull_request' && !inputs.skip_pr_title
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- name: Validate PR Title
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
style
refactor
perf
test
build
ci
chore
revert
repo
deps
license-headers:
name: Check license headers
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- uses: actions/checkout@v4
- name: Check Apache license headers
run: |
echo "๐Ÿ” Checking license headers..."
# Pull the addlicense image
docker pull ghcr.io/google/addlicense:latest
# Run the check
if docker run --rm -v ${{ github.workspace }}:/src -w /src \
ghcr.io/google/addlicense:latest \
-check -f ASF_LICENSE.txt . > missing_files.txt 2>&1; then
echo "โœ… All files have proper license headers"
else
file_count=$(wc -l < missing_files.txt)
echo "โŒ Found $file_count files missing license headers:"
echo ""
cat missing_files.txt | sed 's/^/ โ€ข /'
echo ""
echo "๐Ÿ’ก Run 'addlicense -f ASF_LICENSE.txt .' to fix automatically"
# Add to summary
echo "## โŒ License Headers Missing" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The following files are missing Apache license headers:" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat missing_files.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo 'Please call `just licenses-fix` to fix automatically.' >> $GITHUB_STEP_SUMMARY
exit 1
fi
license-list:
name: Check licenses list
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: ./.github/actions/utils/setup-rust-with-cache
with:
enabled: "false" # Don't need cache for just checking licenses
- run: scripts/licenses-list.sh --check
markdown:
name: Markdown lint
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '23'
- name: Install markdownlint-cli
run: npm install -g markdownlint-cli
- name: Run markdownlint
run: |
echo "๐Ÿ” Checking markdown files..."
# Create config if it doesn't exist
if [ ! -f ".markdownlint.yml" ]; then
cat > .markdownlint.yml << 'EOF'
# Markdown lint configuration
default: true
MD013:
line_length: 120
tables: false
MD033:
allowed_elements: [details, summary, img]
MD041: false # First line in file should be a top level heading
EOF
fi
# Run the linter
if markdownlint '**/*.md' --ignore-path .gitignore; then
echo "โœ… All markdown files are properly formatted"
else
echo "โŒ Markdown linting failed"
echo "๐Ÿ’ก Run 'markdownlint **/*.md --fix' to auto-fix issues"
exit 1
fi
shellcheck:
name: Shell scripts lint
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install shellcheck
run: |
sudo apt-get update --yes && sudo apt-get install --yes shellcheck
- name: Check shell scripts
run: |
echo "๐Ÿ” Checking shell scripts..."
# Find all shell scripts excluding certain directories
if find . -type f -name "*.sh" \
-not -path "./target/*" \
-not -path "./node_modules/*" \
-not -path "./.git/*" \
-not -path "./foreign/node/node_modules/*" \
-not -path "./foreign/python/.venv/*" \
-exec shellcheck -S warning {} +; then
echo "โœ… All shell scripts passed shellcheck"
else
echo "โŒ Shellcheck found issues in shell scripts"
echo "๐Ÿ’ก Fix the issues reported above"
exit 1
fi
trailing-whitespace:
name: Check trailing whitespace
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history to get diff
- name: Check for trailing whitespace in changed files
run: |
echo "๐Ÿ” Checking for trailing whitespace in changed files..."
# Get list of changed files in PR
if [ "${{ github.event_name }}" = "pull_request" ]; then
git fetch --no-tags --depth=1 origin ${{ github.event.pull_request.base.ref }}:${{ github.event.pull_request.base.ref }} || true
BASE_SHA="${{ github.event.pull_request.base.sha }}"
CHANGED_FILES=$(git diff --name-only --diff-filter=ACM "$BASE_SHA"...HEAD || true)
else
CHANGED_FILES=$(git diff --name-only --diff-filter=ACM HEAD~1)
fi
if [ -z "$CHANGED_FILES" ]; then
echo "No files changed to check"
exit 0
fi
echo "Files to check:"
echo "$CHANGED_FILES" | sed 's/^/ โ€ข /'
echo ""
# Check each changed file for trailing whitespace
FILES_WITH_TRAILING=""
for file in $CHANGED_FILES; do
# Skip if file doesn't exist (might be deleted)
if [ ! -f "$file" ]; then
continue
fi
# Skip binary files
if file "$file" | grep -qE "binary|data|executable|compressed"; then
continue
fi
# Check for trailing whitespace
if grep -q '[[:space:]]$' "$file" 2>/dev/null; then
FILES_WITH_TRAILING="$FILES_WITH_TRAILING $file"
fi
done
if [ -z "$FILES_WITH_TRAILING" ]; then
echo "โœ… No trailing whitespace found in changed files"
else
echo "โŒ Found trailing whitespace in the following changed files:"
echo ""
for file in $FILES_WITH_TRAILING; do
echo " โ€ข $file"
# Show lines with trailing whitespace (limit to first 5 occurrences per file)
grep -n '[[:space:]]$' "$file" | head -5 | while IFS=: read -r line_num content; do
# Show the line with visible whitespace markers
visible_content=$(echo "$content" | sed 's/ /ยท/g; s/\t/โ†’/g')
echo " Line $line_num: '${visible_content}'"
done
TOTAL_LINES=$(grep -c '[[:space:]]$' "$file")
if [ "$TOTAL_LINES" -gt 5 ]; then
echo " ... and $((TOTAL_LINES - 5)) more lines"
fi
echo ""
done
echo "๐Ÿ’ก To fix trailing whitespace in these files:"
echo " โ€ข VSCode: Enable 'files.trimTrailingWhitespace' setting"
echo " โ€ข Fix specific file: sed -i 's/[[:space:]]*$//' <filename>"
echo " โ€ข Fix all changed files:"
echo " for f in$FILES_WITH_TRAILING; do sed -i 's/[[:space:]]*$//' \$f; done"
exit 1
fi
trailing-newline:
name: Check trailing newline
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history to get diff
- name: Check for trailing newline in changed text files
run: |
echo "๐Ÿ” Checking for trailing newline in changed text files..."
# Get list of changed files in PR
if [ "${{ github.event_name }}" = "pull_request" ]; then
git fetch --no-tags --depth=1 origin ${{ github.event.pull_request.base.ref }}:${{ github.event.pull_request.base.ref }} || true
BASE_SHA="${{ github.event.pull_request.base.sha }}"
CHANGED_FILES=$(git diff --name-only --diff-filter=ACM "$BASE_SHA"...HEAD || true)
else
CHANGED_FILES=$(git diff --name-only --diff-filter=ACM HEAD~1)
fi
if [ -z "$CHANGED_FILES" ]; then
echo "No files changed to check"
exit 0
fi
echo "Files to check:"
echo "$CHANGED_FILES" | sed 's/^/ โ€ข /'
echo ""
# Check each changed file for missing trailing newline
FILES_WITHOUT_NEWLINE=""
for file in $CHANGED_FILES; do
# Skip if file doesn't exist (might be deleted)
if [ ! -f "$file" ]; then
continue
fi
# Skip binary files
if file "$file" | grep -qE "binary|data|executable|compressed"; then
continue
fi
# Skip empty files
if [ ! -s "$file" ]; then
continue
fi
# Check if file ends with a newline
# Use tail to get last byte and od to check if it's a newline (0x0a)
if [ -n "$(tail -c 1 "$file" | od -An -tx1 | grep -v '0a')" ]; then
FILES_WITHOUT_NEWLINE="$FILES_WITHOUT_NEWLINE $file"
fi
done
if [ -z "$FILES_WITHOUT_NEWLINE" ]; then
echo "โœ… All changed text files have trailing newlines"
else
echo "โŒ Found text files without trailing newline:"
echo ""
for file in $FILES_WITHOUT_NEWLINE; do
echo " โ€ข $file"
# Show last few characters of the file for context
echo -n " Last characters: '"
tail -c 20 "$file" | tr '\n' 'โ†ต' | sed 's/\t/โ†’/g'
echo "'"
echo ""
done
echo "๐Ÿ’ก To add trailing newlines to these files:"
echo " โ€ข VSCode: Enable 'files.insertFinalNewline' setting"
echo " โ€ข Fix specific file: echo >> <filename>"
echo " โ€ข Fix all files:"
echo " for f in$FILES_WITHOUT_NEWLINE; do [ -n \"\$(tail -c 1 \"\$f\")\" ] && echo >> \"\$f\"; done"
exit 1
fi
summary:
name: Common checks summary
needs: [rust-versions, pr-title, license-headers, license-list, markdown, shellcheck, trailing-whitespace, trailing-newline]
if: always()
runs-on: ubuntu-latest
env:
IGGY_CI_BUILD: true
steps:
- name: Summary
run: |
echo "## ๐Ÿ“‹ Common Checks Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Check | Status | Description |" >> $GITHUB_STEP_SUMMARY
echo "|-------|--------|-------------|" >> $GITHUB_STEP_SUMMARY
# PR-specific checks
if [ "${{ github.event_name }}" = "pull_request" ]; then
PR_TITLE="${{ needs.pr-title.result }}"
# Add emoji based on status
if [ "$PR_TITLE" = "success" ]; then
echo "| โœ… PR Title | success | Follows conventional format |" >> $GITHUB_STEP_SUMMARY
elif [ "$PR_TITLE" = "failure" ]; then
echo "| โŒ PR Title | failure | Must follow conventional format |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ PR Title | $PR_TITLE | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
else
echo "| โญ๏ธ PR Title | skipped | Not a pull request |" >> $GITHUB_STEP_SUMMARY
fi
# Always-run checks
RUST_VERSIONS="${{ needs.rust-versions.result }}"
LICENSE_HEADERS="${{ needs.license-headers.result }}"
LICENSE_LIST="${{ needs.license-list.result }}"
MARKDOWN="${{ needs.markdown.result }}"
if [ "$RUST_VERSIONS" = "success" ]; then
echo "| โœ… Rust Versions | success | All Rust versions synchronized |" >> $GITHUB_STEP_SUMMARY
elif [ "$RUST_VERSIONS" = "failure" ]; then
echo "| โŒ Rust Versions | failure | Rust versions mismatch in Dockerfiles |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ Rust Versions | $RUST_VERSIONS | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
if [ "$LICENSE_HEADERS" = "success" ]; then
echo "| โœ… License Headers | success | All files have Apache headers |" >> $GITHUB_STEP_SUMMARY
elif [ "$LICENSE_HEADERS" = "failure" ]; then
echo "| โŒ License Headers | failure | Missing Apache license headers |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ License Headers | $LICENSE_HEADERS | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
if [ "$LICENSE_LIST" = "success" ]; then
echo "| โœ… License List | success | Dependencies licenses validated |" >> $GITHUB_STEP_SUMMARY
elif [ "$LICENSE_LIST" = "failure" ]; then
echo "| โŒ License List | failure | License list needs update |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ License List | $LICENSE_LIST | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
if [ "$MARKDOWN" = "success" ]; then
echo "| โœ… Markdown Lint | success | All markdown files are valid |" >> $GITHUB_STEP_SUMMARY
elif [ "$MARKDOWN" = "failure" ]; then
echo "| โŒ Markdown Lint | failure | Markdown formatting issues found |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ Markdown Lint | $MARKDOWN | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
SHELLCHECK="${{ needs.shellcheck.result }}"
if [ "$SHELLCHECK" = "success" ]; then
echo "| โœ… Shellcheck | success | All shell scripts are valid |" >> $GITHUB_STEP_SUMMARY
elif [ "$SHELLCHECK" = "failure" ]; then
echo "| โŒ Shellcheck | failure | Shell script issues found |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ Shellcheck | $SHELLCHECK | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
TRAILING="${{ needs.trailing-whitespace.result }}"
if [ "$TRAILING" = "success" ]; then
echo "| โœ… Trailing Whitespace | success | No trailing whitespace found |" >> $GITHUB_STEP_SUMMARY
elif [ "$TRAILING" = "failure" ]; then
echo "| โŒ Trailing Whitespace | failure | Trailing whitespace detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ Trailing Whitespace | $TRAILING | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
TRAILING_NL="${{ needs.trailing-newline.result }}"
if [ "$TRAILING_NL" = "success" ]; then
echo "| โœ… Trailing Newline | success | All text files have trailing newlines |" >> $GITHUB_STEP_SUMMARY
elif [ "$TRAILING_NL" = "failure" ]; then
echo "| โŒ Trailing Newline | failure | Missing trailing newlines detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| โญ๏ธ Trailing Newline | $TRAILING_NL | Check skipped |" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Overall status
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
echo "### โŒ Some checks failed" >> $GITHUB_STEP_SUMMARY
echo "Please review the failed checks above and fix the issues." >> $GITHUB_STEP_SUMMARY
elif [[ "${{ contains(needs.*.result, 'skipped') }}" == "true" ]]; then
echo "### โš ๏ธ Some checks were skipped" >> $GITHUB_STEP_SUMMARY
else
echo "### โœ… All checks passed!" >> $GITHUB_STEP_SUMMARY
fi