Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
6 changes: 0 additions & 6 deletions .github/linters/.editorconfig-checker.json

This file was deleted.

3 changes: 2 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ _Include or link to test output here._
_DO NOT POST SENSITIVE INFORMATION HERE._

## Checklist

- [ ] Edit the sections above with relevant information
- [ ] Update in-repo documentation, if applicable
- [ ] Run super-linter locally (or wait for CI) — see `.github/workflows/super-linter.yml`
- [ ] Run `pixi run -e dev lint` locally (or wait for CI) — see `.github/workflows/lint.yml`
- [ ] Test the changes on a representative managed host (or `runansible` deployment)
134 changes: 134 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
# Canonical CI lint gate. Runs the committed .pre-commit-config.yaml
# (the same hook set developers run locally) against changed files only.
#
# Changed-file scope:
# pull_request -> files changed vs. the PR base (origin/main).
# push to main -> files changed in the push (github.event.before..HEAD).
# workflow_dispatch -> all files (no push range available; safe fallback).

name: Lint

permissions:
contents: read

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

jobs:
lint:
name: Lint (changed files)
runs-on: ubuntu-24.04

steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false

- name: Setup Pixi
uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4
with:
pixi-version: v0.67.2
cache: false
frozen: true

- name: Install dev environment
run: pixi install -e dev

- name: Determine changed-file ref range
id: refs
env:
EVENT_NAME: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
SHA: ${{ github.sha }}
BEFORE: ${{ github.event.before }}
run: |
if [[ "$EVENT_NAME" == "pull_request" ]]; then
echo "from_ref=origin/${BASE_REF}" >> "$GITHUB_OUTPUT"
echo "to_ref=${SHA}" >> "$GITHUB_OUTPUT"
elif [[ "$EVENT_NAME" == "push" ]]; then
echo "from_ref=${BEFORE}" >> "$GITHUB_OUTPUT"
echo "to_ref=${SHA}" >> "$GITHUB_OUTPUT"
else
# workflow_dispatch: lint everything
echo "from_ref=" >> "$GITHUB_OUTPUT"
echo "to_ref=" >> "$GITHUB_OUTPUT"
fi

- name: Run pre-commit (changed files)
id: pre_commit
env:
FROM_REF: ${{ steps.refs.outputs.from_ref }}
TO_REF: ${{ steps.refs.outputs.to_ref }}
run: |
set -o pipefail
if [[ -n "$FROM_REF" ]]; then
pixi run -e dev pre-commit run \
--from-ref "$FROM_REF" \
--to-ref "$TO_REF" \
--show-diff-on-failure \
--color always \
2>&1 | tee /tmp/pre-commit-output.txt
else
pixi run -e dev pre-commit run \
--all-files \
--show-diff-on-failure \
--color always \
2>&1 | tee /tmp/pre-commit-output.txt
fi

- name: Write job summary
if: always()
env:
PRE_COMMIT_OUTCOME: ${{ steps.pre_commit.outcome }}
FROM_REF: ${{ steps.refs.outputs.from_ref }}
TO_REF: ${{ steps.refs.outputs.to_ref }}
run: |
if [[ "$PRE_COMMIT_OUTCOME" == "success" ]]; then
BADGE="All linting hooks passed"
else
BADGE="One or more linting hooks failed"
fi

if [[ -n "$FROM_REF" ]]; then
SCOPE="\`${FROM_REF}\`..\`${TO_REF}\`"
else
SCOPE="all files (workflow_dispatch)"
fi

{
echo "## Lint results"
echo ""
echo "$BADGE"
echo ""
echo "**Scope:** changed files — ${SCOPE}"
echo ""
echo "### Hooks run"
echo ""
echo "| Hook | Tool | Version |"
echo "| ---- | ---- | ------- |"
echo "| trailing-whitespace / end-of-file-fixer / check-* | pre-commit-hooks | v5.0.0 |"
echo "| ruff check + ruff format | ruff | 0.15.8 |"
echo "| mypy | mypy | 2.1.0 |"
echo "| codespell | codespell | 2.4.2 |"
echo "| markdownlint | markdownlint-cli | v0.48.0 |"
echo "| yamllint | yamllint | 1.38.0 |"
echo "| actionlint | actionlint | v1.7.12 |"
echo "| zizmor | zizmor | 1.23.1 |"
echo "| shfmt | shfmt | v3.12.0 |"
echo "| shellcheck | shellcheck | v0.11.0 |"
echo "| gitleaks | gitleaks | v8.30.1 |"
echo ""
if [[ -s /tmp/pre-commit-output.txt ]]; then
echo "### Output"
echo ""
echo '```'
sed 's/\x1b\[[0-9;]*m//g' /tmp/pre-commit-output.txt
echo '```'
fi
} >> "$GITHUB_STEP_SUMMARY"
52 changes: 0 additions & 52 deletions .github/workflows/super-linter.yml

This file was deleted.

11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Python bytecode / caches
__pycache__/
*.py[cod]
*$py.class

# pixi environments and caches
.pixi/

# Tool caches
.ruff_cache/
.mypy_cache/
12 changes: 12 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[extend]
useDefault = true

[[allowlists]]
description = "Public MS Graph delegated-scope GUIDs in azoidcapp (not secrets)"
paths = ['''bin/azoidcapp''']
regexes = ['''[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''']

[[allowlists]]
description = "Example AIFAPIM_HOST value in bwclaude help text (not a secret)"
paths = ['''bin/bwclaude''']
regexes = ['''AIFAPIM_HOST=hermes\.nsls2\.bnl\.gov''']
4 changes: 4 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
# MD013 (line-length) is disabled: table rows and long URLs in docs/
# legitimately exceed 80 chars and reflowing them adds no value.
MD013: false
117 changes: 117 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
# Canonical lint configuration. The same hook set runs locally on
# commit and in CI via the Lint workflow
# (.github/workflows/lint.yml). Tool versions are pinned in
# pixi.toml [feature.dev.dependencies] for the pixi-dispatched hooks
# and via `rev:` for the upstream pre-commit-managed hooks.
#
# Linter configs live at the repository root and are auto-discovered
# by each tool by its conventional dotfile name. The only exception is
# zizmor, which has no standard auto-discovery and takes an explicit
# --config argument.

repos:
# ────────────────────────────────────────────────────────────
# Generic hygiene + syntax checks
# ────────────────────────────────────────────────────────────
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: check-toml
- id: check-added-large-files

# ────────────────────────────────────────────────────────────
# Python
# ────────────────────────────────────────────────────────────
# Python-based hooks dispatch through pixi to avoid pip wheel-build
# races inside pre-commit's own env machinery and to keep tool
# versions deterministic via pins in pixi.toml
# [feature.dev.dependencies].
- repo: local
hooks:
- id: ruff-check
name: ruff check (pixi dev)
language: system
entry: pixi run --frozen -e dev ruff check --force-exclude
types_or: [python, pyi]
- id: ruff-format
name: ruff format (pixi dev)
language: system
entry: pixi run --frozen -e dev ruff format --force-exclude
types_or: [python, pyi]
- id: mypy
name: mypy (pixi dev)
language: system
entry: pixi run --frozen -e dev mypy --python-version 3.10 bin/azoidcapp
pass_filenames: false
always_run: true

# ────────────────────────────────────────────────────────────
# Spelling
# ────────────────────────────────────────────────────────────
- repo: local
hooks:
- id: codespell
name: codespell (pixi dev)
language: system
entry: pixi run --frozen -e dev codespell
types: [text]

# ────────────────────────────────────────────────────────────
# Markdown
# ────────────────────────────────────────────────────────────
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.48.0
hooks:
- id: markdownlint
name: Markdownlint
entry: markdownlint --fix

# ────────────────────────────────────────────────────────────
# YAML / GitHub Actions
# ────────────────────────────────────────────────────────────
- repo: local
hooks:
- id: yamllint
name: yamllint (pixi dev)
language: system
entry: pixi run --frozen -e dev yamllint
types: [yaml]

- repo: https://github.com/rhysd/actionlint
rev: v1.7.12
hooks:
- id: actionlint

- repo: local
hooks:
- id: zizmor
name: zizmor (pixi dev)
language: system
entry: pixi run --frozen -e dev zizmor --config zizmor.yaml
files: '^\.github/workflows/.*\.ya?ml$'

# ────────────────────────────────────────────────────────────
# Shell
# ────────────────────────────────────────────────────────────
- repo: https://github.com/scop/pre-commit-shfmt
rev: v3.12.0-2
hooks:
- id: shfmt

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck

# ────────────────────────────────────────────────────────────
# Secrets
# ────────────────────────────────────────────────────────────
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks
6 changes: 6 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Project Python style. 120-col line length kept from the prior super-linter
# baseline; matched by ruff format and ruff check.
line-length = 120

[lint]
ignore = ["E203"]
File renamed without changes.
File renamed without changes.
Loading