Add the guide for reading quality-check results (MIL-003 task 5) #73

Merged
Tirsvad merged 1 commits from mil-003-results-guide into main 2026-10-10 14:26:39 +02:00
10 changed files with 415 additions and 7 deletions
+1 -1
View File
@@ -67,7 +67,7 @@ Rows that say Implemented or Guides written exist today. The rest is planned and
| Configure and validate workflow credentials | Implemented for the sync workflow: preflight checks both tokens before any change ([guide](guides/credentials.md)) |
| Onboard a repository, manage runners, diagnose failures | Guides written ([onboarding](guides/onboarding.md), [troubleshooting](guides/troubleshooting.md)); scoped delivery to other repositories not yet verified; brief use cases open (MIL-002) |
| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; the pilot in a second repository is pending (MIL-006) |
| Shared quality checks | Planned (MIL-003) |
| Shared quality checks (Python and shell) | Implemented as the reusable workflow `.gitea/workflows/quality-checks.yml`, with offline tests and a trial in a second organization; adoption in RepoFoundry is in review ([guide](guides/quality-checks.md)) |
| Versioned release and publishing | Planned (MIL-004) |
### 🔄 Sync GitHub metadata
+105
View File
@@ -0,0 +1,105 @@
# Reading quality-check results
How a software engineer calls the shared quality checks, reads a failed run and
makes it pass. The workflow lints and format-checks the Python and shell files
of a repository with pinned tools, changes no file and needs no secret. Its
contract is ADR-0005 in this repository.
## Calling the workflow
```yaml
name: Quality
on:
pull_request:
push:
branches: [ main ]
jobs:
quality:
permissions:
contents: read
uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@main
with:
languages: python,shell
```
| Input | Default | Meaning |
| --- | --- | --- |
| `languages` | `python,shell` | Comma list of the languages to check |
| `working-directory` | `.` | Directory, relative to the repository root, whose files are checked |
| `ruff-version` | `0.6.9` | Version of ruff |
| `mypy-version` | `1.11.2` | Version of mypy |
| `shellcheck-py-version` | `0.10.0.1` | Version of the shellcheck-py package (ShellCheck 0.10.0) |
| `shfmt-py-version` | `3.11.0.2` | Version of the shfmt-py package (shfmt 3.11.0) |
Reference the workflow at `main` or at a tag, never at the branch of a pull
request: that branch is deleted when the pull request is merged and the
reference stops working.
## What is checked
| Language | Files | Tools |
| --- | --- | --- |
| Python | tracked `*.py` under the working directory | `ruff check`, `ruff format --check`, `mypy --strict` |
| Shell | tracked `*.sh` under the working directory | `shellcheck`, `shfmt -d` |
Untracked files are not checked. A language without files is skipped with a
notice and counts as a pass. Project tests are not run.
## Reading a run
1. Open the status check on the pull request, then the job `quality-checks`.
2. Each tool has its own log group named after it. Every tool runs even when an
earlier one failed, so one run shows all findings.
3. A tool ends with `PASS <tool>` or `FAIL <tool>`. The last line of a failed
run names the tools that failed:
`Quality checks failed: ruff check shellcheck`.
4. A finding is written by the tool itself as `path:line:column: CODE message`.
Paths are relative to `working-directory`.
## Typical failures and fixes
| Tool | What the log shows | Fix |
| --- | --- | --- |
| `ruff check` | `F401 ... imported but unused` | Remove the import, or use it |
| `ruff format --check` | `Would reformat: <file>` | Run `ruff format <file>` and commit |
| `mypy --strict` | `Function is missing a type annotation` | Add parameter and return types |
| `shellcheck` | `SC2086 ... Double quote to prevent globbing` | Quote the expansion: `"$1"` |
| `shfmt -d` | a diff of `<file>.orig` and `<file>` | Run `shfmt -w <file>` with the project's options and commit |
To reproduce a run on your machine, install the same versions and run the
commands of the table:
```bash
python3 -m venv .qc
.qc/bin/pip install ruff==0.6.9 mypy==1.11.2 shellcheck-py==0.10.0.1 shfmt-py==3.11.0.2
.qc/bin/ruff check . && .qc/bin/ruff format --check .
```
## Configuring the tools
The workflow adds no configuration; it runs from the repository root, so the
files of the project apply:
| Tool | File | Example |
| --- | --- | --- |
| ruff | `pyproject.toml` | `[tool.ruff]` with `line-length = 100` |
| mypy | `pyproject.toml` | `[tool.mypy]` with per-module `ignore_missing_imports` |
| shellcheck | `.shellcheckrc` | `external-sources=true` and `source-path=SCRIPTDIR` |
| shfmt | `.editorconfig` | `[*.sh]` with `indent_size = 2` and `switch_case_indent = true` |
shfmt follows a project's style only through `.editorconfig`. A shell project
that formats with its own flags (for example `shfmt -i 2 -ci`) should expect a
first formatting failure and express the flags there; in the first adoption
(RepoFoundry) one line, `switch_case_indent = true`, was enough and no script
changed.
## When the workflow itself fails
| Message | Cause | Fix |
| --- | --- | --- |
| `[configuration] Unknown language '<x>'` | `languages` has a value other than `python` or `shell` | Correct the input |
| `[configuration] working-directory must be a relative path inside the repository.` | An absolute path or `..` | Use a path inside the repository |
| `[configuration] working-directory '<x>' does not exist.` | The directory is not in the repository | Correct the input |
| The install step fails | PyPI or the runner network is unreachable | Re-run the job; see [troubleshooting.md](troubleshooting.md) |
+1 -1
View File
@@ -96,7 +96,7 @@ def _write_sources(root: Path) -> None:
"### 🔄 Sync\nDetails.\n\n## 📄 License\nMIT.\n",
encoding="utf-8",
)
for name in ("onboarding", "credentials", "troubleshooting"):
for name in ("onboarding", "credentials", "troubleshooting", "quality-checks"):
(root / "guides" / f"{name}.md").write_text(
f"# {name.title()}\nBody.\n", encoding="utf-8"
)
+2
View File
@@ -43,6 +43,7 @@ PAGES: tuple[Page, ...] = (
Page("Onboarding", "guides/onboarding.md"),
Page("Credentials", "guides/credentials.md"),
Page("Troubleshooting", "guides/troubleshooting.md"),
Page("QualityChecks", "guides/quality-checks.md"),
Page("Capabilities", "README.md", ("Capabilities",)),
)
@@ -59,6 +60,7 @@ _PAGE_FOR_SOURCE = {
"guides/onboarding.md": "Onboarding",
"guides/credentials.md": "Credentials",
"guides/troubleshooting.md": "Troubleshooting",
"guides/quality-checks.md": "QualityChecks",
}
+2 -2
View File
@@ -1,4 +1,4 @@
<!-- translation of Capabilities.md, source sha256 737481cd7e09 -->
<!-- translation of Capabilities.md, source sha256 c55376110b0c -->
> Dette er en oversættelse af [`Capabilities`](Capabilities). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres.
@@ -14,7 +14,7 @@ Rækker, der siger Implementeret eller Vejledninger er skrevet, findes i dag. Re
| Konfiguration og validering af workflow-credentials | Implementeret for synkroniseringsworkflowet: en forhåndskontrol tjekker begge tokens før enhver ændring ([vejledning](Credentials.da)) |
| Tilslutning af et repository, administration af runners, fejlfinding | Vejledninger er skrevet ([tilslutning](Onboarding.da), [fejlfinding](Troubleshooting.da)); scoped levering til andre repositories er ikke verificeret endnu; korte use cases er åbne (MIL-002) |
| Publicering af et repositorys wiki fra `wiki/` (tilmelding, leveres til alle organisationer) | Implementeret i `.gitea/scoped_workflows/publish-wiki.yml`, med offline-tests; pilotforsøget i et andet repository afventer (MIL-006) |
| Fælles kvalitetskontrol | Planlagt (MIL-003) |
| Fælles kvalitetskontrol (Python og shell) | Implementeret som det genbrugelige workflow `.gitea/workflows/quality-checks.yml`, med offline-tests og et forsøg i en anden organisation; tilslutningen i RepoFoundry er til gennemgang ([vejledning](QualityChecks.da)) |
| Versioneret udgivelse og publicering | Planlagt (MIL-004) |
### Synkronisering af GitHub-metadata
+1 -1
View File
@@ -14,7 +14,7 @@ Rows that say Implemented or Guides written exist today. The rest is planned and
| Configure and validate workflow credentials | Implemented for the sync workflow: preflight checks both tokens before any change ([guide](Credentials)) |
| Onboard a repository, manage runners, diagnose failures | Guides written ([onboarding](Onboarding), [troubleshooting](Troubleshooting)); scoped delivery to other repositories not yet verified; brief use cases open (MIL-002) |
| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; the pilot in a second repository is pending (MIL-006) |
| Shared quality checks | Planned (MIL-003) |
| Shared quality checks (Python and shell) | Implemented as the reusable workflow `.gitea/workflows/quality-checks.yml`, with offline tests and a trial in a second organization; adoption in RepoFoundry is in review ([guide](QualityChecks)) |
| Versioned release and publishing | Planned (MIL-004) |
### Sync GitHub metadata
+2 -2
View File
@@ -1,4 +1,4 @@
<!-- translation of Capabilities.md, source sha256 737481cd7e09 -->
<!-- translation of Capabilities.md, source sha256 c55376110b0c -->
> Ini ialah terjemahan [`Capabilities`](Capabilities). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya.
@@ -14,7 +14,7 @@ Baris yang menyatakan Dilaksanakan atau Panduan telah ditulis wujud hari ini. Se
| Mengkonfigur dan mengesahkan kelayakan (credentials) aliran kerja | Dilaksanakan untuk aliran kerja penyegerakan: semakan awal (preflight) memeriksa kedua-dua token sebelum sebarang perubahan ([panduan](Credentials.ms)) |
| Menyertakan repositori, mengurus runner, mendiagnosis kegagalan | Panduan telah ditulis ([menyertakan repositori](Onboarding.ms), [diagnosis](Troubleshooting.ms)); penghantaran scoped ke repositori lain belum disahkan; use case ringkas masih terbuka (MIL-002) |
| Menerbitkan wiki repositori daripada `wiki/` (pilih menyertai, dihantar ke setiap organisasi) | Dilaksanakan dalam `.gitea/scoped_workflows/publish-wiki.yml`, dengan ujian luar talian; juruterbang dalam repositori kedua belum dibuat (MIL-006) |
| Semakan kualiti bersama | Dirancang (MIL-003) |
| Semakan kualiti bersama (Python dan shell) | Dilaksanakan sebagai aliran kerja boleh guna semula `.gitea/workflows/quality-checks.yml`, dengan ujian luar talian dan percubaan dalam organisasi kedua; penerimaan dalam RepoFoundry sedang disemak ([panduan](QualityChecks.ms)) |
| Keluaran dan penerbitan berversi | Dirancang (MIL-004) |
### Menyegerakkan metadata GitHub
+95
View File
@@ -0,0 +1,95 @@
<!-- translation of QualityChecks.md, source sha256 84ed5e09689a -->
> Dette er en oversættelse af [`QualityChecks`](QualityChecks). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres.
[English](QualityChecks) | Dansk | [Bahasa Melayu](QualityChecks.ms)
# Aflæsning af resultater fra kvalitetskontrol
Sådan kalder en softwareudvikler den fælles kvalitetskontrol, aflæser en mislykket kørsel og får den til at bestå. Workflowet kører lint og formatkontrol på repositoryets Python- og shell-filer med fastlåste værktøjer, ændrer ingen fil og kræver ingen secret. Dets kontrakt er ADR-0005 i dette repository.
## Kald af workflowet
```yaml
name: Quality
on:
pull_request:
push:
branches: [ main ]
jobs:
quality:
permissions:
contents: read
uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@main
with:
languages: python,shell
```
| Input | Standard | Betydning |
| --- | --- | --- |
| `languages` | `python,shell` | Kommasepareret liste over de sprog, der kontrolleres |
| `working-directory` | `.` | Mappe, relativt til repositoryets rod, hvis filer kontrolleres |
| `ruff-version` | `0.6.9` | Version af ruff |
| `mypy-version` | `1.11.2` | Version af mypy |
| `shellcheck-py-version` | `0.10.0.1` | Version af pakken shellcheck-py (ShellCheck 0.10.0) |
| `shfmt-py-version` | `3.11.0.2` | Version af pakken shfmt-py (shfmt 3.11.0) |
Henvis til workflowet ved `main` eller et tag, aldrig ved en pull requests gren: den gren slettes, når pull requesten flettes, og henvisningen holder op med at virke.
## Hvad der kontrolleres
| Sprog | Filer | Værktøjer |
| --- | --- | --- |
| Python | sporede `*.py` under arbejdsmappen | `ruff check`, `ruff format --check`, `mypy --strict` |
| Shell | sporede `*.sh` under arbejdsmappen | `shellcheck`, `shfmt -d` |
Ikke-sporede filer kontrolleres ikke. Et sprog uden filer springes over med en meddelelse og tæller som bestået. Projektets tests køres ikke.
## Aflæsning af en kørsel
1. Åbn statuskontrollen på pull requesten og derefter jobbet `quality-checks`.
2. Hvert værktøj har sin egen logsektion med værktøjets navn. Hvert værktøj kører, selv om et tidligere fejlede, så én kørsel viser alle fund.
3. Et værktøj slutter med `PASS <værktøj>` eller `FAIL <værktøj>`. Sidste linje i en mislykket kørsel nævner de værktøjer, der fejlede: `Quality checks failed: ruff check shellcheck`.
4. Et fund skrives af værktøjet selv som `sti:linje:kolonne: KODE meddelelse`. Stier er relative til `working-directory`.
## Typiske fejl og rettelser
| Værktøj | Hvad loggen viser | Rettelse |
| --- | --- | --- |
| `ruff check` | `F401 ... imported but unused` | Fjern importen, eller brug den |
| `ruff format --check` | `Would reformat: <fil>` | Kør `ruff format <fil>` og commit |
| `mypy --strict` | `Function is missing a type annotation` | Tilføj typer til parametre og returværdi |
| `shellcheck` | `SC2086 ... Double quote to prevent globbing` | Sæt udvidelsen i anførselstegn: `"$1"` |
| `shfmt -d` | en forskel mellem `<fil>.orig` og `<fil>` | Kør `shfmt -w <fil>` med projektets indstillinger og commit |
For at gentage en kørsel på din egen maskine skal du installere de samme versioner og køre kommandoerne fra tabellen:
```bash
python3 -m venv .qc
.qc/bin/pip install ruff==0.6.9 mypy==1.11.2 shellcheck-py==0.10.0.1 shfmt-py==3.11.0.2
.qc/bin/ruff check . && .qc/bin/ruff format --check .
```
## Konfiguration af værktøjerne
Workflowet tilføjer ingen konfiguration; det kører fra repositoryets rod, så projektets egne filer gælder:
| Værktøj | Fil | Eksempel |
| --- | --- | --- |
| ruff | `pyproject.toml` | `[tool.ruff]` med `line-length = 100` |
| mypy | `pyproject.toml` | `[tool.mypy]` med `ignore_missing_imports` pr. modul |
| shellcheck | `.shellcheckrc` | `external-sources=true` og `source-path=SCRIPTDIR` |
| shfmt | `.editorconfig` | `[*.sh]` med `indent_size = 2` og `switch_case_indent = true` |
shfmt følger et projekts stil kun gennem `.editorconfig`. Et shell-projekt, der formaterer med egne flag (fx `shfmt -i 2 -ci`), bør forvente en formateringsfejl ved første kørsel og udtrykke flagene dér; ved den første tilslutning (RepoFoundry) var én linje, `switch_case_indent = true`, nok, og intet script blev ændret.
## Når selve workflowet fejler
| Meddelelse | Årsag | Rettelse |
| --- | --- | --- |
| `[configuration] Unknown language '<x>'` | `languages` har en anden værdi end `python` eller `shell` | Ret inputtet |
| `[configuration] working-directory must be a relative path inside the repository.` | En absolut sti eller `..` | Brug en sti inde i repositoryet |
| `[configuration] working-directory '<x>' does not exist.` | Mappen findes ikke i repositoryet | Ret inputtet |
| Installationstrinnet fejler | PyPI eller runnerens netværk kan ikke nås | Kør jobbet igen; se [troubleshooting.md](Troubleshooting.da) |
+111
View File
@@ -0,0 +1,111 @@
<!-- Generated from guides/quality-checks.md by tools/build_wiki.py. Edit the source, not this page. -->
> This page is generated from [`guides/quality-checks.md`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/guides/quality-checks.md). Changes made here are overwritten the next time the wiki is published.
English | [Dansk](QualityChecks.da) | [Bahasa Melayu](QualityChecks.ms)
# Reading quality-check results
How a software engineer calls the shared quality checks, reads a failed run and
makes it pass. The workflow lints and format-checks the Python and shell files
of a repository with pinned tools, changes no file and needs no secret. Its
contract is ADR-0005 in this repository.
## Calling the workflow
```yaml
name: Quality
on:
pull_request:
push:
branches: [ main ]
jobs:
quality:
permissions:
contents: read
uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@main
with:
languages: python,shell
```
| Input | Default | Meaning |
| --- | --- | --- |
| `languages` | `python,shell` | Comma list of the languages to check |
| `working-directory` | `.` | Directory, relative to the repository root, whose files are checked |
| `ruff-version` | `0.6.9` | Version of ruff |
| `mypy-version` | `1.11.2` | Version of mypy |
| `shellcheck-py-version` | `0.10.0.1` | Version of the shellcheck-py package (ShellCheck 0.10.0) |
| `shfmt-py-version` | `3.11.0.2` | Version of the shfmt-py package (shfmt 3.11.0) |
Reference the workflow at `main` or at a tag, never at the branch of a pull
request: that branch is deleted when the pull request is merged and the
reference stops working.
## What is checked
| Language | Files | Tools |
| --- | --- | --- |
| Python | tracked `*.py` under the working directory | `ruff check`, `ruff format --check`, `mypy --strict` |
| Shell | tracked `*.sh` under the working directory | `shellcheck`, `shfmt -d` |
Untracked files are not checked. A language without files is skipped with a
notice and counts as a pass. Project tests are not run.
## Reading a run
1. Open the status check on the pull request, then the job `quality-checks`.
2. Each tool has its own log group named after it. Every tool runs even when an
earlier one failed, so one run shows all findings.
3. A tool ends with `PASS <tool>` or `FAIL <tool>`. The last line of a failed
run names the tools that failed:
`Quality checks failed: ruff check shellcheck`.
4. A finding is written by the tool itself as `path:line:column: CODE message`.
Paths are relative to `working-directory`.
## Typical failures and fixes
| Tool | What the log shows | Fix |
| --- | --- | --- |
| `ruff check` | `F401 ... imported but unused` | Remove the import, or use it |
| `ruff format --check` | `Would reformat: <file>` | Run `ruff format <file>` and commit |
| `mypy --strict` | `Function is missing a type annotation` | Add parameter and return types |
| `shellcheck` | `SC2086 ... Double quote to prevent globbing` | Quote the expansion: `"$1"` |
| `shfmt -d` | a diff of `<file>.orig` and `<file>` | Run `shfmt -w <file>` with the project's options and commit |
To reproduce a run on your machine, install the same versions and run the
commands of the table:
```bash
python3 -m venv .qc
.qc/bin/pip install ruff==0.6.9 mypy==1.11.2 shellcheck-py==0.10.0.1 shfmt-py==3.11.0.2
.qc/bin/ruff check . && .qc/bin/ruff format --check .
```
## Configuring the tools
The workflow adds no configuration; it runs from the repository root, so the
files of the project apply:
| Tool | File | Example |
| --- | --- | --- |
| ruff | `pyproject.toml` | `[tool.ruff]` with `line-length = 100` |
| mypy | `pyproject.toml` | `[tool.mypy]` with per-module `ignore_missing_imports` |
| shellcheck | `.shellcheckrc` | `external-sources=true` and `source-path=SCRIPTDIR` |
| shfmt | `.editorconfig` | `[*.sh]` with `indent_size = 2` and `switch_case_indent = true` |
shfmt follows a project's style only through `.editorconfig`. A shell project
that formats with its own flags (for example `shfmt -i 2 -ci`) should expect a
first formatting failure and express the flags there; in the first adoption
(RepoFoundry) one line, `switch_case_indent = true`, was enough and no script
changed.
## When the workflow itself fails
| Message | Cause | Fix |
| --- | --- | --- |
| `[configuration] Unknown language '<x>'` | `languages` has a value other than `python` or `shell` | Correct the input |
| `[configuration] working-directory must be a relative path inside the repository.` | An absolute path or `..` | Use a path inside the repository |
| `[configuration] working-directory '<x>' does not exist.` | The directory is not in the repository | Correct the input |
| The install step fails | PyPI or the runner network is unreachable | Re-run the job; see [troubleshooting.md](Troubleshooting) |
+95
View File
@@ -0,0 +1,95 @@
<!-- translation of QualityChecks.md, source sha256 84ed5e09689a -->
> Ini ialah terjemahan [`QualityChecks`](QualityChecks). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya.
[English](QualityChecks) | [Dansk](QualityChecks.da) | Bahasa Melayu
# Membaca keputusan semakan kualiti
Cara seorang jurutera perisian memanggil semakan kualiti bersama, membaca larian yang gagal dan menjadikannya lulus. Aliran kerja ini menjalankan lint dan semakan format ke atas fail Python dan shell sesebuah repositori dengan alat yang disematkan versinya, tidak mengubah sebarang fail dan tidak memerlukan secret. Kontraknya ialah ADR-0005 dalam repositori ini.
## Memanggil aliran kerja
```yaml
name: Quality
on:
pull_request:
push:
branches: [ main ]
jobs:
quality:
permissions:
contents: read
uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@main
with:
languages: python,shell
```
| Input | Lalai | Maksud |
| --- | --- | --- |
| `languages` | `python,shell` | Senarai bahasa yang disemak, dipisahkan koma |
| `working-directory` | `.` | Direktori, relatif kepada akar repositori, yang failnya disemak |
| `ruff-version` | `0.6.9` | Versi ruff |
| `mypy-version` | `1.11.2` | Versi mypy |
| `shellcheck-py-version` | `0.10.0.1` | Versi pakej shellcheck-py (ShellCheck 0.10.0) |
| `shfmt-py-version` | `3.11.0.2` | Versi pakej shfmt-py (shfmt 3.11.0) |
Rujuk aliran kerja pada `main` atau pada tag, jangan sekali-kali pada cabang pull request: cabang itu dipadam apabila pull request digabungkan dan rujukan itu berhenti berfungsi.
## Perkara yang disemak
| Bahasa | Fail | Alat |
| --- | --- | --- |
| Python | `*.py` yang dijejaki di bawah direktori kerja | `ruff check`, `ruff format --check`, `mypy --strict` |
| Shell | `*.sh` yang dijejaki di bawah direktori kerja | `shellcheck`, `shfmt -d` |
Fail yang tidak dijejaki tidak disemak. Bahasa tanpa fail dilangkau dengan notis dan dikira lulus. Ujian projek tidak dijalankan.
## Membaca satu larian
1. Buka semakan status pada pull request, kemudian kerja `quality-checks`.
2. Setiap alat mempunyai kumpulan lognya sendiri yang dinamakan sempena alat itu. Setiap alat dijalankan walaupun alat sebelumnya gagal, jadi satu larian menunjukkan semua dapatan.
3. Satu alat berakhir dengan `PASS <alat>` atau `FAIL <alat>`. Baris terakhir larian yang gagal menamakan alat yang gagal: `Quality checks failed: ruff check shellcheck`.
4. Satu dapatan ditulis oleh alat itu sendiri sebagai `laluan:baris:lajur: KOD mesej`. Laluan relatif kepada `working-directory`.
## Kegagalan biasa dan pembetulan
| Alat | Apa yang ditunjukkan log | Pembetulan |
| --- | --- | --- |
| `ruff check` | `F401 ... imported but unused` | Buang import itu, atau gunakannya |
| `ruff format --check` | `Would reformat: <fail>` | Jalankan `ruff format <fail>` dan commit |
| `mypy --strict` | `Function is missing a type annotation` | Tambah jenis bagi parameter dan nilai pulangan |
| `shellcheck` | `SC2086 ... Double quote to prevent globbing` | Letakkan pengembangan dalam tanda petikan: `"$1"` |
| `shfmt -d` | perbezaan antara `<fail>.orig` dan `<fail>` | Jalankan `shfmt -w <fail>` dengan pilihan projek dan commit |
Untuk mengulang satu larian pada mesin anda, pasang versi yang sama dan jalankan arahan dalam jadual:
```bash
python3 -m venv .qc
.qc/bin/pip install ruff==0.6.9 mypy==1.11.2 shellcheck-py==0.10.0.1 shfmt-py==3.11.0.2
.qc/bin/ruff check . && .qc/bin/ruff format --check .
```
## Mengkonfigur alat
Aliran kerja tidak menambah sebarang konfigurasi; ia berjalan dari akar repositori, jadi fail projek itu sendiri terpakai:
| Alat | Fail | Contoh |
| --- | --- | --- |
| ruff | `pyproject.toml` | `[tool.ruff]` dengan `line-length = 100` |
| mypy | `pyproject.toml` | `[tool.mypy]` dengan `ignore_missing_imports` bagi setiap modul |
| shellcheck | `.shellcheckrc` | `external-sources=true` dan `source-path=SCRIPTDIR` |
| shfmt | `.editorconfig` | `[*.sh]` dengan `indent_size = 2` dan `switch_case_indent = true` |
shfmt mengikut gaya sesebuah projek hanya melalui `.editorconfig`. Projek shell yang memformat dengan bendera sendiri (contohnya `shfmt -i 2 -ci`) patut menjangka kegagalan format pada larian pertama dan menyatakan bendera itu di sana; pada penerimaan pertama (RepoFoundry) satu baris, `switch_case_indent = true`, sudah mencukupi dan tiada skrip diubah.
## Apabila aliran kerja itu sendiri gagal
| Mesej | Punca | Pembetulan |
| --- | --- | --- |
| `[configuration] Unknown language '<x>'` | `languages` mempunyai nilai selain `python` atau `shell` | Betulkan input |
| `[configuration] working-directory must be a relative path inside the repository.` | Laluan mutlak atau `..` | Gunakan laluan di dalam repositori |
| `[configuration] working-directory '<x>' does not exist.` | Direktori itu tiada dalam repositori | Betulkan input |
| Langkah pemasangan gagal | PyPI atau rangkaian runner tidak dapat dicapai | Jalankan semula kerja itu; lihat [troubleshooting.md](Troubleshooting.ms) |