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
42 changes: 42 additions & 0 deletions .github/workflows/sorted.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Check practice exercises are sorted

on:
workflow_call:
inputs:
ordering:
description: "How exercises are ordered"
required: true
type: string

jobs:
check:
name: Check exercises
runs-on: ubuntu-slim
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Check if practice exercises are sorted
env:
ORDERING: ${{ inputs.ordering }}
run: |
diff <( jq -r '.exercises.practice[].slug' config.json ) <(
jq -r '
# Bucket by displayed difficulty. 0-3: easy; 4-7: medium; 8-10: hard.
def bucket(i): [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3][i];

# Code injection to inject the sort literal expression.
def sort: sort_by('"$ORDERING"');

.exercises.practice |
# Add displayed difficulty
map(.bucket = bucket(.difficulty)) |
# Add lowercase name
map(.lowercase_name = (.name | ascii_downcase)) |
# Leave hello-world at the top
if .[0].slug == "hello-world" then
[.[0]] + (.[1:] | sort)
else
sort
end |
map(.slug)[]
' config.json)
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,53 @@ jobs:
uses: exercism/github-actions/.github/workflows/labels.yml@main
```

## Reusable workflow: sorted

The `sorted` reusable workflow checks if the practice exercises on a track are sorted.

### Extra fields

Some extra fields are added to the exercise data for sorting.

* `bucket` is added, which indicates the difficulty "bucket" or "displayed" difficulty (easy, medium, hard).
* `lowercase_name` is added to allow sorting by exercise name, case insensitive.

### Inputs

The workflow takes a single input, `ordering` (required), that determines how sorting works.
The `ordering` input is passed to `sort_by()` and must be a valid JQ path expression.

Some valid ordering values:

* **".name"**: sort alphabetically by the displayed name
* **".lowercase_name"**: sort alphabetically (case insensitive) by the displayed name
* **".slug"**: sort alphabetically by the slug
* **".bucket"**: sort by the difficulty bucket (easy, medium, hard)
* **".bucket, .slug"**: sort by the difficulty bucket then by slug
* **".difficulty"**: sort by the difficulty value (1, 2, 3, ... 10)
* **".difficulty, .name"**: sort by the difficulty then by name
* **".difficulty, .slug"**: sort by the difficulty then by slug

### Example

```yaml
name: Exercise order
on:
pull_request:
branches:
- main
permissions:
contents: read
jobs:
call-gha-workflow:
name: check
uses: exercism/github-actions/.github/workflows/sorted.yml@main
with:
ordering: ".bucket, .slug"
```

[configlet]: https://exercism.org/docs/building/configlet
[configlet-lint]: https://exercism.org/docs/building/configlet/lint