Skip to content

Commit 3082d84

Browse files
committed
Add CONTRIBUTING
1 parent bc65957 commit 3082d84

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

.github/CONTRIBUTING.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Contributing an exercise
2+
3+
## Prerequisites
4+
5+
- Bash environment
6+
- Python 3.13
7+
8+
## Getting started
9+
10+
1. Fork the repository
11+
2. Clone the repository
12+
13+
```bash
14+
git clone https://github.com/<username>/exercises
15+
```
16+
17+
3. Setup a virtual environment
18+
19+
```bash
20+
python -m venv venv
21+
```
22+
23+
4. Activate the virtual environment
24+
25+
```bash
26+
source venv/bin/activate
27+
```
28+
29+
5. Install all dependencies
30+
31+
```bash
32+
pip install -r requirements.txt
33+
```
34+
35+
6. Create a new exercise template, following the prompts to setup the `.gitmastery-exercise.json` configuration file. For more details about the configuration, refer [here]()
36+
37+
```bash
38+
./new.sh
39+
```
40+
41+
42+
You should now see a new exercise with the name you have chosen.
43+
44+
## Exercise structure
45+
46+
### Your template
47+
48+
An exercise comprises of the following structure:
49+
50+
```text
51+
<exercise name>
52+
├── README.md
53+
├── __init__.py
54+
├── download.py
55+
├── res
56+
│ └── ...
57+
├── tests
58+
│ ├── __init__.py
59+
│ ├── specs
60+
│ │ ├── base.yml
61+
│ └── test_verify.py
62+
└── verify.py
63+
```
64+
65+
- `README.md`: contains the instructions for the exercise for the students to attempt
66+
- `download.py`: contains the download instructions to setup the student's exercise
67+
- `verify.py`: contains the verification script for the exercise attempt
68+
- `res/`: contains resources that are available to students (see this section about [types of resources](#types-of-resources))
69+
- `tests/specs/`: contains specification files written using [`repo-smith`](https://github.com/git-mastery/git-autograder)
70+
- `tests/test_verify.py`: contains unit tests for verification script
71+
72+
### What students see
73+
74+
When a student downloads an exercise, they will see the following folder structure:
75+
76+
```text
77+
<exercise name>
78+
├── .gitmastery-exercise.json
79+
├── README.md
80+
└── <sub folder name>
81+
├── .git
82+
└── ...
83+
```
84+
85+
The root of the exercise will contain the `README.md` and `.gitmastery-exercise.json` configured from your template.
86+
87+
It also contains the sub-folder configured in `.gitmastery-exercise.json`, which is where students will attempt the exercise.
88+
89+
## Types of resources
90+
91+
There are two distinct types of resources:
92+
93+
1. Base files: configured through the `base_files` property in `.gitmastery-exercise.json` in your template; files located in `res/` are downloaded to the root of the exercise folder
94+
95+
```text
96+
<exercise name>
97+
├── .gitmastery-exercise.json
98+
├── README.md
99+
├── <base files>
100+
└── <sub folder name>
101+
├── .git
102+
└── ...
103+
```
104+
105+
2. Resources: configured through the `__resources__` field in `download.py`; supporting files for the exercise with files located in `res/` downloaded into the sub folder
106+
107+
```text
108+
<exercise name>
109+
├── .gitmastery-exercise.json
110+
├── README.md
111+
├── <base files>
112+
└── <sub folder name>
113+
├── .git
114+
└── <resources>
115+
```
116+
117+
## `.gitmastery-exercise.json` configuration
118+
119+
The `.gitmastery-exercise.json` is used to tell the [Git-Mastery app](https://git-mastery.github.io/app) how to setup the student's exercise.
120+
121+
The `new.sh` script should have already generated one for you, but you may change your mind with the configuration and modify the file directly:
122+
123+
- `exercise_name`: raw exercise name that will be indexed; recommended to use [kebab case](https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case)
124+
- `tags`: used during indexing on the [exercise directory](https://git-mastery.github.io/exercises)
125+
- `requires_git`: performs a check to ensure that Git is installed and the user has already configured their `user.name` and `user.email`
126+
- `requires_github`: performs a check to ensure that Github CLI is installed and the user has already authenticated themselves
127+
- `base_files`: specifies the files from `res/` to be downloaded into the exercise root; typically used for the `answers.txt` (more about grading types [here]())
128+
- `exercise_repo`: controls the sub-folder that is generated; this is where students work on the exercise
129+
- `repo_type`: `local` or `remote`; if `remote`, then the sub-folder is generated from a remote repository
130+
- `repo_name`: name of the sub-folder; required for both `repo_type`
131+
- `init`: determines if `git init` is run for the sub-folder; required only for `local`
132+
- `create_fork`: determines if a fork is created on the user's Github account; required only for `remote`
133+
- `repo_title`: name of the remote repository to fork + clone; required only for `remote`
134+
135+
## Download script
136+
137+
The `download.py` contains the instructions to setup the local repository.
138+
139+
This is the sequence in which the Git-Mastery app downloads an exercise for a student:
140+
141+
```mermaid
142+
flowchart
143+
a[Download exercise] --> b[Create exercise folder]
144+
b --> c[Download base files to exercise root]
145+
c --> d[Check Git if toggled]
146+
d --> e[Check Github if toggled]
147+
e -- local --> f[Create local repo folder with repo_name]
148+
e -- remote --> g[Fork repository if toggled]
149+
g --> h[Clone repository with repo_name]
150+
f --> i[Download resources]
151+
h --> i
152+
i --> j[Create initial commit if init toggled]
153+
j --> k[Execute download function]
154+
```
155+
156+
As a result, the `download` function is the last step after you have already setup the folder structures and downloaded the base files and resources.
157+
158+
The default download script comes with a helper function to `run_command` to run local commands.
159+
160+
> [!INFO]
161+
> You should be using OS-agnostic commands in the download script
162+
163+
The initial download script also includes a command to attach a tag as the "start tag". This is only useful if you want to iterate through the user's commits in your verification script. Otherwise, this can be removed.
164+
165+
Refer to existing `download.py` for reference on how to setup the download script.
166+
167+
### Testing downloads
168+
169+
To test that your download script works, we have provided a script to simulate the download process in this repository for you to verify.
170+
171+
```bash
172+
./test-download.sh <your exercise folder>
173+
```
174+
175+
## Verification script
176+
177+
The verification process is a simpler on the Git-Mastery app:
178+
179+
```mermaid
180+
flowchart
181+
a[Verify exercise] --> b["Check if in exercise (using .gitmastery-exercise.json)"]
182+
b -- not in exercise --> c[Cancel]
183+
b -- in exercise --> d[Execute verification script on exercise folder]
184+
```
185+
186+
The [`git-autograder`](https://github.com/git-mastery/git-autograder) is built as a wrapper around [`GitPython`](https://github.com/gitpython-developers/GitPython). As a result, if you are writing any verification scripts and there is no available helper function with `git-autograder`, you can fall back to the underlying `Repo` object:
187+
188+
```python
189+
def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
190+
# Access the underlying GitPython repo:
191+
exercise.repo.repo
192+
193+
return exercise.to_output([], GitAutograderStatus.SUCCESSFUL)
194+
```
195+
196+
Refer to existing `verify.py` scripts to understand what are the available helper functions to streamline the grading. Open an issue if there is something that is not yet supported or if you have a question.
197+
198+
### Testing verification
199+
200+
To test the verification, we rely on `repo-smith` to simulate exercise states and write unit tests to verify the verification script's behavior. You don't need to simulate the entire flow, just the end states that you require for your verification script.
201+
202+
Refer to existing `test_verify.py` to see examples of unit testing the verification script.
203+
204+
You can run the unit tests of your exercise via:
205+
206+
```bash
207+
./test.sh <your exercise folder>
208+
```

0 commit comments

Comments
 (0)