Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
be2d8f3
Add CI workflow and document .tool-versions toolchain setup
adamnfish-gu Aug 4, 2026
4172bed
Make the scala example test pass and script/test CI-friendly
adamnfish-gu Aug 4, 2026
15866b3
Fix failing example test in test_pairing_exercise.py
adamnfish-gu Aug 4, 2026
2bb3d29
Fix failing test and make script/test exit non-interactively
adamnfish-gu Aug 4, 2026
2220646
Fix failing test, watch-mode default, and update imports for Deno 2
adamnfish-gu Aug 4, 2026
33349e6
Fix yarn lockfile, test value, and script/test for CI
adamnfish-gu Aug 4, 2026
7c7fafd
Fix returnsFalse returning true and remove print from initialize
adamnfish-gu Aug 4, 2026
2536fe9
Fix failing test and non-terminating test runner
adamnfish-gu Aug 4, 2026
bbd1f7e
Fix build: add go.mod, proper imports, and make test pass
adamnfish-gu Aug 4, 2026
5167278
Adopt .tool-versions and scripts-to-rule-them-all for swift
adamnfish-gu Aug 4, 2026
cc3b6c5
Adopt .tool-versions and standardise script/ for Python
adamnfish-gu Aug 4, 2026
8269fe2
Adopt .tool-versions and standardise scripts
adamnfish-gu Aug 4, 2026
d215db6
Adopt .tool-versions and standardise script/ for Deno 2
adamnfish-gu Aug 4, 2026
4c398c2
Upgrade Gradle, Kotlin, and JUnit to work on JDK 21
adamnfish-gu Aug 4, 2026
decd225
Fix build and failing test for .NET 10
adamnfish-gu Aug 4, 2026
c80207f
Fix skeleton test to pass and expose testable code
adamnfish-gu Aug 4, 2026
94ecdc2
Upgrade Clojure 1.6 to 1.11.1 and fix failing example test
adamnfish-gu Aug 4, 2026
9534d26
Adopt .tool-versions and standardise setup scripts
adamnfish-gu Aug 4, 2026
6790086
Adopt .tool-versions and standardise scripts for dot-net-core
adamnfish-gu Aug 4, 2026
14482b5
Declare the java toolchain in .tool-versions
adamnfish-gu Aug 4, 2026
56616b5
Declare the scala toolchain in .tool-versions
adamnfish-gu Aug 4, 2026
975cf4d
Adopt .tool-versions and standardise scripts for Rust
adamnfish-gu Aug 4, 2026
4db7553
Declare the typescript-node toolchain in .tool-versions
adamnfish-gu Aug 4, 2026
7fd144c
Adopt .tool-versions and standardise setup scripts
adamnfish-gu Aug 4, 2026
dbc77ad
Declare the clojure toolchain in .tool-versions
adamnfish-gu Aug 4, 2026
dbd0876
Adopt .tool-versions and standardise script/setup for ruby
adamnfish-gu Aug 4, 2026
a86b5c5
Adopt .tool-versions toolchain declaration for javascript-esm
adamnfish-gu Aug 4, 2026
96837d7
Adopt .tool-versions and standardise setup script
adamnfish-gu Aug 4, 2026
dfb7aa2
Merge branch 'adopt/java' into integration/verify
adamnfish-gu Aug 5, 2026
94493db
Merge branch 'adopt/rust' into integration/verify
adamnfish-gu Aug 5, 2026
e72eede
Merge branch 'adopt/swift' into integration/verify
adamnfish-gu Aug 5, 2026
eb08124
Merge branch 'adopt/python' into integration/verify
adamnfish-gu Aug 5, 2026
5fd0d25
Merge branch 'adopt/ruby' into integration/verify
adamnfish-gu Aug 5, 2026
512e562
Merge branch 'adopt/javascript' into integration/verify
adamnfish-gu Aug 5, 2026
3efc081
Merge branch 'adopt/javascript-esm' into integration/verify
adamnfish-gu Aug 5, 2026
2ef4818
Merge branch 'adopt/typescript-deno' into integration/verify
adamnfish-gu Aug 5, 2026
543c8d5
Merge branch 'adopt/typescript-node' into integration/verify
adamnfish-gu Aug 5, 2026
1d93404
Merge branch 'adopt/go' into integration/verify
adamnfish-gu Aug 5, 2026
e4dbd25
Merge branch 'adopt/kotlin' into integration/verify
adamnfish-gu Aug 5, 2026
cb969d7
Merge branch 'adopt/dot-net-core' into integration/verify
adamnfish-gu Aug 5, 2026
56edf1e
Merge branch 'adopt/clojure' into integration/verify
adamnfish-gu Aug 5, 2026
f81360a
Merge branch 'adopt/php' into integration/verify
adamnfish-gu Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
98 changes: 98 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: CI

on:
push:
branches: [main]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# Projects opt in to CI simply by having a .tool-versions file in their top level directory
discover:
name: Discover projects
runs-on: ubuntu-latest
outputs:
projects: ${{ steps.find.outputs.projects }}
steps:
- uses: actions/checkout@v5

- name: Find projects with a .tool-versions
id: find
run: |
projects=$(
for dir in */; do
if [[ -f "${dir}.tool-versions" ]]; then
echo "${dir%/}"
fi
done | jq -R . | jq -sc .
)
echo "Discovered: $projects"
echo "projects=$projects" >> "$GITHUB_OUTPUT"

# Guards against a half-adopted project silently dropping out of CI.
# If a project declares a .tool-versions it must also provide the scripts the build job runs.
conform:
name: Check project structure
needs: discover
if: needs.discover.outputs.projects != '[]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Every project must have executable setup and test scripts
env:
PROJECTS: ${{ needs.discover.outputs.projects }}
run: |
status=0
for project in $(jq -r '.[]' <<< "$PROJECTS"); do
for script in setup test; do
path="$project/script/$script"
if [[ ! -f "$path" ]]; then
echo "::error file=$project/.tool-versions::$project declares a .tool-versions but has no $path"
status=1
elif [[ ! -x "$path" ]]; then
echo "::error file=$path::$path is not executable, run: chmod +x $path"
status=1
fi
done
done
exit $status

build:
name: ${{ matrix.project }}
needs: discover
if: needs.discover.outputs.projects != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
project: ${{ fromJSON(needs.discover.outputs.projects) }}
defaults:
run:
working-directory: ${{ matrix.project }}
steps:
- uses: actions/checkout@v5

# Optional extra step for toolchains that build from source and need system
# libraries the runner does not ship (e.g. php).
# Runs before mise, so it cannot rely on dependencies in `.tool-versions`.
- name: Install system packages
run: |
if [[ -x script/system-packages ]]; then
./script/system-packages
fi

- name: Install the toolchain declared in .tool-versions
uses: jdx/mise-action@v2
with:
working_directory: ${{ matrix.project }}

- run: ./script/setup

- run: ./script/test
50 changes: 45 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Coding Exercise Project

[![CI](https://github.com/guardian/coding-exercise-project/actions/workflows/ci.yml/badge.svg)](https://github.com/guardian/coding-exercise-project/actions/workflows/ci.yml)

This repository contains small skeleton projects in a number of programming languages.

It is designed to aid in the coding exercise stage of the Guardian's recruitment process for Software Engineers.
Expand All @@ -22,28 +24,66 @@ You can set up your own environment but please do so **before** you join the Han
If you have any issues with your environment please let your interviewer know as soon as you join the Hangout so that
they can adjust the exercise accordingly.

## Prerequisites

Every skeleton declares the toolchain it needs in a [`.tool-versions`](https://mise.jdx.dev/configuration.html#tool-versions)
file. For example, the Scala project asks for:

```
java corretto-21
sbt 1
```

You are free to install those tools however you like — a system package manager, a language-specific
version manager, or an existing installation. All that matters is that they end up on your `PATH`.
If they are not, `./script/setup` will fail with a "command not found" error.

### Recommended: mise

The quickest way to get the right versions is [mise](https://mise.jdx.dev/), which reads
`.tool-versions` and installs all listed tools.

Follow mise's [getting started guide](https://mise.jdx.dev/getting-started.html) to install it and
activate it in your shell. Then, from inside the language directory of your choice:

```sh
mise install
```

## How to use
This repository has a directory per language. Each skeleton follows the same structure with a README and a failing test.
This repository has a directory per language. Each skeleton follows the same structure with a README and a passing test.

To get started:

💻 Clone the repo `git clone git@github.com:guardian/coding-exercise-project.git`

🗂 Switch directories to the language of your choosing

🔌 Install dependencies and perform other setup tasks `./script/setup` (usually uses [homebrew](https://brew.sh/))
🔧 Install the toolchain listed in `.tool-versions`, e.g. with `mise install`

🧪 Run the tests and witness them fail `./script/test`
🔌 Install dependencies and perform other setup tasks `./script/setup`

🧪 Run the tests and watch them pass `./script/test`

💻 Now it is up to you! Using your editor of choice, start writing code!

## Missing language?
Please raise a PR to add it with:
- A README
- A failing test
- A `./script/setup` script to install dependencies and perform other setup tasks
- A `.tool-versions` declaring the language toolchain, pinned to its major version
- A passing example test
- A `./script/setup` script to install dependencies and do any other initial setup
- A `./script/test` script to run the tests

Adding a `.tool-versions` file enrols a project in CI, so `./script/setup` and `./script/test`
must exist and be executable — the `Check project structure` job enforces this.

If the toolchain is built from source and needs system libraries that may not be present,
add an executable `./script/system-packages` that installs them. CI runs it before installing the
toolchain, and anyone building that toolchain locally can run it themselves. This script is run separately
to `./script/setup`, because `setup` runs after the toolchain is already on your `PATH`.
Only `php` needs this today.

The requirement for the `./script` commands is to keep consistency across languages and make it easy to switch between them.
Read more [here](https://github.com/github/scripts-to-rule-them-all).

Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions clojure/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
java corretto-21
leiningen 2.12
30 changes: 30 additions & 0 deletions clojure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Clojure

Skeleton project for Clojure.

## Prerequisites

The toolchain this project needs is declared in [`.tool-versions`](./.tool-versions):

```
java corretto-21
leiningen 2.12
```

Install those however you prefer, as long as they end up on your `PATH`. The quickest route is
[mise](https://mise.jdx.dev/), which reads the file for you:

```sh
mise install
```

## Usage
- `./script/setup` to fetch dependencies
- `./script/test` to run the tests
- `./script/start` to run the app

## Structure
- Code located in [`core.clj`](./src/pairing/core.clj)
- Tests located in [`core_test.clj`](./test/pairing/core_test.clj)

However, you're free to organise your code as you like.
11 changes: 0 additions & 11 deletions clojure/gol/README.md

This file was deleted.

Loading
Loading