Skip to main content

Configure the Build

Every push to a student repository triggers a build, and the build is what turns code into a result. A new exercise starts with a working build for its language, so most exercises need nothing from this page. Come here when you need to change what the build runs, how long it may take, what the container it runs in is allowed to do, or when you want to add code quality checks.

Each section below says whether it needs Integrated Code Lifecycle — static code analysis and the Jenkins feedback mechanism do not. Everything on this page applies to every build of the exercise: template, solution and student submissions alike.

Adapt Build Phases (Optional)

Only available with Integrated Code Lifecycle

Instructors can configure the build phases. A new exercise starts with a default build plan for its programming language. To adapt it, open the exercise's detail page and click Edit build plan. All changes apply to all builds (template, solution, and student submissions). The build plan editor shows the template and solution build status next to the configuration, so you can immediately see whether your changes still build. You can also view the configured build plan on the exercise's detail page.

Build phases with their scripts and result paths
The build phases

The build plan consists of multiple phases. Each phase can be customized in the following ways:

  • Name: The name of the phase.
  • Inclusion condition: The condition can be either Always or After due date. If a phase is configured to run after the due date, Artemis automatically schedules the latest submission for each student participation to be rebuilt 15 minutes (adjustable) after the due date (or after the exam's due date, including grace period and student time extensions).
  • Script: The script specifying the commands to run for the phase.
  • Tests expected: A toggle indicating whether tests are expected for a phase. If disabled for all phases, the exercise will not collect any test results, but the build status will still be accurately determined by the build's exit code.
  • Result paths: The paths where the test results for this phase are located.
  • Execute at end regardless of previous failures: A toggle indicating whether the phase should run at the end of the build, even if a previous phase failed.

Instructors can freely define how many phases are executed and in which order.

Determining Build Success:

Before a build runs, any phases where the inclusion condition is not met are dropped. Artemis then determines build success based on the remaining phases:

  • If phases expecting tests (excluding static code analysis) remain: Build success is determined by whether the expected tests were successfully found and executed.
  • If no phases expecting tests (excluding static code analysis) remain: Build success is determined by the exit code of the build.

Common Test Setup Scenarios:

Controlling when tests run (via build-phase inclusion conditions) is separate from controlling when results are visible to students (via test-case visibility in the grading page). To achieve the desired outcome, both must be configured accordingly:

  1. Immediate Full Feedback: Set all build phases to Always and configure the corresponding test cases to always be visible. Tests execute on every commit, and all results are shown immediately after submission.
  2. Build Status Only: Remove all phases that expect tests. Students only see if their code compiled successfully based on the build's exit status. Test-case visibility is irrelevant since no tests are executed.
  3. Tests After Due Date: Keep the compilation phase as Always and set any phases expecting tests to After due date. Since the tests do not execute before the deadline, test-case visibility technically does not matter, but can be set to After Due Date for consistency. The tests will only execute after the deadline passes, and their output will become available at that point.
  4. Partial Immediate Feedback: Set specific test phases (e.g., static code analysis) to Always, and other test phases to After due date. For tests running immediately, set their visibility to Always. For tests running after the due date, visibility technically does not matter, but can be set to After Due Date for consistency. Students receive immediate feedback on some aspects and delayed feedback on others.

Default behavior:

  • Creating a course programming exercise: Phases are set to always run. Test results are set to always be visible.
  • Creating a programming exercise in exam mode: Phases that expect tests are automatically set to run after the due date. This means phases without expected test results remain active during the exam. Tests will run after the exam concludes.
  • Importing a programming exercise in exam mode: Tests are automatically set to only show after the release date of results. However, the build plan is imported as-is. This prevents situations where, for example, a build plan with only a single phase is unintentionally set to run After due date.

You can also use a custom Docker image. Make sure to:

  • Publish the image in a publicly available repository (e.g., DockerHub)
  • Build for both amd64 and arm64 architectures
  • Keep the image size small (build agents download before execution)
  • Include all build dependencies to avoid downloading in every build

Edit Repositories Checkout Paths (Optional)

Only available with Integrated Code Lifecycle

Preconfigured checkout paths usually don't need changes.

Checkout paths depend on the programming language and project type:

To change checkout paths, click edit repositories checkout path:

Update the build plan accordingly (see the Adapt Build Phases section).

Edit Maximum Build Duration (Optional)

Only available with Integrated Code Lifecycle

You edit this on the dedicated build plan editor page, which you open with the Edit build plan button on the exercise detail page (see Adapt Build Phases).

The default maximum build duration (120 seconds) usually doesn't need changes.

Use the slider to adjust the time limit for build plan execution:

Docker image, build duration and container limits
The container the build runs in

Edit Container Configuration (Optional)

Only available with Integrated Code Lifecycle

You edit this on the dedicated build plan editor page, which you open with the Edit build plan button on the exercise detail page (see Adapt Build Phases).

In most cases, the default container configuration does not need to be changed.

Currently, instructors can change which network the container joins, add additional environment variables, and configure resource limits such as CPU and memory.

Use custom network selects the container's network: the default bridge, one of the networks your administrators have configured, or None, which cuts the container off from the network entirely. Choosing None is how you stop students downloading additional dependencies during the build. The dependencies must then already be present in the Docker image.

Additional environment variables can be added to the container configuration. This can be useful if the build process requires specific variables to be set.

Instructors can also adjust resource limits for the container. The number of CPU cores allocated to the container can be modified, as well as the maximum amount of memory and memory swap that the container is allowed to use. These settings help ensure that resource usage is balanced while allowing for flexibility in configuring the build environment. If set too high, the specified values may be overwritten by the maximum restrictions set by the administrators. Contact the administrators for more information.

We plan to add more options to the container configuration in the future.

Customize Online IDE Run Configuration (Optional)

The Template repository of several languages ships a .vscode/tasks.json and a .vscode/launch.json, so students can press Run or start a debug session in the online IDE without setting anything up first, provided the exercise has Allow Online IDE enabled. Student repositories inherit both files when they are created from the template.

The following defaults ship with the templates:

Programming LanguageRun commandDebug configuration
C (GCC)make runCodeLLDB, attached to helloWorld.out *
Java (Gradle)./gradlew runJava debugger, attached to the Client class
Java (Maven)mvn compile exec:javaJava debugger, attached to the Client class
JavaScriptnpm startNode.js debugger, attached to src/client.js
Rustcargo runCodeLLDB, target located through cargo

Run does not require a debug extension, but it does require the template's runtime and build command to be available in the online IDE image. Debug additionally requires the matching debug extension.

* The C configuration debugs the binary produced by the last build, so students press Run (or Build) once before Debug, and again after changing the code. The online IDE currently ignores a preLaunchTask, which is why the configuration does not build automatically.

Some templates intentionally leave the entry point to the student, which means Run and Debug report an error until it is written:

  • The C template's helloWorld.c contains no main function, so the build fails to link.
  • The Java DejaGnu (blackbox) template's Client class contains no main method.

The templates define no Test task, because the tests live in the separate Test repository and are therefore not available in a student repository.

To adapt the configuration to your own exercise, edit .vscode/tasks.json (the run command) and .vscode/launch.json (the debug entry point) in the Template repository, then commit and push. Student repositories created afterwards pick up the change; repositories that already exist keep the configuration they were created with.

Adding a Run Configuration to a Template Without One

Not every template ships a run configuration. The Python template, for example, contains sorting algorithms but no entry point that orchestrates them. To enable Run for such an exercise, add an entry point (e.g. main.py) to the Template repository and create a .vscode/tasks.json next to your sources. A .vscode/launch.json for Debug is optional.

.vscode/tasks.json:

{
"version": "2.0.0",
"tasks": [
{
"label": "Run",
"type": "shell",
"command": "python3 main.py",
"group": { "kind": "build", "isDefault": true },
"options": { "cwd": "${workspaceFolder}" },
"presentation": { "reveal": "always", "panel": "shared" }
}
]
}

Add a .vscode/launch.json as well if the online IDE image used by your course ships a debug extension for the language. The type of a debug configuration is defined by that extension, so check its documentation for the correct value and the options it expects.

The same pattern applies to any language: put the run command into tasks.json, and the entry point into launch.json where a debug extension is available, both inside a .vscode directory in the Template repository.

Configure Static Code Analysis

If static code analysis was activated, the Test repository contains configuration files.

For Java exercises, the staticCodeAnalysisConfig folder contains configuration files for each tool. Artemis generates default configurations with predefined rules. Instructors can freely customize these files.

On exercise import, configurations are copied from the imported exercise.

Supported Static Code Analysis Tools

LanguageSupported ToolsConfiguration File
JavaSpotbugsspotbugs-exclusions.xml
Checkstylecheckstyle-configuration.xml
PMDpmd-configuration.xml
PMD CPD(via PMD plugin)
PythonRuffruff-student.toml
CGCC(via compiler flags)
SwiftSwiftLint.swiftlint.yml
RustClippyclippy.toml
JavaScript/TypeScriptESLinteslint.config.mjs
Rlintr.lintr
C++Clang-Tidy.clang-tidy
RubyRubocop.rubocop.yml
Dartdart analyzeanalysis_options.yaml

Sending Feedback back to Artemis

By default, unit test results are extracted and sent to Artemis automatically. Only custom setups may need semi-automatic approaches.

Test results normally reach Artemis as XML files in JUnit format, collected from the result paths of the phases that actually ran. Phases dropped by their inclusion condition — an After due date phase during a student's working time, for instance — contribute no results, so a test only reports once its phase is active. Any language can therefore report results, as long as it writes JUnit XML.

Custom Feedback

When a test result cannot be expressed as a JUnit case, write a JSON file into a result path of an active phase instead. With Integrated Code Lifecycle, Artemis parses every .json file it collects as custom feedback, using this schema:

{
"name": string,
"successful": boolean,
"message": string
}
  • name: Test case name as shown on 'Configure Grading' page. Must be non-null and non-empty
  • successful: Indicates test case success/failure. Defaults to false if not present
  • message: Additional information shown to student. Required for non-successful tests, optional otherwise
Search documentation