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
51 changes: 51 additions & 0 deletions .github/workflows/CODE_QUALITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Code Quality Workflow

## What it does

Lints Markdown files and shell scripts on every pull request to `main`. Also runnable manually via `workflow_dispatch`.

## When it runs

- Pull requests to `main` (opened, reopened, or synchronized) when any of the following paths change:
- `**/*.md`
- `**/.markdownlint*`
- `*.sh`
- `.github/workflows/code-quality.yml`
- Manual trigger via the GitHub Actions UI

## Markdown linting

**Tool:** [`DavidAnson/markdownlint-cli2-action`](https://github.com/DavidAnson/markdownlint-cli2-action)

**Config file:** `.markdownlint-cli2.jsonc` (max line length 240, allowed inline HTML, excludes `CLAUDE.md` and `.github/copilot-instructions.md`)

**Run locally:**

```sh
markdownlint-cli2 '**/*.md'
```

## Shell script linting

**Tool:** [`reviewdog/action-shellcheck`](https://github.com/reviewdog/action-shellcheck) β€” posts inline PR review comments via `github-pr-review` reporter.

**Run locally:**

```sh
shellcheck start.sh stop.sh reset_env_variables.sh
```

**`.shellcheckrc` suppressions** (project-wide):

| Rule | Reason |
| --- | --- |
| `SC1091` | Not following sourced files (`reset_env_variables.sh`) |
| `SC2153` | False positives on variable name misspelling |
| `SC2317` | False positive on unreachable commands in trap/signal handlers |

## Adding new checks

1. Add a "Get changed files" step using `tj-actions/changed-files@v47` scoped to the relevant paths.
2. Add a "Should lint X" step that writes the `any_changed` output to `$GITHUB_OUTPUT`.
3. Add the lint step gated on `if: steps.should_lint_x.outputs.run == 'true'`.
4. Update the paths filter under `on.pull_request.paths` to include the new file patterns.
71 changes: 71 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Code Quality
on:
pull_request:
branches: [main]
types: [opened, reopened, synchronize]
paths:
- '**/*.md'
- '**/.markdownlint*'
- '*.sh'
- '.github/workflows/code-quality.yml'
workflow_dispatch:
jobs:
quality:
name: Lint and test
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: false

- name: Get changed markdown files
id: changed_md
uses: tj-actions/changed-files@v47
with:
files: |
**/*.md

- name: Get changed shell scripts
id: changed_sh
uses: tj-actions/changed-files@v47
with:
files: |
*.sh

- name: Should lint docs
id: should_lint_docs
shell: bash
run: |
run=${{ steps.changed_md.outputs.any_changed }}
echo "run=${run}" >> $GITHUB_OUTPUT

- name: Should lint shell
id: should_lint_shell
shell: bash
run: |
run=${{ steps.changed_sh.outputs.any_changed }}
echo "run=${run}" >> $GITHUB_OUTPUT

- name: Lint markdown
if: steps.should_lint_docs.outputs.run == 'true'
uses: DavidAnson/markdownlint-cli2-action@v22
with:
globs: '**/*.md'

- name: Lint shell scripts
if: steps.should_lint_shell.outputs.run == 'true'
uses: reviewdog/action-shellcheck@v1
with:
reporter: github-pr-review
fail_on_error: true
path: '.'
pattern: '*.sh'
exclude: './.git/*'

- name: Default Job Success
if: steps.should_lint_docs.outputs.run != 'true' && steps.should_lint_shell.outputs.run != 'true'
shell: bash
run: exit 0
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
markdownlint-cli2 0.21.0
shellcheck 0.11.0
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,7 @@ Example usage:
### Linting

See [LINTING.md](./documentation/LINTING.md)

## Other Documentation

See [documentation](./documentation/)
3 changes: 3 additions & 0 deletions documentation/CICD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ci/Cd

See [CODE_QUALITY.md](../.github/workflows/CODE_QUALITY.md)
29 changes: 28 additions & 1 deletion documentation/LINTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,45 @@

- Markdownlint must be installed as an extension (extension id: `DavidAnson.vscode-markdownlint`) for local markdown linting to work within VS Code or Cursor on save.
- Or run in directly using [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2).
- `markdownlint-cli2` is included in the asdf tool versions file.
- `markdownlint-cli2` is included in the asdf [`.tool-versions`](../.tool-versions) file.
See <https://github.com/paulo-ferraz-oliveira/asdf-markdownlint-cli2>.

```sh
markdownlint-cli2 '**/*.md'
```

- [ShellCheck](https://github.com/koalaman/shellcheck) `timonwong.shellcheck`

- ShellCheck must be installed as an extension (extension id: `timonwong.shellcheck`) for local shell script linting to work within VS Code or Cursor on save.
- Or run it directly using the [ShellCheck CLI](https://github.com/koalaman/shellcheck#installing).
- `shellcheck` is included in the asdf [`.tool-versions`](../.tool-versions) file.

```sh
shellcheck *.sh
```

## Configuration

### Markdown

MarkdownLint uses [`.markdownlint-cli2.jsonc`](../..markdownlint-cli2.jsonc) to configure the markdown linting rules and to ignore linting for specific files and paths.
See <https://github.com/DavidAnson/markdownlint-cli2/tree/main?tab=readme-ov-file#markdownlint-cli2jsonc>

### Shell

ShellCheck uses [`.shellcheckrc`](../.shellcheckrc) to configure linting rules.
The following rules are disabled project-wide:

| Rule | Reason |
| --- | --- |
| `SC1091` | Suppresses "not following" warnings for sourced files (e.g. `reset_env_variables.sh`) |
| `SC2153` | Suppresses false-positive variable name misspelling warnings |
| `SC2317` | Suppresses unreachable-command false positives in trap/signal handlers |

`external-sources=true` is also set to allow ShellCheck to follow sourced files when they are available.

See <https://github.com/koalaman/shellcheck/wiki/Checks>

## Continuous Integration

Linting is automatically run in CI/CD via the [Code Quality workflow](../.github/workflows/code-quality.yml) on pull requests to `main`.
Expand Down
6 changes: 3 additions & 3 deletions start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function start() {
# Cursor invisible
tput civis
while sleep 0.1; do
i=$(((i + $charwidth) % ${#char}))
i=$(((i + charwidth) % ${#char}))
printf "%s" "${char:$i:$charwidth}"
echo -en "\033[1D"
done
Expand Down Expand Up @@ -120,7 +120,7 @@ function start() {
function check_status() {
local max_num_tries=35
local status_code
status_code=$(curl --write-out %{http_code} --silent --output /dev/null localhost:"${pga_port}")
status_code=$(curl --write-out '%{http_code}' --silent --output /dev/null localhost:"${pga_port}")
if [[ ${iterator} -lt ${max_num_tries} && ${status_code} -eq 200 || ${status_code} -eq 302 ]]
then
# Stop the progress indicator.
Expand All @@ -140,7 +140,7 @@ function start() {
tput cnorm
>&2 echo -e "${yellow}Did not work. Perhaps the server is taking a long time to start?${nc}"
else
echo -en "${chars:$iterator:1}" "\r"
echo -en "${char:$iterator:1}" "\r"
sleep 1
((iterator++))
check_status
Expand Down
Loading