docs: latest README
All checks were successful
submodules sync / sync (push) Successful in 39s
build / build (push) Successful in 1m35s
build / trigger-build-image (push) Successful in 8s

This commit is contained in:
张泊明518370910136 2025-02-11 11:41:28 -05:00
parent c474a5d493
commit ff30641171
GPG Key ID: D47306D7062CDA9D

View File

@ -51,7 +51,7 @@ For now, the following checking tools are needed for test:
2. `clang-tidy-18` 2. `clang-tidy-18`
3. `cmake` 3. `cmake`
4. `make` 4. `make`
5. `cpplint` 4. `cpplint`
```bash ```bash
$ make test $ make test
@ -65,7 +65,6 @@ ok github.com/joint-online-judge/JOJ3/cmd/joj3 2.290s coverage: 74.0% of
### For developers ### For developers
1. Install [`pre-commit`](https://pre-commit.com/), [`golangci-lint`](https://golangci-lint.run). 1. Install [`pre-commit`](https://pre-commit.com/), [`golangci-lint`](https://golangci-lint.run).
2. Install the pre-commit hooks. It will run some checks before you commit. 2. Install the pre-commit hooks. It will run some checks before you commit.
```bash ```bash
@ -75,39 +74,38 @@ pre-commit installed at .git/hooks/pre-commit
3. You only need to run steps 5, 7, and 8 in the quick start during development. If the test cases need to be updated, step 6 is also needed. 3. You only need to run steps 5, 7, and 8 in the quick start during development. If the test cases need to be updated, step 6 is also needed.
## How does it work? ## Workflow
These steps are executed in runner-images. We use `sudo -u tt` to elevate the permission and run `joj3`. All the secret files should be stored in the host machine with user `tt` and mounted into the runner (e.g. `/home/tt/.config`). Since the runner uses user `student`, we can keep the data safe. A single call to `joj3` executable will run 2 parts: These steps are executed in runner-images. We use `sudo -E -u tt` to elevate the permission and run `joj3` with environment variables from gitea actions. All the secret files should be stored in the host machine with user `tt` and mounted into the runner (e.g. `/home/tt/.config`). Since the runner uses user `student`, we can keep the data safe.
1. Run JOJ3 stages
1. Parse the message. 1. Parse the message.
- It will use the git commit message from `HEAD`. The message should meet the [Conventional Commits specification](https://www.conventionalcommits.org/). We use `scope` and `description` here. - It will use the git commit message from `HEAD`. The message should meet the [Conventional Commits specification](https://www.conventionalcommits.org/). We use `scope` and `description` here. Also, a suffix `[group]` will be used to decide which stages will be run later.
- If `-tag` is specified, then it should equal to the scope of the message, or JOJ3 will not run. - If `-tag` is specified, then it should equal to the scope of the message, or JOJ3 will not run.
2. Find the configuration file. 2. Find the configuration file.
- We have `conf-root` and `conf-name` specified in the CLI argument. Then the full path of configuration file is `<conf-root>/<scope>/<conf-name>`. - We have `conf-root` and `conf-name` specified in the CLI argument. Then the full path of configuration file is `<conf-root>/<scope>/<conf-name>`.
- If that configuration file does not exist, and `fallback-conf-name` is passed, it will try to read `<conf-root>/<fallback-conf-name>`.
3. Generate stages. 3. Generate stages.
- We have an empty list of stages at the beginning. - We have an empty list of stages at the beginning.
- We check all the stages from the configuration file. Stages with empty `group` field will always be added. Stages with non-empty `group` field requires that value (case insensitive) appears in the commit description. e.g. with commit msg `feat(h5/e3): joj msan`, stages with the following `group` field will run: `""`, `"joj"`, `"msan"`. - We check all the stages from the configuration file. Stages with empty `group` field will always be added. Stages with non-empty `group` field requires that value (case insensitive) appears in the commit group. e.g. with commit msg `feat(h5/e3): joj msan [joj]`, stages with the following `group` field will run: `""`, `"joj"`. If the group specified in the commit message is `[all]`, then all groups will run.
- Every stage needs to have an unique `name`, which means if two stages have the same name, only the first one will be added. - Every stage needs to have an unique `name`, which means if two stages have the same name, only the first one will be added.
4. Run stages. 4. Run stages.
- By default, all the stages will run sequentially. - By default, all the stages will run sequentially.
- Each stage contains a executor and multiple parsers. The executor (currently only sandbox) executes the command and parsers parse the output generated by the executor. The parsers in one stage will run sequentially, and all the output will be aggregated (scores being summed up and comment being concatenated). - Each stage contains a executor and multiple parsers. The executor executes the command and parsers parse the output generated by the executor. The parsers in one stage will run sequentially, and all the output will be aggregated (scores being summed up and comment being concatenated).
- The parser can return a force quit, which means all the stages after it will be skipped, but the remaining parsers in the current stage will run. - The parser can return a force quit, which means all the stages after it will be skipped, but the remaining parsers in the current stage will run.
5. Generate results. 5. Generate results.
- Once the running of stages is done, it will generate a result file where the path is specified in the configuration file. - Once the running of stages is done, it will generate a result file where the path is specified in the configuration file.
6. Run optional stages.
- If pre-stages and post-stages is specified, it will run before step 4 and after step 5, responsively. The result of these optional stages will not affect regular stages. Now we run `joint-teapot` in post-stages as it needs the output file from regulara stages to post the issue to the corresponding repo for students.
## Models (for developers only) ## Models
The program parses the configuration file to run multiple stages. The program parses the configuration file to run multiple stages.
Each stage contains an executor and parser. An executor just executes a command and returns the original result (stdout, stderr, output files). We can limit the time and memory used by each command in the executor. We run all kinds of commands in executors of different stages, including code formatting, static check, compilation, and execution. A parser takes the result and the configuration of the stage to parse the result and return the score and comment. e.g. If in the current stage, the executor runs a `clang-tidy` command, then we can use the clang-tidy parser in the configuration file to parse the stdout of the executor result and check whether some of the rules are followed. We can deduct the score and add some comments based on the result, and return the score and comment as the output of this stage. This stage ends here and the next stage starts. Each stage contains an executor and multiple parsers. An executor takes a `Cmd` and returns an `ExecutorResult`, while a parser takes an `ExecutorResult` and its configuration and returns a `ParserResult` and `bool` to indicate whether we should skip the rest stages.
In codes, an executor takes a `Cmd` and returns an `ExecutorResult`, while a parser takes an `ExecutorResult` and its conf and returns a `ParserResult` and `bool` to indicate whether we should skip the rest stages.
### `Cmd` ### `Cmd`
Check `Cmd` at <https://github.com/criyle/go-judge#rest-api-interface>. Check `Cmd` at <https://github.com/criyle/go-judge#rest-api-interface>.
Some difference: Some difference:
- `CopyInDir string`: set to non-empty string to add everything in that directory to `CopyIn`. - `CopyInDir string`: set to non-empty string to add everything in that directory to `CopyIn`.
@ -120,5 +118,5 @@ Check the `Result` at <https://github.com/criyle/go-judge#rest-api-interface>.
### `ParserResult` ### `ParserResult`
- `Score int`: score of the stage. - `Score int`: score of the executor result.
- `Comment string`: comment on the stage. - `Comment string`: comment on the executor result.