feat(workflow): add WorkflowRunner for event-driven workflow firing #33
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: Lint | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| branches: [master] | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Elixir | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: "26" | |
| elixir-version: "1.15" | |
| - name: Restore dependencies cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: deps | |
| key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} | |
| restore-keys: ${{ runner.os }}-mix- | |
| - name: Install dependencies | |
| run: mix deps.get | |
| # Master carries ~33 files of pre-existing format drift from before | |
| # this workflow ever ran; blocking every PR on that backlog would be | |
| # disproportionate. Scope the check to files the PR actually changes | |
| # so drift cleans up organically as files are touched. | |
| - name: Check formatting (PR-changed files) | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| files=$(git diff --name-only --diff-filter=AM \ | |
| "origin/${{ github.base_ref }}...HEAD" -- '*.ex' '*.exs' | tr '\n' ' ') | |
| if [ -z "$files" ]; then | |
| echo "No Elixir files changed; skipping format check." | |
| exit 0 | |
| fi | |
| echo "Checking: $files" | |
| mix format --check-formatted $files | |
| # Same reasoning as the format check: master has ~30 pre-existing | |
| # Credo findings from the period before this workflow ran. We scope | |
| # the check to source files under lib/ and test/ the PR actually | |
| # modifies so drift cleans up organically and new issues still block | |
| # merge. | |
| # | |
| # `--files-included` filters which files Credo *reports on* but | |
| # Credo's exit code still reflects the whole codebase's analysis, | |
| # so we run with `--mute-exit-status` and grep the output for any | |
| # mention of the PR-changed files. If a PR-changed file appears as | |
| # an issue, fail. Otherwise exit 0 even if pre-existing issues exist | |
| # elsewhere. | |
| - name: Run Credo (PR-changed files) | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| # Newline-separated list of PR-changed lib/test Elixir files. | |
| mapfile -t changed_files < <(git diff --name-only --diff-filter=AM \ | |
| "origin/${{ github.base_ref }}...HEAD" \ | |
| -- 'lib/**/*.ex' 'lib/**/*.exs' 'test/**/*.ex' 'test/**/*.exs') | |
| if [ "${#changed_files[@]}" -eq 0 ]; then | |
| echo "No lib/ or test/ Elixir files changed; skipping credo." | |
| exit 0 | |
| fi | |
| echo "Changed files:" | |
| printf ' %s\n' "${changed_files[@]}" | |
| # Run Credo over the whole project (--files-included alone does | |
| # not reliably scope analysis). Strip ANSI colors so simple grep | |
| # works against the output. | |
| raw=$(mix credo --strict --mute-exit-status 2>&1) || true | |
| output=$(printf '%s' "$raw" | sed -E 's/\x1b\[[0-9;]*[mK]//g') | |
| echo "$output" | |
| # For each PR-changed file, fail if Credo reports it. fgrep'ing | |
| # for a literal `path:` token avoids regex-escaping pitfalls. | |
| hit=0 | |
| for f in "${changed_files[@]}"; do | |
| if printf '%s\n' "$output" | grep -F "$f:" > /dev/null; then | |
| echo "::error file=$f::Credo found issue(s) in this PR-changed file." | |
| hit=1 | |
| fi | |
| done | |
| if [ "$hit" -ne 0 ]; then | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "No Credo issues in PR-changed files (pre-existing drift on master is ignored)." |