remove version numbers; correct attribution (#55) #221
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: CI Tests | |
| "on": | |
| push: | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| detect-changes: | |
| name: Detect File Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| shell-scripts: ${{ steps.changes.outputs.shell-scripts }} | |
| markdown: ${{ steps.changes.outputs.markdown }} | |
| yaml: ${{ steps.changes.outputs.yaml }} | |
| python: ${{ steps.changes.outputs.python }} | |
| html: ${{ steps.changes.outputs.html }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v2 | |
| id: changes | |
| with: | |
| filters: | | |
| shell-scripts: | |
| - '**/*.sh' | |
| - 'scripts/**' | |
| - '.github/workflows/.shellcheckrc' | |
| markdown: | |
| - '**/*.md' | |
| yaml: | |
| - '**/*.yml' | |
| - '**/*.yaml' | |
| - '.github/workflows/**' | |
| - '.github/workflows/.yamllint' | |
| python: | |
| - '**/*.py' | |
| html: | |
| - '**/*.html' | |
| shellcheck: | |
| name: Shell Script Analysis | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.shell-scripts == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install shellcheck | |
| run: sudo apt-get update && sudo apt-get install -y shellcheck | |
| - name: Find and validate shell scripts | |
| run: | | |
| echo "=== Shell scripts found ===" | |
| find . -name "*.sh" -type f | |
| echo "=== Files with shell shebangs ===" | |
| find . -type f -executable -exec grep -l '^#!/.*sh' {} + || true | |
| - name: Run shellcheck | |
| run: | | |
| set -e | |
| # shellcheck will automatically use .shellcheckrc from current directory | |
| if [[ -f ".github/workflows/.shellcheckrc" ]]; then | |
| echo "Found .shellcheckrc in .github/workflows/" | |
| cd .github/workflows | |
| WORKING_DIR="../../" | |
| else | |
| echo "Using shellcheck with default settings" | |
| WORKING_DIR="." | |
| fi | |
| # Check .sh files (excluding .git directory) | |
| while IFS= read -r -d '' file; do | |
| if [[ -f "$WORKING_DIR/$file" && -r "$WORKING_DIR/$file" ]]; then | |
| echo "Checking $file" | |
| shellcheck "$WORKING_DIR/$file" | |
| fi | |
| done < <(find "$WORKING_DIR" -name "*.sh" -type f -not -path './.git/*' -print0 \ | |
| | sed "s|^$WORKING_DIR/||") | |
| # Check executable files with shell shebangs (excluding .git directory) | |
| while IFS= read -r -d '' file; do | |
| if [[ -f "$WORKING_DIR/$file" && -r "$WORKING_DIR/$file" ]] && \ | |
| grep -q '^#!/.*sh' "$WORKING_DIR/$file" 2>/dev/null; then | |
| echo "Checking executable $file" | |
| shellcheck "$WORKING_DIR/$file" | |
| fi | |
| done < <(find "$WORKING_DIR" -type f -executable -not -path './.git/*' -print0 \ | |
| 2>/dev/null | sed "s|^$WORKING_DIR/||") | |
| shfmt: | |
| name: Shell Script Formatting | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.shell-scripts == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install shfmt | |
| run: | | |
| SHFMT_VERSION="3.7.0" | |
| curl -L \ | |
| "https://github.com/mvdan/sh/releases/download/v${SHFMT_VERSION}/shfmt_v${SHFMT_VERSION}_linux_amd64" \ | |
| -o shfmt | |
| chmod +x shfmt | |
| sudo mv shfmt /usr/local/bin/ | |
| shfmt --version | |
| - name: Check formatting | |
| run: | | |
| set -e | |
| # Check .sh files (excluding .git directory) | |
| while IFS= read -r -d '' file; do | |
| if [[ -f "$file" && -r "$file" ]]; then | |
| echo "Checking $file formatting" | |
| shfmt -d -i 2 -ci -bn "$file" | |
| fi | |
| done < <(find . -name "*.sh" -type f -not -path './.git/*' -print0) | |
| # Check executable shell files (excluding .git directory) | |
| while IFS= read -r -d '' file; do | |
| if [[ -f "$file" && -r "$file" ]] && grep -q '^#!/.*sh' "$file" 2>/dev/null; then | |
| echo "Checking executable $file formatting" | |
| shfmt -d -i 2 -ci -bn "$file" | |
| fi | |
| done < <(find . -type f -executable -not -path './.git/*' -print0 2>/dev/null) | |
| markdownlint: | |
| name: Markdown Linting | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.markdown == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| - name: Install markdownlint-cli | |
| run: npm install -g markdownlint-cli | |
| - name: Find markdown files | |
| run: | | |
| echo "=== Markdown files found (excluding LICENSE.md) ===" | |
| find . -name "*.md" -type f -not -path './.git/*' | grep -v 'LICENSE\.md$' | |
| - name: Run markdownlint | |
| run: | | |
| # Use same config as global pre-commit (MD013 disabled) | |
| echo "Using markdownlint with MD013 disabled (matching global config)" | |
| find . -name "*.md" -type f -not -path './.git/*' -print0 | \ | |
| grep -zv 'LICENSE\.md$' | \ | |
| xargs -0 markdownlint --disable=MD013 | |
| yamllint: | |
| name: YAML Linting | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.yaml == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.x' | |
| - name: Install yamllint | |
| run: pip install yamllint | |
| - name: Find YAML files | |
| run: | | |
| echo "=== YAML files found ===" | |
| find . \( -name "*.yml" -o -name "*.yaml" \) -type f -not -path './.git/*' | |
| - name: Run yamllint | |
| run: | | |
| # Use config from .github/workflows if available, fallback to repo root | |
| if [[ -f ".github/workflows/.yamllint" ]]; then | |
| export YAMLLINT_CONFIG_FILE=".github/workflows/.yamllint" | |
| echo "Using yamllint config from .github/workflows/.yamllint" | |
| elif [[ -f ".yamllint" ]]; then | |
| export YAMLLINT_CONFIG_FILE=".yamllint" | |
| echo "Using yamllint config from .yamllint" | |
| else | |
| echo "No yamllint config found, using defaults" | |
| fi | |
| find . \( -name "*.yml" -o -name "*.yaml" \) -type f -not -path './.git/*' -print0 | \ | |
| xargs -0 yamllint | |
| python-lint: | |
| name: Python Linting and Formatting | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.python == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.x' | |
| - name: Install Python tools | |
| run: | | |
| pip install black flake8 flake8-bugbear | |
| - name: Find Python files | |
| run: | | |
| echo "=== Python files found ===" | |
| find . -name "*.py" -type f -not -path './.git/*' | |
| - name: Run black (formatter check) | |
| run: | | |
| echo "Checking Python formatting with black..." | |
| black --check --quiet . | |
| - name: Run flake8 (linter) | |
| run: | | |
| echo "Running Python linter with flake8..." | |
| flake8 . | |
| html-lint: | |
| name: HTML Validation | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.html == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install HTML Tidy | |
| run: sudo apt-get update && sudo apt-get install -y tidy | |
| - name: Find HTML files | |
| run: | | |
| echo "=== HTML files found ===" | |
| find . -name "*.html" -type f -not -path './.git/*' | |
| - name: Run HTML validation | |
| run: | | |
| echo "Validating HTML files with tidy..." | |
| find . -name "*.html" -type f -not -path './.git/*' -print0 | \ | |
| xargs -0 -I {} tidy -q -e {} | |
| # Future test placeholders | |
| configuration-validation: | |
| name: Configuration Validation (Future) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Validate configuration files | |
| run: | | |
| echo "🔮 Future: Validate config.conf syntax" | |
| echo "🔮 Future: Validate 1Password item references" | |
| echo "🔮 Future: Validate package lists (formulae.txt, casks.txt)" | |
| # For now, just check files exist and are readable | |
| test -r config/config.conf.template | |
| test -r config/formulae.txt | |
| test -r config/casks.txt | |
| # security-scanning: | |
| # name: Security Scanning (Future) | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # | |
| # - name: Security placeholder | |
| # run: | | |
| # echo "🔮 Future: Scan for hardcoded secrets" | |
| # echo "🔮 Future: Validate SSH key handling" | |
| # echo "🔮 Future: Check for insecure shell patterns" | |
| # # Basic check for obvious secrets (this could catch accidents) | |
| # if grep -r "password.*=" . --include="*.sh" --include="*.conf" | \ | |
| # grep -v "PASSWORD_FILE\|1Password\|#.*password\|\\\${.*PASSWORD.*}\|encoded_password" | \ | |
| # grep -v "KEYCHAIN_PASSWORD\|dynamically generated"; then | |
| # echo "⚠️ Warning: Found potential hardcoded passwords" | |
| # exit 1 | |
| # fi |