From eb9f6a0f1ababb3f1b76d230bc2e1e0751f2af7c Mon Sep 17 00:00:00 2001 From: Ali Zein Yousuf Date: Fri, 19 Jun 2026 20:29:20 -0500 Subject: [PATCH] ci: add Justfile + lint gate (markdown/shell/yaml/actions) Mirror the homeserver repo's lint setup. Add a `Justfile` with lint-md/lint-sh/lint-yaml/lint-actions recipes (and a `lint` aggregate + fix recipes), an `.github`-style `.markdownlint.json`, and a `lint` job in ci.yaml that runs `just lint` on the plain runner and gates the Gentoo `build` job via `needs: lint`. The overlay has no custom runner labels (workflows use ubuntu-latest), so lint-actions calls actionlint without a -config-file, and no .github/actionlint.yaml is needed. Also add the blank line before a list in CLAUDE.md that markdownlint (MD032) flagged, and make the .markdownlint.json referenced by .yamllint.yaml's comment actually exist. All linters pass locally. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_018MsAYv5RhNLE54fPrviVgS --- .gitea/workflows/ci.yaml | 43 ++++++++++++++++++++++++ .markdownlint.json | 9 ++++++ CLAUDE.md | 1 + Justfile | 70 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 .markdownlint.json create mode 100644 Justfile diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 9cdf777..4475735 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -2,7 +2,50 @@ name: CI on: [push] jobs: + # Lint gate: runs on the plain Docker-backend runner (not the Gentoo + # container) and must pass before the build job starts. Mirrors the lint job + # in the homeserver repo; `just lint` runs markdownlint/shellcheck/yamllint/ + # actionlint over the repo. + lint: + runs-on: ubuntu-latest + steps: + # SHA-256 Gitea repo: actions/checkout's internal `git init` must also + # create a SHA-256 repo or the fetch-by-OID fails ("mismatched + # algorithms"). GIT_DEFAULT_HASH makes init match. (The build job below + # avoids checkout for the same SHA-256 reason but predates this + # workaround; its curl+tar still works, so it is left as-is.) + - uses: actions/checkout@v4 + env: + GIT_DEFAULT_HASH: sha256 + + # setup-just fetches its binary from GitHub; on a Gitea runner the default + # github-token is the *Gitea* token (GitHub rejects it 401), so pass none + # and use GitHub's unauthenticated API. + - uses: extractions/setup-just@v4 + with: + github-token: "" + + - uses: taiki-e/install-action@v2 + env: + GITHUB_TOKEN: "" + with: + tool: shellcheck + + - name: Install markdownlint-cli + run: npm install -g markdownlint-cli + + # actionlint has no maintained setup-action and uv ships via astral.sh; + # both installers hit their own release assets (no GitHub token needed). + - name: Install yamllint + actionlint tooling + run: | + curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh + bash <(curl -fsSL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) latest /usr/local/bin + + - name: Run linters + run: just lint + build: + needs: lint # The label only schedules the job on the (Docker-backend) runner; the steps # actually run inside the Gentoo container declared below. runs-on: ubuntu-latest diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..dd7faa3 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,9 @@ +{ + "MD013": false, + "MD024": { + "siblings_only": true + }, + "MD060": { + "style": "compact" + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 81debd4..99b312c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,7 @@ fetched at build time. Instead they are vendored ahead of time: verifies against the Manifest, then compiles offline from `vendor/`. Consequences when editing the ebuild: + - `LICENSE` must cover **every vendored module's** license, not just upstream's MIT. The bump PR checklist suggests `go-licenses report ./...` to confirm. - `BDEPEND` Go version tracks upstream's `go.mod` `go` directive. diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..8571d04 --- /dev/null +++ b/Justfile @@ -0,0 +1,70 @@ +# azy5030 overlay management commands + +# Install dev tooling (linters) used by the lint recipes and CI +setup-dev: + brew install just markdownlint-cli shellcheck actionlint uv + +# Lint Markdown: all repo files, or only the .md files in a passed list +lint-md files="": + #!/usr/bin/env bash + set -euo pipefail + if [ -z "{{files}}" ]; then + markdownlint --ignore node_modules '**/*.md' + else + targets=$(printf '%s\n' {{files}} | grep -E '\.md$' || true) + if [ -n "$targets" ]; then markdownlint --ignore node_modules $targets; fi + fi + +# Lint shell scripts: all repo files, or only the .sh files in a passed list +lint-sh files="": + #!/usr/bin/env bash + set -euo pipefail + if [ -z "{{files}}" ]; then + targets=$(find . -name '*.sh' -not -path './node_modules/*') + else + targets=$(printf '%s\n' {{files}} | grep -E '\.sh$' || true) + fi + if [ -n "$targets" ]; then shellcheck $targets; fi + +# Lint YAML: all repo files, or only the .yaml/.yml in a passed list (via uv) +lint-yaml files="": + #!/usr/bin/env bash + set -euo pipefail + if [ -z "{{files}}" ]; then + targets=$(find . \( -name '*.yaml' -o -name '*.yml' \) -not -path './node_modules/*') + else + targets=$(printf '%s\n' {{files}} | grep -E '\.ya?ml$' || true) + fi + if [ -n "$targets" ]; then uvx yamllint $targets; fi + +# Lint Gitea Actions workflows: all, or only the workflow files in a passed list +lint-actions files="": + #!/usr/bin/env bash + set -euo pipefail + if [ -z "{{files}}" ]; then + targets=$(find .gitea/workflows \( -name '*.yaml' -o -name '*.yml' \) 2>/dev/null || true) + else + targets=$(printf '%s\n' {{files}} | grep -E '^\.gitea/workflows/.*\.ya?ml$' || true) + fi + # actionlint also runs shellcheck on each `run:` block. No custom runner + # labels here (workflows use ubuntu-latest), so no -config-file is needed. + if [ -n "$targets" ]; then actionlint $targets; fi + +# Autofix all Markdown files +fix-md: + markdownlint --fix --ignore node_modules '**/*.md' + +# Apply shellcheck's auto-fixable suggestions to all shell scripts +fix-sh: + #!/usr/bin/env bash + set -euo pipefail + targets=$(find . -name '*.sh' -not -path './node_modules/*') + # shellcheck's diff carries ./ path segments that `git apply` rejects; strip them. + diff=$(shellcheck -f diff $targets 2>/dev/null | sed 's|/\./|/|g' || true) + if [ -n "$diff" ]; then printf '%s\n' "$diff" | git apply; fi + +# Lint everything (all repo files, or only a passed list of files) +lint files="": (lint-md files) (lint-sh files) (lint-yaml files) (lint-actions files) + +# Autofix everything +fix: fix-md fix-sh