<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stronk7</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stronk7"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Stronk7"/>
	<updated>2026-06-04T20:45:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Eloy_Lafuente_(stronk7)/Phpdoc_types&amp;diff=64096</id>
		<title>User:Eloy Lafuente (stronk7)/Phpdoc types</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Eloy_Lafuente_(stronk7)/Phpdoc_types&amp;diff=64096"/>
		<updated>2024-04-10T11:14:45Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
===Scope===&lt;br /&gt;
&lt;br /&gt;
This document describes &#039;&#039;&#039;style&#039;&#039;&#039; guidelines for developers working on or with Moodle code.  It talks purely about the mechanics of code layout and the choices we have made for Moodle.&lt;br /&gt;
&lt;br /&gt;
For details about using the Moodle API to get things done, see the [[Coding|coding guidelines]].&lt;br /&gt;
&lt;br /&gt;
===Goals===&lt;br /&gt;
&lt;br /&gt;
Consistent coding style is important in any development project, and particularly when many developers are involved.  A standard style helps to ensure that the code is easier to read and understand, which helps overall quality.&lt;br /&gt;
&lt;br /&gt;
Abstract goals we strive for:&lt;br /&gt;
&lt;br /&gt;
* simplicity&lt;br /&gt;
* readability&lt;br /&gt;
* tool friendliness, such as use of method signatures, constants, and patterns that support IDE tools and auto-completion of method, class, and constant names.&lt;br /&gt;
&lt;br /&gt;
When considering the goals above, each situation requires an examination of the circumstances and balancing of various trade-offs.&lt;br /&gt;
&lt;br /&gt;
Note that much of the existing Moodle code may not follow all of these guidelines - we continue to upgrade this code when we see it.&lt;br /&gt;
&lt;br /&gt;
===Useful tools===&lt;br /&gt;
&lt;br /&gt;
There are a couple of different tools available to help you in writing code that conforms to this guide.&lt;br /&gt;
&lt;br /&gt;
; Code checker (integrates with [https://github.com/moodlehq/moodle-local_codechecker/blob/main/README.md#ide-integration eclipse/phpstorm]): http://moodle.org/plugins/view.php?plugin=local_codechecker&lt;br /&gt;
; Marina Glancy&#039;s Moodle PHPdoc checker : https://github.com/marinaglancy/moodle-local_moodlecheck&lt;br /&gt;
&lt;br /&gt;
It is worth using both tools to check the code you are writing as they both perform slightly different checks.&lt;br /&gt;
If you can get your code to pass both then you are well on the way to making friends with those who will be reviewing your work.&lt;br /&gt;
&lt;br /&gt;
==File Formatting==&lt;br /&gt;
&lt;br /&gt;
===PHP tags===&lt;br /&gt;
&lt;br /&gt;
Always use &amp;quot;long&amp;quot; php tags.  However, to avoid whitespace problems, DO NOT include the closing tag at the very end of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require(&#039;config.php&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Indentation===&lt;br /&gt;
&lt;br /&gt;
Use an indent of &#039;&#039;&#039;4 spaces&#039;&#039;&#039; with no tab characters. Editors should be configured to treat tabs as spaces in order to prevent injection of new tab characters into the source code.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t indent the main script level:&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
require(&#039;config.php&#039;);&lt;br /&gt;
$a = required_param(&#039;a&#039;, PARAM_INT);&lt;br /&gt;
if ($a &amp;gt; 10) {&lt;br /&gt;
    call_some_error($a);&lt;br /&gt;
} else {&lt;br /&gt;
    do_something_with($a);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    require(&#039;config.php&#039;);&lt;br /&gt;
    $a = required_param(&#039;a&#039;, PARAM_INT);&lt;br /&gt;
    if ($a &amp;gt; 10) {&lt;br /&gt;
        call_some_error($a);&lt;br /&gt;
    } else {&lt;br /&gt;
        do_something_with($a);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SQL queries use special indentation, see [[SQL coding style]].&lt;br /&gt;
&lt;br /&gt;
===Maximum Line Length===&lt;br /&gt;
&lt;br /&gt;
The key issue is readability.&lt;br /&gt;
&lt;br /&gt;
Aim for 132 characters if it is convenient,  it is not recommended to use more than 180 characters.&lt;br /&gt;
&lt;br /&gt;
====Wrapping lines====&lt;br /&gt;
&lt;br /&gt;
When wrapping a line, indent the follow-on line by 8 spaces rather than 4. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if (a_long_condition() &amp;amp;&amp;amp;&lt;br /&gt;
        a_nother_long_condition()) {&lt;br /&gt;
    do_something();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using eight spaces makes it easier to spot the difference between wrapped lines and indented blocks.&lt;br /&gt;
&lt;br /&gt;
The example above is only an illustration; it is best practice to avoid wrapping lines in control structures. See below.&lt;br /&gt;
&lt;br /&gt;
====Wrapping Arrays====&lt;br /&gt;
&lt;br /&gt;
Associative arrays are a exception to the rule about 8-space indent for follow-on lines. The correct layout is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$plugininfo[&#039;preferences&#039;][$plugin] = array(&lt;br /&gt;
    &#039;id&#039;     =&amp;gt; $plugin, &lt;br /&gt;
    &#039;link&#039;   =&amp;gt; $pref_url, &lt;br /&gt;
    &#039;string&#039; =&amp;gt; $modulenamestr&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Lining up the =&amp;gt;s is optional. Small arrays can be done on one line.&lt;br /&gt;
&lt;br /&gt;
====Wrapping function declarations====&lt;br /&gt;
If you have many parameters, indent them in line with the first parameter:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function graded_users_iterator($course, $grade_items = null, $groupid = 0,&lt;br /&gt;
                                      $sortfield1 = &#039;lastname&#039;, $sortorder1 = &#039;ASC&#039;,&lt;br /&gt;
                                      $sortfield2 = &#039;firstname&#039;, $sortorder2 = &#039;ASC&#039;) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Wrapping Control Structures====&lt;br /&gt;
If you have too many conditions in one control structure, try setting some variables before the start of the structure to improve readability.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$coursecategory = $element[&#039;object&#039;]-&amp;gt;is_course_item() or $element[&#039;object&#039;]-&amp;gt;is_category_item();&lt;br /&gt;
$scalevalue = in_array($element[&#039;object&#039;]-&amp;gt;gradetype, array(GRADE_TYPE_SCALE, GRADE_TYPE_VALUE));&lt;br /&gt;
&lt;br /&gt;
if ($coursecategory and $scalevalue) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if (($element[&#039;object&#039;]-&amp;gt;is_course_item() or $element[&#039;object&#039;]-&amp;gt;is_category_item())&lt;br /&gt;
    and ($element[&#039;object&#039;]-&amp;gt;gradetype == GRADE_TYPE_SCALE&lt;br /&gt;
    or $element[&#039;object&#039;]-&amp;gt;gradetype == GRADE_TYPE_VALUE)) {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Line Termination===&lt;br /&gt;
&lt;br /&gt;
Use standard &#039;&#039;&#039;Unix&#039;&#039;&#039; text format. Lines must end only with a linefeed (LF). Linefeeds are represented as ordinal 10, or hexadecimal 0x0A.&lt;br /&gt;
&lt;br /&gt;
Do not use carriage returns (CR) like old &#039;&#039;Macintosh&#039;&#039; computers (0x0D).&lt;br /&gt;
&lt;br /&gt;
Do not use the carriage return/linefeed combination (CRLF) as &#039;&#039;Windows&#039;&#039; computers (0x0D, 0x0A).&lt;br /&gt;
&lt;br /&gt;
Lines should not contain trailing spaces. In order to facilitate this convention, most editors can be configured to strip trailing spaces, such as upon a save operation. However, if you are editing an existing Moodle file and are planning to submit your changes for integration, please switch off that feature so that whitespace changes do not pollute the patch (other developers will have trouble viewing what you&#039;ve done if every other line has been edited for whitespace).&lt;br /&gt;
&lt;br /&gt;
==Naming Conventions==&lt;br /&gt;
&lt;br /&gt;
===Filenames===&lt;br /&gt;
&lt;br /&gt;
Filenames should :&lt;br /&gt;
* be whole english words&lt;br /&gt;
* be as short as possible&lt;br /&gt;
* use lowercase letters only &lt;br /&gt;
* end in .php, .html, .js, .css or .xml&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
&lt;br /&gt;
Class names should always be lower-case English words, separated by underscores:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class some_custom_class {&lt;br /&gt;
    function class_method() {&lt;br /&gt;
        echo &#039;foo&#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Always use () when creating new instances even if constructor does not need any parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$instance = new some_custom_class();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you want an plain object of no particular class, for example when you are preparing some data to insert into the database with $DB-&amp;gt;insert_record, you should use the PHP standard class &#039;&#039;&#039;stdClass&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$row = new stdClass();&lt;br /&gt;
$row-&amp;gt;id    = $id;&lt;br /&gt;
$row-&amp;gt;field = &#039;something&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;table&#039;, $row);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Before Moodle 2.0, we used to define a class &#039;&#039;&#039;object&#039;&#039;&#039; extending stdClass, and use new object(); This has now been deprecated. Please use stdClass instead.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Functions and Methods===&lt;br /&gt;
&lt;br /&gt;
Function names should be simple English lowercase words, and start with the [[Frankenstyle]] prefix and plugin name to avoid conflicts between plugins. (Modules still use only plugin name for legacy reasons.) Words should be separated by underscores. &lt;br /&gt;
&lt;br /&gt;
Verbosity is encouraged: function names should be as illustrative as is practical to enhance understanding.&lt;br /&gt;
&lt;br /&gt;
Note there is no space between the function name and the following (brackets). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function forum_set_display_mode($mode = 0) {&lt;br /&gt;
    global $USER, $CFG;&lt;br /&gt;
         &lt;br /&gt;
    if ($mode) {&lt;br /&gt;
        $USER-&amp;gt;mode = $mode;&lt;br /&gt;
    } else if (empty($USER-&amp;gt;mode)) {&lt;br /&gt;
        $USER-&amp;gt;mode = $CFG-&amp;gt;forum_displaymode;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Function Parameters====&lt;br /&gt;
&lt;br /&gt;
Parameters are always simple lowercase English words (sometimes more than one, like $initialvalue), and should always have sensible defaults if possible. &lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;null&amp;quot; as the default value instead of &amp;quot;false&amp;quot; for situations like this where a default value isn&#039;t needed.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function foo($required, $optional = null)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, if an optional parameter is boolean, and its logical default value should be true, or false, then using true or false is acceptable.&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
&lt;br /&gt;
Variable names should always be easy-to-read, meaningful lower-case English words. If you really need more than one word then run them together, but keep them short as possible. Use &#039;&#039;&#039;plural&#039;&#039;&#039; names for arrays of objects. Use &#039;&#039;&#039;positive&#039;&#039;&#039; variables names always (allow, enable not prevent, disable).&lt;br /&gt;
&lt;br /&gt;
 GOOD: $quiz&lt;br /&gt;
 GOOD: $errorstring&lt;br /&gt;
 GOOD: $assignments (for an array of objects)&lt;br /&gt;
 GOOD: $i (but only in little loops)&lt;br /&gt;
 GOOD: $allowfilelocking = false&lt;br /&gt;
&lt;br /&gt;
 BAD: $Quiz&lt;br /&gt;
 BAD: $camelCase&lt;br /&gt;
 BAD: $aReallyLongVariableNameWithoutAGoodReason&lt;br /&gt;
 BAD: $error_string&lt;br /&gt;
 BAD: $preventfilelocking = true&lt;br /&gt;
&lt;br /&gt;
Core global variables in Moodle are identified using uppercase variables (ie $CFG, $SESSION, $USER, $COURSE, $SITE, $PAGE, $DB and $THEME).  Don&#039;t create any more!&lt;br /&gt;
&lt;br /&gt;
===Constants===&lt;br /&gt;
&lt;br /&gt;
Constants should always be in upper case, and always start with [[Frankenstyle]] prefix and plugin name (in case of activities the module name only for legacy reasons). They should have words separated by underscores. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;FORUM_MODE_FLATOLDEST&#039;, 1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Booleans and the null value===&lt;br /&gt;
&lt;br /&gt;
Use lower case for &#039;&#039;&#039;true&#039;&#039;&#039;, &#039;&#039;&#039;false&#039;&#039;&#039; and &#039;&#039;&#039;null&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Namespaces ===&lt;br /&gt;
&lt;br /&gt;
Namespaces are not required for any new code and there is no requirement to move non-namespaced classes to namespaces. If&lt;br /&gt;
namespaces are used - they must conform to these rules.&lt;br /&gt;
&lt;br /&gt;
Classes belonging to a namespace must be created in a classes directory inside a plugin (e.g. mod/forum/classes), or for core code,&lt;br /&gt;
in lib/classes or subsystemdir/classes.&lt;br /&gt;
&lt;br /&gt;
The classname and filename for all namespaced classes must conform to the&lt;br /&gt;
[[Automatic class loading|automatic class loading]] rules.&lt;br /&gt;
&lt;br /&gt;
Use at most one namespace declaration per file.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;? // This is a file mod/porridge/classes/local/equipment/spoon.php&lt;br /&gt;
&lt;br /&gt;
namespace mod_porridge\local\equipment;&lt;br /&gt;
&lt;br /&gt;
class spoon {&lt;br /&gt;
    // Your code here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End of file.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace mod_porridge\local\equipment;&lt;br /&gt;
&lt;br /&gt;
class spoon {&lt;br /&gt;
    // Your code here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace mod_porridge\local\procedures; // We are changing the namespace here, do not do it.&lt;br /&gt;
&lt;br /&gt;
class eat {&lt;br /&gt;
    // Another code here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End of file.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The namespace declaration may be preceded with a doc block.&lt;br /&gt;
&lt;br /&gt;
The [[Coding style#Classes|class naming]] rules also apply to the names for each level of namespace.&lt;br /&gt;
&lt;br /&gt;
The namespace declaration must be the first non-comment line in the file, followed by one blank line, followed by the (optional)&lt;br /&gt;
&amp;quot;use&amp;quot; statements, one per line, followed by one blank line.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;use&amp;quot; statements should be used to avoid repetition of long namespaces in the code.&lt;br /&gt;
&lt;br /&gt;
Do not import an entire namespace with a &amp;quot;use&amp;quot; statement, import individual classes only.&lt;br /&gt;
&lt;br /&gt;
Do not use named imports (&amp;quot;use XXX as YYY;&amp;quot;) unless it is absolutely required to resolve a conflict.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;use mod_porridge\local\equipment\spoon; // One class per line.&lt;br /&gt;
use mod_porridge\local\equipment\bowl; // One class per line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;use mod_porridge\local\equipment\spoon, mod_porridge\local\equipment\bowl; // Multiple classes per line.&lt;br /&gt;
use mod_porridge\local; // Importing an entire namespace.&lt;br /&gt;
use core; // Importing an entire namespace.&lt;br /&gt;
use mod_breakfast; // Importing an entire namespace.&lt;br /&gt;
use mod_porridge\local\equipment\spoon as silverspoon; // Named import with no good reason.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Never use the __NAMESPACE__ magic constant.&lt;br /&gt;
&lt;br /&gt;
Never use the &amp;quot;namespace&amp;quot; keyword anywhere but the namespace declaration.&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$obj = new namespace\Another();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not use bracketed &amp;quot;namespace&amp;quot; blocks.&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace {&lt;br /&gt;
    // Global scope.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namespaces MUST only be used for classes existing in a subfolder of &amp;quot;classes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For new classes - the maximum level of detail should be used when deciding the namespace.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace xxxx\yyyy; // xxxx is the component, yyyy is the api.&lt;br /&gt;
&lt;br /&gt;
class zzzz {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Never use a leading backslash (\) in &amp;quot;namespace&amp;quot; and &amp;quot;use&amp;quot; statements.&lt;br /&gt;
&lt;br /&gt;
Global functions called from namespaced code should never use a leading&lt;br /&gt;
backslash (\). Classes from outside the current scope use the leading backslash&lt;br /&gt;
or are imported by the &amp;quot;use&amp;quot; keyword. See&lt;br /&gt;
[http://www.php.net/manual/en/language.namespaces.fallback.php PHP manual] for&lt;br /&gt;
details.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace mod_breakfast\local;&lt;br /&gt;
&lt;br /&gt;
use moodle_url;&lt;br /&gt;
&lt;br /&gt;
echo get_string(&#039;goodmorning&#039;, &#039;mod_breakfast&#039;); // No leading backslash for global functions.&lt;br /&gt;
$url = new moodle_url(...); // Leading backslash not needed here because we imported it into our namespace via &amp;quot;use&amp;quot;.&lt;br /&gt;
$tasks = \core\task\manager::get_all_scheduled_tasks(); // Leading slash needed here.&lt;br /&gt;
$a = new \stdClass(); // Leading slash needed here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace \mod_breakfast; // The leading backslash should not be here.&lt;br /&gt;
&lt;br /&gt;
use \core\task\manager; // The leading backslash should not be here.&lt;br /&gt;
&lt;br /&gt;
\get_string(&#039;xxxx&#039;, &#039;yyyy&#039;); // The leading backslash should not be here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Parts of a namespace ====&lt;br /&gt;
&lt;br /&gt;
Given the following fully qualified name of a class:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;\&amp;lt;level1&amp;gt;\&amp;lt;level2&amp;gt;\&amp;lt;level3&amp;gt;\...\&amp;lt;classname&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There are clear rules for what is allowable at each level of namespace. Only the first level is mandatory. Nested namespaces are used when the class implements some core API or when the plugin maintainer want to organise classes to separate namespaces within the plugin - see rules regarding the level2 for details.&lt;br /&gt;
&lt;br /&gt;
==== Rules for level1 ====&lt;br /&gt;
&lt;br /&gt;
The first level MUST BE EITHER:&lt;br /&gt;
* a full component name (e.g. &amp;quot;\mod_forum&amp;quot;). All classes using namespaces in a plugin MUST be contained in&lt;br /&gt;
this level 1 namespace.&lt;br /&gt;
or&lt;br /&gt;
* &amp;quot;\core&amp;quot; for all core apis&lt;br /&gt;
&lt;br /&gt;
==== Rules for level2 ====&lt;br /&gt;
&lt;br /&gt;
The second level, when used, MUST BE EITHER:&lt;br /&gt;
* The short name of a core API (must be defined on https://docs.moodle.org/dev/API). The classes in this namespace must either implement or use the API in some way.&lt;br /&gt;
or&lt;br /&gt;
* &amp;quot;\local&amp;quot; for any other classes in a plugin, if the maintainer wants to organise them further (note that for most plugins, it&#039;s probably enough to have all their own classes in the root level1 namespace only).&lt;br /&gt;
&lt;br /&gt;
==== Rules for level3 ====&lt;br /&gt;
&lt;br /&gt;
There are no rules limiting what can be used as a level 3 namespace. This is where a plugin or addon can make extensive use of&lt;br /&gt;
namespaces with no chance of conflict with any other plugin or api, now and forever onwards.&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace mod_breakfast;                // Plugin&#039;s own namespace when not using nested namespaces (typical)&lt;br /&gt;
namespace mod_breakfast\local;          // Plugin&#039;s own namespace when using nested namespaces&lt;br /&gt;
namespace mod_breakfast\local\utils;    // Plugin&#039;s own namespace when using nested namespaces with further organisation&lt;br /&gt;
namespace mod_breakfast\event;          // Plugin&#039;s namespace to implement core API&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
namespace mymodule;                     // Violates the level1 rules - invalid component name&lt;br /&gt;
namespace mod_breakfast\myutilities;    // Violates the level2 rules - invalid core API name&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Since string performance is not an issue in current versions of PHP, the main criteria for strings is readability. &lt;br /&gt;
&lt;br /&gt;
===Single quotes===&lt;br /&gt;
&lt;br /&gt;
Always use single quotes when a string is literal, or contains a lot of double quotes (like HTML):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$a = &#039;Example string&#039;; &lt;br /&gt;
echo &#039;&amp;lt;span class=&amp;quot;&#039;.s($class).&#039;&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;; &lt;br /&gt;
$html = &#039;&amp;lt;a href=&amp;quot;http://something&amp;quot; title=&amp;quot;something&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Double quotes===&lt;br /&gt;
&lt;br /&gt;
These are a lot less useful in Moodle. Use double quotes when you need to include plain variables or a lot of single quotes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;&amp;lt;span&amp;gt;$string&amp;lt;/span&amp;gt;&amp;quot;; &lt;br /&gt;
$statement = &amp;quot;You aren&#039;t serious!&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Complex SQL queries should be always enclosed in double quotes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$sql = &amp;quot;SELECT e.*, ue.userid&lt;br /&gt;
          FROM {user_enrolments} ue&lt;br /&gt;
          JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = &#039;self&#039; AND e.customint2 &amp;gt; 0)&lt;br /&gt;
          JOIN {user} u ON u.id = ue.userid&lt;br /&gt;
         WHERE :now - u.lastaccess &amp;gt; e.customint2&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variable substitution===&lt;br /&gt;
&lt;br /&gt;
Variable substitution can use either of these forms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$greeting = &amp;quot;Hello $name, welcome back!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$greeting = &amp;quot;Hello {$name}, welcome back!&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===String concatenation===&lt;br /&gt;
&lt;br /&gt;
Strings must be concatenated using the &amp;quot;.&amp;quot; operator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$longstring = $several.$short.&#039;strings&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the lines are long, break the statement into multiple lines to improve readability.  In these cases, put the &amp;quot;dot&amp;quot; at the end of each line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string = &#039;This is a very long and stupid string because &#039;.$editorname.&lt;br /&gt;
          &amp;quot; couldn&#039;t think of a better example at the time.&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The dot operator may be used without any space to either side (as shown in the above examples), or with spaces on each side; whichever the developer prefers.&lt;br /&gt;
&lt;br /&gt;
===Language strings===&lt;br /&gt;
&lt;br /&gt;
====Capitals====&lt;br /&gt;
&lt;br /&gt;
Language strings should &amp;quot;Always look like this&amp;quot; and &amp;quot;Never Like This Example&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Capitals should only be used when:&lt;br /&gt;
# starting a sentence, or&lt;br /&gt;
# starting a proper name, like Moodle.&lt;br /&gt;
&lt;br /&gt;
====Structure====&lt;br /&gt;
&lt;br /&gt;
Strings should not be designed for UI concatenation, as it may cause problems in other languages.   Each string should stand alone.&lt;br /&gt;
&lt;br /&gt;
BAD:   &lt;br /&gt;
 $string[&#039;overduehandling&#039;] = &#039;When time expires&#039;;&lt;br /&gt;
 $string[&#039;overduehandlingautosubmit&#039;] = &#039;the attempt is submitted automatically&#039;;&lt;br /&gt;
 $string[&#039;overduehandlinggraceperiod&#039;] = &#039;there is a grace period in which to submit the attempt, but not answer more questions&#039;;&lt;br /&gt;
 $string[&#039;overduehandlingautoabandon&#039;] = &#039;that is it. The attempt must be submitted before time expires, or it is not counted&#039;;&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
 $string[&#039;overduehandling&#039;] = &#039;Time expiry behaviour&#039;;&lt;br /&gt;
 $string[&#039;overduehandlingautosubmit&#039;] = &#039;Unfinished attempts will be auto-submitted immediately&#039;;&lt;br /&gt;
 $string[&#039;overduehandlinggraceperiod&#039;] = &#039;Unfinished attempts have a short grace period to be submitted for grading&#039;;&lt;br /&gt;
 $string[&#039;overduehandlingautoabandon&#039;] = &#039;Unfinished attempts are immediately discarded&#039;;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
&lt;br /&gt;
===Numerically indexed arrays===&lt;br /&gt;
&lt;br /&gt;
When declaring indexed arrays with the array function, a trailing space must be added after each comma delimiter to improve readability:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$myarray = array(1, 2, 3, &#039;Stuff&#039;, &#039;Here&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Multi-line indexed arrays are fine, but pad each successive lines as above with an 8-space indent:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$myarray = array(&lt;br /&gt;
        1, 2, 3, &#039;Stuff&#039;, &#039;Here&#039;,&lt;br /&gt;
        $a, $b, $c, 56.44, $d, 500);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Associative arrays===&lt;br /&gt;
&lt;br /&gt;
Use multiple lines if this helps readability. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$myarray = array(&lt;br /&gt;
    &#039;firstkey&#039; =&amp;gt; &#039;firstvalue&#039;,&lt;br /&gt;
    &#039;secondkey&#039; =&amp;gt; &#039;secondvalue&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Classes==&lt;br /&gt;
&lt;br /&gt;
=== Class declarations ===&lt;br /&gt;
&lt;br /&gt;
* Classes must be named according to Moodle&#039;s naming conventions.&lt;br /&gt;
* The brace should always be written on the line beside the class name.&lt;br /&gt;
* Every class must have a documentation block that conforms to the PHPDocumentor standard.&lt;br /&gt;
* All code in a class must be indented with 4 spaces.&lt;br /&gt;
* Placing additional code in class files is permitted but discouraged. In such files, two blank lines must separate the class from any additional PHP code in the class file.&lt;br /&gt;
&lt;br /&gt;
: An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Documentation Block Here&lt;br /&gt;
 */&lt;br /&gt;
class sample_class {&lt;br /&gt;
    // All contents of class&lt;br /&gt;
    // must be indented 4 spaces.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Class member variables===&lt;br /&gt;
&lt;br /&gt;
Member variables must be named according to Moodle&#039;s variable naming conventions.&lt;br /&gt;
&lt;br /&gt;
Any variables declared in a class must be listed at the top of the class, above the declaration of any methods.&lt;br /&gt;
&lt;br /&gt;
The var construct is not permitted. Member variables always declare their visibility by using one of the &#039;&#039;&#039;private&#039;&#039;&#039;, &#039;&#039;&#039;protected&#039;&#039;&#039;, or &#039;&#039;&#039;public&#039;&#039;&#039; modifiers. Giving access to member variables directly by declaring them as public is permitted but discouraged in favor of accessor methods (set/get).&lt;br /&gt;
&lt;br /&gt;
==Functions and methods==&lt;br /&gt;
===Function and method declaration===&lt;br /&gt;
&lt;br /&gt;
Functions must be named according to the Moodle function naming conventions.&lt;br /&gt;
&lt;br /&gt;
Methods inside classes must always declare their visibility by using one of the private, protected, or public modifiers.&lt;br /&gt;
&lt;br /&gt;
As with classes, the brace should always be written on same line as the function name. &lt;br /&gt;
&lt;br /&gt;
Don&#039;t leave spaces between the function name and the opening parenthesis for the arguments.&lt;br /&gt;
&lt;br /&gt;
The return value must not be enclosed in parentheses. This can hinder readability, in additional to breaking code if a method is later changed to return by reference. &lt;br /&gt;
&lt;br /&gt;
Return should only be one data type. It is discouraged to have multiple return types&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Documentation Block Here&lt;br /&gt;
 */&lt;br /&gt;
class sample_class {&lt;br /&gt;
    &lt;br /&gt;
    /**&lt;br /&gt;
     * Documentation Block Here&lt;br /&gt;
     */&lt;br /&gt;
    public function sample_function() {&lt;br /&gt;
        // All contents of function&lt;br /&gt;
        // must be indented four spaces.&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Function and method usage===&lt;br /&gt;
&lt;br /&gt;
Function arguments should be separated by a single trailing space after the comma delimiter. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
three_arguments(1, 2, 3);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Control statements==&lt;br /&gt;
&lt;br /&gt;
In general, use white space liberally between lines and so on, to add clarity.&lt;br /&gt;
&lt;br /&gt;
===If / else===&lt;br /&gt;
&lt;br /&gt;
Put a space before and after the control statement in brackets, and separate the operators by spaces within the brackets.  Use inner brackets to improve logical grouping if it helps. &lt;br /&gt;
&lt;br /&gt;
Indent with four spaces. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Don&#039;t use elseif!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Always use braces (even if the block is one line and PHP doesn&#039;t require it).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($x == $y) {&lt;br /&gt;
    $a = $b;&lt;br /&gt;
} else if ($x == $z) {&lt;br /&gt;
    $a = $c;&lt;br /&gt;
} else {&lt;br /&gt;
    $a = $d;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Switch===&lt;br /&gt;
&lt;br /&gt;
Put a space before and after the control statement in brackets, and separate the operators by spaces within the brackets.  Use inner brackets to improve logical grouping if it helps. &lt;br /&gt;
&lt;br /&gt;
Always indent with four spaces.  Content under each case statement should be indented a further four spaces.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
switch ($something) {&lt;br /&gt;
    case 1:&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    case 2:&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
        break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Foreach===&lt;br /&gt;
&lt;br /&gt;
As above, uses spaces like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($objects as $key =&amp;gt; $thing) {&lt;br /&gt;
    process($thing);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ternary Operator===&lt;br /&gt;
&lt;br /&gt;
The ternary operator is only permitted to be used for &#039;&#039;&#039;short&#039;&#039;&#039;, &#039;&#039;&#039;simple to understand&#039;&#039;&#039; statements. If the statement can&#039;t be understood in one sentance, use an if statement instead.&lt;br /&gt;
&lt;br /&gt;
Whitespace must be used around the operators to make it clear where the operation is taking place.&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$username = isset($user-&amp;gt;username) ? $user-&amp;gt;username : &#039;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$toload = (empty($CFG-&amp;gt;navshowallcourses))?self::LOAD_ROOT_CATEGORIES:self::LOAD_ALL_CATEGORIES;&lt;br /&gt;
$coefstring = ($coefstring==&#039;&#039; or $coefstring==&#039;aggregationcoefextrasum&#039;) ? &#039;aggregationcoefextrasum&#039; : &#039;aggregationcoef&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Require / include==&lt;br /&gt;
&lt;br /&gt;
Each file that is accessed via browser should start by including the main config.php file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
require(__DIR__ . &#039;/../../config.php&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any other include/require should use an absolute path starting with &amp;lt;tt&amp;gt;$CFG-&amp;gt;dirroot&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;$CFG-&amp;gt;libdir&amp;lt;/tt&amp;gt; or path starting with __FILE__ or __DIR__. Relative includes starting with &amp;quot;../&amp;quot; can [http://uk.php.net/manual/en/function.include.php sometimes behave strangely under PHP], so it is safer to avoid them. Our CLI script must not use relative config.php paths starting with &amp;quot;../&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Includes should generally only be done at the top of files or inside functions/methods that need them. Using include/require in the middle of a file in global scope very hard to audit the security of the code.&lt;br /&gt;
&lt;br /&gt;
All other scripts with the exception of imported 3rd party libraries should use following code at the very top to prevent direct execution which might reveal error messages on misconfigured production servers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Documentation and comments==&lt;br /&gt;
&lt;br /&gt;
Code documentation explains the code flow and the purpose of functions and variables.  Use it whenever practical.&lt;br /&gt;
&lt;br /&gt;
==PHPDoc==&lt;br /&gt;
&lt;br /&gt;
Moodle stays as close as possible to &amp;quot;standard&amp;quot; [http://www.phpdoc.org/ PHPDoc format] to document our files, classes and functions.  This helps IDEs (like Netbeans or Eclipse) work properly for Moodle developers, and also allows us to generate web documentation automatically.&lt;br /&gt;
&lt;br /&gt;
PHPDoc has a number of tags that can be used in different places (files, classes and functions).  We have some particular rules for using them in Moodle that you must follow:&lt;br /&gt;
&lt;br /&gt;
===Types===&lt;br /&gt;
&lt;br /&gt;
Some of the tags below (@param, @return...) do require the specification of a valid php type and a description. All these are allowed:&lt;br /&gt;
&lt;br /&gt;
* PHP primitive types: int, bool, string...&lt;br /&gt;
* PHP complex types: array, stdClass (not Array, object).&lt;br /&gt;
* PHP classes:full or relative (to current namespace) class names.&lt;br /&gt;
* true, false, null (always lowercase).&lt;br /&gt;
* static: for methods returning a new instance of the child/caller class.&lt;br /&gt;
* self: for methods returning a new instance of the parent/called class.&lt;br /&gt;
* $this: for methods returning the current instance of the class.&lt;br /&gt;
* void: for methods with a explicit empty &amp;quot;return&amp;quot; statement.&lt;br /&gt;
&lt;br /&gt;
Also, there are some basic rules about how to use those types:&lt;br /&gt;
&lt;br /&gt;
* We use [http://php.net/manual/en/language.types.type-juggling.php short type names] (bool instead of boolean, int instead of integer).&lt;br /&gt;
* When multiple occurrences of a given &amp;quot;type&amp;quot; are used, it&#039;s highly recommended to document them as type[] instead of the simpler and less informative &amp;quot;array&amp;quot; alternative.&lt;br /&gt;
* When multiple different types are possible, they must be separated by a vertical bar (pipe).&lt;br /&gt;
* All primitives and keywords must be lowercase. The case of the complex types and classes must match the original.&lt;br /&gt;
&lt;br /&gt;
===Tags===&lt;br /&gt;
&lt;br /&gt;
==== @copyright ====&lt;br /&gt;
&lt;br /&gt;
These include the year and copyright holder (creator) of the original file.  Do not change these in existing files!&lt;br /&gt;
&lt;br /&gt;
  @copyright 2008 Kim Bloggs&lt;br /&gt;
&lt;br /&gt;
==== @license ====&lt;br /&gt;
&lt;br /&gt;
These must be GPL v3+ and use this format: &lt;br /&gt;
&lt;br /&gt;
  @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
&lt;br /&gt;
==== @param ====&lt;br /&gt;
&lt;br /&gt;
Don&#039;t put hyphens or anything fancy after the variable name, just a space.&lt;br /&gt;
&lt;br /&gt;
  @param [[#Types|type]] $name Description.&lt;br /&gt;
&lt;br /&gt;
==== @return ====&lt;br /&gt;
&lt;br /&gt;
The @return tag is mandatory if the function has a return statement, but can be left out if it does not have one.&lt;br /&gt;
&lt;br /&gt;
The description portion is optional, it can be left out if the function is simple and already describes what is returned.&lt;br /&gt;
&lt;br /&gt;
  @return [[#Types|type]] Description.&lt;br /&gt;
&lt;br /&gt;
==== @var ====&lt;br /&gt;
&lt;br /&gt;
The @var tag is used to document class properties.&lt;br /&gt;
&lt;br /&gt;
  @var [[#Types|type]] Description.&lt;br /&gt;
&lt;br /&gt;
Exceptionally, when none of the available [[#Types|type]] define the returned value, inline @ var phpdocs (within the body of the methods) are allowed clarifying the returned type. Don&#039;t abuse!&lt;br /&gt;
&lt;br /&gt;
==== @uses ====&lt;br /&gt;
&lt;br /&gt;
If a function uses die or exit, please add this tag to the docblock to help developers know this function could terminate the page:&lt;br /&gt;
&lt;br /&gt;
  @uses exit&lt;br /&gt;
&lt;br /&gt;
==== @access ====&lt;br /&gt;
&lt;br /&gt;
The access can be used to specify access control for an element&lt;br /&gt;
&lt;br /&gt;
# Should only be used when the method definition does not already specify access control.&lt;br /&gt;
# In the case of functions, specifying public access is redundant and so should be avoided.&lt;br /&gt;
&lt;br /&gt;
  @access private&lt;br /&gt;
&lt;br /&gt;
==== @package ====&lt;br /&gt;
&lt;br /&gt;
The package tag should always be used to label php files with the correct [[Frankenstyle]] component name.  Full rules are explained on that page, but in summary:&lt;br /&gt;
&lt;br /&gt;
# If the file is part of any component plugin, then use the plugin component name (eg &#039;&#039;&#039;mod_quiz&#039;&#039;&#039; or &#039;&#039;&#039;gradereport_xls&#039;&#039;&#039;)&lt;br /&gt;
# If the file is part of a core subsystem then it will be core_xxxx where xxxx is the name defined in get_core_subsystems().  (eg &#039;&#039;&#039;core_enrol&#039;&#039;&#039; or &#039;&#039;&#039;core_group&#039;&#039;&#039;)&lt;br /&gt;
# If the file is one of the select few files in core that are not part of a subsystem (such as lib/moodlelib.php) then it just as a package of &#039;&#039;&#039;core&#039;&#039;&#039;.&lt;br /&gt;
# Each file can only be part of ONE package.&lt;br /&gt;
&lt;br /&gt;
(We do not have standards for @subpackage at all.  You can use within your @package how you like.)&lt;br /&gt;
&lt;br /&gt;
  @package gradereport_xls&lt;br /&gt;
&lt;br /&gt;
==== @category ====&lt;br /&gt;
&lt;br /&gt;
We use @category only to highlight the public classes, functions or files that are part of one of our [[Core APIs]], or that provide good example implementations of a Core API.  The value must be one of the ones on the [[Core APIs]] page.  &lt;br /&gt;
&lt;br /&gt;
  @category preferences &lt;br /&gt;
&lt;br /&gt;
==== @since ====&lt;br /&gt;
&lt;br /&gt;
When adding a new classes or function to the Moodle core libraries (or adding a new method to an existing class), use a @since tag to document which version of Moodle it was added in. For example:&lt;br /&gt;
 &lt;br /&gt;
  @since Moodle 2.1&lt;br /&gt;
&lt;br /&gt;
==== @see ====&lt;br /&gt;
&lt;br /&gt;
If you want to refer the user to another related element (include, page, class, function, define, method, variable) then you can use @see.&lt;br /&gt;
 &lt;br /&gt;
  @see some_other_function()&lt;br /&gt;
&lt;br /&gt;
==== @link ====&lt;br /&gt;
&lt;br /&gt;
If you want to refer the user to an external URL, use @link.&lt;br /&gt;
&lt;br /&gt;
  @link https://docs.moodle.org/dev/Core_APIs&lt;br /&gt;
&lt;br /&gt;
==== inline @link ====&lt;br /&gt;
&lt;br /&gt;
Occasionally you might want to refer to something else inline within your text, say in a function description.  For these cases you can use an inline @link (with an element name OR a URL) and it looks like this:&lt;br /&gt;
&lt;br /&gt;
   /**&lt;br /&gt;
    * This function uses {@link get_string()} to obtain the currency names...&lt;br /&gt;
    * .....&lt;br /&gt;
&lt;br /&gt;
==== @deprecated ====&lt;br /&gt;
&lt;br /&gt;
When deprecating an old API, use a @deprecated tag to document which version of Moodle it was deprecated in, and add @todo and @see if possible.  Make sure to mention relevant MDL issues.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * ...&lt;br /&gt;
 * @deprecated since Moodle 2.0 MDL-12345 - please do not use this function any more.   &lt;br /&gt;
 * @todo MDL-22334 This will be deleted in Moodle 2.2.&lt;br /&gt;
 * @see class_name::new_function()&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If it is important that developers update their code, consider also adding a debugging(&#039;...&#039;, DEBUG_DEVELOPER); call to repeat the deprecated message. If the old function can no longer be supported at all, you may have to throw a coding_exception. There are examples of the various options in lib/deprecatedlib.php.&lt;br /&gt;
&lt;br /&gt;
==== @throws ====&lt;br /&gt;
&lt;br /&gt;
This tag is valid and can be used optionally to indicate the method or function will throw and exception. This is to help developers know they may have to handle the exceptions from such functions.&lt;br /&gt;
&lt;br /&gt;
===Files===&lt;br /&gt;
&lt;br /&gt;
All files that contain PHP code should contain, without any blank line after the php open tag, a full GPL copyright statement at the top, plus a SEPARATE docblock right under it containing a:&lt;br /&gt;
&lt;br /&gt;
# short one-line description of the file&lt;br /&gt;
# longer description of the file&lt;br /&gt;
# @package tag (required)&lt;br /&gt;
# @category tag (only when everything in the file is related to one of the [[Core APIs]])&lt;br /&gt;
# @copyright (required)&lt;br /&gt;
# @license (required)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is a one-line short description of the file.&lt;br /&gt;
 *&lt;br /&gt;
 * You can have a rather longer description of the file as well,&lt;br /&gt;
 * if you like, and it can span multiple lines.&lt;br /&gt;
 *&lt;br /&gt;
 * @package    mod_mymodule&lt;br /&gt;
 * @category   backup&lt;br /&gt;
 * @copyright  2008 Kim Bloggs&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
&lt;br /&gt;
All classes must have a complete docblock like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Short description for class.&lt;br /&gt;
 *&lt;br /&gt;
 * Long description for class (if any)...&lt;br /&gt;
 *&lt;br /&gt;
 * @package    mod_mymodule&lt;br /&gt;
 * @copyright  2008 Kim Bloggs&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(NOTE that classes that are fundamental to core APIs will also need a @category tag)&lt;br /&gt;
&lt;br /&gt;
The exception are files containing only one class and nothing else. In that case the class is covered by the file docblock and adding an explicit class docblock is optional.&lt;br /&gt;
&lt;br /&gt;
===Properties===&lt;br /&gt;
&lt;br /&gt;
All properties should have a docblock with the following minimum information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class example {&lt;br /&gt;
    /** @var string This variable does something */&lt;br /&gt;
    protected $something;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class example {&lt;br /&gt;
    /** &lt;br /&gt;
     * This variable does something and has a very long description which can&lt;br /&gt;
     * wrap on multiple lines&lt;br /&gt;
     * @var string &lt;br /&gt;
     */&lt;br /&gt;
    protected $something;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Even if there are several properties all sharing something in common, do not use [http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#basics.docblocktemplate DocBlock templates]. Instead, document every property explicitly as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class zebra {&lt;br /&gt;
    /** @var int The number of white stripes */&lt;br /&gt;
    protected $whitestripes = 0;&lt;br /&gt;
&lt;br /&gt;
    /** @var int The number of black stripes */&lt;br /&gt;
    protected $blackstripes = 0;&lt;br /&gt;
&lt;br /&gt;
    /** @var int The number of red stripes */&lt;br /&gt;
    protected $redstripes = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Constants===&lt;br /&gt;
&lt;br /&gt;
Class constants should be documented in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class sam {&lt;br /&gt;
   /**&lt;br /&gt;
    * This is used when Sam is in a good mood.&lt;br /&gt;
    */&lt;br /&gt;
   const MOOD_GOOD = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Functions===&lt;br /&gt;
&lt;br /&gt;
All functions and methods should have a complete docblock like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * The description should be first, with asterisks laid out exactly&lt;br /&gt;
 * like this example. If you want to refer to a another function,&lt;br /&gt;
 * use @see as below.   If it&#039;s useful to link to Moodle&lt;br /&gt;
 * documentation on the web, you can use a @link below or also &lt;br /&gt;
 * inline like this {@link https://docs.moodle.org/dev/something}&lt;br /&gt;
 * Then, add descriptions for each parameter and the return value as follows.&lt;br /&gt;
 *&lt;br /&gt;
 * @see clean_param()&lt;br /&gt;
 * @param int   $postid The PHP type is followed by the variable name&lt;br /&gt;
 * @param array $scale The PHP type is followed by the variable name&lt;br /&gt;
 * @param array $ratings The PHP type is followed by the variable name&lt;br /&gt;
 * @return bool A status indicating success or failure&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exception is overridden methods not changing the purpose of the parent one, nor the meaning of the arguments or return values. In this case you should omit the comment completely. Use of the @inheritdoc or @see tags is explicitly forbidden as a replacement for any complete docblock.&lt;br /&gt;
&lt;br /&gt;
===Defines===&lt;br /&gt;
&lt;br /&gt;
All defines should be documented in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * PARAM_INT - integers only, use when expecting only numbers.&lt;br /&gt;
 */&lt;br /&gt;
define(&#039;PARAM_INT&#039;, &#039;int&#039;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * PARAM_ALPHANUM - expected numbers and letters only.&lt;br /&gt;
 */&lt;br /&gt;
define(&#039;PARAM_ALPHANUM&#039;, &#039;alphanum&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Inline comments===&lt;br /&gt;
&lt;br /&gt;
Inline comments must use the &amp;quot;// &amp;quot; (2 slashes + whitespace) style, laid out neatly so that it fits among the code and lines up with it. The first line of the comment must begin with a capital letter (or a digit, or &#039;...&#039;) and the comment must end with a proper punctuation character. Permitted final characters are &#039;.&#039;, &#039;?&#039; or &#039;!&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function forum_get_ratings_mean($postid, $scale, $ratings = null) {&lt;br /&gt;
    if (!$ratings) {&lt;br /&gt;
&lt;br /&gt;
        $ratings = array();     // Initialize the empty array.&lt;br /&gt;
&lt;br /&gt;
        $rates = $DB-&amp;gt;get_records(&#039;forum_ratings&#039;, array(&#039;post&#039; =&amp;gt; $postid));&lt;br /&gt;
&lt;br /&gt;
        // ... then process each rating in&lt;br /&gt;
        // turn.&lt;br /&gt;
        foreach ($rates as $rate) {&lt;br /&gt;
            do_something_with($rate);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Do we need to tidy up?&lt;br /&gt;
        if (!empty($rates))&lt;br /&gt;
            // 42 more things happen here!&lt;br /&gt;
            finsh_up();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GOOD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Comment explaining this piece of code.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
BAD:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/*  Comment explaining this piece of code. */&lt;br /&gt;
# Comment explaining this piece of code. &lt;br /&gt;
// comment explaining this piece of code (without capital letter and punctuation)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If your comment is due to some MDL issue, please feel free to include the correct MDL-12345 in your comment.  This makes it easier to track down decisions and discussions about things.&lt;br /&gt;
&lt;br /&gt;
====Using TODO====&lt;br /&gt;
&lt;br /&gt;
This is especially important if you know an issue still exists in that code that should be dealt with later.  Use a TODO along with a MDL code to mark this.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// TODO MDL-12345 This works but is a bit of a hack and should be revised in future.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a big task that is nearly done, apart a few TODOs, and you really want to mark the big task as finished, then you should file new tracker tasks for each TODO and change the TODOs comments to point at the new issue numbers.&lt;br /&gt;
&lt;br /&gt;
(The script .../lib/simpletest/todochecker.php in Moodle 2.0 will check this. Requires an admin login. This is a new requirement, see MDL-19772)&lt;br /&gt;
&lt;br /&gt;
===CVS keywords===&lt;br /&gt;
&lt;br /&gt;
We have stopped using CVS keywords such as $Id$ in Moodle 2.0 completely.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
Use exceptions to report errors, especially in library code.&lt;br /&gt;
&lt;br /&gt;
Throwing an exception has almost exactly the same effect as calling print_error, but it is more flexible. For example, the caller can choose to catch the exception and handle it in some way. It also makes it easier to write unit tests.&lt;br /&gt;
&lt;br /&gt;
Any exception that is not caught will trigger an appropriate call to print_error, to report the problem to the user.&lt;br /&gt;
&lt;br /&gt;
Do not abuse exceptions for normal code flow. Exceptions should only be used in erroneous situations.&lt;br /&gt;
&lt;br /&gt;
===Exception classes===&lt;br /&gt;
&lt;br /&gt;
We have a set of custom exception classes. The base class is moodle_exception. You will see that the arguments you pass to new moodle_exception(...) are very similar to the ones you would pass to print_error. There are more specific subclasses for particular types of error.&lt;br /&gt;
&lt;br /&gt;
To get the full list of exception types, search for the regular expression &#039;class +\w+_exception +extends&#039; or ask your IDE to list all the subclasses of moodle_exception.&lt;br /&gt;
&lt;br /&gt;
Where appropriate, you should create new subclasses of moodle_exception for use in your code.&lt;br /&gt;
&lt;br /&gt;
A few notable exception types:&lt;br /&gt;
; moodle_exception : base class for exceptions in Moodle. Use this when a more specific type is not appropriate.&lt;br /&gt;
; coding_exception : thrown when the problem seems to be caused by a developer&#039;s mistake. Often thrown by core code that interacts with plugins. If you throw an exception of this type, try to make the error message helpful to the plugin author, so they know how to fix their code.&lt;br /&gt;
; dml_exception (and subclasses) : thrown when a database query fails.&lt;br /&gt;
; file_exception : thrown by the File API.&lt;br /&gt;
&lt;br /&gt;
==Dangerous functions and constructs==&lt;br /&gt;
PHP includes multiple questionable features that are highly discouraged because they are very often source of serious security problems.&lt;br /&gt;
&lt;br /&gt;
# do not use &#039;&#039;eval()&#039;&#039; function - language packs are exception (to be solved in future).&lt;br /&gt;
# do not use &#039;&#039;preg_replace()&#039;&#039; with /e modifier - use callbacks in order to prevent unintended PHP execution.&lt;br /&gt;
# do not use backticks for shell command execution.&lt;br /&gt;
# do not use &#039;&#039;goto&#039;&#039;, neither the operator neither labels - use other programming techniques to control the execution flow.&lt;br /&gt;
&lt;br /&gt;
==Policy about coding-style only fixes==&lt;br /&gt;
&lt;br /&gt;
Way before this coding-style guide was defined and agreed, a lot of code had been written already. Obviously such code does not follow the coding-style at all. While &#039;&#039;&#039;we enforce conformance for all the new code&#039;&#039;&#039;, we are not paranoid about the status of all the previous one.&lt;br /&gt;
&lt;br /&gt;
In any case, in order to normalize the (progressive, non-critical) transition, a policy issue (MDL-43233) was created and agreed about. And these are the rules to apply to coding-style only changes:&lt;br /&gt;
&lt;br /&gt;
# Related coding-style changes (same lines, a variable within a method/function, adjacent comments...) within a real issue are allowed.&lt;br /&gt;
# Unrelated coding-style changes (other methods, blocks of code, comments...) within a real issue are only accepted for main and in a separate commit.&lt;br /&gt;
# Coding-style only issues are only accepted for main along the first 2 months of every cycle.&lt;br /&gt;
&lt;br /&gt;
== Git commits ==&lt;br /&gt;
&lt;br /&gt;
Constructing a clear and informative commit is an important aspect of the craft of creating open source code and the history of commits is a vital part of the communication between developers. Time should be spent on crafting commits appropriately and using the git tools to achieve it.&lt;br /&gt;
&lt;br /&gt;
Git commits should:&lt;br /&gt;
&lt;br /&gt;
* Tell a perfect, cleaned up version of the history. As if the code was written perfectly first time.&lt;br /&gt;
* Include the MDL-xxxx issue number associated with the change&lt;br /&gt;
* Include CODE AREA when appropriate. (Code area, is just a short name for the area of Moodle that this change affects. It can be a component name if that makes sense, but does not have to be.)&lt;br /&gt;
* Be formatted as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MDL-xxxx CODE AREA: short summary (72 chars soft limit)&lt;br /&gt;
&lt;br /&gt;
Blank line on line 2, followed by an unlimited length detailed explanation&lt;br /&gt;
following if necessary. This section might include the motivation for the change&lt;br /&gt;
and contrast it with the previous behaviour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Git commits should not:&lt;br /&gt;
* Include changes from bugs found and fixed before integration&lt;br /&gt;
* Include many separate revisions to the same lines of code for a single issue&lt;br /&gt;
* Arbitrarily split when part of a atomic set of logical changes&lt;br /&gt;
&lt;br /&gt;
For more guidance, see [[Commit cheat sheet]]&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
This document was drawn from the following sources:&lt;br /&gt;
&lt;br /&gt;
# The original [https://docs.moodle.org/en/index.php?title=Development:Coding&amp;amp;oldid=53799 Coding guidelines] page&lt;br /&gt;
# The [http://framework.zend.com/manual/en/coding-standard.html Zend guidelines] and &lt;br /&gt;
# Feedback from all core Moodle developers&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Javascript/Coding_style|Javascript coding style]]&lt;br /&gt;
* [[SQL coding style]]&lt;br /&gt;
* [[Coding]]&lt;br /&gt;
* [[CodeSniffer]]&lt;br /&gt;
* [http://moodle.org/plugins/view.php?plugin=local_codechecker Code Checker plugin]&lt;br /&gt;
* [[Accessibility#Moodle-related_accessibility_coding_guidelines|Accessibility coding guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|Coding style]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=String_API&amp;diff=64095</id>
		<title>String API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=String_API&amp;diff=64095"/>
		<updated>2024-04-10T11:13:13Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
The String API is how you get language text strings to use in the user interface. It handles internationalisation issues, and will use a number of settings and environment variables to present the best text to every user. Moodle has a mechanism that allows a number of places to be searched (in order) to find language strings. This enables language strings to be packaged with plugins and avoids the step of having to copy the language files over to the language directory when a plugin is installed.&lt;br /&gt;
&lt;br /&gt;
Moodle also provide general string functions like substr, strlen etc. for multibyte safe, string operations. It uses mbstring or iconv for UTF-8 strings and falls back to typo3.&lt;br /&gt;
==Basic concepts==&lt;br /&gt;
When it is required to lookup a string, two basic items of information are required.&lt;br /&gt;
# The component providing the string.&lt;br /&gt;
# The identifier of the string.&lt;br /&gt;
Example: The function call &amp;lt;tt&amp;gt;get_string(&#039;editingquiz&#039;, &#039;mod_quiz&#039;)&amp;lt;/tt&amp;gt; will return &amp;quot;Editing quiz&amp;quot; if the current language is English, or relevant translation of the text. Here the string identifier is &amp;quot;editingquiz&amp;quot; and the string is provided by the &amp;quot;mod_quiz&amp;quot; component (that is the Quiz activity module).&lt;br /&gt;
===Adding language file to plugin===&lt;br /&gt;
Language support for plugin(s) is added by creating a &#039;&#039;&#039;lang/en/&#039;&#039;&#039; subdirectory in the plugin directory and putting the plugin&#039;s English string file there. The name of the string file is supposed to follow the plugin&#039;s [[Frankenstyle|component name]], so that it is something like &amp;lt;tt&amp;gt;plugintype_pluginname.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The default &amp;quot;en&amp;quot; language is the [[:en:Language FAQ#Which_is_the_official_language_for_Moodle.3F|Australian English]] which is same as the British English when it comes to spelling and grammar. American English is a separate language pack &amp;quot;en_us&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
There is no need to include languages other than the default English, as almost all approved [https://lang.moodle.org/mod/forum/discuss.php?d=2485 plugin strings will be automatically imported into AMOS] for translation by the language packs translators.&lt;br /&gt;
===Adding a string to the language file===&lt;br /&gt;
Strings are defined via the associative array &amp;lt;tt&amp;gt;$string&amp;lt;/tt&amp;gt; provided by the string file. The array key is the string identifier, the value is the string text in the given language.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;editingquiz&#039;] = &#039;Editing quiz&#039;;&lt;br /&gt;
$string[&#039;editingquiz_help&#039;] = &#039;Help for editing quiz&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Run-time parameters===&lt;br /&gt;
Strings can define placeholders like &amp;lt;tt&amp;gt;{$a}&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;{$a-&amp;gt;foobar}&amp;lt;/tt&amp;gt;. These placeholders are replaced with a value passed to the &amp;lt;tt&amp;gt;get_string()&amp;lt;/tt&amp;gt; function call.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Strings defined in the language file.&lt;br /&gt;
$string[&#039;greeting&#039;] = &#039;Dear {$a}&#039;;&lt;br /&gt;
$string[&#039;info&#039;] = &#039;There are {$a-&amp;gt;count} new messages from {$a-&amp;gt;from}.&#039;;&lt;br /&gt;
&lt;br /&gt;
// Passing values for the placeholders.&lt;br /&gt;
echo get_string(&#039;greeting&#039;, &#039;tool_example&#039;, &#039;Mr. Anderson&#039;);&lt;br /&gt;
echo get_string(&#039;info&#039;, &#039;tool_example&#039;, [&#039;count&#039; =&amp;gt; 42, &#039;from&#039; =&amp;gt; &#039;Mr. Smith&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Help strings ==&lt;br /&gt;
Help strings are texts that are displayed in the help tooltips. There are certain conventions on how to define them.&lt;br /&gt;
[[Image:Roles help popup.png|thumb|Help popup containing &amp;quot;More help&amp;quot; link]] Help strings names start with the string name of the setting to which they apply, so that they are kept together in the language file.&lt;br /&gt;
* &#039;&#039;stringname&#039;&#039; - identifier of the string we provide the help for, may be used as a title of the help popup&lt;br /&gt;
* &#039;&#039;stringname_help&#039;&#039; - string with the help text&lt;br /&gt;
* &#039;&#039;stringname_link&#039;&#039; - an optional string naming a path in Moodle Docs, only if required, calculated just like the link in the footer to go to the right language etc, and shown after the help text in the popup as a link with an icon to &amp;quot;More help...&amp;quot;. These strings don&#039;t usually need to be translated. (They were previously hidden in the AMOS UI then unhidden in 2023. See MDLSITE-7236 for details.)&lt;br /&gt;
* &#039;&#039;stringname_desc&#039;&#039; - an admin setting description replacing the legacy &#039;&#039;configstringname&#039;&#039;&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;submissionsize&#039;] = &#039;Submission size&#039;;&lt;br /&gt;
$string[&#039;submissionsize_help&#039;] = &#039;Blah blah blah some useful text, optionally using Markdown syntax&#039;;&lt;br /&gt;
$string[&#039;submissionsize_link&#039;] = &#039;mod/workshop/submission&#039;;&lt;br /&gt;
$string[&#039;submissionsize_desc&#039;] = &#039;Default value for submission size. This value will be pre-filled and can be blah blah ...&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Help string text should be short and simple - two small paragraphs maximum with no headings, no links, no bold, no tables etc.&lt;br /&gt;
&lt;br /&gt;
[[:en:Markdown|Markdown]] can be used for some basic formatting of strings with the &amp;quot;_help&amp;quot; suffix. It is recommended to stick to paragraphs and lists only. Markdown can only be used for help strings, not for other language strings.&lt;br /&gt;
=== More help links ===&lt;br /&gt;
To display the optional &#039;&#039;More help...&#039;&#039; link at the bottom of the help popup, a string with the &amp;quot;_link&amp;quot; suffix must exist beside the relevant &amp;quot;_help&amp;quot; string. These link strings should consist of a short relative path like &#039;component/thing&#039; (eg. &#039;mod/folder/view&#039; or &#039;group/import&#039;). This gets turned into a link to MoodleDocs in the user&#039;s language, and for the appropriate Moodle version.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;groupimport_link&#039;] = &#039;group/import&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
will make a link to something like &amp;lt;nowiki&amp;gt;&#039;https://docs.moodle.org/32/en/group/import&#039;&amp;lt;/nowiki&amp;gt; (if you are an English user of Moodle 3.2). This page in turn should be a redirect page to the actual page providing the info. Note the &amp;lt;nowiki&amp;gt;&#039;https://docs.moodle.org&#039;&amp;lt;/nowiki&amp;gt; part comes from $CFG-&amp;gt;docroot.&lt;br /&gt;
&lt;br /&gt;
The second option is that you can give an absolute link, if you want, and that will be used unmodified.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;patronising_link&#039;] = &amp;lt;nowiki&amp;gt;&#039;http://lmgtfy.com/?q=Moodle+for+dummies&#039;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This case is detected by seeing if the string starts with &amp;lt;nowiki&amp;gt;http:// or https://&amp;lt;/nowiki&amp;gt;. This option is useful if the documentation for your plugin is hosted at Github wiki, for example.&lt;br /&gt;
&lt;br /&gt;
The third option is to start the link with &amp;lt;tt&amp;gt;%%WWWROOT%%&amp;lt;/tt&amp;gt;. That is replaced by &amp;lt;tt&amp;gt;$CFG-&amp;gt;wwwroot&amp;lt;/tt&amp;gt;. This is useful for contributed plugins that want to keep the help within the plugin.&lt;br /&gt;
=== Words for roles ===&lt;br /&gt;
The following words should be used in the English (en) help strings whenever it is necessary to refer to people with particular roles in a generic sense.&lt;br /&gt;
* Participants - all people with a role&lt;br /&gt;
* Teachers - people with some sort of a facilitation/editing role&lt;br /&gt;
* Students - people primarily there to learn&lt;br /&gt;
* Users - people across the site&lt;br /&gt;
([[User:Martin Dougiamas|Martin Dougiamas]] 16:13, 20 April 2010 (UTC): I&#039;m not entirely comfortable with this choice even though I just re-confirmed it, as I&#039;d prefer to be using words like facilitator/moderator to subtly and continually promote a less transmissionist pedgagogy and I know many Moodle users would agree. However, I think these terms are far more commonly used in the community and in discussion, and from the point of view that we need to build a consistent system for usability they are less distracting and better for documentation.)&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
String functions are defined in &lt;br /&gt;
# lib/moodlelib.php - locale related functions&lt;br /&gt;
# lib/textlib.class.php - general string functions (substr, strlen etc.)&lt;br /&gt;
==Functions and examples==&lt;br /&gt;
There are three main functions, used in moodle for getting/displaying the localised string, based on user preferred language.&lt;br /&gt;
===get_string()===&lt;br /&gt;
Returns a localised string for current user.&lt;br /&gt;
&lt;br /&gt;
Example for displaying string &amp;quot;This is my plug-in&amp;quot; in any language that supports on your site, then you need to use the following identifier in language file (located in appropriate lang directory)&lt;br /&gt;
   $string[&#039;plugintitle&#039;] = &#039;This is my plug-in&#039;;&lt;br /&gt;
If you want to display this string in any supported language, then you would use this function.&lt;br /&gt;
   echo get_string(&#039;plugintitle&#039;, &#039;module_pluginlangfilename&#039;);&lt;br /&gt;
If you want to substitute value in the language string then use &#039;&#039;&#039;{$a}&#039;&#039;&#039; for substituting value. $a is an object, string or number that can be used within translation strings. The variable has to be $a, and it has to be in single quotes. For example, if you want to display answer number in Drag &amp;amp; drop plugin then add&lt;br /&gt;
   $string[&#039;answerno1&#039;] = &#039;Answer {$a}&#039;; //Substituting string/integer&lt;br /&gt;
   $string[&#039;answerno2&#039;] = &#039;Answer {$a-&amp;gt;name}&#039;; //Substituting object member&lt;br /&gt;
in qtype_dragdrop.php (Drag &amp;amp; Drop language file). And call it using&lt;br /&gt;
   //Get string by substituting integer. &lt;br /&gt;
   get_string(&#039;answerno1&#039;, &#039;qtype_dragdrop&#039;, $number);&lt;br /&gt;
   //Get string by substituting object member integer&lt;br /&gt;
   $user-&amp;gt;number = 10;&lt;br /&gt;
   get_string(&#039;answerno2&#039;, &#039;qtype_dragdrop&#039;, $user);&lt;br /&gt;
In Moodle 2.3 there is a new argument to this function $lazyload. Setting $lazyload to true causes get_string to return a lang_string object rather than the string itself. &lt;br /&gt;
   $stringobject = get_string(&#039;answerno&#039;, &#039;qtype_dragdrop&#039;, $number, true);&lt;br /&gt;
The fetching of the string is then put off until the string object is first used. The object can be used by calling it&#039;s out method or by casting the object to a string, either directly e.g. &lt;br /&gt;
   (string)$stringobject &lt;br /&gt;
or indirectly by using the string within another string or echoing it out e.g.&lt;br /&gt;
   echo $stringobject;&lt;br /&gt;
return &amp;quot;&amp;lt;p&amp;gt;{$stringobject}&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
Note: using $lazyload and attempting to use the string as an array key will cause a fatal error as objects cannot be used as array keys.&lt;br /&gt;
===get_strings()===&lt;br /&gt;
Converts an array of string names to localised strings for a specific plugin. lazy loading is not supported in this function.&lt;br /&gt;
   $txt = get_strings(array(&#039;enable&#039;, &#039;disable&#039;, &#039;up&#039;, &#039;down&#039;, &#039;none&#039;), &#039;qtype_dragdrop&#039;);&lt;br /&gt;
   echo $txt-&amp;gt;up;  //Display localised string for up&lt;br /&gt;
   echo $txt-&amp;gt;down //Display localised string for down&lt;br /&gt;
===print_string()===&lt;br /&gt;
Prints out a translated string by using &#039;&#039;&#039;get_string()&#039;&#039;&#039; function&lt;br /&gt;
===lang_string class===&lt;br /&gt;
In Moodle 2.3 a special class (lang_string) is used to create an object representation of a string request. In this case string processing doesn&#039;t occur until the object is first used. The class was created especially to aid performance in areas where strings were required to be generated but were not necessarily used. As an example the admin navigation tree when generated uses over 1500 strings, of which normally only 1/3 are ever actually printed at any time. The performance advantage is achieved by not actually processing strings that aren&#039;t being used, as such reducing the processing required for the page.&lt;br /&gt;
&lt;br /&gt;
lang_string class can be used in two ways&lt;br /&gt;
# Setting $lazyload (fourth argument of the get_string function), to true.&lt;br /&gt;
   $string = get_string(&#039;yes&#039;, &#039;qtype_dragdrop&#039;, null, true);&lt;br /&gt;
# Direct instantiation&lt;br /&gt;
   $string = new lang_string(&#039;yes&#039;, &#039;qtype_dragdrop&#039;, null, &#039;en&#039;);&lt;br /&gt;
== String manager ==&lt;br /&gt;
Most of function listed above are just handful wrappers for the methods provided by the string manager class. Some strings related functionality is available only via directly calling the manager&#039;s methods.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$stringman = get_string_manager();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The factory function get_string_manager() returns singleton instance of &amp;lt;tt&amp;gt;core_string_manager_install&amp;lt;/tt&amp;gt; in early stages of the site installation, or instance of &amp;lt;tt&amp;gt;core_string_manager_standard&amp;lt;/tt&amp;gt; in all normal situations. These managers implement interface &amp;lt;tt&amp;gt;core_string_manager&amp;lt;/tt&amp;gt;. Methods provided by the interface are&lt;br /&gt;
;get_string():Returns the given component string localised in the given language. Can be used to obtain the translation of the string in the other language than the current user&#039;s language.&lt;br /&gt;
;string_exists():Does the given string actually exist? This is typically checked by a code like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if (get_string_manager()-&amp;gt;string_exists(&#039;stringidentifier&#039;, &#039;component_name&#039;)) {&lt;br /&gt;
    // Do something.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;string_deprecated():Has the string been deprecated? See [[String deprecation]] for details.&lt;br /&gt;
;get_list_of_countries():Returns a localised list of all country names, sorted by country keys.&lt;br /&gt;
;get_list_of_languages():Returns a localised list of languages, sorted by code keys.&lt;br /&gt;
;translation_exists():Checks if the translation exists for the given language.&lt;br /&gt;
;get_list_of_translations():Returns localised list of installed language packs.&lt;br /&gt;
;get_list_of_currencies():Returns localised list of known currencies.&lt;br /&gt;
;load_component_strings():Loads all strings for one component.&lt;br /&gt;
;reset_caches():Invalidates all caches, should the manager use some.&lt;br /&gt;
;get_revision():Returns string revision counter.&lt;br /&gt;
=== Custom string managers ===&lt;br /&gt;
{{Moodle 2.9}}Plugins can provide custom implementation of the string manager. This is supposed to be used in experimental and/or development scenarios only, not in typical production environment. See MDL-49361 for use cases and implementation details. An example of such an implementation can be found at [https://github.com/mudrd8mz/moodle-local_stringman moodle-local_stringman.git] repository.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Custom string manager class can be defined in the main config.php file.&lt;br /&gt;
$CFG-&amp;gt;customstringmanager = &#039;\local_stringman\dummy_string_manager&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==textlib (core_text) class==&lt;br /&gt;
textlib class provide pool of safe functions to operate on UTF-8 text. textlib provide set of static functions to operate on strings and gets included in setup.php&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.6}}In Moodle 2.6 the textlib class was renamed to &#039;&#039;&#039;core_text&#039;&#039;&#039;.&lt;br /&gt;
===asort()===&lt;br /&gt;
Locale aware sorting, the key associations are kept, values are sorted alphabetically.&lt;br /&gt;
===code2utf8===&lt;br /&gt;
Returns the utf8 string corresponding to the unicode value&lt;br /&gt;
===convert===&lt;br /&gt;
Converts the text between different encodings. It uses iconv extension with //TRANSLIT parameter, fall back to typo3&lt;br /&gt;
===encode_mimeheader===&lt;br /&gt;
Generate a correct base64 encoded header to be used in MIME mail messages.&lt;br /&gt;
===entities_to_utf8===&lt;br /&gt;
Converts all the numeric entities &amp;amp;#nnnn; or &amp;amp;#xnnn; to UTF-8&lt;br /&gt;
===specialtoascii===&lt;br /&gt;
Converts upper unicode characters to plain ascii, the returned string may contain unconverted unicode characters.&lt;br /&gt;
===strlen===&lt;br /&gt;
Multibyte safe strlen() function, uses iconv for utf-8, falls back to typo3.&lt;br /&gt;
===strpos===&lt;br /&gt;
Find the position of the first occurrence of a substring in a string. UTF-8 ONLY safe strpos(), uses iconv.&lt;br /&gt;
===strrpos===&lt;br /&gt;
Find the position of the last occurrence of a substring in a string. UTF-8 ONLY safe strrpos(), uses iconv.&lt;br /&gt;
===strtolower===&lt;br /&gt;
Multibyte safe strtolower() function, uses mbstring, falls back to typo3.&lt;br /&gt;
===strtotitle===&lt;br /&gt;
Makes first letter of each word capital - words must be separated by spaces.&lt;br /&gt;
===strtoupper===&lt;br /&gt;
Multibyte safe strtoupper() function, uses mbstring, falls back to typo3.&lt;br /&gt;
===substr===&lt;br /&gt;
Multibyte safe substr() function, uses iconv for utf-8, falls back to typo3.&lt;br /&gt;
===trim_utf8_bom===&lt;br /&gt;
Removes the BOM from unicode string. [http://unicode.org/faq/utf_bom.html more info]&lt;br /&gt;
===utf8_to_entities===&lt;br /&gt;
Converts all Unicode chars &amp;gt; 127 to numeric entities &amp;amp;#nnnn; or &amp;amp;#xnnn;&lt;br /&gt;
==FAQ==&lt;br /&gt;
===When should I use a lang_string object?===&lt;br /&gt;
The lang_string object is designed to be used in any situation where a string may not be needed, but needs to be generated. The admin navigation tree is a good example of where lang_string objects should be used. A more practical example would be any class that requires strings that may not be printed (after all classes get renderer by renderers and who knows what they will do ;))&lt;br /&gt;
===When should I not use a lang_string object?===&lt;br /&gt;
Don&#039;t use lang_strings when you are going to use a string immediately. There is no need as it will be processed immediately and there will be no advantage, and in fact perhaps a negative hit as a class has to be instantiated for a lang_string object, however get_string won&#039;t require that.&lt;br /&gt;
===Limitation of lang_string===&lt;br /&gt;
lang_string object cannot be used as an array offset. Doing so will result in PHP throwing an error. (You can use it as an object property!)&lt;br /&gt;
===How to compare strings properties in two object===&lt;br /&gt;
collatorlib_property_comparison class can be used to compare properties of two objects&lt;br /&gt;
===Should the colon sign be hard-coded or included in a language string?===&lt;br /&gt;
The colon sign should not be hard-coded because languages may use a different symbol, or have a space before or after the colon sign. Instead, the colon sign may be included in a language string, though please consider first if it is really necessary. A colon sign in a field label is not recommended. (MDL-12192 is for removing existing hard-coded colon signs.)&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Do NOT hard code any punctuation:&lt;br /&gt;
$string[&#039;fieldname&#039;] = &#039;Name&#039;;&lt;br /&gt;
&lt;br /&gt;
echo get_string(&#039;fieldname&#039;, &#039;mod_foobar&#039;) . &#039;: &#039; . $somevalue;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Slightly better with no hard coded colon:&lt;br /&gt;
$string[&#039;fieldname&#039;] = &#039;Name: &#039;;&lt;br /&gt;
&lt;br /&gt;
echo get_string(&#039;fieldname&#039;, &#039;mod_foobar&#039;) . $somevalue;&lt;br /&gt;
&lt;br /&gt;
// Better with no assumed word order:&lt;br /&gt;
$string[&#039;fieldname&#039;] = &#039;Name: {$a-&amp;gt;name}&#039;;&lt;br /&gt;
&lt;br /&gt;
echo get_string(&#039;fieldname&#039;, &#039;mod_foobar&#039;, [&#039;name&#039; =&amp;gt; $somevalue]);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changing or creating a new lang string?===&lt;br /&gt;
New strings were required in 1.x times when we did not have branches for translations. Since 2.0, for changes in main, structural and/or semantic modification of a string (such as adding or removing {$a} placeholders etc) is acceptable as such strings are highlighted in AMOS as outdated. Of course, if lang pack maintainers do not pay attention to it, mismatch can happen - but this is considered to be the lang pack bug.&lt;br /&gt;
&lt;br /&gt;
When a new string is introduced, the old one should be [[String deprecation | deprecated or removed]] so that unused strings do not accumulate.&lt;br /&gt;
:A) Basically I see it as (for main only issues):&lt;br /&gt;
:&lt;br /&gt;
:# Any change is allowed (semantic or structural). It does not have sense to keep the old string because there won&#039;t be use for it when the new Moodle version is released. So we can forget about the old one 100%. Of course if the string is radically different, then it may have sense to create a new, completely different string (and proceed with next point).&lt;br /&gt;
:# If for any reason we stop using any string (because a feature is out or because we have decided to create a new different string instead of change existing)), then:&lt;br /&gt;
:#* if the old string is really specific (not suitable for reuse) we can safely proceed to delete it,.&lt;br /&gt;
:#* If the string belongs to a plugin, IMO we can also proceed to delete it (reuse of plugin strings should not be allowed).&lt;br /&gt;
:#* But, if the string is generic (may be reused) and it&#039;s not part of a plugin then the string must be deprecated.&lt;br /&gt;
&lt;br /&gt;
:B) And, for issues involving stables, only small semantic changes are allowed. No structural, no deprecation and no deletion. Ever. If still something different must be shown it will be, always, via new string. When applied to main, these changes will also imply the [[String deprecation | standard old string deprecation]]. No CPY instruction will be performed between the old and the new strings (safest, easier, consistent behavior, no matter there are some cases where the instruction may be acceptable. Stop overthinking. Now!).&lt;br /&gt;
===User names placeholders===&lt;br /&gt;
Some strings may contain placeholders to display the user&#039;s name. Common examples include various email templates or welcome messages. Developers may be tempted to use just the user&#039;s firstname in such cases, to make the text feel informal and friendlier:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Do NOT do this.&lt;br /&gt;
$string[&#039;welcome&#039;] = &#039;Hello {$a}! Welcome to the course.&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
But some cultures or institutions may want the full name or last name to be used, rather than the first name. To enable sites to easily customise such strings and have lastname and alternatename placeholders available, the following pattern should be used.&lt;br /&gt;
&lt;br /&gt;
Let the language strings file for the given component define the default display of the name:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;welcome&#039;] = &#039;Hello {$a-&amp;gt;firstname}! Welcome to the course.&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Then in the file making use of the string:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$namefields = [&lt;br /&gt;
    &#039;fullname&#039; =&amp;gt; fullname($USER),&lt;br /&gt;
    &#039;alternativefullname&#039; =&amp;gt; fullname($USER, true),&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
foreach (\core_user\fields::get_name_fields() as $namefield) {&lt;br /&gt;
    $namefields[$namefield] = $USER-&amp;gt;{$namefield};&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
echo get_string(&#039;welcome&#039;, &#039;xyz_component&#039;, $namefields);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
That way, the string can be locally customised and use any combination of the following placeholders as needed: firstnamephonetic, lastnamephonetic, middlename, alternatename, firstname, lastname, fullname and alternativefullname.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Locally customised variant of the string.&lt;br /&gt;
$string[&#039;welcome&#039;] = &#039;Welcome to the course, {$a-&amp;gt;fullname}&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Output_functions]]&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[AMOS]]&lt;br /&gt;
* The section &#039;Language strings&#039; in [[Coding style]]&lt;br /&gt;
* [[String deprecation]]&lt;br /&gt;
* [[Improving English language strings]]&lt;br /&gt;
[[Category:API]]&lt;br /&gt;
[[Category:Language]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Commit_cheat_sheet&amp;diff=64094</id>
		<title>Commit cheat sheet</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Commit_cheat_sheet&amp;diff=64094"/>
		<updated>2024-04-10T11:11:38Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can consider this page as a list to check before you submit a patch for inclusion into Moodle.&lt;br /&gt;
&lt;br /&gt;
== Split your work into a logical set of patches ==&lt;br /&gt;
&lt;br /&gt;
Keep in mind that your commits will be reviewed before they are accepted. If the patch does one clear thing and does it well, the review process is fun. Git allows you to prepare patches on your branch into a sequence of logical steps. For example, when changing some API, divide the change into two steps. In the first commit, change the API. In the following commit, change all places that use the API. &amp;lt;tt&amp;gt;git rebase -i&amp;lt;/tt&amp;gt; is one of the commands you can use to do this.&lt;br /&gt;
&lt;br /&gt;
== Provide clear commit messages ==&lt;br /&gt;
&lt;br /&gt;
Consider the commit message as an email for the developer who would explore the change in the future. We recommend to follow common Git guidelines for formatting. The first line of commit message is generally treated as commit subject and should not exceed 72 characters. Include the MDL issue number and the area/component at the beginning of the subject line. Please note that &#039;code area&#039; refers to the code areas being affected by this commit - correct the MDL&#039;s components reported against if needed. If you are writing more than one line, the second line must be empty. All the lines should though wrap at the 72nd mark. We can only hardly follow the [https://www.google.com/?q=git%2050/72%20rule 50/72 rule] in Moodle given the extra information expected at first (subject) line.&lt;br /&gt;
&lt;br /&gt;
    MDL-xxxxx code area: short description of the patch&lt;br /&gt;
    &lt;br /&gt;
    The subject line is followed by an empty line and then a paragraph or two of&lt;br /&gt;
    a longer description follows if necessary. This longer description is useful&lt;br /&gt;
    for issues with longer history of comments in the linked MDL so that it&lt;br /&gt;
    summarizes the patch without the need to go through the whole discussion.&lt;br /&gt;
    &lt;br /&gt;
    Obviously, avoid messages like &amp;quot;as agreed in the chat&amp;quot; as they will become&lt;br /&gt;
    useless after a relatively short time.&lt;br /&gt;
&lt;br /&gt;
Most of Git tools are optimised for this format and they can display the log of commits best then.&lt;br /&gt;
&lt;br /&gt;
::Tip: the command &amp;lt;tt&amp;gt;git log --no-merges&amp;lt;/tt&amp;gt; will show you recent commit messages. Hopefully those are all good examples to copy.&lt;br /&gt;
&lt;br /&gt;
== Names in the commit message ==&lt;br /&gt;
&lt;br /&gt;
Retain the authorship of the patch. If the patch was submitted by someone else - for example a community member who published it in the tracker or in a forum - use the --author parameter. Make sure that your &#039;&#039;real&#039;&#039; name and contact email are recorded in patch. We use real names written in capital letters like &amp;quot;John Smith&amp;quot;. Please do not use names like &amp;lt;strike&amp;gt;&amp;quot;john smith&amp;quot;, &amp;quot;John S&amp;quot;, &amp;quot;johnny7887&amp;quot;&amp;lt;/strike&amp;gt;. If you use --author parameter, apply the same rules for the name of the author. See almost any Git tutorial on how to set your name and email in the global Git configuration.&lt;br /&gt;
&lt;br /&gt;
=== Creating a commit with multiple authors ===&lt;br /&gt;
&lt;br /&gt;
If your work is the result of collaborative work, you can use the [https://docs.github.com/en/github/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors github convention] to credit other authors.&lt;br /&gt;
&lt;br /&gt;
Rebase all the commits into a single commit, and add the mention &#039;&#039;Co-authored-by: Firstname Lastname &amp;lt;email&amp;gt;&#039;&#039; at the end of the commit message. You must credit only one author per line. You don&#039;t need to add yourself in the commit message.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/moodle/moodle/commit/fbb219617b5&lt;br /&gt;
&lt;br /&gt;
== Provide clear and operational instructions to test your patch ==&lt;br /&gt;
&lt;br /&gt;
In the tracker issue, please describe how the change can be tested. Please avoid vague phrases like &amp;quot;Make sure there is no regression in the core&amp;quot; or &amp;quot;Test all places where XXX is used&amp;quot;. Also, try to avoid requiring resources that are really difficult to gather, if possible - as in &amp;quot;Use production data from a server with 100.000+ students&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
If you have permission, edit the tracker issue and put the testing instructions into the &amp;quot;Testing instructions&amp;quot; field. If you do not have permission to edit that field, then write them in a comment on the tracker issue.&lt;br /&gt;
&lt;br /&gt;
It helps if you state your estimation of the testing difficulty so that testers can pick issues for them:&lt;br /&gt;
&lt;br /&gt;
;Easy : (average community member should be able to test it) - can be tested pretty easily via the web interface only at a public test site&lt;br /&gt;
;Moderate : (knowledgeable administrator should be able to test it) - requires local installation, for example to test some 1.9 -&amp;gt; 2.0 upgrade steps or some non-standard environment (for example MNet features, specific platform etc)&lt;br /&gt;
;Hard : (development skills are required to test it) - for example may require data hacking at SQL level to simulate data corruption or modifying the code to reproduce the problem&lt;br /&gt;
&lt;br /&gt;
Example testing instructions:&lt;br /&gt;
&lt;br /&gt;
    (difficulty: easy, requires teacher access to a course)&lt;br /&gt;
    1. Log in as a teacher and go to a course&lt;br /&gt;
    2. Turn editing mode on&lt;br /&gt;
    3. TEST: Make sure that the control icons appear next to the activity titles&lt;br /&gt;
    4. Turn editing mode off&lt;br /&gt;
    5. TEST: Make sure that the control icons are not displayed now&lt;br /&gt;
&lt;br /&gt;
== Introducing new strings ==&lt;br /&gt;
&lt;br /&gt;
Firstly, think twice and try to think in a non-English language. Any string you introduce is supposed to be translated by translators who usually do it for free in their own time. Do not waste their time by using get_string() for debugging messages that are likely to almost never appear. It is warmly recommended to let Helen review your strings before you submit them. This way we can keep the terminology and the style consistent. When introducing new strings, keep them alphabetically sorted. Using a self-descriptive names of the string identifier and the placeholder properties helps the translators to guess the context. Compare the following&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;grade&#039;] = &#039;Grade {$a}&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;maxgradevalue&#039;] = &#039;Grade {$a-&amp;gt;value}&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the first case, it is pretty difficult to guess whether the &amp;quot;Grade&amp;quot; in the string is a noun (as in &amp;quot;Grade 12/30&amp;quot;) or a verb (as in &amp;quot;Grade submission&amp;quot;). In many languages, the translation depends on it. The second case is more self-descriptive as it indicates that the placeholder will contain a value.&lt;br /&gt;
&lt;br /&gt;
Another good example of how _not_ to name string identifiers would be something like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$string[&#039;post&#039;] = &#039;Post&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that there is no clue if the &amp;quot;post&amp;quot; here is used as a noun (e.g. describing one particular forum post) or a verb (such as an action of posting into a forum). In many languages, the translation is different for either case.&lt;br /&gt;
&lt;br /&gt;
See [[Help strings]] if you are introducing a new help string.&lt;br /&gt;
&lt;br /&gt;
== Include AMOS script in the commit if needed ==&lt;br /&gt;
&lt;br /&gt;
If you change the identifier of a string or split a string into two forks, provide a script for AMOS in the commit message. Since Moodle 2.0, the translations are kept on separated branches again. The AMOS plugin at http://lang.moodle.org tracks the changes in string files and automatically records modifications, additions and removals of strings. Therefore strings can be re-worded freely on stable branches and should be removed from the main branch if they are not needed any more (do not remove strings from stable branches).&lt;br /&gt;
&lt;br /&gt;
If you change the identifier of the string (that is the key in the $string array), move the string from one file to another or you are introducing a new string as a copy of some current one, you should provide instructions for AMOS so that the action can be applied in all language packs. That will save valuable translators&#039; time. Instructions for AMOS are being put into the commit message of a commit that modifies the original English string files. The commit message containing such a script may look like this:&lt;br /&gt;
&lt;br /&gt;
    MDL-xxxxx code area: short description of the patch&amp;lt;br /&amp;gt;&lt;br /&gt;
    It is recommended to leave a blank line between the commit message and the&lt;br /&gt;
    script block.&amp;lt;br /&amp;gt;&lt;br /&gt;
    AMOS BEGIN&lt;br /&gt;
     MOV [configfoobar,core_admin],[foobar_desc,core_admin]&lt;br /&gt;
     CPY [submission,mod_assignment],[submission,mod_workshop]&lt;br /&gt;
    AMOS END&lt;br /&gt;
&lt;br /&gt;
See [[Automated_Manipulation_of_Strings_2.0#AMOS_script]] for more details of the syntax. See [http://git.moodle.org/gw?p=moodle.git&amp;amp;a=search&amp;amp;h=HEAD&amp;amp;st=commit&amp;amp;s=AMOS+BEGIN the log history] real examples of usage.&lt;br /&gt;
&lt;br /&gt;
==Removing strings==&lt;br /&gt;
&lt;br /&gt;
When a new feature completely replaces an existing feature, any strings which are no longer used should be removed from the code in the main branch. See [[String deprecation]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Main version changes ==&lt;br /&gt;
&lt;br /&gt;
If your commit requires a change to the main version number in version.php (and corresponding upgrade in lib/db/upgrade.php), you should increment that version number by .01, and let integrators deal with merge conflicts (for example if multiple people that week submit several .01 updates).&lt;br /&gt;
&lt;br /&gt;
(Note there may be policies about avoiding the type of changes which require version.php updates, especially in stable branches.)&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Tracker_issue_versions&amp;diff=64093</id>
		<title>Tracker issue versions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Tracker_issue_versions&amp;diff=64093"/>
		<updated>2024-04-10T11:05:49Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here there are some notes about how we handle both the affected and fix versions fields in the Tracker. To be applied along the whole [[Process]].&lt;br /&gt;
&lt;br /&gt;
=== Some general and simple rules ===&lt;br /&gt;
&lt;br /&gt;
* When &#039;&#039;&#039;filling &amp;quot;affected versions&amp;quot;&#039;&#039;&#039; (creating an issue or triaging it, usually) it&#039;s interesting to add there &#039;&#039;&#039;as many versions as possible&#039;&#039;&#039; (as far as they are affected, of course). And ideally not more than &#039;&#039;&#039;1 version by branch&#039;&#039;&#039; (i.e. don&#039;t put 3.6.1 and 3.6.2 together, the former alone is enough).&lt;br /&gt;
* When &#039;&#039;&#039;filling &amp;quot;fix versions&amp;quot;&#039;&#039;&#039; (usually as part of the integration process) a simple rule must be observed: &#039;&#039;&#039;&amp;quot;or stables or main&amp;quot;&#039;&#039;&#039;. Never mix them in the same issue. The idea beyond that is to avoid presenting in release notes for the next major release something that has been already fixed in the latest stable minor.&lt;br /&gt;
&lt;br /&gt;
=== Must fix versions ===&lt;br /&gt;
&lt;br /&gt;
Part of the process, some weeks before X.Y freeze, the corresponding &amp;quot;Must fix for X.Y&amp;quot; version is created. That version is critical to be able to detect, filter and organize all the issues that need to be fixed before release. Some important points about the handling of those &amp;quot;must fix&amp;quot; versions:&lt;br /&gt;
* They must be &#039;&#039;&#039;added to the &amp;quot;fix versions&amp;quot;&#039;&#039;&#039; field. That&#039;s their correct place (there is a [https://tracker.moodle.org/issues/?filter=20021 filter in charge of detecting wrong uses], in order to proceed to fix them).&lt;br /&gt;
* Once the issue is integrated, the &amp;quot;Must fix for X.Y&amp;quot; version &#039;&#039;&#039;must be removed&#039;&#039;&#039;.&lt;br /&gt;
* Once the release happens, there must be ZERO &amp;quot;must-fix&amp;quot; issues and &#039;&#039;&#039;the version is archived&#039;&#039;&#039; as part of the release process.&lt;br /&gt;
* Issues having a &amp;quot;must-fix&amp;quot; fix version &#039;&#039;&#039;must be given absolute priority&#039;&#039;&#039; within the process.&lt;br /&gt;
&lt;br /&gt;
=== Regression versions ===&lt;br /&gt;
&lt;br /&gt;
At the same time that a major X.Y version is packaged and released, its corresponding &amp;quot;X.Y regressions&amp;quot; version is created. That version is important to mark and track all the issues (on creation or triaging) that are a direct regression caused by the X.Y release. Some important points about the use of those &amp;quot;regression&amp;quot; versions:&lt;br /&gt;
* They must be &#039;&#039;&#039;added to the &amp;quot;affected versions&amp;quot;&#039;&#039;&#039; field. That&#039;s their correct place (there is a [https://tracker.moodle.org/issues/?filter=21627 filter in charge of detecting wrong uses], in order to proceed to fix them).&lt;br /&gt;
* They &#039;&#039;&#039;are not removed&#039;&#039;&#039; once an issue is fixed. They remain there, in the &amp;quot;affected versions&amp;quot; field, forever.&lt;br /&gt;
* Eventually, once a &#039;&#039;&#039;given X.Y version falls out of support&#039;&#039;&#039; and given that there are ZERO unresolved issues with a &amp;quot;X.Y regression&amp;quot; version, &#039;&#039;&#039;the version is archived&#039;&#039;&#039;.&lt;br /&gt;
* Issues having a &amp;quot;regressions&amp;quot; affected version &#039;&#039;&#039;should be given high priority&#039;&#039;&#039; within the process.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Tracker]]&lt;br /&gt;
* [[Bug triage]]&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Tracker]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_versions&amp;diff=64092</id>
		<title>Moodle versions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_versions&amp;diff=64092"/>
		<updated>2024-04-10T11:03:55Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Moodle versions and branches==&lt;br /&gt;
&lt;br /&gt;
Understanding the Moodle versioning scheme will help you when using our repositories to get your code (e.g. for an [[:en:Upgrading|upgrade]]).  Knowing the correct versions is also very useful when reporting bugs in our [http://tracker.moodle.org tracker].&lt;br /&gt;
&lt;br /&gt;
[[Image:versions.png|thumb|left|668px|Schema of Moodle source code branches, versions and maturity levels]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Major and minor versions ==&lt;br /&gt;
&lt;br /&gt;
Moodle version numbers consist of three numbers separated by a dot, for example 1.9.11 or 2.0.2. The first two numbers, like 1.9 or 2.0, represent the &#039;&#039;major version&#039;&#039;. The third number distinguishes &#039;&#039;minor versions&#039;&#039; within the same major version. When a new major version is released, it starts with the minor version set to 0 (zero). So Moodle 2.0.1 was the first minor update of Moodle 2.0.0.&lt;br /&gt;
&lt;br /&gt;
Generally, the Moodle HQ team maintains the two most recent major versions of Moodle (a notable exception to the rule was for Moodle 1.9 which was supported much longer).&lt;br /&gt;
&lt;br /&gt;
== Versions and branches ==&lt;br /&gt;
&lt;br /&gt;
Moodle developers use the source code management (SCM) system &#039;&#039;&#039;&#039;Git&#039;&#039;&#039;&#039; to track changes in the code. As in many SCMs, the history of changes in Git is represented via so called branches. You can consider a branch as a labeled sequence of source code changes.&lt;br /&gt;
&lt;br /&gt;
There is a branch created for every major version of Moodle. All Moodle 1.9 versions come from MOODLE_19_STABLE branch and all Moodle 2.0 versions come from MOODLE_20_STABLE branch. There is also a main development branch called &amp;quot;main&amp;quot; that holds the changes for the next future version. At the moment, the changes on the main branch will be included in Moodle 2.1 release.&lt;br /&gt;
&lt;br /&gt;
== Releases ==&lt;br /&gt;
&lt;br /&gt;
Since version 2.0, Moodle aims to release the new major version every six months or so. See [[Roadmap]] page for a schedule.&lt;br /&gt;
&lt;br /&gt;
Minor versions are released every two months, including both bugs and security issues fixed. See [[Releases#General release calendar|Releases]] page for more details and information. &lt;br /&gt;
&lt;br /&gt;
In the meantime between two releases, Moodle HQ team publish updates for the most recent stable versions. These updates are published every week, usually on Thursday. They are known as &#039;&#039;weekly builds&#039;&#039; and are identified by a small increment in the version and a build date like [https://git.moodle.org/gw?p=moodle.git;a=commitdiff;h=d8b0be3eb38b8b7991af470776cfb15d30d43de6 20200723]. That is a timestamp in a form YYYYMMDD when the weekly build was released. These weekly builds are labelled with a version number suffixed with a plus sign. So 3.9.1+ denotes some weekly build extending the 3.9.1 minor release.&lt;br /&gt;
&lt;br /&gt;
== Source code maturity levels ==&lt;br /&gt;
&lt;br /&gt;
During its life cycle, the Moodle code branch goes through several maturity levels.&lt;br /&gt;
* At the beginning, the branch is considered as being in &#039;&#039;alpha&#039;&#039; state. During this period, new features are added to the branch. API and database structure may change as needed. These versions are intended mainly for developers as nothing is guaranteed (the version may or may not install and upgrade, for example).&lt;br /&gt;
* When it is decided that no new feature will be added to the branch (so called feature freeze), &#039;&#039;beta&#039;&#039; maturity level is reached. Developers focus on testing, bugs fixing and stabilizing the branch.&lt;br /&gt;
* When all known critical and blocker bugs are fixed and no new bugs are reported for some time of testing, a preview version of the branch can be released as so called release candidate. When the first release candidate version (RC1) has been published, &#039;&#039;release candidate&#039;&#039; maturity level is reached. During this period, several RC versions can be issued, for example 2.1RC1, 2.1RC2, 2.1RC3 etc.&lt;br /&gt;
* Finally, the new major version is released and the branch reaches &#039;&#039;stable&#039;&#039; maturity level. From now on, the database structure and API do not change on this branch. A corresponding MOODLE_xx_STABLE is created and minor versions and weekly builds are created off it.&lt;br /&gt;
&lt;br /&gt;
==Version numbers==&lt;br /&gt;
&lt;br /&gt;
Each plugin&#039;s version.php file can specify a minimum version of Moodle required for the plugin to work, for example&lt;br /&gt;
&lt;br /&gt;
 $plugin-&amp;gt;version = 2011080200;&lt;br /&gt;
 $plugin-&amp;gt;requires = 2011070101;&lt;br /&gt;
&lt;br /&gt;
For the version numbers related to each release, see the [[Releases]] page.&lt;br /&gt;
&lt;br /&gt;
==How to increment version numbers in core==&lt;br /&gt;
&lt;br /&gt;
In Moodle core, when we branch from main, we also branch version numbers. That means that no version number in a stable branch should ever be higher than on main (or a higher branched version). &lt;br /&gt;
&lt;br /&gt;
The version number is constructed as &#039;&#039;&#039;YYYYMMDDRR.XX&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;YYYYMMDD&#039;&#039;&#039; is the date of the branching point. If on main, a branch has not happened, so it should be set to the current date. Otherwise it should not be changed (left as it was)&lt;br /&gt;
* &#039;&#039;&#039;RR&#039;&#039;&#039; is the release increment. This is the incremental counter for changes on a single branch or day (if in main).&lt;br /&gt;
* &#039;&#039;&#039;XX&#039;&#039;&#039; is the micro increment. This &#039;fraction increment&#039; was introduced when after we realised that it might be possible to have more than 99 upgrade steps on a stable branch (in the RR increment). It tends to only be used in the main version number file.&lt;br /&gt;
&lt;br /&gt;
===Rules for  stable branches===&lt;br /&gt;
&lt;br /&gt;
* If a &#039;micro increment&#039; (.XX) exists&lt;br /&gt;
** Developers should only increment the &#039;micro increment&#039; &#039;XX&#039;&lt;br /&gt;
** The integration team reserve the use of &#039;RR&#039; to branch between point releases.&lt;br /&gt;
* If a &#039;micro increment&#039; (.XX) does not exist&lt;br /&gt;
** Please increment the RR.&lt;br /&gt;
&lt;br /&gt;
===Rules for main===&lt;br /&gt;
* You must increment the whole version number to the current date.&lt;br /&gt;
* So, on 6th February 2013, the version number is set to: &#039;&#039;&#039;2013020600.00&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Why we branch versions ===&lt;br /&gt;
Imagine the following problem scenario:&lt;br /&gt;
# Moodle 2.4 is released, mod_forum is set to version 2012120300&lt;br /&gt;
# In main only, Eloy updates drops a DB field in an upgrade step and sets the moodle version to 2013010100&lt;br /&gt;
# In 2.4.1 and main, Dan fixes a problem in a capability definition and sets the version in both branches to 2013010200. (note: Oh no! we&#039;ve incorrectly changed the branching date for the entire future 2.4.x!)&lt;br /&gt;
# Moodle 2.5 is released and the mod_forum is set to version 2013060100&lt;br /&gt;
# After the release,  Helen updates her Moodle from Moodle 2.4.1 to 2.5.&lt;br /&gt;
&lt;br /&gt;
The implications of Dan changing the 2.4.x version to 2013010200 in step 3, means that Eloy&#039;s upgrade step from 2 will never get run. &#039;&#039;&#039;This is very bad!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===I know that there are no changes between STABLE and main, can I set the version number as the same? ===&lt;br /&gt;
Not for core plugins, sorry. There are too many developers working on the same code and it prevents accidents if we avoid doing this for core.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Releases]]&lt;br /&gt;
* [[:en:Git for Administrators|Git for Administrators]]&lt;br /&gt;
* http://download.moodle.org&lt;br /&gt;
&lt;br /&gt;
[[es:Versiones de Moodle]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Maintaining_Moodle_customisations_with_Git&amp;diff=64091</id>
		<title>Maintaining Moodle customisations with Git</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Maintaining_Moodle_customisations_with_Git&amp;diff=64091"/>
		<updated>2024-04-10T11:00:33Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: master2main&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{draft}}&lt;br /&gt;
&lt;br /&gt;
Git makes it very easy to maintain local customisations to Moodle alongside updates from the official Moodle repository.&lt;br /&gt;
This page assumes you installed Moodle following [[Installing Moodle from Git repository]]. It also assumes you understand basic version control principles (repositories, branches, conflicts) and have a basic working knowledge of Git.&lt;br /&gt;
&lt;br /&gt;
First, from your moodle directory, create a branch of &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; which will contain your customised Moodle. This is the branch you&#039;ll publish to other servers.&lt;br /&gt;
 git checkout main&lt;br /&gt;
 git checkout -b mycustommoodle&lt;br /&gt;
&lt;br /&gt;
 Switched to a new branch &#039;mycustommoodle&#039;&lt;br /&gt;
Next, create a new branch for developing your customisation, and move to that branch:&lt;br /&gt;
 git checkout -b myfeature&lt;br /&gt;
&lt;br /&gt;
 Switched to a new branch &#039;myfeature&#039;&lt;br /&gt;
This will give you a seperate copy of the Moodle code to work on without affecting the main branch. It&#039;s not recommended that you do this on your production server, as it will cause the code to be available immediately as it&#039;s saved.&lt;br /&gt;
&lt;br /&gt;
Do your customisations, add any new files to git, and commit the changes&lt;br /&gt;
 git add .&lt;br /&gt;
 git status&lt;br /&gt;
 git commit -m &amp;quot;Description of the change&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Switch back to the &amp;lt;tt&amp;gt;mycustommoodle&amp;lt;/tt&amp;gt; branch and merge the changes&lt;br /&gt;
 git checkout mycustommoodle&lt;br /&gt;
 git merge myfeature&lt;br /&gt;
Any future development can take place on the myfeature branch, and be merged into mycustommoodle in this way&lt;br /&gt;
&lt;br /&gt;
Even after local modifications have been made, you can pull in updates from the official git repository&lt;br /&gt;
 git checkout main&lt;br /&gt;
 git fetch&lt;br /&gt;
 git merge origin/main&lt;br /&gt;
 git checkout mycustommoodle&lt;br /&gt;
 git merge main&lt;br /&gt;
&lt;br /&gt;
=== Conflicts ===&lt;br /&gt;
If you create a local modification to a file, and that same file is modified in the official repository, you may find that a conflict is created when you do &amp;lt;tt&amp;gt;git merge origin/main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To resolve this, you will need to find the conflicts (the attempt to merge will tell you where they are) and resolve them.  The [http://www.kernel.org/pub/software/scm/git/docs/git-merge.html|&amp;lt;tt&amp;gt;git merge&amp;lt;/tt&amp;gt; man page] has more information on the presentation and resolution of conflicts.&lt;br /&gt;
&lt;br /&gt;
After the conflict is resolved, you&#039;ll need to commit the resolved files.&lt;br /&gt;
 git commit -a&lt;br /&gt;
Once a conflict has been resolved, even if you keep your local modification over the upstream modification, there wont be a conflict next time you merge.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
; Moodle forum discussions&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=168094 GIT help needed]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=165236 Best way to manage CONTRIB code with GIT]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167063 Handy Git tip for tracking 3rd-party modules and plugins]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167730 Moodle Git repositories]&lt;br /&gt;
&lt;br /&gt;
; External resources &lt;br /&gt;
* [http://www.kernel.org/pub/software/scm/git/docs/everyday.html Everyday GIT With 20 Commands Or So]&lt;br /&gt;
* [http://gitref.org/ Git Reference]&lt;br /&gt;
* [http://progit.org/book/ Pro Git book]&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64089</id>
		<title>Writing PHPUnit tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64089"/>
		<updated>2024-03-25T15:26:35Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: (amend commitid)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.3}}&lt;br /&gt;
&lt;br /&gt;
Moodle PHPUnit integration is designed to allow easy adding of new tests. At the start of each test the state is automatically reset to fresh new installation (unless explicitly told not to reset).&lt;br /&gt;
=Namespaces=&lt;br /&gt;
All the stuff under **/tests directories is [[Coding style#Namespaces_within_.2A.2A.2Ftests_directories|subject to some simple rules]] when using namespaces. They apply to test cases, fixtures, generators and, in general, any class within those directories. Take a look to them! (grand summary = 100% the same rules that are applied to **/classes directories).&lt;br /&gt;
=Testcase classes=&lt;br /&gt;
There are three basic test class that are supposed to used in all Moodle unit tests - basic_testcase, advanced_testcase and provider_testcase. &#039;&#039;&#039;Please note it is strongly recommended to put only one testcase into each class file.&#039;&#039;&#039;&lt;br /&gt;
;basic_testcase : Very simple tests that do not modify database, dataroot or any PHP globals. It can be used for example when trying examples from the official PHPUnit tutorial.&lt;br /&gt;
;advanced_testcase : Enhanced testcase class enhanced for easy testing of Moodle code.&lt;br /&gt;
;provider_testcase: Enhanced testcase class, enhanced for easy testing of [[Privacy API|Privacy Providers]].&lt;br /&gt;
There is a fourth testcase class that is specially designed for testing of our Moodle database layer, it should not be used for other purposes.&lt;br /&gt;
== Assertions ==&lt;br /&gt;
The complete list of assertions can be found in the links below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle version&lt;br /&gt;
! PHPUnit version&lt;br /&gt;
!Links&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.11&lt;br /&gt;
| PHPUnit 9.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/9.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.10&lt;br /&gt;
| PHPUnit 8.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/8.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.7 - 3.9&lt;br /&gt;
| PHPUnit 7.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/7.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.4 - 3.6&lt;br /&gt;
| PHPUnit 6.5&lt;br /&gt;
|[https://phpunit.de/manual/6.5/en/assertions.html Documentation]&lt;br /&gt;
|}&lt;br /&gt;
==Sample plugin testcase==&lt;br /&gt;
PHPUnit tests are located in &amp;lt;tt&amp;gt;tests/*_test.php&amp;lt;/tt&amp;gt; files in your plugin, for example &amp;lt;tt&amp;gt;mod/myplugin/tests/sample_test.php&amp;lt;/tt&amp;gt;, the file should contain only one class that extends &amp;lt;tt&amp;gt;advanced_testcase&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class sample_test extends \advanced_testcase {&lt;br /&gt;
     public function test_adding() {&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, 1+2);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
See [[PHPUnit integration#Class and file naming rules]] for more information.&lt;br /&gt;
==Inclusion of Moodle library files==&lt;br /&gt;
If you want to include some Moodle library files you should always declare &#039;&#039;&#039;global $CFG&#039;&#039;&#039;. The reason is that testcase files may be included from non-moodle code which does not make the global $CFG available automatically.&lt;br /&gt;
==Automatic state reset==&lt;br /&gt;
By default after each test Moodle database and dataroot is automatically reset to the original state which was present right after installation. make sure to use $this-&amp;gt;resetAfterTest() to indicate that the database or changes of standard global variables are expected.&lt;br /&gt;
&lt;br /&gt;
If you received the error &amp;quot;Warning: unexpected database modification, resetting DB state&amp;quot; it is because the test is not using &amp;lt;tt&amp;gt;$this-&amp;gt;resetAfterTest()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class test_something extends \advanced_testcase {&lt;br /&gt;
     public function test_deleting() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;resetAfterTest(true);&lt;br /&gt;
         $DB-&amp;gt;delete_records(&#039;user&#039;);&lt;br /&gt;
         $this-&amp;gt;assertEmpty($DB-&amp;gt;get_records(&#039;user&#039;));&lt;br /&gt;
     }&lt;br /&gt;
     public function test_user_table_was_reset() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, $DB-&amp;gt;count_records(&#039;user&#039;, array()));&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Generators=&lt;br /&gt;
Tests that need to modify default installation may use generators to create new courses, users, etc. All examples on this page should be used from test methods of a test class derived from advanced_testcase.&lt;br /&gt;
&lt;br /&gt;
Note if you are using PHPUnit [https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers @dataProvider] functions to provide parameters to unit tests, you can not use the data generator or change the user etc in the data provider function. Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation.&lt;br /&gt;
==Creating users==&lt;br /&gt;
At the start of each test there are only two users present - guest and administrator. If you need to add more test accounts use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You may also specify properties of the user account, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user(array(&#039;email&#039;=&amp;gt;&#039;user1@example.com&#039;, &#039;username&#039;=&amp;gt;&#039;user1&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
By default no user is logged-in, use setUser() method to change current $USER value:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser($user1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Guest and admin accounts have a shortcut methods:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setGuestUser();&lt;br /&gt;
 $this-&amp;gt;setAdminUser();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Null can be used to set current user back to not-logged-in:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser(null);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating course categories==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $category1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $category2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category(array(&#039;name&#039;=&amp;gt;&#039;Some subcategory&#039;, &#039;parent&#039;=&amp;gt;$category1-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating courses==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 &lt;br /&gt;
 $category = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $course2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course(array(&#039;name&#039;=&amp;gt;&#039;Some course&#039;, &#039;category&#039;=&amp;gt;$category-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating activities==&lt;br /&gt;
Some activity plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php.&lt;br /&gt;
&lt;br /&gt;
Example of creation of new course with one page resource:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $generator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator(&#039;mod_page&#039;);&lt;br /&gt;
 $generator-&amp;gt;create_instance(array(&#039;course&#039;=&amp;gt;$course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The following is functionally the same, but a bit shorter:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $page = $this-&amp;gt;getDataGenerator()-&amp;gt;create_module(&#039;page&#039;, array(&#039;course&#039; =&amp;gt; $course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating cohorts==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Since 2.4 there the data generator supports creation of new cohorts.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $cohort = $this-&amp;gt;getDataGenerator()-&amp;gt;create_cohort();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Simplified user enrolments==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Instead of standard enrolment API it is possible to use simplified method in data generator. It is intended to be used with self and manual enrolment plugins.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid, &#039;manual&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating scales==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale(array(&#039;name&#039; =&amp;gt; $name, &#039;scale&#039; =&amp;gt; $scale, &#039;courseid&#039; =&amp;gt; $courseid, &#039;userid&#039; =&amp;gt; $userid, &#039;description&#039; =&amp;gt; description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating roles==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role(array(&#039;shortname&#039; =&amp;gt; $shortname, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; description, &#039;archetype&#039; =&amp;gt; $archetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating tags==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag(array(&lt;br /&gt;
    &#039;userid&#039; =&amp;gt; $userid, &lt;br /&gt;
    &#039;rawname&#039; =&amp;gt; $rawname,&lt;br /&gt;
    &#039;name&#039; =&amp;gt; $name, &lt;br /&gt;
    &#039;description&#039; =&amp;gt; $description, &lt;br /&gt;
    &#039;descriptionformat&#039; =&amp;gt; $descriptionformat,&lt;br /&gt;
    &#039;flag&#039; =&amp;gt; $flag&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Groups==&lt;br /&gt;
===Creating groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding users to groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid, &#039;component&#039; =&amp;gt; $component, &#039;itemid&#039; =&amp;gt; $itemid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding groups to groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping_group(array(&#039;groupingid&#039; =&amp;gt; $groupingid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Repositories==&lt;br /&gt;
===Creating repository instances===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating repository types===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include type generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository_type($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating grades==&lt;br /&gt;
===Grade categories===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Grade items===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;itemtype&#039; =&amp;gt; $itemtype, &#039;itemname&#039; =&amp;gt; $itemname, &#039;outcomeid&#039; =&amp;gt; $outcomeid, &#039;scaleid&#039; =&amp;gt; $scaleid, &#039;gradetype&#039; =&amp;gt; $gradetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Outcomes===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_outcome();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Other types of plugin==&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Any other type of plugin can have a generator. The generator class should extend component_generator_base, and then you can get an instance using $mygenerator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator($frankenstylecomponentname);&lt;br /&gt;
&lt;br /&gt;
For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.&lt;br /&gt;
=Long tests=&lt;br /&gt;
All standard test should execute as fast as possible. Tests that take a longer time to execute (&amp;gt;10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.&lt;br /&gt;
=Large test data=&lt;br /&gt;
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]&lt;br /&gt;
=Testing sending of messages=&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
You can temporarily redirect all messages sent via message_send() to a message sink object. This allows developers to verify that the tested code is sending expected messages.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first disable the use of transactions and then redirect the messaging into a new message sink, you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
$sink = $this-&amp;gt;redirectMessages();&lt;br /&gt;
//... code that is sending messages&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(3, count($messages));&lt;br /&gt;
//.. test messages were generated in correct order with appropriate content&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Testing sending of emails=&lt;br /&gt;
{{Moodle 2.6}}&lt;br /&gt;
You can temporarily redirect emails sent via email_to_user() to a email message sink object. This allows developers to verify that the tested code is sending expected emails.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first unset &#039;noemailever&#039; setting and then redirect the emails into a new message sink where you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
unset_config(&#039;noemailever&#039;);&lt;br /&gt;
$sink = $this-&amp;gt;redirectEmails();&lt;br /&gt;
//... code that is sending email&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(1, count($messages));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Logstores=&lt;br /&gt;
You can test events which were written to a logstore, but you must disable transactions, enable at least one valid logstore, and disable logstore buffering to ensure that the events are written to the database before the tests execute.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
set_config(&#039;enabled_stores&#039;, &#039;logstore_standard&#039;, &#039;tool_log&#039;);&lt;br /&gt;
set_config(&#039;buffersize&#039;, 0, &#039;logstore_standard&#039;);&lt;br /&gt;
get_log_manager(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Check your coverage=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests.&lt;br /&gt;
&lt;br /&gt;
Prior to Moodle 3.7, this coverage would load all files and generate coverage for everything regardless of whether that file could be covered at all, or whether it was intentionally covered.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.7 the &#039;&#039;&#039;phpunit.xml&#039;&#039;&#039; configuration contains generated coverage include and exclude information for each component.&lt;br /&gt;
==Generating include and exclude configuration==&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
You can programatically describe which files will be checked for coverage by creating a &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file alongside the tests that you are writing.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, a default configuration is applied for all plugins and it is not necessary to supply a coverage.php unless you wish to cover additional files.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file allows you to list include and exclude files and folders within the component being&lt;br /&gt;
tested. All paths specified are relative to the component being tested. For example, when working with &#039;&#039;&#039;mod_forum&#039;&#039;&#039; your&lt;br /&gt;
code will be in &#039;&#039;&#039;mod/forum&#039;&#039;&#039;, and its unit tests will be in &#039;&#039;&#039;mod/forum/tests/example_test.php&#039;&#039;&#039;. The coverage file&lt;br /&gt;
for this would be in &#039;&#039;&#039;mod/forum/tests/coverage.php&#039;&#039;&#039; and all paths specified would be relative to &#039;&#039;&#039;mod/forum&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to specify a combination of included files, included folders, excluded files, and excluded folders. This would allow you, for example, to include the entire &#039;&#039;&#039;classes&#039;&#039;&#039; directory, but exclude.a specific file or folder within it.&lt;br /&gt;
&lt;br /&gt;
The following is an example &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file from &#039;&#039;&#039;mod_forum&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Note: For Moodle versions 3.7 to 3.10, the [https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;amp;oldid=58177#Check_your_coverage syntax used] was slightly different.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also, note that you can better define which class or function each test is effectively covering by using the &amp;lt;tt&amp;gt;@covers&amp;lt;/tt&amp;gt; annotation as [https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#specifying-covered-code-parts described in the documention].&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, the following default configuration is applied:{{Moodle 4.0}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;tests/generator&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
        &#039;lib.php&#039;,&lt;br /&gt;
        &#039;locallib.php&#039;,&lt;br /&gt;
        &#039;renderer.php&#039;,&lt;br /&gt;
        &#039;rsslib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If a coverage.php file already exists, then the defaults will be added to the values already defined.&lt;br /&gt;
=Best practice=&lt;br /&gt;
There are several best practices, suggestions, and things to avoid which you should consider when writing unit tests. Some of these are described below.&lt;br /&gt;
==Code coverage==&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests and this is well supported since.Moodle 3.7. We recommend that you consider checking the coverage of your plugins when you write your code.&lt;br /&gt;
&lt;br /&gt;
We recommend that you explicitly set the @covers annotation as described in the [https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnit documentation].&lt;br /&gt;
==Keep use of resetAfterTest to a minimum==&lt;br /&gt;
Although many of the examples described above use the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;resetAfterTest&amp;lt;/syntaxhighlight&amp;gt; nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.&lt;br /&gt;
Generally speaking you should aim to write code which is mockable, and does not require real fixtures.&lt;br /&gt;
Use of resetAfterTest will also slow your tests down.&lt;br /&gt;
==Be careful with shared setUp and instance variables==&lt;br /&gt;
You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:&lt;br /&gt;
# If you create any fixtures in the setUp, or call the resetAfterTest function, these fixtures and conditions will apply for _all_ tests in the testsuite. You will not be able to add another test to the suite which does not require these conditions without those conditions being fulfilled anyway. This can lead to slow tests.&lt;br /&gt;
# PHPUnit creates an instance of each testcase during its bootstrap phase, and does not dispose of it for the lifetime of the test run. Anything which causes data to be stored as instance data within the testcase will be stored in memory until the _entire suite_ completes. This means that any fixture which is setup and not actively discarded will not be garbage collected and lead to memory bloat. In severe cases this can lead to memory exhaustion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing testcases which contain setUp which either generate data, or set resetAfterTest should be phased out, and no new cases should be introduced.&lt;br /&gt;
==Make use of the dataProvider functionality==&lt;br /&gt;
The dataProvider functionality of PHPUnit is an extremely powerful and useful feature which allows you to verify a function quickly and easily with a range of different conditions.&lt;br /&gt;
However, the following rules should be followed when using dataProviders:&lt;br /&gt;
* Keep addition of resettable data requiring resetAfterTest to a minimum - this will lead to many slow tests&lt;br /&gt;
* Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation. The dataProvider is called after the testSuite is instantiated, but before any tests are run. Each test will run a full setUp and tearDown, which will destroy any data which was created.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Test function accepts parameters passed from the specified data provider.&lt;br /&gt;
 *&lt;br /&gt;
 * @dataProvider foobar_provider&lt;br /&gt;
 * @param int $foor&lt;br /&gt;
 * @param int $bar&lt;br /&gt;
 */&lt;br /&gt;
public function test_foobar(int $foo, int $bar) {&lt;br /&gt;
    // Perform the tests here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Data provider for {@see self::test_foobar()}.&lt;br /&gt;
 *&lt;br /&gt;
 * @return array List of data sets - (string) data set name =&amp;gt; (array) data&lt;br /&gt;
 */&lt;br /&gt;
public function foobar_provider(): array {&lt;br /&gt;
    return [&lt;br /&gt;
        &#039;Same numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 42,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 42,&lt;br /&gt;
        ],&lt;br /&gt;
        &#039;Different numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 21,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 84,&lt;br /&gt;
        ],&lt;br /&gt;
    ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Extra test settings=&lt;br /&gt;
Usually the test should not interact with any external systems and it should work the same on all systems. But sometimes you need to specify some option for connection to external systems or system configuration. It is intentionally not possible to use $CFG settings from config.php.&lt;br /&gt;
&lt;br /&gt;
There are several ways how to inject your custom settings:&lt;br /&gt;
* define test setting constants in your phpunit.xml file&lt;br /&gt;
* define test setting constants in your config.php&lt;br /&gt;
These constants may be then used in your test or plugin code.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 4.4 and up (PHPUnit 9.6)=&lt;br /&gt;
{{Moodle 4.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 4.4, &#039;&#039;&#039;PHPUnit was upgraded to 9.6&#039;&#039;&#039; (from 9.5 being used in previous versions). This was done to &#039;&#039;&#039;warn to developers in advance&#039;&#039;&#039; about functionality that has been deprecated in the 9.5 series and will be removed so will stop working with the next major update to PHPUnit 10.x (see MDL-81266 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While everything should continue working without modification with PHPUnit 9.6, you will may get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be analysed&#039;&#039;&#039;, replacing or removing them as soon as possible, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/stronk7/moodle/commit/b2131ceff74da4c23928936f238d676a08e07d7f lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* MDL-81281. A number of attribute-related assertions have been deprecated, will be removed with PHPUnit 10. Alternatives for &#039;&#039;&#039;some&#039;&#039;&#039; of them are available:&lt;br /&gt;
  - assertClassHasAttribute()&lt;br /&gt;
  - assertClassNotHasAttribute()&lt;br /&gt;
  - assertClassHasStaticAttribute()&lt;br /&gt;
  - assertClassNotHasStaticAttribute()&lt;br /&gt;
  - assertObjectHasAttribute()         =&amp;gt; assertObjectHasProperty()&lt;br /&gt;
  - assertObjectNotHasAttribute()      =&amp;gt; assertObjectNotHasProperty()&lt;br /&gt;
* MDL-81266. A number of deprecation, notice, warning and error expectations have been deprecated, will be removed with PHPUnit 10. No alternative exists. A working replacement is available in the linked issue, hopefully there aren&#039;t many cases.&lt;br /&gt;
  - expectDeprecation()&lt;br /&gt;
  - expectDeprecationMessage()&lt;br /&gt;
  - expectDeprecationMessageMatches()&lt;br /&gt;
  - expectError()&lt;br /&gt;
  - expectErrorMessage()&lt;br /&gt;
  - expectErrorMessageMatches()&lt;br /&gt;
  - expectNotice()&lt;br /&gt;
  - expectNoticeMessage()&lt;br /&gt;
  - expectNoticeMessageMatches()&lt;br /&gt;
  - expectWarning()&lt;br /&gt;
 - expectWarningMessage()&lt;br /&gt;
 - expectWarningMessageMatches()&lt;br /&gt;
* MDL-81308. The &amp;lt;tt&amp;gt;-&amp;gt;withConsecutive()&amp;lt;/tt&amp;gt; functionality on PHPUnit mocks has been &#039;&#039;&#039;silently&#039;&#039;&#039; deprecated, will be removed with PHPUnit 10. Note that this won&#039;t affect PHPUnit 9.6 runs and an alternative path will be proposed in the linked issue, part of the PHPUnit 10 epic.&lt;br /&gt;
* &amp;lt;tt&amp;gt;PHPUnit\Framework\TestCase::getMockClass()&amp;lt;/tt&amp;gt; has been deprecated, will be removed with PHPUnit 10. No clear alternative exists and won&#039;t be investigated, because there aren&#039;t cases in core.&lt;br /&gt;
* Cannot use the &amp;lt;tt&amp;gt;Test&amp;lt;/tt&amp;gt; suffix on abstract test case classes. Proceed to rename them to end with &amp;lt;tt&amp;gt;TestCase&amp;lt;/tt&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.11 and up (PHPUnit 9.5)=&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.11, &#039;&#039;&#039;PHPUnit was upgraded to 9.5&#039;&#039;&#039; (from 8.5 being used in previous versions). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.11 (7.3, 7.4 and [[Moodle and PHP|8.0]]) (see MDL-71036 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While a lot of existing tests will work without modification with PHPUnit 9.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 9.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2020/02/migrating-to-phpunit-9 A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-9.html PHPUnit 9 release Announcement].&lt;br /&gt;
* These multiple detailed changelogs (because all them have included modifications requiring changes): [https://github.com/sebastianbergmann/phpunit/blob/9.0.0/ChangeLog-9.0.md 9.0], [https://github.com/sebastianbergmann/phpunit/blob/9.1.0/ChangeLog-9.1.md 9.1], [https://github.com/sebastianbergmann/phpunit/blob/9.3.0/ChangeLog-9.3.md 9.3], [https://github.com/sebastianbergmann/phpunit/blob/9.5.0/ChangeLog-9.5.md 9.5]&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/9.5/ Official PHPUnit manual].&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/e3a46964dc6d8ca1558c6e1e8dfdf3c1745eeaed/lib/upgrade.txt#L5-L65 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* All the changes that were deprecated with PHPUnit 8.5 (see the section below) are now removed and will lead to errors.&lt;br /&gt;
* &amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt; now performs stricter comparison (like &amp;lt;tt&amp;gt;assertSame()&amp;lt;/tt&amp;gt; does). New &amp;lt;tt&amp;gt;assertContainsEquals()&amp;lt;/tt&amp;gt; has been created to provide the old behavior.&lt;br /&gt;
* Changes to the &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; schema, mostly internal. These only will impact if you are using custom &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; files:&lt;br /&gt;
** The previous &amp;lt;tt&amp;gt;&amp;lt;filter&amp;gt;&amp;lt;/tt&amp;gt; section is now (better) called &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;. And, within it:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; has been replaced by &amp;lt;tt&amp;gt;&amp;lt;include&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;exclude&amp;gt;&amp;lt;/tt&amp;gt; is not a child of &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; anymore, but of &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** But with implications when defining the [[#Check your coverage|coverage information]] because &amp;lt;tt&amp;gt;$whitelistxxx&amp;lt;/tt&amp;gt; properties used by the &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; files have been deprecated, instead use &amp;lt;tt&amp;gt;includelistfolders&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;includelistfiles&amp;lt;/tt&amp;gt; (to better map the elements in the xml).&lt;br /&gt;
* Warning: It&#039;s not possible to run individual test files any more. Use any of the alternative execution methods (filter, suite, config) to specify which tests you want to run. This will be hopefully fixed in MDL-71049 once it has been agreed which the best way to proceed is.&lt;br /&gt;
* Deprecations, deprecations, deprecations. Lots of them in often used assertions: file assertions, regexp assertions, exception expectations... again, note that all them will become errors with the next PHPUnit update, so &#039;&#039;&#039;the recommendation is to update them ASAP&#039;&#039;&#039;.&lt;br /&gt;
Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/fc335f5...713722c browse the changes associated with the issue], hopefully with useful explanations in the commit messages.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.10 and up (PHPUnit 8.5)=&lt;br /&gt;
{{Moodle 3.10}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.10, &#039;&#039;&#039;PHPUnit was upgraded to 8.5&#039;&#039;&#039; (from 7.5 being used in older version). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.10 (7.2, 7.3 and 7.4) and also to provide an &#039;&#039;&#039;easier jump to PHPUnit 9.x&#039;&#039;&#039; that will be needed for Moodle 3.11 (php versions 7.3, 7.4 and 8.0), removing a lot of deprecated stuff in advance. (see MDL-67673 and MDL-64600 for more details).&lt;br /&gt;
&lt;br /&gt;
While 99% of existing tests will work without modification with PHPUnit 8.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 8.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2019/02/help-my-tests-stopped-working A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-8.html PHPUnit 8 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/130104cf796a88dd1547dc5beb8bd555c2deb55e/ChangeLog-8.0.md Detailed changelog of the release].&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/8.5/ Official PHPUnit manual].&lt;br /&gt;
* A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/6594c54b2eef62499d304bfa0939999e3a14246e/lib/upgrade.txt#L5-L37 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
** Support for PHP 7.0 dropped (because all template methods (&amp;lt;tt&amp;gt;setUp()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tearDown()&amp;lt;/tt&amp;gt;..) now require to return void. This will mostly impact 3rd-part plugins that were still running the same tests against old branches of Moodle with PHP 7.0 support.&lt;br /&gt;
** &amp;lt;tt&amp;gt;PHPUnit/DBUnit&amp;lt;/tt&amp;gt; has been removed are replaced by a lightweight alternative.&lt;br /&gt;
** Deprecations, deprecations, deprecations. Lots of them in often used assertions (&amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;assertEquals()&amp;lt;/tt&amp;gt;...) and also &amp;lt;tt&amp;gt;@expectedExceptionXXX&amp;lt;/tt&amp;gt; annotations. Again, note that all them will become errors with PHPUnit 9.&lt;br /&gt;
* Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/5903054...b13ec3c browse the changes associated with the issue], hopefully with useful enough explanations in the commit messages.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.7 and up (PHPUnit 7.5)=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.7, &#039;&#039;&#039;PHPUnit was upgraded to 7.5&#039;&#039;&#039; (from 6.x being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.7 (7.1, 7.2 and 7.3). (see MDL-65204 and linked issues for more details). While internally [https://phpunit.de/announcements/phpunit-7.html a lot of things changed with PHPUnit 7] (PHP 7.1-isms, typed signatures, void returns, assertEquals() changes), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 7, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-7.html  PHPUnit 7 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/520723129e2b3fc1dc4c0953e43c9d40e1ecb352/ChangeLog-7.5.md Detailed changelog of the release], paying special attention to the added, deprecated, changed and deleted sections.&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/7.5/ Official PHPUnit manual].&lt;br /&gt;
* Changes performed into core, mainly: new, stricter, signatures ([https://github.com/moodle/moodle/commit/26218b7 26218b7]) and assertEquals() changes, specially important when comparing strings, now performed using strict (===) equals ([https://github.com/moodle/moodle/commit/85f47ba 85f47ba]).&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.4 and up (PHPUnit 6)=&lt;br /&gt;
{{Moodle 3.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.4, &#039;&#039;&#039;PHPUnit was upgraded to 6.4&#039;&#039;&#039; (from 5.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.4 (7.0, 7.1 and 7.2). (see MDL-60611 and linked issues for more details). While internally [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues a lot of things changed with PHPUnit 6] (namespaced classes being the more noticeable), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
Still, in &#039;&#039;&#039;some cases, it will impossible to maintain compatibility&#039;&#039;&#039; of tests between old (pre 3.4) tests and new ones, especially &#039;&#039;&#039;when direct use of any phpunit class is performed&#039;&#039;&#039;. Luckily, both GitHub Actions and CI tests will detect this situation and it shouldn&#039;t be hard to keep all supported branches in core passing ok. Plugins may be trickier, if the same branch is attempting to work against multiple core branches and they are using some phpunit class directly.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 6, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2017/02/migrating-to-phpunit-6 A very good mini-guide] showing all the important changes.&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues PHPUnit 6 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/9d0c024d2099531442d862b66b0ad7cf35ed8e78/ChangeLog-6.0.md Detailed changelog of the release], paying special attention to the changed and deleted sections.&lt;br /&gt;
* Changes performed into core, mainly: namespace class renaming ([https://github.com/moodle/moodle/commit/801a372dadb6e11c8781547603e3f0a59ce5638f 801a372]) and deprecated stuff ([https://github.com/moodle/moodle/commit/796e48a58bf18533bdca423fff7949ab119101c4 796e48a])&lt;br /&gt;
=See also=&lt;br /&gt;
* [[PHPUnit integration]]&lt;br /&gt;
* [[PHPUnit]]&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64088</id>
		<title>Writing PHPUnit tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64088"/>
		<updated>2024-03-25T13:58:22Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: /* Upgrading unit tests to work with Moodle 4.4 and up (PHPUnit 9.6) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.3}}&lt;br /&gt;
&lt;br /&gt;
Moodle PHPUnit integration is designed to allow easy adding of new tests. At the start of each test the state is automatically reset to fresh new installation (unless explicitly told not to reset).&lt;br /&gt;
=Namespaces=&lt;br /&gt;
All the stuff under **/tests directories is [[Coding style#Namespaces_within_.2A.2A.2Ftests_directories|subject to some simple rules]] when using namespaces. They apply to test cases, fixtures, generators and, in general, any class within those directories. Take a look to them! (grand summary = 100% the same rules that are applied to **/classes directories).&lt;br /&gt;
=Testcase classes=&lt;br /&gt;
There are three basic test class that are supposed to used in all Moodle unit tests - basic_testcase, advanced_testcase and provider_testcase. &#039;&#039;&#039;Please note it is strongly recommended to put only one testcase into each class file.&#039;&#039;&#039;&lt;br /&gt;
;basic_testcase : Very simple tests that do not modify database, dataroot or any PHP globals. It can be used for example when trying examples from the official PHPUnit tutorial.&lt;br /&gt;
;advanced_testcase : Enhanced testcase class enhanced for easy testing of Moodle code.&lt;br /&gt;
;provider_testcase: Enhanced testcase class, enhanced for easy testing of [[Privacy API|Privacy Providers]].&lt;br /&gt;
There is a fourth testcase class that is specially designed for testing of our Moodle database layer, it should not be used for other purposes.&lt;br /&gt;
== Assertions ==&lt;br /&gt;
The complete list of assertions can be found in the links below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle version&lt;br /&gt;
! PHPUnit version&lt;br /&gt;
!Links&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.11&lt;br /&gt;
| PHPUnit 9.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/9.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.10&lt;br /&gt;
| PHPUnit 8.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/8.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.7 - 3.9&lt;br /&gt;
| PHPUnit 7.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/7.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.4 - 3.6&lt;br /&gt;
| PHPUnit 6.5&lt;br /&gt;
|[https://phpunit.de/manual/6.5/en/assertions.html Documentation]&lt;br /&gt;
|}&lt;br /&gt;
==Sample plugin testcase==&lt;br /&gt;
PHPUnit tests are located in &amp;lt;tt&amp;gt;tests/*_test.php&amp;lt;/tt&amp;gt; files in your plugin, for example &amp;lt;tt&amp;gt;mod/myplugin/tests/sample_test.php&amp;lt;/tt&amp;gt;, the file should contain only one class that extends &amp;lt;tt&amp;gt;advanced_testcase&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class sample_test extends \advanced_testcase {&lt;br /&gt;
     public function test_adding() {&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, 1+2);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
See [[PHPUnit integration#Class and file naming rules]] for more information.&lt;br /&gt;
==Inclusion of Moodle library files==&lt;br /&gt;
If you want to include some Moodle library files you should always declare &#039;&#039;&#039;global $CFG&#039;&#039;&#039;. The reason is that testcase files may be included from non-moodle code which does not make the global $CFG available automatically.&lt;br /&gt;
==Automatic state reset==&lt;br /&gt;
By default after each test Moodle database and dataroot is automatically reset to the original state which was present right after installation. make sure to use $this-&amp;gt;resetAfterTest() to indicate that the database or changes of standard global variables are expected.&lt;br /&gt;
&lt;br /&gt;
If you received the error &amp;quot;Warning: unexpected database modification, resetting DB state&amp;quot; it is because the test is not using &amp;lt;tt&amp;gt;$this-&amp;gt;resetAfterTest()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class test_something extends \advanced_testcase {&lt;br /&gt;
     public function test_deleting() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;resetAfterTest(true);&lt;br /&gt;
         $DB-&amp;gt;delete_records(&#039;user&#039;);&lt;br /&gt;
         $this-&amp;gt;assertEmpty($DB-&amp;gt;get_records(&#039;user&#039;));&lt;br /&gt;
     }&lt;br /&gt;
     public function test_user_table_was_reset() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, $DB-&amp;gt;count_records(&#039;user&#039;, array()));&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Generators=&lt;br /&gt;
Tests that need to modify default installation may use generators to create new courses, users, etc. All examples on this page should be used from test methods of a test class derived from advanced_testcase.&lt;br /&gt;
&lt;br /&gt;
Note if you are using PHPUnit [https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers @dataProvider] functions to provide parameters to unit tests, you can not use the data generator or change the user etc in the data provider function. Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation.&lt;br /&gt;
==Creating users==&lt;br /&gt;
At the start of each test there are only two users present - guest and administrator. If you need to add more test accounts use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You may also specify properties of the user account, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user(array(&#039;email&#039;=&amp;gt;&#039;user1@example.com&#039;, &#039;username&#039;=&amp;gt;&#039;user1&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
By default no user is logged-in, use setUser() method to change current $USER value:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser($user1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Guest and admin accounts have a shortcut methods:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setGuestUser();&lt;br /&gt;
 $this-&amp;gt;setAdminUser();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Null can be used to set current user back to not-logged-in:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser(null);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating course categories==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $category1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $category2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category(array(&#039;name&#039;=&amp;gt;&#039;Some subcategory&#039;, &#039;parent&#039;=&amp;gt;$category1-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating courses==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 &lt;br /&gt;
 $category = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $course2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course(array(&#039;name&#039;=&amp;gt;&#039;Some course&#039;, &#039;category&#039;=&amp;gt;$category-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating activities==&lt;br /&gt;
Some activity plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php.&lt;br /&gt;
&lt;br /&gt;
Example of creation of new course with one page resource:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $generator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator(&#039;mod_page&#039;);&lt;br /&gt;
 $generator-&amp;gt;create_instance(array(&#039;course&#039;=&amp;gt;$course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The following is functionally the same, but a bit shorter:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $page = $this-&amp;gt;getDataGenerator()-&amp;gt;create_module(&#039;page&#039;, array(&#039;course&#039; =&amp;gt; $course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating cohorts==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Since 2.4 there the data generator supports creation of new cohorts.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $cohort = $this-&amp;gt;getDataGenerator()-&amp;gt;create_cohort();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Simplified user enrolments==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Instead of standard enrolment API it is possible to use simplified method in data generator. It is intended to be used with self and manual enrolment plugins.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid, &#039;manual&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating scales==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale(array(&#039;name&#039; =&amp;gt; $name, &#039;scale&#039; =&amp;gt; $scale, &#039;courseid&#039; =&amp;gt; $courseid, &#039;userid&#039; =&amp;gt; $userid, &#039;description&#039; =&amp;gt; description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating roles==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role(array(&#039;shortname&#039; =&amp;gt; $shortname, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; description, &#039;archetype&#039; =&amp;gt; $archetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating tags==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag(array(&lt;br /&gt;
    &#039;userid&#039; =&amp;gt; $userid, &lt;br /&gt;
    &#039;rawname&#039; =&amp;gt; $rawname,&lt;br /&gt;
    &#039;name&#039; =&amp;gt; $name, &lt;br /&gt;
    &#039;description&#039; =&amp;gt; $description, &lt;br /&gt;
    &#039;descriptionformat&#039; =&amp;gt; $descriptionformat,&lt;br /&gt;
    &#039;flag&#039; =&amp;gt; $flag&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Groups==&lt;br /&gt;
===Creating groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding users to groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid, &#039;component&#039; =&amp;gt; $component, &#039;itemid&#039; =&amp;gt; $itemid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding groups to groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping_group(array(&#039;groupingid&#039; =&amp;gt; $groupingid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Repositories==&lt;br /&gt;
===Creating repository instances===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating repository types===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include type generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository_type($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating grades==&lt;br /&gt;
===Grade categories===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Grade items===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;itemtype&#039; =&amp;gt; $itemtype, &#039;itemname&#039; =&amp;gt; $itemname, &#039;outcomeid&#039; =&amp;gt; $outcomeid, &#039;scaleid&#039; =&amp;gt; $scaleid, &#039;gradetype&#039; =&amp;gt; $gradetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Outcomes===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_outcome();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Other types of plugin==&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Any other type of plugin can have a generator. The generator class should extend component_generator_base, and then you can get an instance using $mygenerator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator($frankenstylecomponentname);&lt;br /&gt;
&lt;br /&gt;
For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.&lt;br /&gt;
=Long tests=&lt;br /&gt;
All standard test should execute as fast as possible. Tests that take a longer time to execute (&amp;gt;10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.&lt;br /&gt;
=Large test data=&lt;br /&gt;
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]&lt;br /&gt;
=Testing sending of messages=&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
You can temporarily redirect all messages sent via message_send() to a message sink object. This allows developers to verify that the tested code is sending expected messages.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first disable the use of transactions and then redirect the messaging into a new message sink, you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
$sink = $this-&amp;gt;redirectMessages();&lt;br /&gt;
//... code that is sending messages&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(3, count($messages));&lt;br /&gt;
//.. test messages were generated in correct order with appropriate content&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Testing sending of emails=&lt;br /&gt;
{{Moodle 2.6}}&lt;br /&gt;
You can temporarily redirect emails sent via email_to_user() to a email message sink object. This allows developers to verify that the tested code is sending expected emails.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first unset &#039;noemailever&#039; setting and then redirect the emails into a new message sink where you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
unset_config(&#039;noemailever&#039;);&lt;br /&gt;
$sink = $this-&amp;gt;redirectEmails();&lt;br /&gt;
//... code that is sending email&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(1, count($messages));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Logstores=&lt;br /&gt;
You can test events which were written to a logstore, but you must disable transactions, enable at least one valid logstore, and disable logstore buffering to ensure that the events are written to the database before the tests execute.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
set_config(&#039;enabled_stores&#039;, &#039;logstore_standard&#039;, &#039;tool_log&#039;);&lt;br /&gt;
set_config(&#039;buffersize&#039;, 0, &#039;logstore_standard&#039;);&lt;br /&gt;
get_log_manager(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Check your coverage=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests.&lt;br /&gt;
&lt;br /&gt;
Prior to Moodle 3.7, this coverage would load all files and generate coverage for everything regardless of whether that file could be covered at all, or whether it was intentionally covered.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.7 the &#039;&#039;&#039;phpunit.xml&#039;&#039;&#039; configuration contains generated coverage include and exclude information for each component.&lt;br /&gt;
==Generating include and exclude configuration==&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
You can programatically describe which files will be checked for coverage by creating a &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file alongside the tests that you are writing.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, a default configuration is applied for all plugins and it is not necessary to supply a coverage.php unless you wish to cover additional files.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file allows you to list include and exclude files and folders within the component being&lt;br /&gt;
tested. All paths specified are relative to the component being tested. For example, when working with &#039;&#039;&#039;mod_forum&#039;&#039;&#039; your&lt;br /&gt;
code will be in &#039;&#039;&#039;mod/forum&#039;&#039;&#039;, and its unit tests will be in &#039;&#039;&#039;mod/forum/tests/example_test.php&#039;&#039;&#039;. The coverage file&lt;br /&gt;
for this would be in &#039;&#039;&#039;mod/forum/tests/coverage.php&#039;&#039;&#039; and all paths specified would be relative to &#039;&#039;&#039;mod/forum&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to specify a combination of included files, included folders, excluded files, and excluded folders. This would allow you, for example, to include the entire &#039;&#039;&#039;classes&#039;&#039;&#039; directory, but exclude.a specific file or folder within it.&lt;br /&gt;
&lt;br /&gt;
The following is an example &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file from &#039;&#039;&#039;mod_forum&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Note: For Moodle versions 3.7 to 3.10, the [https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;amp;oldid=58177#Check_your_coverage syntax used] was slightly different.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also, note that you can better define which class or function each test is effectively covering by using the &amp;lt;tt&amp;gt;@covers&amp;lt;/tt&amp;gt; annotation as [https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#specifying-covered-code-parts described in the documention].&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, the following default configuration is applied:{{Moodle 4.0}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;tests/generator&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
        &#039;lib.php&#039;,&lt;br /&gt;
        &#039;locallib.php&#039;,&lt;br /&gt;
        &#039;renderer.php&#039;,&lt;br /&gt;
        &#039;rsslib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If a coverage.php file already exists, then the defaults will be added to the values already defined.&lt;br /&gt;
=Best practice=&lt;br /&gt;
There are several best practices, suggestions, and things to avoid which you should consider when writing unit tests. Some of these are described below.&lt;br /&gt;
==Code coverage==&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests and this is well supported since.Moodle 3.7. We recommend that you consider checking the coverage of your plugins when you write your code.&lt;br /&gt;
&lt;br /&gt;
We recommend that you explicitly set the @covers annotation as described in the [https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnit documentation].&lt;br /&gt;
==Keep use of resetAfterTest to a minimum==&lt;br /&gt;
Although many of the examples described above use the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;resetAfterTest&amp;lt;/syntaxhighlight&amp;gt; nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.&lt;br /&gt;
Generally speaking you should aim to write code which is mockable, and does not require real fixtures.&lt;br /&gt;
Use of resetAfterTest will also slow your tests down.&lt;br /&gt;
==Be careful with shared setUp and instance variables==&lt;br /&gt;
You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:&lt;br /&gt;
# If you create any fixtures in the setUp, or call the resetAfterTest function, these fixtures and conditions will apply for _all_ tests in the testsuite. You will not be able to add another test to the suite which does not require these conditions without those conditions being fulfilled anyway. This can lead to slow tests.&lt;br /&gt;
# PHPUnit creates an instance of each testcase during its bootstrap phase, and does not dispose of it for the lifetime of the test run. Anything which causes data to be stored as instance data within the testcase will be stored in memory until the _entire suite_ completes. This means that any fixture which is setup and not actively discarded will not be garbage collected and lead to memory bloat. In severe cases this can lead to memory exhaustion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing testcases which contain setUp which either generate data, or set resetAfterTest should be phased out, and no new cases should be introduced.&lt;br /&gt;
==Make use of the dataProvider functionality==&lt;br /&gt;
The dataProvider functionality of PHPUnit is an extremely powerful and useful feature which allows you to verify a function quickly and easily with a range of different conditions.&lt;br /&gt;
However, the following rules should be followed when using dataProviders:&lt;br /&gt;
* Keep addition of resettable data requiring resetAfterTest to a minimum - this will lead to many slow tests&lt;br /&gt;
* Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation. The dataProvider is called after the testSuite is instantiated, but before any tests are run. Each test will run a full setUp and tearDown, which will destroy any data which was created.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Test function accepts parameters passed from the specified data provider.&lt;br /&gt;
 *&lt;br /&gt;
 * @dataProvider foobar_provider&lt;br /&gt;
 * @param int $foor&lt;br /&gt;
 * @param int $bar&lt;br /&gt;
 */&lt;br /&gt;
public function test_foobar(int $foo, int $bar) {&lt;br /&gt;
    // Perform the tests here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Data provider for {@see self::test_foobar()}.&lt;br /&gt;
 *&lt;br /&gt;
 * @return array List of data sets - (string) data set name =&amp;gt; (array) data&lt;br /&gt;
 */&lt;br /&gt;
public function foobar_provider(): array {&lt;br /&gt;
    return [&lt;br /&gt;
        &#039;Same numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 42,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 42,&lt;br /&gt;
        ],&lt;br /&gt;
        &#039;Different numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 21,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 84,&lt;br /&gt;
        ],&lt;br /&gt;
    ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Extra test settings=&lt;br /&gt;
Usually the test should not interact with any external systems and it should work the same on all systems. But sometimes you need to specify some option for connection to external systems or system configuration. It is intentionally not possible to use $CFG settings from config.php.&lt;br /&gt;
&lt;br /&gt;
There are several ways how to inject your custom settings:&lt;br /&gt;
* define test setting constants in your phpunit.xml file&lt;br /&gt;
* define test setting constants in your config.php&lt;br /&gt;
These constants may be then used in your test or plugin code.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 4.4 and up (PHPUnit 9.6)=&lt;br /&gt;
{{Moodle 4.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 4.4, &#039;&#039;&#039;PHPUnit was upgraded to 9.6&#039;&#039;&#039; (from 9.5 being used in previous versions). This was done to &#039;&#039;&#039;warn to developers in advance&#039;&#039;&#039; about functionality that has been deprecated in the 9.5 series and will be removed so will stop working with the next major update to PHPUnit 10.x (see MDL-81266 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While everything should continue working without modification with PHPUnit 9.6, you will may get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be analysed&#039;&#039;&#039;, replacing or removing them as soon as possible, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/commit/28892562ca4c06f4f57ca1588c04e608b3d0e22c lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* MDL-81281. A number of attribute-related assertions have been deprecated, will be removed with PHPUnit 10. Alternatives for &#039;&#039;&#039;some&#039;&#039;&#039; of them are available:&lt;br /&gt;
  - assertClassHasAttribute()&lt;br /&gt;
  - assertClassNotHasAttribute()&lt;br /&gt;
  - assertClassHasStaticAttribute()&lt;br /&gt;
  - assertClassNotHasStaticAttribute()&lt;br /&gt;
  - assertObjectHasAttribute()         =&amp;gt; assertObjectHasProperty()&lt;br /&gt;
  - assertObjectNotHasAttribute()      =&amp;gt; assertObjectNotHasProperty()&lt;br /&gt;
* MDL-81266. A number of deprecation, notice, warning and error expectations have been deprecated, will be removed with PHPUnit 10. No alternative exists. A working replacement is available in the linked issue, hopefully there aren&#039;t many cases.&lt;br /&gt;
  - expectDeprecation()&lt;br /&gt;
  - expectDeprecationMessage()&lt;br /&gt;
  - expectDeprecationMessageMatches()&lt;br /&gt;
  - expectError()&lt;br /&gt;
  - expectErrorMessage()&lt;br /&gt;
  - expectErrorMessageMatches()&lt;br /&gt;
  - expectNotice()&lt;br /&gt;
  - expectNoticeMessage()&lt;br /&gt;
  - expectNoticeMessageMatches()&lt;br /&gt;
  - expectWarning()&lt;br /&gt;
 - expectWarningMessage()&lt;br /&gt;
 - expectWarningMessageMatches()&lt;br /&gt;
* MDL-81308. The &amp;lt;tt&amp;gt;-&amp;gt;withConsecutive()&amp;lt;/tt&amp;gt; functionality on PHPUnit mocks has been &#039;&#039;&#039;silently&#039;&#039;&#039; deprecated, will be removed with PHPUnit 10. Note that this won&#039;t affect PHPUnit 9.6 runs and an alternative path will be proposed in the linked issue, part of the PHPUnit 10 epic.&lt;br /&gt;
* &amp;lt;tt&amp;gt;PHPUnit\Framework\TestCase::getMockClass()&amp;lt;/tt&amp;gt; has been deprecated, will be removed with PHPUnit 10. No clear alternative exists and won&#039;t be investigated, because there aren&#039;t cases in core.&lt;br /&gt;
* Cannot use the &amp;lt;tt&amp;gt;Test&amp;lt;/tt&amp;gt; suffix on abstract test case classes. Proceed to rename them to end with &amp;lt;tt&amp;gt;TestCase&amp;lt;/tt&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.11 and up (PHPUnit 9.5)=&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.11, &#039;&#039;&#039;PHPUnit was upgraded to 9.5&#039;&#039;&#039; (from 8.5 being used in previous versions). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.11 (7.3, 7.4 and [[Moodle and PHP|8.0]]) (see MDL-71036 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While a lot of existing tests will work without modification with PHPUnit 9.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 9.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2020/02/migrating-to-phpunit-9 A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-9.html PHPUnit 9 release Announcement].&lt;br /&gt;
* These multiple detailed changelogs (because all them have included modifications requiring changes): [https://github.com/sebastianbergmann/phpunit/blob/9.0.0/ChangeLog-9.0.md 9.0], [https://github.com/sebastianbergmann/phpunit/blob/9.1.0/ChangeLog-9.1.md 9.1], [https://github.com/sebastianbergmann/phpunit/blob/9.3.0/ChangeLog-9.3.md 9.3], [https://github.com/sebastianbergmann/phpunit/blob/9.5.0/ChangeLog-9.5.md 9.5]&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/9.5/ Official PHPUnit manual].&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/e3a46964dc6d8ca1558c6e1e8dfdf3c1745eeaed/lib/upgrade.txt#L5-L65 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* All the changes that were deprecated with PHPUnit 8.5 (see the section below) are now removed and will lead to errors.&lt;br /&gt;
* &amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt; now performs stricter comparison (like &amp;lt;tt&amp;gt;assertSame()&amp;lt;/tt&amp;gt; does). New &amp;lt;tt&amp;gt;assertContainsEquals()&amp;lt;/tt&amp;gt; has been created to provide the old behavior.&lt;br /&gt;
* Changes to the &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; schema, mostly internal. These only will impact if you are using custom &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; files:&lt;br /&gt;
** The previous &amp;lt;tt&amp;gt;&amp;lt;filter&amp;gt;&amp;lt;/tt&amp;gt; section is now (better) called &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;. And, within it:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; has been replaced by &amp;lt;tt&amp;gt;&amp;lt;include&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;exclude&amp;gt;&amp;lt;/tt&amp;gt; is not a child of &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; anymore, but of &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** But with implications when defining the [[#Check your coverage|coverage information]] because &amp;lt;tt&amp;gt;$whitelistxxx&amp;lt;/tt&amp;gt; properties used by the &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; files have been deprecated, instead use &amp;lt;tt&amp;gt;includelistfolders&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;includelistfiles&amp;lt;/tt&amp;gt; (to better map the elements in the xml).&lt;br /&gt;
* Warning: It&#039;s not possible to run individual test files any more. Use any of the alternative execution methods (filter, suite, config) to specify which tests you want to run. This will be hopefully fixed in MDL-71049 once it has been agreed which the best way to proceed is.&lt;br /&gt;
* Deprecations, deprecations, deprecations. Lots of them in often used assertions: file assertions, regexp assertions, exception expectations... again, note that all them will become errors with the next PHPUnit update, so &#039;&#039;&#039;the recommendation is to update them ASAP&#039;&#039;&#039;.&lt;br /&gt;
Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/fc335f5...713722c browse the changes associated with the issue], hopefully with useful explanations in the commit messages.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.10 and up (PHPUnit 8.5)=&lt;br /&gt;
{{Moodle 3.10}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.10, &#039;&#039;&#039;PHPUnit was upgraded to 8.5&#039;&#039;&#039; (from 7.5 being used in older version). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.10 (7.2, 7.3 and 7.4) and also to provide an &#039;&#039;&#039;easier jump to PHPUnit 9.x&#039;&#039;&#039; that will be needed for Moodle 3.11 (php versions 7.3, 7.4 and 8.0), removing a lot of deprecated stuff in advance. (see MDL-67673 and MDL-64600 for more details).&lt;br /&gt;
&lt;br /&gt;
While 99% of existing tests will work without modification with PHPUnit 8.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 8.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2019/02/help-my-tests-stopped-working A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-8.html PHPUnit 8 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/130104cf796a88dd1547dc5beb8bd555c2deb55e/ChangeLog-8.0.md Detailed changelog of the release].&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/8.5/ Official PHPUnit manual].&lt;br /&gt;
* A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/6594c54b2eef62499d304bfa0939999e3a14246e/lib/upgrade.txt#L5-L37 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
** Support for PHP 7.0 dropped (because all template methods (&amp;lt;tt&amp;gt;setUp()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tearDown()&amp;lt;/tt&amp;gt;..) now require to return void. This will mostly impact 3rd-part plugins that were still running the same tests against old branches of Moodle with PHP 7.0 support.&lt;br /&gt;
** &amp;lt;tt&amp;gt;PHPUnit/DBUnit&amp;lt;/tt&amp;gt; has been removed are replaced by a lightweight alternative.&lt;br /&gt;
** Deprecations, deprecations, deprecations. Lots of them in often used assertions (&amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;assertEquals()&amp;lt;/tt&amp;gt;...) and also &amp;lt;tt&amp;gt;@expectedExceptionXXX&amp;lt;/tt&amp;gt; annotations. Again, note that all them will become errors with PHPUnit 9.&lt;br /&gt;
* Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/5903054...b13ec3c browse the changes associated with the issue], hopefully with useful enough explanations in the commit messages.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.7 and up (PHPUnit 7.5)=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.7, &#039;&#039;&#039;PHPUnit was upgraded to 7.5&#039;&#039;&#039; (from 6.x being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.7 (7.1, 7.2 and 7.3). (see MDL-65204 and linked issues for more details). While internally [https://phpunit.de/announcements/phpunit-7.html a lot of things changed with PHPUnit 7] (PHP 7.1-isms, typed signatures, void returns, assertEquals() changes), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 7, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-7.html  PHPUnit 7 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/520723129e2b3fc1dc4c0953e43c9d40e1ecb352/ChangeLog-7.5.md Detailed changelog of the release], paying special attention to the added, deprecated, changed and deleted sections.&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/7.5/ Official PHPUnit manual].&lt;br /&gt;
* Changes performed into core, mainly: new, stricter, signatures ([https://github.com/moodle/moodle/commit/26218b7 26218b7]) and assertEquals() changes, specially important when comparing strings, now performed using strict (===) equals ([https://github.com/moodle/moodle/commit/85f47ba 85f47ba]).&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.4 and up (PHPUnit 6)=&lt;br /&gt;
{{Moodle 3.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.4, &#039;&#039;&#039;PHPUnit was upgraded to 6.4&#039;&#039;&#039; (from 5.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.4 (7.0, 7.1 and 7.2). (see MDL-60611 and linked issues for more details). While internally [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues a lot of things changed with PHPUnit 6] (namespaced classes being the more noticeable), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
Still, in &#039;&#039;&#039;some cases, it will impossible to maintain compatibility&#039;&#039;&#039; of tests between old (pre 3.4) tests and new ones, especially &#039;&#039;&#039;when direct use of any phpunit class is performed&#039;&#039;&#039;. Luckily, both GitHub Actions and CI tests will detect this situation and it shouldn&#039;t be hard to keep all supported branches in core passing ok. Plugins may be trickier, if the same branch is attempting to work against multiple core branches and they are using some phpunit class directly.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 6, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2017/02/migrating-to-phpunit-6 A very good mini-guide] showing all the important changes.&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues PHPUnit 6 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/9d0c024d2099531442d862b66b0ad7cf35ed8e78/ChangeLog-6.0.md Detailed changelog of the release], paying special attention to the changed and deleted sections.&lt;br /&gt;
* Changes performed into core, mainly: namespace class renaming ([https://github.com/moodle/moodle/commit/801a372dadb6e11c8781547603e3f0a59ce5638f 801a372]) and deprecated stuff ([https://github.com/moodle/moodle/commit/796e48a58bf18533bdca423fff7949ab119101c4 796e48a])&lt;br /&gt;
=See also=&lt;br /&gt;
* [[PHPUnit integration]]&lt;br /&gt;
* [[PHPUnit]]&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64087</id>
		<title>Writing PHPUnit tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=64087"/>
		<updated>2024-03-25T13:21:09Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Documenting the upgrade to PHPUnit 9.6&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.3}}&lt;br /&gt;
&lt;br /&gt;
Moodle PHPUnit integration is designed to allow easy adding of new tests. At the start of each test the state is automatically reset to fresh new installation (unless explicitly told not to reset).&lt;br /&gt;
=Namespaces=&lt;br /&gt;
All the stuff under **/tests directories is [[Coding style#Namespaces_within_.2A.2A.2Ftests_directories|subject to some simple rules]] when using namespaces. They apply to test cases, fixtures, generators and, in general, any class within those directories. Take a look to them! (grand summary = 100% the same rules that are applied to **/classes directories).&lt;br /&gt;
=Testcase classes=&lt;br /&gt;
There are three basic test class that are supposed to used in all Moodle unit tests - basic_testcase, advanced_testcase and provider_testcase. &#039;&#039;&#039;Please note it is strongly recommended to put only one testcase into each class file.&#039;&#039;&#039;&lt;br /&gt;
;basic_testcase : Very simple tests that do not modify database, dataroot or any PHP globals. It can be used for example when trying examples from the official PHPUnit tutorial.&lt;br /&gt;
;advanced_testcase : Enhanced testcase class enhanced for easy testing of Moodle code.&lt;br /&gt;
;provider_testcase: Enhanced testcase class, enhanced for easy testing of [[Privacy API|Privacy Providers]].&lt;br /&gt;
There is a fourth testcase class that is specially designed for testing of our Moodle database layer, it should not be used for other purposes.&lt;br /&gt;
== Assertions ==&lt;br /&gt;
The complete list of assertions can be found in the links below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle version&lt;br /&gt;
! PHPUnit version&lt;br /&gt;
!Links&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.11&lt;br /&gt;
| PHPUnit 9.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/9.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.10&lt;br /&gt;
| PHPUnit 8.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/8.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.7 - 3.9&lt;br /&gt;
| PHPUnit 7.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/7.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.4 - 3.6&lt;br /&gt;
| PHPUnit 6.5&lt;br /&gt;
|[https://phpunit.de/manual/6.5/en/assertions.html Documentation]&lt;br /&gt;
|}&lt;br /&gt;
==Sample plugin testcase==&lt;br /&gt;
PHPUnit tests are located in &amp;lt;tt&amp;gt;tests/*_test.php&amp;lt;/tt&amp;gt; files in your plugin, for example &amp;lt;tt&amp;gt;mod/myplugin/tests/sample_test.php&amp;lt;/tt&amp;gt;, the file should contain only one class that extends &amp;lt;tt&amp;gt;advanced_testcase&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class sample_test extends \advanced_testcase {&lt;br /&gt;
     public function test_adding() {&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, 1+2);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
See [[PHPUnit integration#Class and file naming rules]] for more information.&lt;br /&gt;
==Inclusion of Moodle library files==&lt;br /&gt;
If you want to include some Moodle library files you should always declare &#039;&#039;&#039;global $CFG&#039;&#039;&#039;. The reason is that testcase files may be included from non-moodle code which does not make the global $CFG available automatically.&lt;br /&gt;
==Automatic state reset==&lt;br /&gt;
By default after each test Moodle database and dataroot is automatically reset to the original state which was present right after installation. make sure to use $this-&amp;gt;resetAfterTest() to indicate that the database or changes of standard global variables are expected.&lt;br /&gt;
&lt;br /&gt;
If you received the error &amp;quot;Warning: unexpected database modification, resetting DB state&amp;quot; it is because the test is not using &amp;lt;tt&amp;gt;$this-&amp;gt;resetAfterTest()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class test_something extends \advanced_testcase {&lt;br /&gt;
     public function test_deleting() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;resetAfterTest(true);&lt;br /&gt;
         $DB-&amp;gt;delete_records(&#039;user&#039;);&lt;br /&gt;
         $this-&amp;gt;assertEmpty($DB-&amp;gt;get_records(&#039;user&#039;));&lt;br /&gt;
     }&lt;br /&gt;
     public function test_user_table_was_reset() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, $DB-&amp;gt;count_records(&#039;user&#039;, array()));&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Generators=&lt;br /&gt;
Tests that need to modify default installation may use generators to create new courses, users, etc. All examples on this page should be used from test methods of a test class derived from advanced_testcase.&lt;br /&gt;
&lt;br /&gt;
Note if you are using PHPUnit [https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers @dataProvider] functions to provide parameters to unit tests, you can not use the data generator or change the user etc in the data provider function. Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation.&lt;br /&gt;
==Creating users==&lt;br /&gt;
At the start of each test there are only two users present - guest and administrator. If you need to add more test accounts use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You may also specify properties of the user account, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user(array(&#039;email&#039;=&amp;gt;&#039;user1@example.com&#039;, &#039;username&#039;=&amp;gt;&#039;user1&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
By default no user is logged-in, use setUser() method to change current $USER value:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser($user1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Guest and admin accounts have a shortcut methods:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setGuestUser();&lt;br /&gt;
 $this-&amp;gt;setAdminUser();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Null can be used to set current user back to not-logged-in:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser(null);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating course categories==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $category1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $category2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category(array(&#039;name&#039;=&amp;gt;&#039;Some subcategory&#039;, &#039;parent&#039;=&amp;gt;$category1-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating courses==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 &lt;br /&gt;
 $category = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $course2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course(array(&#039;name&#039;=&amp;gt;&#039;Some course&#039;, &#039;category&#039;=&amp;gt;$category-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating activities==&lt;br /&gt;
Some activity plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php.&lt;br /&gt;
&lt;br /&gt;
Example of creation of new course with one page resource:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $generator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator(&#039;mod_page&#039;);&lt;br /&gt;
 $generator-&amp;gt;create_instance(array(&#039;course&#039;=&amp;gt;$course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The following is functionally the same, but a bit shorter:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $page = $this-&amp;gt;getDataGenerator()-&amp;gt;create_module(&#039;page&#039;, array(&#039;course&#039; =&amp;gt; $course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating cohorts==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Since 2.4 there the data generator supports creation of new cohorts.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $cohort = $this-&amp;gt;getDataGenerator()-&amp;gt;create_cohort();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Simplified user enrolments==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Instead of standard enrolment API it is possible to use simplified method in data generator. It is intended to be used with self and manual enrolment plugins.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid, &#039;manual&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating scales==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale(array(&#039;name&#039; =&amp;gt; $name, &#039;scale&#039; =&amp;gt; $scale, &#039;courseid&#039; =&amp;gt; $courseid, &#039;userid&#039; =&amp;gt; $userid, &#039;description&#039; =&amp;gt; description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating roles==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role(array(&#039;shortname&#039; =&amp;gt; $shortname, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; description, &#039;archetype&#039; =&amp;gt; $archetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating tags==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag(array(&lt;br /&gt;
    &#039;userid&#039; =&amp;gt; $userid, &lt;br /&gt;
    &#039;rawname&#039; =&amp;gt; $rawname,&lt;br /&gt;
    &#039;name&#039; =&amp;gt; $name, &lt;br /&gt;
    &#039;description&#039; =&amp;gt; $description, &lt;br /&gt;
    &#039;descriptionformat&#039; =&amp;gt; $descriptionformat,&lt;br /&gt;
    &#039;flag&#039; =&amp;gt; $flag&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Groups==&lt;br /&gt;
===Creating groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding users to groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid, &#039;component&#039; =&amp;gt; $component, &#039;itemid&#039; =&amp;gt; $itemid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding groups to groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping_group(array(&#039;groupingid&#039; =&amp;gt; $groupingid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Repositories==&lt;br /&gt;
===Creating repository instances===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating repository types===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include type generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository_type($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating grades==&lt;br /&gt;
===Grade categories===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Grade items===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;itemtype&#039; =&amp;gt; $itemtype, &#039;itemname&#039; =&amp;gt; $itemname, &#039;outcomeid&#039; =&amp;gt; $outcomeid, &#039;scaleid&#039; =&amp;gt; $scaleid, &#039;gradetype&#039; =&amp;gt; $gradetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Outcomes===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_outcome();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Other types of plugin==&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Any other type of plugin can have a generator. The generator class should extend component_generator_base, and then you can get an instance using $mygenerator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator($frankenstylecomponentname);&lt;br /&gt;
&lt;br /&gt;
For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.&lt;br /&gt;
=Long tests=&lt;br /&gt;
All standard test should execute as fast as possible. Tests that take a longer time to execute (&amp;gt;10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.&lt;br /&gt;
=Large test data=&lt;br /&gt;
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]&lt;br /&gt;
=Testing sending of messages=&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
You can temporarily redirect all messages sent via message_send() to a message sink object. This allows developers to verify that the tested code is sending expected messages.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first disable the use of transactions and then redirect the messaging into a new message sink, you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
$sink = $this-&amp;gt;redirectMessages();&lt;br /&gt;
//... code that is sending messages&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(3, count($messages));&lt;br /&gt;
//.. test messages were generated in correct order with appropriate content&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Testing sending of emails=&lt;br /&gt;
{{Moodle 2.6}}&lt;br /&gt;
You can temporarily redirect emails sent via email_to_user() to a email message sink object. This allows developers to verify that the tested code is sending expected emails.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first unset &#039;noemailever&#039; setting and then redirect the emails into a new message sink where you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
unset_config(&#039;noemailever&#039;);&lt;br /&gt;
$sink = $this-&amp;gt;redirectEmails();&lt;br /&gt;
//... code that is sending email&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(1, count($messages));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Logstores=&lt;br /&gt;
You can test events which were written to a logstore, but you must disable transactions, enable at least one valid logstore, and disable logstore buffering to ensure that the events are written to the database before the tests execute.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
set_config(&#039;enabled_stores&#039;, &#039;logstore_standard&#039;, &#039;tool_log&#039;);&lt;br /&gt;
set_config(&#039;buffersize&#039;, 0, &#039;logstore_standard&#039;);&lt;br /&gt;
get_log_manager(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Check your coverage=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests.&lt;br /&gt;
&lt;br /&gt;
Prior to Moodle 3.7, this coverage would load all files and generate coverage for everything regardless of whether that file could be covered at all, or whether it was intentionally covered.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.7 the &#039;&#039;&#039;phpunit.xml&#039;&#039;&#039; configuration contains generated coverage include and exclude information for each component.&lt;br /&gt;
==Generating include and exclude configuration==&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
You can programatically describe which files will be checked for coverage by creating a &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file alongside the tests that you are writing.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, a default configuration is applied for all plugins and it is not necessary to supply a coverage.php unless you wish to cover additional files.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file allows you to list include and exclude files and folders within the component being&lt;br /&gt;
tested. All paths specified are relative to the component being tested. For example, when working with &#039;&#039;&#039;mod_forum&#039;&#039;&#039; your&lt;br /&gt;
code will be in &#039;&#039;&#039;mod/forum&#039;&#039;&#039;, and its unit tests will be in &#039;&#039;&#039;mod/forum/tests/example_test.php&#039;&#039;&#039;. The coverage file&lt;br /&gt;
for this would be in &#039;&#039;&#039;mod/forum/tests/coverage.php&#039;&#039;&#039; and all paths specified would be relative to &#039;&#039;&#039;mod/forum&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to specify a combination of included files, included folders, excluded files, and excluded folders. This would allow you, for example, to include the entire &#039;&#039;&#039;classes&#039;&#039;&#039; directory, but exclude.a specific file or folder within it.&lt;br /&gt;
&lt;br /&gt;
The following is an example &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file from &#039;&#039;&#039;mod_forum&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Note: For Moodle versions 3.7 to 3.10, the [https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;amp;oldid=58177#Check_your_coverage syntax used] was slightly different.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also, note that you can better define which class or function each test is effectively covering by using the &amp;lt;tt&amp;gt;@covers&amp;lt;/tt&amp;gt; annotation as [https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#specifying-covered-code-parts described in the documention].&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, the following default configuration is applied:{{Moodle 4.0}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;tests/generator&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
        &#039;lib.php&#039;,&lt;br /&gt;
        &#039;locallib.php&#039;,&lt;br /&gt;
        &#039;renderer.php&#039;,&lt;br /&gt;
        &#039;rsslib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If a coverage.php file already exists, then the defaults will be added to the values already defined.&lt;br /&gt;
=Best practice=&lt;br /&gt;
There are several best practices, suggestions, and things to avoid which you should consider when writing unit tests. Some of these are described below.&lt;br /&gt;
==Code coverage==&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests and this is well supported since.Moodle 3.7. We recommend that you consider checking the coverage of your plugins when you write your code.&lt;br /&gt;
&lt;br /&gt;
We recommend that you explicitly set the @covers annotation as described in the [https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnit documentation].&lt;br /&gt;
==Keep use of resetAfterTest to a minimum==&lt;br /&gt;
Although many of the examples described above use the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;resetAfterTest&amp;lt;/syntaxhighlight&amp;gt; nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.&lt;br /&gt;
Generally speaking you should aim to write code which is mockable, and does not require real fixtures.&lt;br /&gt;
Use of resetAfterTest will also slow your tests down.&lt;br /&gt;
==Be careful with shared setUp and instance variables==&lt;br /&gt;
You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:&lt;br /&gt;
# If you create any fixtures in the setUp, or call the resetAfterTest function, these fixtures and conditions will apply for _all_ tests in the testsuite. You will not be able to add another test to the suite which does not require these conditions without those conditions being fulfilled anyway. This can lead to slow tests.&lt;br /&gt;
# PHPUnit creates an instance of each testcase during its bootstrap phase, and does not dispose of it for the lifetime of the test run. Anything which causes data to be stored as instance data within the testcase will be stored in memory until the _entire suite_ completes. This means that any fixture which is setup and not actively discarded will not be garbage collected and lead to memory bloat. In severe cases this can lead to memory exhaustion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing testcases which contain setUp which either generate data, or set resetAfterTest should be phased out, and no new cases should be introduced.&lt;br /&gt;
==Make use of the dataProvider functionality==&lt;br /&gt;
The dataProvider functionality of PHPUnit is an extremely powerful and useful feature which allows you to verify a function quickly and easily with a range of different conditions.&lt;br /&gt;
However, the following rules should be followed when using dataProviders:&lt;br /&gt;
* Keep addition of resettable data requiring resetAfterTest to a minimum - this will lead to many slow tests&lt;br /&gt;
* Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation. The dataProvider is called after the testSuite is instantiated, but before any tests are run. Each test will run a full setUp and tearDown, which will destroy any data which was created.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Test function accepts parameters passed from the specified data provider.&lt;br /&gt;
 *&lt;br /&gt;
 * @dataProvider foobar_provider&lt;br /&gt;
 * @param int $foor&lt;br /&gt;
 * @param int $bar&lt;br /&gt;
 */&lt;br /&gt;
public function test_foobar(int $foo, int $bar) {&lt;br /&gt;
    // Perform the tests here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Data provider for {@see self::test_foobar()}.&lt;br /&gt;
 *&lt;br /&gt;
 * @return array List of data sets - (string) data set name =&amp;gt; (array) data&lt;br /&gt;
 */&lt;br /&gt;
public function foobar_provider(): array {&lt;br /&gt;
    return [&lt;br /&gt;
        &#039;Same numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 42,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 42,&lt;br /&gt;
        ],&lt;br /&gt;
        &#039;Different numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 21,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 84,&lt;br /&gt;
        ],&lt;br /&gt;
    ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Extra test settings=&lt;br /&gt;
Usually the test should not interact with any external systems and it should work the same on all systems. But sometimes you need to specify some option for connection to external systems or system configuration. It is intentionally not possible to use $CFG settings from config.php.&lt;br /&gt;
&lt;br /&gt;
There are several ways how to inject your custom settings:&lt;br /&gt;
* define test setting constants in your phpunit.xml file&lt;br /&gt;
* define test setting constants in your config.php&lt;br /&gt;
These constants may be then used in your test or plugin code.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 4.4 and up (PHPUnit 9.6)=&lt;br /&gt;
{{Moodle 4.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 4.4, &#039;&#039;&#039;PHPUnit was upgraded to 9.6&#039;&#039;&#039; (from 9.5 being used in previous versions). This was done to &#039;&#039;&#039;warn to developers in advance&#039;&#039;&#039; about functionality that has been deprecated in the 9.5 series and will be removed so will stop working with the next major update to PHPUnit 10.x (see MDL-81266 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While everything should continue working without modification with PHPUnit 9.6, you will may get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be analysed&#039;&#039;&#039;, replacing or removing them as soon as possible, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/commit/28892562ca4c06f4f57ca1588c04e608b3d0e22c lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* MDL-81281. A number of attribute-related assertions have been deprecated, will be removed with PHPUnit 10. Alternatives for &#039;&#039;&#039;some&#039;&#039;&#039; of them are available:&lt;br /&gt;
  - assertClassHasAttribute()&lt;br /&gt;
  - assertClassNotHasAttribute()&lt;br /&gt;
  - assertClassHasStaticAttribute()&lt;br /&gt;
  - assertClassNotHasStaticAttribute()&lt;br /&gt;
  - assertObjectHasAttribute()         =&amp;gt; assertObjectHasProperty()&lt;br /&gt;
  - assertObjectNotHasAttribute()      =&amp;gt; assertObjectNotHasProperty()&lt;br /&gt;
* MDL-81266. A number of deprecation, notice, warning and error expectations have been deprecated, will be removed with PHPUnit 10. No alternative exists. A working replacement is available in the linked issue, hopefully there aren&#039;t many cases.&lt;br /&gt;
  - expectDeprecation()&lt;br /&gt;
  - expectDeprecationMessage()&lt;br /&gt;
  - expectDeprecationMessageMatches()&lt;br /&gt;
  - expectError()&lt;br /&gt;
  - expectErrorMessage()&lt;br /&gt;
  - expectErrorMessageMatches()&lt;br /&gt;
  - expectNotice()&lt;br /&gt;
  - expectNoticeMessage()&lt;br /&gt;
  - expectNoticeMessageMatches()&lt;br /&gt;
  - expectWarning()&lt;br /&gt;
 - expectWarningMessage()&lt;br /&gt;
 - expectWarningMessageMatches()&lt;br /&gt;
* MDL-81308. The &amp;lt;tt&amp;gt;-&amp;gt;withConsecutive()&amp;lt;/tt&amp;gt; functionality on PHPUnit mocks has been &#039;&#039;&#039;silently&#039;&#039;&#039; deprecated, will be removed with PHPUnit 10. Note that this won&#039;t affect PHPUnit 9.6 runs and an alternative path will be proposed in the linked issue, part of the PHPUnit 10 epic.&lt;br /&gt;
* &amp;lt;tt&amp;gt;PHPUnit\Framework\TestCase::getMockClass()&amp;lt;/tt&amp;gt; has been deprecated, will be removed with PHPUnit 10. No clear alternative exists and won&#039;t be investigated, because there aren&#039;t case in core.&lt;br /&gt;
* Cannot use the &amp;lt;tt&amp;gt;Test&amp;lt;/tt&amp;gt; suffix on abstract test case classes. Proceed to rename them to end with &amp;lt;tt&amp;gt;TestCase&amp;lt;/tt&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.11 and up (PHPUnit 9.5)=&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.11, &#039;&#039;&#039;PHPUnit was upgraded to 9.5&#039;&#039;&#039; (from 8.5 being used in previous versions). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.11 (7.3, 7.4 and [[Moodle and PHP|8.0]]) (see MDL-71036 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While a lot of existing tests will work without modification with PHPUnit 9.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 9.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2020/02/migrating-to-phpunit-9 A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-9.html PHPUnit 9 release Announcement].&lt;br /&gt;
* These multiple detailed changelogs (because all them have included modifications requiring changes): [https://github.com/sebastianbergmann/phpunit/blob/9.0.0/ChangeLog-9.0.md 9.0], [https://github.com/sebastianbergmann/phpunit/blob/9.1.0/ChangeLog-9.1.md 9.1], [https://github.com/sebastianbergmann/phpunit/blob/9.3.0/ChangeLog-9.3.md 9.3], [https://github.com/sebastianbergmann/phpunit/blob/9.5.0/ChangeLog-9.5.md 9.5]&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/9.5/ Official PHPUnit manual].&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/e3a46964dc6d8ca1558c6e1e8dfdf3c1745eeaed/lib/upgrade.txt#L5-L65 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* All the changes that were deprecated with PHPUnit 8.5 (see the section below) are now removed and will lead to errors.&lt;br /&gt;
* &amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt; now performs stricter comparison (like &amp;lt;tt&amp;gt;assertSame()&amp;lt;/tt&amp;gt; does). New &amp;lt;tt&amp;gt;assertContainsEquals()&amp;lt;/tt&amp;gt; has been created to provide the old behavior.&lt;br /&gt;
* Changes to the &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; schema, mostly internal. These only will impact if you are using custom &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; files:&lt;br /&gt;
** The previous &amp;lt;tt&amp;gt;&amp;lt;filter&amp;gt;&amp;lt;/tt&amp;gt; section is now (better) called &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;. And, within it:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; has been replaced by &amp;lt;tt&amp;gt;&amp;lt;include&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;exclude&amp;gt;&amp;lt;/tt&amp;gt; is not a child of &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; anymore, but of &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** But with implications when defining the [[#Check your coverage|coverage information]] because &amp;lt;tt&amp;gt;$whitelistxxx&amp;lt;/tt&amp;gt; properties used by the &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; files have been deprecated, instead use &amp;lt;tt&amp;gt;includelistfolders&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;includelistfiles&amp;lt;/tt&amp;gt; (to better map the elements in the xml).&lt;br /&gt;
* Warning: It&#039;s not possible to run individual test files any more. Use any of the alternative execution methods (filter, suite, config) to specify which tests you want to run. This will be hopefully fixed in MDL-71049 once it has been agreed which the best way to proceed is.&lt;br /&gt;
* Deprecations, deprecations, deprecations. Lots of them in often used assertions: file assertions, regexp assertions, exception expectations... again, note that all them will become errors with the next PHPUnit update, so &#039;&#039;&#039;the recommendation is to update them ASAP&#039;&#039;&#039;.&lt;br /&gt;
Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/fc335f5...713722c browse the changes associated with the issue], hopefully with useful explanations in the commit messages.&lt;br /&gt;
&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.10 and up (PHPUnit 8.5)=&lt;br /&gt;
{{Moodle 3.10}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.10, &#039;&#039;&#039;PHPUnit was upgraded to 8.5&#039;&#039;&#039; (from 7.5 being used in older version). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.10 (7.2, 7.3 and 7.4) and also to provide an &#039;&#039;&#039;easier jump to PHPUnit 9.x&#039;&#039;&#039; that will be needed for Moodle 3.11 (php versions 7.3, 7.4 and 8.0), removing a lot of deprecated stuff in advance. (see MDL-67673 and MDL-64600 for more details).&lt;br /&gt;
&lt;br /&gt;
While 99% of existing tests will work without modification with PHPUnit 8.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 8.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2019/02/help-my-tests-stopped-working A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-8.html PHPUnit 8 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/130104cf796a88dd1547dc5beb8bd555c2deb55e/ChangeLog-8.0.md Detailed changelog of the release].&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/8.5/ Official PHPUnit manual].&lt;br /&gt;
* A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/6594c54b2eef62499d304bfa0939999e3a14246e/lib/upgrade.txt#L5-L37 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
** Support for PHP 7.0 dropped (because all template methods (&amp;lt;tt&amp;gt;setUp()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tearDown()&amp;lt;/tt&amp;gt;..) now require to return void. This will mostly impact 3rd-part plugins that were still running the same tests against old branches of Moodle with PHP 7.0 support.&lt;br /&gt;
** &amp;lt;tt&amp;gt;PHPUnit/DBUnit&amp;lt;/tt&amp;gt; has been removed are replaced by a lightweight alternative.&lt;br /&gt;
** Deprecations, deprecations, deprecations. Lots of them in often used assertions (&amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;assertEquals()&amp;lt;/tt&amp;gt;...) and also &amp;lt;tt&amp;gt;@expectedExceptionXXX&amp;lt;/tt&amp;gt; annotations. Again, note that all them will become errors with PHPUnit 9.&lt;br /&gt;
* Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/5903054...b13ec3c browse the changes associated with the issue], hopefully with useful enough explanations in the commit messages.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.7 and up (PHPUnit 7.5)=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.7, &#039;&#039;&#039;PHPUnit was upgraded to 7.5&#039;&#039;&#039; (from 6.x being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.7 (7.1, 7.2 and 7.3). (see MDL-65204 and linked issues for more details). While internally [https://phpunit.de/announcements/phpunit-7.html a lot of things changed with PHPUnit 7] (PHP 7.1-isms, typed signatures, void returns, assertEquals() changes), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 7, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-7.html  PHPUnit 7 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/520723129e2b3fc1dc4c0953e43c9d40e1ecb352/ChangeLog-7.5.md Detailed changelog of the release], paying special attention to the added, deprecated, changed and deleted sections.&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/7.5/ Official PHPUnit manual].&lt;br /&gt;
* Changes performed into core, mainly: new, stricter, signatures ([https://github.com/moodle/moodle/commit/26218b7 26218b7]) and assertEquals() changes, specially important when comparing strings, now performed using strict (===) equals ([https://github.com/moodle/moodle/commit/85f47ba 85f47ba]).&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.4 and up (PHPUnit 6)=&lt;br /&gt;
{{Moodle 3.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.4, &#039;&#039;&#039;PHPUnit was upgraded to 6.4&#039;&#039;&#039; (from 5.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.4 (7.0, 7.1 and 7.2). (see MDL-60611 and linked issues for more details). While internally [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues a lot of things changed with PHPUnit 6] (namespaced classes being the more noticeable), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
Still, in &#039;&#039;&#039;some cases, it will impossible to maintain compatibility&#039;&#039;&#039; of tests between old (pre 3.4) tests and new ones, especially &#039;&#039;&#039;when direct use of any phpunit class is performed&#039;&#039;&#039;. Luckily, both GitHub Actions and CI tests will detect this situation and it shouldn&#039;t be hard to keep all supported branches in core passing ok. Plugins may be trickier, if the same branch is attempting to work against multiple core branches and they are using some phpunit class directly.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 6, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2017/02/migrating-to-phpunit-6 A very good mini-guide] showing all the important changes.&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues PHPUnit 6 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/9d0c024d2099531442d862b66b0ad7cf35ed8e78/ChangeLog-6.0.md Detailed changelog of the release], paying special attention to the changed and deleted sections.&lt;br /&gt;
* Changes performed into core, mainly: namespace class renaming ([https://github.com/moodle/moodle/commit/801a372dadb6e11c8781547603e3f0a59ce5638f 801a372]) and deprecated stuff ([https://github.com/moodle/moodle/commit/796e48a58bf18533bdca423fff7949ab119101c4 796e48a])&lt;br /&gt;
=See also=&lt;br /&gt;
* [[PHPUnit integration]]&lt;br /&gt;
* [[PHPUnit]]&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=XMLDB_Defining_one_XML_structure&amp;diff=63994</id>
		<title>XMLDB Defining one XML structure</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=XMLDB_Defining_one_XML_structure&amp;diff=63994"/>
		<updated>2023-09-10T15:00:09Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Redirected page to XMLDB defining an XML structure&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[XMLDB defining an XML structure]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=XMLDB_defining_an_XML_structure&amp;diff=63993</id>
		<title>XMLDB defining an XML structure</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=XMLDB_defining_an_XML_structure&amp;diff=63993"/>
		<updated>2023-09-10T14:50:24Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: MDL-76459 - expand database identifiers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[XMLDB Documentation|XMLDB Documentation]] &amp;gt; [[XMLDB roadmap|Roadmap]] &amp;gt; Defining one XML structure&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
&lt;br /&gt;
Moodle supports a number of Database Engines, including MySQL, MariaDB, Postgresql, OCI, and MS SQL Server. Each of&lt;br /&gt;
these has a slightly different format for some of their table creation statements.&lt;br /&gt;
&lt;br /&gt;
XMLDB has been created as a standardised format to describe the structure of the database in a human-readable format&lt;br /&gt;
which the Moodle installer can turn into DDL commands to create the database structure.&lt;br /&gt;
&lt;br /&gt;
The Moodle XMLDB editor must be used to correctly define the XMLDB structure for all tables within Moodle. It is also able to convert the XMLDB structure into upgrade scripts which can be copied and pasted into Moodle &amp;lt;tt&amp;gt;upgrade.php&amp;lt;/tt&amp;gt; files.&lt;br /&gt;
&lt;br /&gt;
== The XMLDB editor ==&lt;br /&gt;
[[XMLDB_editor | Main article]]&lt;br /&gt;
&lt;br /&gt;
Although the XML is pretty simple to read (and to write), one of the major drawbacks was its easy and error-prone adoption by the developers. Also some problems with versioning systems getting crazy with XML files (thanks ML!) pointed us to the requirement to use one high-density format (it means, physically &#039;&#039;&#039;long lines&#039;&#039;&#039;) in our XML files. &lt;br /&gt;
&lt;br /&gt;
After some intense thoughts we decided to build one specialised editor for our XML format. This editor should be easy to use and provide support for all the objects present one Moodle DB. And it&#039;s done (and will support future enhancements easily, we hope).&lt;br /&gt;
&lt;br /&gt;
The XMLDB Editor makes the addition of tables/fields/keys/indexes practically a trivial task, allowing the developer to spend  the time coding and improving things instead of fighting against XML files and the errors caused by manual editing (of course, the developer is free to use such extra-time as desired, beers, dance, books, music...) ;-)&lt;br /&gt;
&lt;br /&gt;
All the new &#039;&#039;&#039;install.xml&#039;&#039;&#039; files, present under each &#039;&#039;&#039;db&#039;&#039;&#039; directory in Moodle can be edited (and we recommend it) with just some clicks and keystrokes. Those &#039;&#039;&#039;install.xml&#039;&#039;&#039; will contain all the info needed to generate the specific objects needed for each RDBMS supported. Obviously, such files, are the neutral replacement for all the *.sql files used until now.&lt;br /&gt;
&lt;br /&gt;
=== Launching ===&lt;br /&gt;
&lt;br /&gt;
Just login to your server as an administrator and, under the Development tab of the Administration Block, you&#039;ll see a new link pointing to the &amp;quot;XMLDB Editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
One &#039;&#039;&#039;important note&#039;&#039;&#039; is that, to be able to handle files properly, the web server needs write access to all those &amp;quot;db&amp;quot; directories where the &amp;quot;install.xml&amp;quot; files reside (and to the files themselves, of course). ;-)&lt;br /&gt;
&lt;br /&gt;
That&#039;s all!&lt;br /&gt;
&lt;br /&gt;
=== Use===&lt;br /&gt;
&lt;br /&gt;
We really think the XMLDB Editor is pretty easy to use, so here you won&#039;t see a complete guide to use it. We highly recommend you to play with it for a while, viewing how it works and how it modifies the &#039;&#039;&#039;install.xml&#039;&#039;&#039; files.&lt;br /&gt;
&lt;br /&gt;
It&#039;s organised in a top-bottom structure, where you start &#039;&#039;&#039;loading&#039;&#039;&#039; (or &#039;&#039;&#039;creating&#039;&#039;&#039;) a new XMLDB file. Then, you can &#039;&#039;&#039;edit&#039;&#039;&#039; such file and its &#039;&#039;&#039;general structure&#039;&#039;&#039; will be showed. This structure has one type of elements, &#039;&#039;&#039;tables&#039;&#039;&#039;  and the XMLDB Editor allows you to &#039;&#039;&#039;add&#039;&#039;&#039;, &#039;&#039;&#039;edit&#039;&#039;&#039;, &#039;&#039;&#039;delete&#039;&#039;&#039;, and &#039;&#039;&#039;move&#039;&#039;&#039; them easily.  Additionally it is possible to turn an existing table (under MySQL and MariaDB) into an XMLDB structure, allowing you to retrofit any table from the DB to XMLDB Editor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you can&#039;t click on the create links....&#039;&#039;&#039; you must first create the /db folder (as shown in the list, but it may not really exist) and then make sure it is writeable by the webserver&lt;br /&gt;
&lt;br /&gt;
While editing tables you will see their &#039;&#039;&#039;fields&#039;&#039;&#039;, &#039;&#039;&#039;keys&#039;&#039;&#039; and &#039;&#039;&#039;indexes&#039;&#039;&#039; and you&#039;ll be able to handle all them easily. Note that some fields can be no-editable. It uses to be because they are being used in some way (part of one key or index) and the idea is to warn you about that.&lt;br /&gt;
&lt;br /&gt;
Fields can be edited and you can specify their &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039;, &#039;&#039;&#039;length&#039;&#039;&#039;, &#039;&#039;&#039;decimals&#039;&#039;&#039;, &#039;&#039;&#039;null-ability&#039;&#039;&#039;, &#039;&#039;&#039;defaults&#039;&#039;&#039; and so one. Exactly the same for both &#039;&#039;&#039;keys&#039;&#039;&#039; and &#039;&#039;&#039;indexes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
One interesting feature is that all the XMLDB Editor pages allow you to enter one &#039;&#039;&#039;comment&#039;&#039;&#039; about the item being modified (table, index, key, field, etc). Use it at your entire needs, sure it helps other developers to understand a bit more the DB model.&lt;br /&gt;
&lt;br /&gt;
Please, don&#039;t forget to read and understand the next section, where we talk about &#039;&#039;&#039;some important guidelines&#039;&#039;&#039; to create and handle XMLDB files.&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
&lt;br /&gt;
Apart of the [[Database| Database Structures guidelines]], some more conventions should be followed:&lt;br /&gt;
&lt;br /&gt;
# About names:&lt;br /&gt;
## All lowercase names (tables, indexes, keys and fields).&lt;br /&gt;
## Table names and field names must use only a-z, 0-9 and _ chars. Table names can be at most 53 characters long (28 before Moodle 4.3); column names at most 63 characters long (30 before Moodle 4.3).&lt;br /&gt;
## Key and index names under the XMLDB Files must be formed by concatenating the name of the fields present in the key/index with the &#039;&amp;quot;-&amp;quot; (minus) character.&lt;br /&gt;
## Primary key always must be named &amp;quot;primary&amp;quot; (this is one exception to the previous convention).&lt;br /&gt;
## It&#039;s highly recommended to avoid [[XMLDB_reserved_words|reserved words]] completely. We know we have some of them now but they should be completely out for next releases.&lt;br /&gt;
# About NULLS&lt;br /&gt;
## Avoid creating all the fields as NOT NULL with the &#039;&#039;silly&#039;&#039; default value &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; (empty string). The underlying code used to create tables will handle it properly but the XMLDB structure must be REAL. Read more in the [[XMLDB_Problems#NOT_NULL_fields_using_a_DEFAULT_.27.27_clause|Problems Page]].&lt;br /&gt;
# About FOREIGN KEYS&lt;br /&gt;
## Under the tables of every XMLDB file, you must define the existing &#039;&#039;&#039;Foreign Keys&#039;&#039;&#039; (FK) properly. This will allow everybody to know a bit better the structure, allow to evolve to a better constrained system in the future and will provide the underlying code with the needed info to create the proper indexes. &lt;br /&gt;
## Note that, if you define any field combination as FK you won&#039;t have to create any index on that fields, the code will do it automatically! &lt;br /&gt;
## Respect Convention 1.3&lt;br /&gt;
# About UNIQUE KEYS&lt;br /&gt;
## Declare any fields as UNIQUE KEY (UK) only if they are going to be used as target for one FK. Create unique indexes instead.&lt;br /&gt;
## Respect Convention 1.3&lt;br /&gt;
&lt;br /&gt;
== One example: the assignment module ==&lt;br /&gt;
&lt;br /&gt;
Here we are going to examine the [http://cvs.moodle.org/moodle/mod/assignment/db/install.xml?view=markup current implementation of the XMLDB Schema for the assignment module] (a simple one). It has been completely generated with the XMLDB Editor but it&#039;s nice to know a bit more about the XML internals.&lt;br /&gt;
&lt;br /&gt;
As you can see the structure is pretty simple:&lt;br /&gt;
&lt;br /&gt;
* XMLDB&lt;br /&gt;
** TABLES, one or more, each one with&lt;br /&gt;
*** FIELDS&lt;br /&gt;
*** KEYS&lt;br /&gt;
*** INDEXES&lt;br /&gt;
*** SENTENCES&lt;br /&gt;
&lt;br /&gt;
First of all you should note that all the elements contain the &#039;&#039;&#039;PREVIOUS&#039;&#039;&#039; and &#039;&#039;&#039;NEXT&#039;&#039;&#039; attributes. They allow us to keep everything ordered although it isn&#039;t meaningful at all from the RDBMS perspective. Also the &#039;&#039;&#039;COMMENT&#039;&#039;&#039; field is present everywhere to be used as desired.&lt;br /&gt;
&lt;br /&gt;
=== The TABLE element ===&lt;br /&gt;
&lt;br /&gt;
We can ignore the TABLE element, as it&#039;s simply one container for the internals (FIELDS, KEYS and INDEXES). Let&#039;s go to examine them a bit more:&lt;br /&gt;
&lt;br /&gt;
==== The FIELD element ====&lt;br /&gt;
&lt;br /&gt;
It maps with one field in the DB (obviously). For each field you can define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039; (from a list of [[XMLDB column types|neutral types]]), &#039;&#039;&#039;length&#039;&#039;&#039;, &#039;&#039;&#039;decimals&#039;&#039;&#039; (for some types), &#039;&#039;&#039;notnull&#039;&#039;&#039; (true/false), &#039;&#039;&#039;unsigned&#039;&#039;&#039; (true/false), &#039;&#039;&#039;sequence&#039;&#039;&#039; (if it&#039;s autonumeric or serial, true/false) and &#039;&#039;&#039;default&#039;&#039;&#039; (to assign a default value).&lt;br /&gt;
&lt;br /&gt;
So, in our example, we have two tables, assignment and assignment_submissions, each one with its own fields, defining all the information related above. Please note that naming conventions are followed.&lt;br /&gt;
&lt;br /&gt;
==== The KEY element ====&lt;br /&gt;
&lt;br /&gt;
Here is where all the PRIMARY KEYS (PK), UNIQUE KEYS (UK) and FOREIGN KEYS (FK) will be defined. For each key we define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039;, &#039;&#039;&#039;fields&#039;&#039;&#039; (that belongs to it) and optionally (if the key is one FK) the target &#039;&#039;&#039;reftable&#039;&#039;&#039; and &#039;&#039;&#039;reffields&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In our example, the assignment table has one (mandatory!) PK (called, &amp;quot;primary&amp;quot;, rules are rules) built with the &amp;quot;id&amp;quot; field. &lt;br /&gt;
&lt;br /&gt;
The other table, the &amp;quot;assignment_submissions&amp;quot; one, also has its PK (called &amp;quot;primary&amp;quot; once more) and one FK, with the field &amp;quot;assignment&amp;quot; pointing to the field &amp;quot;id&amp;quot; of the table &amp;quot;assignment&amp;quot;. Note that the FK follows the name conventions and its name is, simply, the name of the fields being part of it (&amp;quot;assignment&amp;quot;). Also, the FK has as target to one PK of the same module.&lt;br /&gt;
&lt;br /&gt;
Finally, note that there isn&#039;t any index created for all these keys. Moodle will generate them automatically when the table is created. All the keys will have their corresponding index. Point. ;-)&lt;br /&gt;
&lt;br /&gt;
==== The INDEX element ====&lt;br /&gt;
&lt;br /&gt;
Where all the indexes will be defined. For each index you can define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;unique&#039;&#039;&#039; (true/false) and the &#039;&#039;&#039;fields&#039;&#039;&#039; (as a comma-separated string) that it comprises. Please note that naming conventions are followed.&lt;br /&gt;
&lt;br /&gt;
Also, some &amp;quot;obvious index&amp;quot;, like the one based in the &amp;quot;assignment&amp;quot; field of the &amp;quot;assignment_submissions&amp;quot; table doesn&#039;t exist. Yes, you know why: Because such column has been defined as a FK and the index will be automatically created (see previous section).&lt;br /&gt;
&lt;br /&gt;
== DTD and XML schema ==&lt;br /&gt;
&lt;br /&gt;
Not sure if this will be usable for somebody but here you can find one [http://cvs.moodle.org/moodle/lib/xmldb/xmldb.dtd?view=co automatically generated DTD] for the XMLDB files. Also one [http://cvs.moodle.org/moodle/lib/xmldb/xmldb.xsd?view=co automatically generated XML Schema] is available. Any improvement/fix to them will be welcome!&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[XMLB List of files to create|List of files to create]]: The list of files to be created from scratch. Used to follow the progress.&lt;br /&gt;
* http://www.hitsw.com/xml_utilites/: One online XML-DTD-Schema converter.&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_XMLDB&amp;diff=63992</id>
		<title>Using XMLDB</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_XMLDB&amp;diff=63992"/>
		<updated>2023-09-10T14:24:03Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: MDL-76459 - expand database identifiers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This page is a work in progress. It is intended to help developers of third-party modules, and other plugins, to help them switch to XMLDB.&lt;br /&gt;
&lt;br /&gt;
==What is XMLDB and how can it help you==&lt;br /&gt;
&lt;br /&gt;
XMLDB stores the database definition in an XML format that can be used to install Moodle on any database. Everywhere in Moodle now uses XMLDB.&lt;br /&gt;
&lt;br /&gt;
In every module (or other plugin) folder, there is a &#039;&#039;db/&#039;&#039; folder where the database structure is stored. In the past, this used to contain separate files &#039;&#039;mysql.php&#039;&#039;, &#039;&#039;mysql.sql&#039;&#039;, etc. for different databases. It meant that you had to create different files for each database system. If there were more databases you wanted your module to be compatible with, you had to create more files. Switching to XMLDB means that you only have to create one file, and there is an editor to help you, so it saves you time.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The XMLDB database definition is stored in the file &#039;&#039;db/install.xml&#039;&#039;. You can use a built-in XMLDB editor to create or edit any &#039;&#039;install.xml&#039;&#039; files. If you&#039;re using MySQL as your default database schemes. XMLDB editor&#039;s powerful tools allowing retrofit MySQL table to XMLDB format.&lt;br /&gt;
&lt;br /&gt;
The XMLDB editor is located in administration block, go to &#039;&#039;Miscellaneous &amp;gt; XMLDB editor&#039;&#039;. Find your module name. Initially you won&#039;t be able to click on &#039;&#039;Create&#039;&#039; link and also can&#039;t edit your module (If the &#039;&#039;Create&#039;&#039; link is clickable you can skip this step). Since you must make your module folder has write permission first (And if you haven&#039;t created &#039;&#039;db/&#039;&#039; folder in your module folder yet, create it now). In Linux operating system, &#039;&#039;chmod&#039;&#039; your &#039;&#039;/db&#039;&#039; folder to 777 solves this. Now you&#039;re ready to create your module&#039;s XMLDB files.&lt;br /&gt;
&lt;br /&gt;
Note that XMLDB editor is not a tool for creating your module, though it can help you with the database. It is a tool to manage XMLDB database file (think about phpmyadmin manages SQL database). You can create tables/fields/keys/indexes or export your existing MySQL tables to XMLDB.&lt;br /&gt;
&lt;br /&gt;
Another XMLDB&#039;s advantage is you can create table comments as you want. To describe it to other developer.&lt;br /&gt;
&lt;br /&gt;
XMLDB editor is really easy to work with. We strongly recommend you to play with it for a while and read [[XMLDB editor]] and  about XMLDB structure [[XMLDB defining an XML structure]].&lt;br /&gt;
&lt;br /&gt;
===Create &#039;&#039;install.xml&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
If you never create &#039;&#039;install.xml&#039;&#039; before (your &#039;&#039;db/&#039;&#039; doesn&#039;t have &#039;&#039;install.xml&#039;&#039;), click &#039;&#039;Create&#039;&#039; first. install.xml will store your database info for this module.&lt;br /&gt;
&lt;br /&gt;
===Start editing===&lt;br /&gt;
&lt;br /&gt;
To start editing &#039;&#039;install.xml&#039;&#039;, click &#039;&#039;Load&#039;&#039; and then &#039;&#039;Edit&#039;&#039;. You need to do this every time before editing any XMLDB file.  If this is your first time, there is a default table named like your module stored.&lt;br /&gt;
&lt;br /&gt;
===Create new table===&lt;br /&gt;
&lt;br /&gt;
# Go to &#039;&#039;New Table&#039;&#039;.&lt;br /&gt;
# Enter table name and comment, click &#039;&#039;change&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Add field in table===&lt;br /&gt;
&lt;br /&gt;
# Click &#039;&#039;Edit&#039;&#039; on your desired table.&lt;br /&gt;
# Click &#039;&#039;New Field&#039;&#039;, You can now edit field information like name, comment, type, length, etc. See [[XMLDB column types]] for XMLDB column type comparing with other database system.&lt;br /&gt;
# When you&#039;re done, click &#039;&#039;Change&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Retrofit MySQL table to XMLDB===&lt;br /&gt;
&lt;br /&gt;
XMLDB editor can retrofit MySQL table to XMLDB. In other word, it can create XMLDB table from existing SQL. This is useful if your module database already using MySQL.&lt;br /&gt;
First, your module has to be installed. Then follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Click &#039;&#039;New Table from MySQL&#039;&#039;&lt;br /&gt;
# In &#039;&#039;Create Table&#039;&#039; box, choose your table from MySQL database. In &#039;&#039;After Table&#039;&#039; choose where would you like to add this table to (It doesn&#039;t matter, just for arrangement). Click &#039;&#039;Create&#039;&#039;.&lt;br /&gt;
# Do it again until every table added, you are done!&lt;br /&gt;
&lt;br /&gt;
Note: Table name must contains only lowercase character, number, underscore and length must not exceed 53 characters (28 before Moodle 4.3). More info here: [[XMLDB defining an XML structure]]&lt;br /&gt;
&lt;br /&gt;
===Other operation===&lt;br /&gt;
&lt;br /&gt;
It&#039;s intuitive once you use it. There are visible links for editing, moving up or down and deleting.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[XMLDB editor]]&lt;br /&gt;
*[[XMLDB introduction]]&lt;br /&gt;
*[[XMLDB defining an XML structure]]&lt;br /&gt;
*[[XMLDB column types]]&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Database&amp;diff=63991</id>
		<title>Database</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Database&amp;diff=63991"/>
		<updated>2023-09-10T12:37:20Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: MDL-76459 - expand database identifiers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Database structures==&lt;br /&gt;
&lt;br /&gt;
To help you create tables that meet these guidelines, we recommend you use the built in [[XMLDB_defining_an_XML_structure#The_XMLDB_editor|database definition (XMLDB) editor]].&lt;br /&gt;
&lt;br /&gt;
There are [[Moodle_versions#How_to_increment_version_numbers_in_core|rules for how what numbers to use in version.php files in Moodle core]].&lt;br /&gt;
&lt;br /&gt;
# Every table must have an auto-incrementing id field (INT10) as primary key. (see [[IdColumnReasons]])&lt;br /&gt;
# The main table containing instances of each module must have the same name as the module (eg widget) and contain the following minimum fields:&lt;br /&gt;
#* id - as described above&lt;br /&gt;
#* course - the id of the course that each instance belongs to&lt;br /&gt;
#* name - the full name of each instance of the module&lt;br /&gt;
# Other tables associated with a module that contain information about &#039;things&#039; should be named widget_things (note the plural).&lt;br /&gt;
# Core tables in general should have single word names non-pluralised, and double word names pluralised only for the last word e.g. &#039;course&#039;, &#039;course_categories&#039;. The only exceptions should be for reserved words e.g. &#039;files&#039;. Some tables don&#039;t fit this pattern right now for historical reasons, but this will eventually be changed.&lt;br /&gt;
# Table and column names should avoid using [[XMLDB_reserved_words|reserved words in any database]]. Please check them before creation. Table names may be up to 53 characters long (only 28 before Moodle 4.3), and Column names up to 63 characters long (only 30 before Moodle 4.3). &lt;br /&gt;
# Column names should be always lowercase, simple and short, following the same rules as for variable names.&lt;br /&gt;
# Where possible, columns that contain a reference to the id field of another table (eg widget) should be called widgetid. (Note that this convention is newish and not followed in some older tables)&lt;br /&gt;
# Boolean fields should be implemented as small integer fields (eg INT4) containing 0 or 1, to allow for later expansion of values if necessary.&lt;br /&gt;
# Most tables should have a timemodified field (INT10) which is updated with a current timestamp obtained with the PHP time() function.&lt;br /&gt;
# Always define a default value for each field (and make it sensible)&lt;br /&gt;
# Each table name should start with the database prefix ($CFG-&amp;gt;prefix). In a lot of cases, this is taken care of for you automatically. Also, under Postgres, the name of every index must start with the prefix too. Note that, since Moodle 4.3 the max allowed prefix length is 10 characters.&lt;br /&gt;
# &amp;lt;span id=&amp;quot;as_keyword&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;In order to guarantee [[XMLDB problems#Table and column aliases - the AS keyword|cross-db compatibility]] follow these simple rules about the use of the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword (only if you need table/column aliases, of course):&lt;br /&gt;
#* &#039;&#039;&#039;Don&#039;t use&#039;&#039;&#039; the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword for &#039;&#039;&#039;table aliases&#039;&#039;&#039;.&lt;br /&gt;
#* &#039;&#039;&#039;Don&#039;t use&#039;&#039;&#039; &#039;&#039;&#039;table aliases&#039;&#039;&#039; at all for DELETE statments (Mysql doesn&#039;t like it).&lt;br /&gt;
#* &#039;&#039;&#039;Do use&#039;&#039;&#039; the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword for &#039;&#039;&#039;column aliases&#039;&#039;&#039;.&lt;br /&gt;
# &#039;&#039;&#039;Never&#039;&#039;&#039; create UNIQUE KEYs (constraints) at all. Instead use UNIQUE INDEXes. In the future, if we decide to add referential integrity to Moodle and we need UNIQUE KEYs they will be used, but not now. Please note that the XMLDB editor allows you to specify both XMLDB-only UNIQUE and FOREIGN constraints (and that&#039;s good, in order to have the XML well defined) but only underlying INDEXes will be generated. &lt;br /&gt;
# Those XMLDB-only UNIQUE KEYs (read previous point) only must be defined if such field/fields &#039;&#039;&#039;are going to be the target&#039;&#039;&#039; for some (XMLDB-only too) FOREIGN KEY. Else, create them as simple UNIQUE INDEXes.&lt;br /&gt;
# Tables associated &#039;&#039;&#039;with one block&#039;&#039;&#039; must follow this convention with their names: &#039;&#039;&#039;$CFG-&amp;gt;prefix + &amp;quot;block_&amp;quot; + name_of_the_block + anything_else&#039;&#039;&#039;. For example, assuming that $CFG-&amp;gt;prefix is &#039;mdl_&#039;, all the tables for the block &amp;quot;rss_client&amp;quot; must start by &#039;mdl_block_rss_client&#039; (being possible to add more words at the end, i.e. &#039;mdl_block_rss_client_anothertable&#039;...). This rule will be 100% enforced with Moodle 2.0, giving time to developers until then. See [http://tracker.moodle.org/browse/MDL-6786 Task 6786] for more info about this.&lt;br /&gt;
# &#039;&#039;&#039;Never&#039;&#039;&#039; make database changes in the STABLE branches.  If we did, then users upgrading from one stable version to the next would have duplicate changes occurring, which may cause serious errors.&lt;br /&gt;
# When refering to integer variable in SQL queries, do not surround the value in quotes. For example, get_records_select(&#039;question&#039;, &amp;quot;category=$catid&amp;quot;) is right. get_records_select(&#039;question&#039;, &amp;quot;category=&#039;$catid&#039;&amp;quot;) is wrong. It hides bugs where $catid is undefined. ([http://moodle.org/mod/forum/discuss.php?d=80629 This thread explains].)&lt;br /&gt;
# Never use double quotes for variable values in SQL queries (e.g. &amp;lt;strike&amp;gt;&#039;SELECT * FROM {user} WHERE username = &amp;quot;someuser&amp;quot;&#039;&amp;lt;/strike&amp;gt;). While this is OK for MySQL, which does not respect ANSI standard for databases, Postgresql is treating double quoted variable this as system identifier (e.g. field name).&lt;br /&gt;
# Moodle does not support database &amp;quot;views&amp;quot;, don&#039;t use them. See Petr&#039;s comment on [http://tracker.moodle.org/browse/MDL-25407 Task 25407] for more info about this.&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|Database]]&lt;br /&gt;
[[Category:DB|Database]]&lt;br /&gt;
[[Category:XMLDB|Database]]&lt;br /&gt;
&lt;br /&gt;
[[es:dev/BasedeDatos]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=63851</id>
		<title>Release process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=63851"/>
		<updated>2023-03-24T11:04:13Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/process/release}}&lt;br /&gt;
== 8 weeks prior ==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Recurring release epics review:&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure we are running latest/good behat, phpunit and nodejs (npm) versions.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm external testers daily availability from -6w to release (internally with dev manager and then, externally, with contractors). They start in just 2 weeks!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| - Move QA tests for new features in old release with automated tests from MDLQA-1 to MDLQA-5249.&lt;br /&gt;
- Remind devs:&lt;br /&gt;
* To label issues qa_test_required when a new feature/improvement is landing without automated tests. Also add a comment advising exactly what should be covered in the QA test e.g. steps 6-10 in testing instructions.&lt;br /&gt;
* The best possible lang strings land at first attempt. Given the proximity of the major release and to facilitate the work of translators and others... the sooner, the better, instead of relying on (late) en_fixes too much. &lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| - Create a &amp;quot;Must fix for X.Y&amp;quot; version in the Tracker and adjust the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Set%20integration%20priority%20to%20one/ &amp;quot;TR - Set integration priority to one&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20reopened%20out%20from%20current/ &amp;quot;TR - Move reopened out from current&amp;quot;] jobs in &#039;&#039;&#039;all CI servers&#039;&#039;&#039; to point to it.&lt;br /&gt;
- Apply the following changes to filters and dashboards:&lt;br /&gt;
*  Edit the [https://tracker.moodle.org/issues/?filter=21363 All &amp;quot;must fix&amp;quot; issues] filter used both in the release dashboard and to detect wrong uses of must-fix issues. Note that, since 3.7, this filter is fully automated and does not need edition (uses regexp to catch all must fix versions).&lt;br /&gt;
* Comment about its creation within HQ, to get people applying for it. &lt;br /&gt;
* Verify that these filters ([https://tracker.moodle.org/issues/?filter=18596 1], [https://tracker.moodle.org/issues/?filter=18594 2] and [https://tracker.moodle.org/issues/?filter=18861 3]), used in the [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard], are working ok (they should be, automatically based in the filter edited in the previous point). &lt;br /&gt;
* Rename [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard] to point to incoming release (QA part of the dashboard will not work yet)&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==7 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Full demo of new code and sign-off for internal HQ projects. Decide which projects will be completed by the code freeze.&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Check [https://tracker.moodle.org/issues/?jql=labels%20%3D%20qa_test_required%20AND%20status%20%3D%20Closed closed qa_test_required-labelled issues] and create new QA tests as required.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==6 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period Continuous Integration] period begins. Warn about it everywhere (telegram, exposed posts...).&lt;br /&gt;
Rolling (on demand, beta, rc... all them together with stable weeklies) happens often (Tuesday &amp;amp; Friday are the usual days). All the team is on integration 100% since this week and until the end of continuous.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create the next &amp;quot;X.Y+1&amp;quot; (next dev) version in the Tracker (MDL and CONTRIB), so people can move delayed stuff to next major release if needed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Warn external developers about the impending code freeze in a post to the [http://moodle.org/mod/forum/view.php?id=55 General developer forum]. ([https://moodle.org/mod/forum/discuss.php?d=225854 example])&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Let the community know [[QA testing]] starts in two weeks and how they can participate. &lt;br /&gt;
| Community Manager&lt;br /&gt;
|}&lt;br /&gt;
==5 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm the code freeze by replying to the previous warning in the [http://moodle.org/mod/forum/view.php?id=55 General developer forum].&lt;br /&gt;
| Development manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| This week, once the freeze has happened at 11:00 UTC:&lt;br /&gt;
* The [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job has to be disabled.&lt;br /&gt;
* Immediately after that, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20awaiting%20issues%20to%20current%20integration/ Move awaiting issues to current integration] job must be enabled and executed, only once, and all the candidate issues already @ integration will come to the current queue. All them did the freeze.&lt;br /&gt;
* Once run, disable the job again to avoid executing it by mistake.&lt;br /&gt;
* Once the previous job has ended, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job, in charge of managing the integration queues after freeze, will be enabled (until the end of on-sync). It performs some tasks like moving important (must fix, qa, security...) issues to the current integration queue and also keep if fed by priority when there are few issues remaining. &#039;&#039;&#039;Don&#039;t forget&#039;&#039;&#039; to configure the &amp;quot;releasedate&amp;quot; date to get it automatically holding issues the last week (instead of moving them to current integration) and also processing issues over the on-sync (after release) period.&lt;br /&gt;
Irrespectively from any automation, issues can, also, be manually picked for integration until the post-release &amp;quot;On Sync&amp;quot; period ends, usually 2 weeks after release.&lt;br /&gt;
&lt;br /&gt;
Review all the new features and improvements so, everything &amp;quot;unrelated&amp;quot; with the release, is given the &amp;quot;integration_held&amp;quot; label. That means that will be ignored unless there is an [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period unhold request process] started on them.&lt;br /&gt;
&lt;br /&gt;
Dev leaders promptly vote on held issues labelled with unhold_requested label and decide whether they can be allowed to break the freeze.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare a fresh installation of the [http://qa.moodle.net QA site] based on the beta code to make sure the site is not affected by incremental upgrade steps during the development cycle.&lt;br /&gt;
| QA Master Site Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Begin reviewing [https://lang.moodle.org/mod/forum/view.php?id=7 new and changed English language strings] ready for en_fix to be merged 2 weeks prior.&lt;br /&gt;
| English fixes lang pack maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review standards certifications (Open Badges, LTI, etc) and schedule in recertification to be performed.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==4 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Start reviewing fixed issues and add the release_notes label to all issues to be listed in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review requirements for adding user tours for new features in the upcoming release (clone of MDL-72783). Review existing tours and remove very old ones (clone of MDL-72781)&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Beta release (The Moodle release tool - mdlrelease - manages it): Release normal weeklies but with these changes in the master branch being considered all the time, until we are feature complete (can happen @ -4w - ideally - but also later):&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_BETA and $release = &#039;X.Ybeta (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-beta&amp;quot; (and MOODLE_XY_BETA as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Once the beta is available create the &amp;quot;[https://docs.google.com/spreadsheets/d/1TcMJT3o2Cnyq006lmLWrXJeNQQzyNXz2E_Vbc8ff5EE/edit?usp=sharing|Release testing matrix for X.Y.0]&amp;quot; and share it @ HQ &amp;amp; Dev. chat.&lt;br /&gt;
* (Optionally) Announce Beta release in forums (ideally once packages are available).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-72815 for the X.Y release, adding there all the debugging / PHP notices happening in the web server logs while running tests.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Release candidates release (The Moodle release tool - mdlrelease - manages it): At some points (between beta to final release) produce release candidates (Z = 1, 2, 3..), which are normal builds with the following changes:&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_RC and $release = &#039;X.YrcZ (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-rcZ&amp;quot; (and MOODLE_XY_RCZ as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Upgrade all the Moodle CI sites to recent release candidate by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Add a new version in the Plugins Directory with the version&#039;s name and the beta release version build number (https://moodle.org/plugins/admin/softwareversions.php).&lt;br /&gt;
* Any standard plugins being retired from the release can transition to Add-on (that supports this release and/or any previous ones) now.&lt;br /&gt;
* These plugins currently collect at https://moodle.org/plugins/browse.php?list=contributor&amp;amp;id=1532512&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Push any plugins to the plugins database which were previously a part of core.&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Tidy up current latest en version of Moodle Docs prior to copying it to create new version wiki as described in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new QA test cycle and post in moodle.org front page news forum about [[QA testing]].&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Invite community volunteers to start [[QA testing]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Modify [https://tracker.moodle.org/issues/?filter=11824 Current QA cycle filter] to link to the new QA test cycle&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor QA fails. Check each fail is real and if so ensure an MDL issue has been created and correctly linked and labelled.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor MDL issues created for QA fails. Add them to the &amp;quot;Must fix for X.Y&amp;quot; list and get a developer to work on the issue immediately.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the [https://tracker.moodle.org/issues/?filter=17705&amp;amp;jql=filter%20%3D%2011701%20AND%20type%20!%3D%20Bug list of features and improvements submitted before code freeze] which are awaiting integration review and decide on related QA tests to be put on hold.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==3 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ask developers to begin QA tests marked [https://tracker.moodle.org/issues/?filter=22055 external_skipped] then [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20test_server_required%20 test_server_required tests] and [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20credentials_required credentials_required tests].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new en and de Moodle Docs version wikis.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Go through all points listed under 3 weeks prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review issues with labelled with [https://tracker.moodle.org/issues/?filter=11824&amp;amp;jql=labels%20in%20%28dev_docs_required%29%20AND%20resolution%20%3D%20fixed%20ORDER%20BY%20assignee%20ASC%2C%20created%20ASC dev_docs_required], prompting assigned developers to create/update this documentation and remove this label when relevant docs are updated.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify how everything is going and, before the end of the week, decide (dev leaders &amp;amp; integrators) if there are real reasons for delaying any release. Whenever a delay is agreed, run the &#039;&#039;&amp;quot;Release delaying process&amp;quot;&#039;&#039; (doc) actions ASAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; ASAP stands for as soon as possible ;-), the delay needs to happen before the last week before release begins (there are flows changing that week requiring the decision and actions to be taken and applied earlier).&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Check the number of open QA tests. Depending on the amount of work involved, encourage HQ developers to assist from the start of the week or later in the week in order to achieve the target of 100% pass rate by the end of the week.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Create MDLSITE issue to ensure all prototype.moodle.net sites which are no longer relevant (part of release) are removed from prototype.moodle.net&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Merge [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc fixes from en_fix] pack and then integrate them.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Give Partners complete brandable Marketing pack for release including list and description of major new features.&lt;br /&gt;
| Marketing Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Label (ui_change) in the Tracker all pending issues having &#039;&#039;&#039;noticeable UI modifications&#039;&#039;&#039; and track them in the &amp;quot;[https://docs.google.com/spreadsheets/d/18xZf9OgKrndi7CwSTwjwjF_rzGYCWFuGjNNaaDVZDM4/edit?usp=sharing Late landing UI changes]&amp;quot; sheet, in order to have all the associated docs, screenshots, videos under control. The Integration and Documentation people will try to &#039;&#039;&#039;keep the sheet updated until release&#039;&#039;&#039;.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
For major releases, use (clone if needed) MDL-72836 to keep the security.txt files in all supported branches updated. For minor releases, also check the security.txt expiry dates in all security supported branches in case known release delays will result in any security.txt expiring before the next release - in that case relevant branches should also be updated.&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
|7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
Identify issues that may block the release (e.g. security, must-fix issues, etc.) and confirm with team leads. This is to ensure that these issues are prioritised and allow us to be able to land them as early as possible and ensure a timely release schedule.&lt;br /&gt;
|Integration Lead&lt;br /&gt;
|}&lt;br /&gt;
==1 week prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |#&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
|1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|Clone as many filters as needed in the Tracker, modifying them to point to the new, upcoming, branch (keeping same perms, title...).&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Create new minor version X.Y.Z+1 in the Tracker (MDL and CONTRIB). Archive any version &amp;gt; 6 months old, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Clone MDL-71583 and bump all versions, requires and dependencies along all plugins in codebase to planned release dates.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Post a &amp;quot;Heads-up&amp;quot; message on the [http://moodle.org/mod/forum/view.php?id=55 General Developer forum] and [https://moodleassociation.org/ MUA website].&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Post a &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
|6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Post a &amp;quot;Heads-up&amp;quot; message on Twitter and other outlets.&lt;br /&gt;
|Marketing Officer&lt;br /&gt;
|-&lt;br /&gt;
|7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&lt;br /&gt;
&amp;amp;#10003;&lt;br /&gt;
|Identify security issues that need to be integrated using the [https://tracker.moodle.org/issues/?filter=21712 security issues under integration filter] (includes held, being integrated and ready issues).&lt;br /&gt;
*Integrate from provided patches into supported branches (including branches supported only for security issues).&lt;br /&gt;
* Ensure security issues are given priority in weekly integration and testing. Note that the --weekly releases to be performed this week are 100% normal and cover the standard (supported) branches. security branches will come as part of the release process later in the week.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Collect security issues into a clone of the [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20level%20is%20not%20EMPTY%20AND%20summary%20~%20%22security%20advisories%22%20ORDER%20BY%20updated%20DESC last advisory in the list] to prepare for release of Security Advisories.&lt;br /&gt;
*Determine which security issues will be integrated.&lt;br /&gt;
* Request CVE Identifiers by emailing issue descriptions to [mailto:secalert@redhat.com secalert@redhat.com] with a message like... &amp;lt;tt&amp;gt; The following security issues have been discovered in Moodle. We request CVE Identifiers for these issues. We will be releasing the security announcements for these on moodle.org on XXX at 12noon AWST which is 04:00 UTC.&amp;lt;/tt&amp;gt; The email subject should include the characters &amp;lt;tt&amp;gt;[vs]&amp;lt;/tt&amp;gt;. The format needs to be plain text or encrypted. When granted CVE Identifiers, our issues should appear in the [http://cve.mitre.org/cve/cve.html CVE list]. More [http://oss-security.openwall.org/wiki/mailing-lists/distros instructions] are available (since 2015 we request identifiers from redhat and not from distros).&lt;br /&gt;
* Post security issues as a reply to the &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
|9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Release notes tasks:&lt;br /&gt;
* Review and complete the [[Releases|release notes]], making sure that issues have easily understandable summaries. Aim to have the release notes mostly complete on the Wednesday before release, and fully complete on the Friday, to give translators time to translate them.&lt;br /&gt;
*Ensure all issues labelled with &amp;quot;ui_change&amp;quot;, &amp;quot;api_change&amp;quot; and &amp;quot;release_notes&amp;quot; are listed as UI changes, functional changed and fixes/improvements respectively in the release notes.&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Review the following issues:&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=21363 &amp;quot;Must fix for X.Y version&amp;quot;]. Filter out unrealistic issues.&lt;br /&gt;
*Check on the [https://tracker.moodle.org/issues/?filter=22350 &amp;quot;Bug issues held last week before release&amp;quot;]. Consider to request the unholding of release related/blocker ones.&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Upgrade moodle.org to beta release&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Prepare pull requests for CI Repositories:&lt;br /&gt;
*MR1: Create a new version, with unit tests, in Jobs repository ([https://git.in.moodle.com/integration/nightlyjobs/merge_requests/24 see example from 3.11 release])&lt;br /&gt;
* MR2: Create a new symlink for the version in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/41 see example from 3.11 release])&lt;br /&gt;
* MR3: Configure CIs to skip language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/35 see example from 3.10 release])&lt;br /&gt;
*MR4: Configure CIs to stop skipping language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository for after on-sync ([https://github.com/moodlehq/moodle-ci-runner/pull/40 see example from 3.10 release]) -- Note: This change should be based on the previous and only applied when the lang packs corresponding to the version being released are available.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Go through all points listed under 1 week prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==Releasing ==&lt;br /&gt;
===Packaging===&lt;br /&gt;
This should happen immediately before the next integration cycle begins on Monday (i.e., some days after last weekly, 2 days prior to official release).&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |#&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
|1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Check list:&lt;br /&gt;
*Make sure there are no real blockers introduced in the last weekly (install / upgrade ...).&lt;br /&gt;
* Confirm that the latest [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc en_fix changes]have been generated and integrated.&lt;br /&gt;
* Verify that [https://tracker.moodle.org/issues/?jql=text%20~%20%22%2BPrepare%20%2Bsecurity%20%2Badvisories%20%2Bfriends%22%20ORDER%20BY%20updated%20DESC all security issues] have been integrated and there are not leftovers in the security area (but for delayed majors, where some security issues may have been introduced along the delay and they will be postponed to next minors).&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Verify all unit tests and integration tests have passed (check all current CI servers in use).&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Verify QA tests have passed.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Timing prerequisites (don&#039;t continue with the process if not within the time window!):&lt;br /&gt;
#Latest weeklies before the minor/major releases must be done (moodle-package-extract-and-postprocess email should confirm this has happened around 09:00 Australia/Perth).&lt;br /&gt;
#Minor and major releases can be packaged at any time within the 96 hours before the automatic releasing time (Monday 09:00 Australia/Perth). And always, at very least, 4 hours before then (to allow the server to prepare all the stuff).&lt;br /&gt;
(in practice, this means that the packaging of minor/major releases must be done, assuming that weeklies were rolled normally on Thursday, between Friday 09:00 and Monday 05:00 (Australia/Perth times). Breaking any of these rules will require manual operation in the server, forcing repackaging and releasing.&lt;br /&gt;
&lt;br /&gt;
Follow the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
*Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script to generate the target minor (--type minor) and major (--type major) releases and their corresponding tags. Pay attention to the complete output of the process: permissions, svg... changes (only for majors)... Triple verify all changes are correct! (can use the --show option to inspect them). Follow the on-screen instructions.&lt;br /&gt;
*Push changes to integration.git (but tags).&lt;br /&gt;
For major releases, only when a new STABLE branch has been created:&lt;br /&gt;
*Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script (--type back-to-dev) to move master to next X.Y+1 development version/branch.&lt;br /&gt;
*Push changes to integration.git - note this will lead to the &amp;quot;versions checker&amp;quot; failing for master, no problem, it will be fixed by the 1st cloned issue at #12 below).&lt;br /&gt;
*Configure &amp;quot;mdlrelease&amp;quot; (config.sh) to know about the new MOODLE_XY stable branch.&lt;br /&gt;
*Update the old CI server(s) by cloning all the &amp;quot;master&amp;quot; jobs to a new &amp;quot;MXY&amp;quot; view (trick: do it down-top, way easier). Don&#039;t forget to re-chain the jobs properly.&lt;br /&gt;
**Adjust &amp;quot;master&amp;quot; compare DB jobs to check for upgrade from MOODLE_XY_STABLE.&lt;br /&gt;
**Configure the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
**Run all them.&lt;br /&gt;
*Update the new CI infrastructure:&lt;br /&gt;
**MR1: Merge pull request for new version in [https://git.in.moodle.com/integration/nightlyjobs CI Jobs Repository]&lt;br /&gt;
**MR2: Merge pull request for symlink in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
**MR3: Merge pull request for skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
**Clone all the &amp;quot;B - master&amp;quot; jobs to a new &amp;quot;B - XY&amp;quot; view (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Clone%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
Both with minors and majors, continue with the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
*Once CI servers have ended and all jobs have passed, &#039;&#039;&#039;push tags&#039;&#039;&#039; and run the &#039;&#039;&#039;release.sh&#039;&#039;&#039; script to apply the changes to moodle.git.&lt;br /&gt;
*If needed configure &amp;quot;mdlrelease&amp;quot; (config.sh) to get rid of any unsupported version and adjust stable and security branches. Make a pull request with the changes.&lt;br /&gt;
*Don&#039;t forget the &amp;quot;[https://github.com/moodlehq/mdlrelease/#after-the-release After the release]&amp;quot; tasks.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|Post a &amp;quot;git repos updated &amp;amp; tagged&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=810 Partner forum]&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|In the [https://github.com/moodlehq/moodle-performance-comparison performance comparison repository], set the new release commit hash as $basecommit in the master branch and create a new MOODLE_XY_STABLE branch from it. ([https://github.com/moodlehq/moodle-performance-comparison/commit/7c875f03e52641f69674235a8947131d77691299 example]). Also, apply it to the current performance testing infrastructure.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Wait for the automated (every 2 hours) moodle-package to finish building for all versions. Verify the process has ended successfully (email).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
*Create new windows packager script (cloning the current master one and configuring it).&lt;br /&gt;
*Edit the stats.php script (in the moodle-local_downloadmoodleorg repository), adding the new branch to the versions. Push it. Next time the plugin is deployed (normally 1 week after release, aprox.) the stats will start showing the new branch statistics.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|In the Tracker...&lt;br /&gt;
* Visit the versions page and make the release, bumping all remaining open bugs to the next point release. If there is not next (end of support), clean that version from all the issues having it as &amp;quot;Fix for&amp;quot;. This must be done both for the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10011 Moodle Project] and the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10033 Plugins project].&lt;br /&gt;
*Archive all versions but the ones being released, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
*Remove from all screens the custom fields belonging to 100% unsupported branches.&lt;br /&gt;
For major releases only:&lt;br /&gt;
*Release and archive the [https://tracker.moodle.org/issues/?jql=affectedVersion%20~%20%22must%20fix%20for*%22%20OR%20fixVersion%20~%20%22must%20fix%20for*%22 &amp;quot;Must fix for X.Y&amp;quot; versions], it must be empty to do so.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
* Create the new &amp;quot;Pull X.Y Branch&amp;quot; and &amp;quot;Pull X.Y Diff URL&amp;quot; custom fields and spread them to all the screens needing them (copy from previous ones). Order them properly on each screen. Re-index Tracker.&lt;br /&gt;
*In the CI server edit the [http://integration.moodle.org/view/tracker/job/Tracker%20-%20CI%20-%20Bulk%20precheck%20issues/ &amp;quot;Bulk precheck issues&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(awaiting_integration)/ &amp;quot;Pre-launch DEV jobs (awaiting_integration)&amp;quot;], [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch DEV jobs (list_of_mdsl)&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/STR%20-%20Bulk%20pre-launch%20SDEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch SDEV jobs (list_of_mdsl)&amp;quot;] jobs to make them meet the new &amp;quot;Pull X.Y Branch&amp;quot; field created. At the same time, remove from those jobs any branch belonging to 100% unsupported branches.&lt;br /&gt;
*Edit the &amp;quot;Tracker - CI - Check marked as integrated&amp;quot; job ([https://ci.moodle.org/view/Tracker/job/TR%20-%20Check%20marked%20as%20integrated/ link]) to configure the development branches (devbranches) (39, 310, 311, 400...) actually active. Normally only the branch corresponding to master, but also accepts a comma separated list when under parallel development (&amp;quot;310,400&amp;quot; or &amp;quot;311,400&amp;quot; for example). Ordered by planned release date.&lt;br /&gt;
*Check/configure (again, this may be has been already executed few steps above) the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|In the Tracker...&lt;br /&gt;
For major releases only:&lt;br /&gt;
*Create the new &amp;quot;X.Y regressions&amp;quot; version to be applied to every issue found to be a recent problem introduced by the major release. These issues should get priority after release.&lt;br /&gt;
*Adjust the [https://tracker.moodle.org/issues/?filter=17528 Latest regressions] filter (requires login).&lt;br /&gt;
For all releases:&lt;br /&gt;
*Verify how the &amp;quot;X.Y regressions&amp;quot; versions [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20resolution%20%3D%20Unresolved%20AND%20affectedVersion%20in%20(versionMatches(%22.*regressions%22)) are going] (requires login) and ping Development Managers about. Package and archive them once empty.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Clone MDL-74509 and MDL-74510, to be resolved ASAP.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
*Create the new MOODLE_XY_STABLE and lastbased-MOODLE_XY_STABLE branches in the security repo (branching from the just created upstream MOODLE_XY_STABLE branch).&lt;br /&gt;
*Cherry pick any security commit present in the security repository&#039;s master branch to the new MOODLE_XY_STABLE branch (note that normally there should not be any, see point #1 check list above).&lt;br /&gt;
*Verify the new security jobs exist for the new branch and check it&#039;s working in all servers, keeping only enabled the public one.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Protect the MOODLE_XY_STABLE branches in github interface to prevent non-FF accidents ( MDLSITE-4183 )&lt;br /&gt;
|Integration Team&lt;br /&gt;
|}&lt;br /&gt;
===Release day===&lt;br /&gt;
Usually on Monday&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |#&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
|1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|The execution of &amp;quot;moodle-package-extract-and-postprocess X&amp;quot; script may be needed if the releases &#039;&#039;&#039;are not going to be published on Monday&#039;&#039;&#039; but another weekday (X is the weekday, (1-7) starting in Monday).&lt;br /&gt;
By default it happens automatically around 09:00 AM Perth/Australia time (check emails then). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Verify release status, download pages and windows packages.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| If needed, modify the downloads cfg script (serverscripts) to decide about branches status, master visibility and windows availability. Push changes, will be autodeployed in a few minutes.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Add/update the release date, build number and link on the [[Releases|Releases page]] and date in new version pages.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Notify all registered sys admins, including security notes with CVE identifiers, using the [http://lists.moodle.org/ mailing list server].&lt;br /&gt;
|Security Officer&lt;br /&gt;
|-&lt;br /&gt;
|6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Post about the Major release on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
|Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
|7.&lt;br /&gt;
|&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| Post about minor releases on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|New &amp;quot;X.Y+1dev&amp;quot; branch to be created in AMOS, to have master changes performed there. New install_XY_STABLE processing set up. These needs to be done anytime during the on-sync period.&lt;br /&gt;
|AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Verify, 24h after tagging, that https://moodle.org/dev/contributions.php has been updated with new versions. If not, file an urgent mdlsite issue, crons must be running!&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| For en and de Moodle Docs, update default redirects and enable email notifications.&lt;br /&gt;
|Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Go through all points listed under Day of release in [[New docs version process]].&lt;br /&gt;
|Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
*Decide the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot; and &amp;quot;QA begins&amp;quot; dates for the next X.(Y+1) major release and put them in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar]. They will be -7w, -5w and -4w before release date respectively.&lt;br /&gt;
*Update the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot;, &amp;quot;QA begins&amp;quot; and Release dates on the [[Roadmap]] page.&lt;br /&gt;
*Add events to the HQ calendar for next Major release 6-months cycle according to [[Process#Sprints|the cycle plan]]: ~4 weeks planning and regression fixing, 2 sprints, 1 personal project week, 2 sprints, 1 personal project week, 1 sprint (which should lead up to code freeze).&lt;br /&gt;
*Notify the Community Manager of new dates to be added to the moodle.org calendar.&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&lt;br /&gt;
|Add calendar events in the [https://moodle.org/calendar moodle.org calendar] for coming Major and Minor releases up to the next Major release.&lt;br /&gt;
|Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Update release schedule image on [[Releases#Version_support|Releases page]]&lt;br /&gt;
|Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|15.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Important: This must be done &#039;&#039;&#039;once it&#039;s already release day @ UTC&#039;&#039;&#039; (aka, after Australia/Perth 08:00) or the &#039;&#039;&#039;queues manage with hold them again&#039;&#039;&#039; because it&#039;s still &amp;quot;last week before release&amp;quot;.&lt;br /&gt;
The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed &#039;&#039;&#039;only&#039;&#039;&#039; [https://tracker.moodle.org/issues/?jql=filter%3D13669%20AND%20type%20in%20(bug%2C%20task%2C%20Sub-task) from &#039;&#039;&#039;bug issues&#039;&#039;&#039; awaiting integration]; they correspond to last-week bugs that were held because of them being unrelated with the release. Now they can be processed, under on-sync rules. Standard message will be used to explain the un-hold.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==1 week after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
|1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Publish the X.Y+ packages for download.moodle.org (should be automatic once weeklies are packaged).&lt;br /&gt;
For major releases, within the on-sync period, master packages will be generated using the prerelease.sh script (--type on-sync). That guarantees XY_STABLE and master versions are kept the same. The last week, when leaving the on-sync period, master package will be generated normally (implicit --type weekly), so versions will diverge and dev can continue separately from that point.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|Update the version.php in git to be X.Y.Z+ during the next weekly integration process&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Create a new release notes page for the next minor versions (using the [[Release notes template|release notes template]].) Add note to top of relevant version page about security support.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
|4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|Add all security advisories to [http://moodle.org/security Security news] and [[:Category:Release notes|release notes]] with links to security advisories&lt;br /&gt;
||Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|Notify about publications of CVE using form: https://cveform.mitre.org/&lt;br /&gt;
|Security Officer&lt;br /&gt;
|-&lt;br /&gt;
|6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Upgrade moodle.org and all other Moodle community sites (next sites first, then production)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Deprecations:&#039;&#039;&#039;&lt;br /&gt;
*Create the next deprecation epic (for X.Y+1+2y) similar to MDL-74579 and add standard issues to it:&lt;br /&gt;
**Final deprecation of lib/deprecatedlib.php (like MDL-74580)&lt;br /&gt;
**Removal of deprecated Behat steps (like MDL-74581)&lt;br /&gt;
**Removal of strings (like MDL-74582) and&lt;br /&gt;
**Removal of renamed classes (MDL-74583).&lt;br /&gt;
The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it.&lt;br /&gt;
*Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Libraries:&#039;&#039;&#039;&lt;br /&gt;
*Create the next third party libraries epic for X.Y+1, similar to MDL-73715. The issue should refer to the list of [[Moodle libraries credits]]. The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it. &#039;&#039;&#039;Drag/link opened issues from the previous one&#039;&#039;&#039;, avoiding leaving unfinished stuff.&lt;br /&gt;
*Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20(summary%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20OR%20summary%20~%20%22Review%20third-party%20libraries%20for%20upgrade%22)%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|}&lt;br /&gt;
== 2 weeks after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |#&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
|1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Once the &amp;quot;On Sync&amp;quot; period ends:&lt;br /&gt;
*Confirm that versions (XY_STABLE and master) diverged properly the last on-sync week. If not, proceed to it by manually bumping master the version to the current date @ integration.git.&lt;br /&gt;
* Disable the &amp;quot;[https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous&amp;quot;] job. It has served us well.&lt;br /&gt;
*The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed from all issues awaiting integration, so they will be, automatically (see next point), be moved to the current integration queue. Send an &amp;quot;unholding + rebase&amp;quot; message to all those issues.&lt;br /&gt;
*Enable the &amp;quot;[https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal&amp;quot;] job. It will control the queues over the coming months, until the next freeze.&lt;br /&gt;
*In the [https://ci.moodle.org/ Jenkins CI server] enable all the jobs corresponding to the new branch (B-XYZ view) that were created on packaging day.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| The discussion about environmental requirements for next X.Y+1 major release (MDL-71747) will end and the issue will be resolved &#039;&#039;&#039;immediately&#039;&#039;&#039;. A new issue, about the requirements for nextthe -next X.Y+2 major release wil,l be created at the same time by cloning the previous one and dragging any non-resolved detail (due date = 3w after release).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&lt;br /&gt;
&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Ensure [https://download.moodle.org/langpack/X.Y+1/ Language pack for master (X.Y+1)] is available and merge the pull request MR4 for stop skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Ensure release retrospectives are held for each of the LMS teams and results are actioned.&lt;br /&gt;
|Development Manager / Head of LMS&lt;br /&gt;
|}&lt;br /&gt;
==1 month after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |#&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; |Minor&lt;br /&gt;
!Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; |Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Remove, in CI servers, all the jobs and views corresponding to branches which support has ended completely. (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Remove%20all%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Upgrade all the Moodle CI sites to recent major release by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
|3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; |&amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|Confirm that there isn&#039;t any remaining [https://tracker.moodle.org/issues/?filter=13669 integration_held] issue from latest release, proceeding to uhhold them immediately. Note that there may exist [https://tracker.moodle.org/issues/?filter=13669&amp;amp;jql=project%20%3D%20MDL%20AND%20labels%20in%20(integration_held)%20ORDER%20BY%20%22Integration%20priority%22%20DESC%2C%20priority%20DESC%2C%20votes%20DESC%2C%20%22Last%20comment%20date%22%20ASC other &amp;quot;held&amp;quot; issues], unrelated with latest release. This process step does not affect them.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Deprecation|Deprecation process]]&lt;br /&gt;
[[Category:Processes|Release process]]&lt;br /&gt;
[[Category:Release notes|Release process]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=63850</id>
		<title>Writing PHPUnit tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;diff=63850"/>
		<updated>2023-03-24T11:03:30Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.3}}&lt;br /&gt;
&lt;br /&gt;
Moodle PHPUnit integration is designed to allow easy adding of new tests. At the start of each test the state is automatically reset to fresh new installation (unless explicitly told not to reset).&lt;br /&gt;
=Namespaces=&lt;br /&gt;
All the stuff under **/tests directories is [[Coding style#Namespaces_within_.2A.2A.2Ftests_directories|subject to some simple rules]] when using namespaces. They apply to test cases, fixtures, generators and, in general, any class within those directories. Take a look to them! (grand summary = 100% the same rules that are applied to **/classes directories).&lt;br /&gt;
=Testcase classes=&lt;br /&gt;
There are three basic test class that are supposed to used in all Moodle unit tests - basic_testcase, advanced_testcase and provider_testcase. &#039;&#039;&#039;Please note it is strongly recommended to put only one testcase into each class file.&#039;&#039;&#039;&lt;br /&gt;
;basic_testcase : Very simple tests that do not modify database, dataroot or any PHP globals. It can be used for example when trying examples from the official PHPUnit tutorial.&lt;br /&gt;
;advanced_testcase : Enhanced testcase class enhanced for easy testing of Moodle code.&lt;br /&gt;
;provider_testcase: Enhanced testcase class, enhanced for easy testing of [[Privacy API|Privacy Providers]].&lt;br /&gt;
There is a fourth testcase class that is specially designed for testing of our Moodle database layer, it should not be used for other purposes.&lt;br /&gt;
== Assertions ==&lt;br /&gt;
The complete list of assertions can be found in the links below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle version&lt;br /&gt;
! PHPUnit version&lt;br /&gt;
!Links&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.11&lt;br /&gt;
| PHPUnit 9.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/9.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.10&lt;br /&gt;
| PHPUnit 8.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/8.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.7 - 3.9&lt;br /&gt;
| PHPUnit 7.5&lt;br /&gt;
|[https://phpunit.readthedocs.io/en/7.5/assertions.html Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Moodle 3.4 - 3.6&lt;br /&gt;
| PHPUnit 6.5&lt;br /&gt;
|[https://phpunit.de/manual/6.5/en/assertions.html Documentation]&lt;br /&gt;
|}&lt;br /&gt;
==Sample plugin testcase==&lt;br /&gt;
PHPUnit tests are located in &amp;lt;tt&amp;gt;tests/*_test.php&amp;lt;/tt&amp;gt; files in your plugin, for example &amp;lt;tt&amp;gt;mod/myplugin/tests/sample_test.php&amp;lt;/tt&amp;gt;, the file should contain only one class that extends &amp;lt;tt&amp;gt;advanced_testcase&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class sample_test extends \advanced_testcase {&lt;br /&gt;
     public function test_adding() {&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, 1+2);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
See [[PHPUnit integration#Class and file naming rules]] for more information.&lt;br /&gt;
==Inclusion of Moodle library files==&lt;br /&gt;
If you want to include some Moodle library files you should always declare &#039;&#039;&#039;global $CFG&#039;&#039;&#039;. The reason is that testcase files may be included from non-moodle code which does not make the global $CFG available automatically.&lt;br /&gt;
==Automatic state reset==&lt;br /&gt;
By default after each test Moodle database and dataroot is automatically reset to the original state which was present right after installation. make sure to use $this-&amp;gt;resetAfterTest() to indicate that the database or changes of standard global variables are expected.&lt;br /&gt;
&lt;br /&gt;
If you received the error &amp;quot;Warning: unexpected database modification, resetting DB state&amp;quot; it is because the test is not using &amp;lt;tt&amp;gt;$this-&amp;gt;resetAfterTest()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 namespace mod_myplugin;&lt;br /&gt;
&lt;br /&gt;
 class test_something extends \advanced_testcase {&lt;br /&gt;
     public function test_deleting() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;resetAfterTest(true);&lt;br /&gt;
         $DB-&amp;gt;delete_records(&#039;user&#039;);&lt;br /&gt;
         $this-&amp;gt;assertEmpty($DB-&amp;gt;get_records(&#039;user&#039;));&lt;br /&gt;
     }&lt;br /&gt;
     public function test_user_table_was_reset() {&lt;br /&gt;
         global $DB;&lt;br /&gt;
         $this-&amp;gt;assertEquals(2, $DB-&amp;gt;count_records(&#039;user&#039;, array()));&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Generators=&lt;br /&gt;
Tests that need to modify default installation may use generators to create new courses, users, etc. All examples on this page should be used from test methods of a test class derived from advanced_testcase.&lt;br /&gt;
&lt;br /&gt;
Note if you are using PHPUnit [https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers @dataProvider] functions to provide parameters to unit tests, you can not use the data generator or change the user etc in the data provider function. Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation.&lt;br /&gt;
==Creating users==&lt;br /&gt;
At the start of each test there are only two users present - guest and administrator. If you need to add more test accounts use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You may also specify properties of the user account, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $user1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_user(array(&#039;email&#039;=&amp;gt;&#039;user1@example.com&#039;, &#039;username&#039;=&amp;gt;&#039;user1&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
By default no user is logged-in, use setUser() method to change current $USER value:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser($user1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Guest and admin accounts have a shortcut methods:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setGuestUser();&lt;br /&gt;
 $this-&amp;gt;setAdminUser();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Null can be used to set current user back to not-logged-in:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $this-&amp;gt;setUser(null);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating course categories==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $category1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $category2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category(array(&#039;name&#039;=&amp;gt;&#039;Some subcategory&#039;, &#039;parent&#039;=&amp;gt;$category1-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating courses==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course1 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 &lt;br /&gt;
 $category = $this-&amp;gt;getDataGenerator()-&amp;gt;create_category();&lt;br /&gt;
 $course2 = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course(array(&#039;name&#039;=&amp;gt;&#039;Some course&#039;, &#039;category&#039;=&amp;gt;$category-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating activities==&lt;br /&gt;
Some activity plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php.&lt;br /&gt;
&lt;br /&gt;
Example of creation of new course with one page resource:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $generator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator(&#039;mod_page&#039;);&lt;br /&gt;
 $generator-&amp;gt;create_instance(array(&#039;course&#039;=&amp;gt;$course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The following is functionally the same, but a bit shorter:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $course = $this-&amp;gt;getDataGenerator()-&amp;gt;create_course();&lt;br /&gt;
 $page = $this-&amp;gt;getDataGenerator()-&amp;gt;create_module(&#039;page&#039;, array(&#039;course&#039; =&amp;gt; $course-&amp;gt;id));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating cohorts==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Since 2.4 there the data generator supports creation of new cohorts.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $cohort = $this-&amp;gt;getDataGenerator()-&amp;gt;create_cohort();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Simplified user enrolments==&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
Instead of standard enrolment API it is possible to use simplified method in data generator. It is intended to be used with self and manual enrolment plugins.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid);&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;enrol_user($userid, $courseid, $teacherroleid, &#039;manual&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating scales==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_scale(array(&#039;name&#039; =&amp;gt; $name, &#039;scale&#039; =&amp;gt; $scale, &#039;courseid&#039; =&amp;gt; $courseid, &#039;userid&#039; =&amp;gt; $userid, &#039;description&#039; =&amp;gt; description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating roles==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_role(array(&#039;shortname&#039; =&amp;gt; $shortname, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; description, &#039;archetype&#039; =&amp;gt; $archetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating tags==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_tag(array(&lt;br /&gt;
    &#039;userid&#039; =&amp;gt; $userid, &lt;br /&gt;
    &#039;rawname&#039; =&amp;gt; $rawname,&lt;br /&gt;
    &#039;name&#039; =&amp;gt; $name, &lt;br /&gt;
    &#039;description&#039; =&amp;gt; $description, &lt;br /&gt;
    &#039;descriptionformat&#039; =&amp;gt; $descriptionformat,&lt;br /&gt;
    &#039;flag&#039; =&amp;gt; $flag&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Groups==&lt;br /&gt;
===Creating groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding users to groups===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_group_member(array(&#039;userid&#039; =&amp;gt; $userid, &#039;groupid&#039; =&amp;gt; $groupid, &#039;component&#039; =&amp;gt; $component, &#039;itemid&#039; =&amp;gt; $itemid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;name&#039; =&amp;gt; $name, &#039;description&#039; =&amp;gt; $description, &#039;descriptionformat&#039; =&amp;gt; $descriptionformat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Adding groups to groupings===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grouping_group(array(&#039;groupingid&#039; =&amp;gt; $groupingid, &#039;groupid&#039; =&amp;gt; $groupid));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Repositories==&lt;br /&gt;
===Creating repository instances===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include instance generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Creating repository types===&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Some respository plugins include type generators. The generator class are defined in plugindirectory/tests/generator/lib.php..&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_repository_type($type, $record, $options);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Creating grades==&lt;br /&gt;
===Grade categories===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid));&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_category(array(&#039;courseid&#039; =&amp;gt; $courseid, &#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Grade items===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;itemtype&#039; =&amp;gt; $itemtype, &#039;itemname&#039; =&amp;gt; $itemname, &#039;outcomeid&#039; =&amp;gt; $outcomeid, &#039;scaleid&#039; =&amp;gt; $scaleid, &#039;gradetype&#039; =&amp;gt; $gradetype));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Outcomes===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_outcome();&lt;br /&gt;
$this-&amp;gt;getDataGenerator()-&amp;gt;create_grade_item(array(&#039;fullname&#039; =&amp;gt; $fullname));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Other types of plugin==&lt;br /&gt;
{{Moodle 2.5}}&lt;br /&gt;
Any other type of plugin can have a generator. The generator class should extend component_generator_base, and then you can get an instance using $mygenerator = $this-&amp;gt;getDataGenerator()-&amp;gt;get_plugin_generator($frankenstylecomponentname);&lt;br /&gt;
&lt;br /&gt;
For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.&lt;br /&gt;
=Long tests=&lt;br /&gt;
All standard test should execute as fast as possible. Tests that take a loner time to execute (&amp;gt;10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.&lt;br /&gt;
=Large test data=&lt;br /&gt;
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]&lt;br /&gt;
=Testing sending of messages=&lt;br /&gt;
{{Moodle 2.4}}&lt;br /&gt;
You can temporarily redirect all messages sent via message_send() to a message sink object. This allows developers to verify that the tested code is sending expected messages.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first disable the use of transactions and then redirect the messaging into a new message sink, you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
$sink = $this-&amp;gt;redirectMessages();&lt;br /&gt;
//... code that is sending messages&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(3, count($messages));&lt;br /&gt;
//.. test messages were generated in correct order with appropriate content&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Testing sending of emails=&lt;br /&gt;
{{Moodle 2.6}}&lt;br /&gt;
You can temporarily redirect emails sent via email_to_user() to a email message sink object. This allows developers to verify that the tested code is sending expected emails.&lt;br /&gt;
&lt;br /&gt;
To test code using messaging first unset &#039;noemailever&#039; setting and then redirect the emails into a new message sink where you can inspect the results later.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
unset_config(&#039;noemailever&#039;);&lt;br /&gt;
$sink = $this-&amp;gt;redirectEmails();&lt;br /&gt;
//... code that is sending email&lt;br /&gt;
$messages = $sink-&amp;gt;get_messages();&lt;br /&gt;
$this-&amp;gt;assertEquals(1, count($messages));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Logstores=&lt;br /&gt;
You can test events which were written to a logstore, but you must disable transactions, enable at least one valid logstore, and disable logstore buffering to ensure that the events are written to the database before the tests execute.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;preventResetByRollback();&lt;br /&gt;
set_config(&#039;enabled_stores&#039;, &#039;logstore_standard&#039;, &#039;tool_log&#039;);&lt;br /&gt;
set_config(&#039;buffersize&#039;, 0, &#039;logstore_standard&#039;);&lt;br /&gt;
get_log_manager(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Check your coverage=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests.&lt;br /&gt;
&lt;br /&gt;
Prior to Moodle 3.7, this coverage would load all files and generate coverage for everything regardless of whether that file could be covered at all, or whether it was intentionally covered.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.7 the &#039;&#039;&#039;phpunit.xml&#039;&#039;&#039; configuration contains generated coverage include and exclude information for each component.&lt;br /&gt;
==Generating include and exclude configuration==&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
You can programatically describe which files will be checked for coverage by creating a &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file alongside the tests that you are writing.&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, a default configuration is applied for all plugins and it is not necessary to supply a coverage.php unless you wish to cover additional files.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file allows you to list include and exclude files and folders within the component being&lt;br /&gt;
tested. All paths specified are relative to the component being tested. For example, when working with &#039;&#039;&#039;mod_forum&#039;&#039;&#039; your&lt;br /&gt;
code will be in &#039;&#039;&#039;mod/forum&#039;&#039;&#039;, and its unit tests will be in &#039;&#039;&#039;mod/forum/tests/example_test.php&#039;&#039;&#039;. The coverage file&lt;br /&gt;
for this would be in &#039;&#039;&#039;mod/forum/tests/coverage.php&#039;&#039;&#039; and all paths specified would be relative to &#039;&#039;&#039;mod/forum&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to specify a combination of included files, included folders, excluded files, and excluded folders. This would allow you, for example, to include the entire &#039;&#039;&#039;classes&#039;&#039;&#039; directory, but exclude.a specific file or folder within it.&lt;br /&gt;
&lt;br /&gt;
The following is an example &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; file from &#039;&#039;&#039;mod_forum&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Note: For Moodle versions 3.7 to 3.10, the [https://docs.moodle.org/dev/index.php?title=Writing_PHPUnit_tests&amp;amp;oldid=58177#Check_your_coverage syntax used] was slightly different.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also, note that you can better define which class or function each test is effectively covering by using the &amp;lt;tt&amp;gt;@covers&amp;lt;/tt&amp;gt; annotation as [https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#specifying-covered-code-parts described in the documention].&lt;br /&gt;
&lt;br /&gt;
Since Moodle 4.0, the following default configuration is applied:{{Moodle 4.0}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return new class extends phpunit_coverage_info {&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfolders = [&lt;br /&gt;
        &#039;classes&#039;,&lt;br /&gt;
        &#039;tests/generator&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to include in coverage generation. */&lt;br /&gt;
    protected $includelistfiles = [&lt;br /&gt;
        &#039;externallib.php&#039;,&lt;br /&gt;
        &#039;lib.php&#039;,&lt;br /&gt;
        &#039;locallib.php&#039;,&lt;br /&gt;
        &#039;renderer.php&#039;,&lt;br /&gt;
        &#039;rsslib.php&#039;,&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfolders = [];&lt;br /&gt;
&lt;br /&gt;
    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */&lt;br /&gt;
    protected $excludelistfiles = [];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If a coverage.php file already exists, then the defaults will be added to the values already defined.&lt;br /&gt;
=Best practice=&lt;br /&gt;
There are several best practices, suggestions, and things to avoid which you should consider when writing unit tests. Some of these are described below.&lt;br /&gt;
==Code coverage==&lt;br /&gt;
PHPUnit has the ability to generate code coverage information for your unit tests and this is well supported since.Moodle 3.7. We recommend that you consider checking the coverage of your plugins when you write your code.&lt;br /&gt;
&lt;br /&gt;
We recommend that you explicitly set the @covers annotation as described in the [https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnit documentation].&lt;br /&gt;
==Keep use of resetAfterTest to a minimum==&lt;br /&gt;
Although many of the examples described above use the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;resetAfterTest&amp;lt;/syntaxhighlight&amp;gt; nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.&lt;br /&gt;
Generally speaking you should aim to write code which is mockable, and does not require real fixtures.&lt;br /&gt;
Use of resetAfterTest will also slow your tests down.&lt;br /&gt;
==Be careful with shared setUp and instance variables==&lt;br /&gt;
You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:&lt;br /&gt;
# If you create any fixtures in the setUp, or call the resetAfterTest function, these fixtures and conditions will apply for _all_ tests in the testsuite. You will not be able to add another test to the suite which does not require these conditions without those conditions being fulfilled anyway. This can lead to slow tests.&lt;br /&gt;
# PHPUnit creates an instance of each testcase during its bootstrap phase, and does not dispose of it for the lifetime of the test run. Anything which causes data to be stored as instance data within the testcase will be stored in memory until the _entire suite_ completes. This means that any fixture which is setup and not actively discarded will not be garbage collected and lead to memory bloat. In severe cases this can lead to memory exhaustion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Existing testcases which contain setUp which either generate data, or set resetAfterTest should be phased out, and no new cases should be introduced.&lt;br /&gt;
==Make use of the dataProvider functionality==&lt;br /&gt;
The dataProvider functionality of PHPUnit is an extremely powerful and useful feature which allows you to verify a function quickly and easily with a range of different conditions.&lt;br /&gt;
However, the following rules should be followed when using dataProviders:&lt;br /&gt;
* Keep addition of resettable data requring resetAfterTest to a minimum - this will lead to many slow tests&lt;br /&gt;
* Data providers &#039;&#039;&#039;must not instantiate/create data&#039;&#039;&#039;. Just define it. And then, the test body can proceed with the instantiation/creation. The dataProvider is called after the testSuite is instantiated, but before any tests are run. Each test will run a full setUp and tearDown, which will destroy any data which was created.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Test function accepts parameters passed from the specified data provider.&lt;br /&gt;
 *&lt;br /&gt;
 * @dataProvider foobar_provider&lt;br /&gt;
 * @param int $foor&lt;br /&gt;
 * @param int $bar&lt;br /&gt;
 */&lt;br /&gt;
public function test_foobar(int $foo, int $bar) {&lt;br /&gt;
    // Perform the tests here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Data provider for {@see self::test_foobar()}.&lt;br /&gt;
 *&lt;br /&gt;
 * @return array List of data sets - (string) data set name =&amp;gt; (array) data&lt;br /&gt;
 */&lt;br /&gt;
public function foobar_provider(): array {&lt;br /&gt;
    return [&lt;br /&gt;
        &#039;Same numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 42,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 42,&lt;br /&gt;
        ],&lt;br /&gt;
        &#039;Different numbers&#039; =&amp;gt; [&lt;br /&gt;
            &#039;foo&#039; =&amp;gt; 21,&lt;br /&gt;
            &#039;bar&#039; =&amp;gt; 84,&lt;br /&gt;
        ],&lt;br /&gt;
    ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=Extra test settings=&lt;br /&gt;
Usually the test should not interact with any external systems and it should work the same on all systems. But sometimes you need to specify some option for connection to external systems or system configuration. It is intentionally not possible to use $CFG settings from config.php.&lt;br /&gt;
&lt;br /&gt;
There are several ways how to inject your custom settings:&lt;br /&gt;
* define test setting constants in your phpunit.xml file&lt;br /&gt;
* define test setting constants in your config.php&lt;br /&gt;
These constants may be then used in your test or plugin code.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.11 and up (PHPUnit 9.5)=&lt;br /&gt;
{{Moodle 3.11}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.11, &#039;&#039;&#039;PHPUnit was upgraded to 9.5&#039;&#039;&#039; (from 8.5 being used in previous versions). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.11 (7.3, 7.4 and [[Moodle and PHP|8.0]]) (see MDL-71036 and linked issues for more details).&lt;br /&gt;
&lt;br /&gt;
While a lot of existing tests will work without modification with PHPUnit 9.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 9.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2020/02/migrating-to-phpunit-9 A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-9.html PHPUnit 9 release Announcement].&lt;br /&gt;
* These multiple detailed changelogs (because all them have included modifications requiring changes): [https://github.com/sebastianbergmann/phpunit/blob/9.0.0/ChangeLog-9.0.md 9.0], [https://github.com/sebastianbergmann/phpunit/blob/9.1.0/ChangeLog-9.1.md 9.1], [https://github.com/sebastianbergmann/phpunit/blob/9.3.0/ChangeLog-9.3.md 9.3], [https://github.com/sebastianbergmann/phpunit/blob/9.5.0/ChangeLog-9.5.md 9.5]&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/9.5/ Official PHPUnit manual].&lt;br /&gt;
A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/e3a46964dc6d8ca1558c6e1e8dfdf3c1745eeaed/lib/upgrade.txt#L5-L65 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
* All the changes that were deprecated with PHPUnit 8.5 (see the section below) are now removed and will lead to errors.&lt;br /&gt;
* &amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt; now performs stricter comparison (like &amp;lt;tt&amp;gt;assertSame()&amp;lt;/tt&amp;gt; does). New &amp;lt;tt&amp;gt;assertContainsEquals()&amp;lt;/tt&amp;gt; has been created to provide the old behavior.&lt;br /&gt;
* Changes to the &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; schema, mostly internal. These only will impact if you are using custom &amp;lt;tt&amp;gt;phpunit.xml&amp;lt;/tt&amp;gt; files:&lt;br /&gt;
** The previous &amp;lt;tt&amp;gt;&amp;lt;filter&amp;gt;&amp;lt;/tt&amp;gt; section is now (better) called &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;. And, within it:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; has been replaced by &amp;lt;tt&amp;gt;&amp;lt;include&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*** &amp;lt;tt&amp;gt;&amp;lt;exclude&amp;gt;&amp;lt;/tt&amp;gt; is not a child of &amp;lt;tt&amp;gt;&amp;lt;whitelist&amp;gt;&amp;lt;/tt&amp;gt; anymore, but of &amp;lt;tt&amp;gt;&amp;lt;coverage&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** But with implications when defining the [[#Check your coverage|coverage information]] because &amp;lt;tt&amp;gt;$whitelistxxx&amp;lt;/tt&amp;gt; properties used by the &amp;lt;tt&amp;gt;coverage.php&amp;lt;/tt&amp;gt; files have been deprecated, instead use &amp;lt;tt&amp;gt;includelistfolders&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;includelistfiles&amp;lt;/tt&amp;gt; (to better map the elements in the xml).&lt;br /&gt;
* Warning: It&#039;s not possible to run individual test files any more. Use any of the alternative execution methods (filter, suite, config) to specify which tests you want to run. This will be hopefully fixed in MDL-71049 once it has been agreed which the best way to proceed is.&lt;br /&gt;
* Deprecations, deprecations, deprecations. Lots of them in often used assertions: file assertions, regexp assertions, exception expectations... again, note that all them will become errors with the next PHPUnit update, so &#039;&#039;&#039;the recommendation is to update them ASAP&#039;&#039;&#039;.&lt;br /&gt;
Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/fc335f5...713722c browse the changes associated with the issue], hopefully with useful explanations in the commit messages.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.10 and up (PHPUnit 8.5)=&lt;br /&gt;
{{Moodle 3.10}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.10, &#039;&#039;&#039;PHPUnit was upgraded to 8.5&#039;&#039;&#039; (from 7.5 being used in older version). This was done to &#039;&#039;&#039;better align&#039;&#039;&#039; the testing environment with PHP versions supported by Moodle 3.10 (7.2, 7.3 and 7.4) and also to provide an &#039;&#039;&#039;easier jump to PHPUnit 9.x&#039;&#039;&#039; that will be needed for Moodle 3.11 (php versions 7.3, 7.4 and 8.0), removing a lot of deprecated stuff in advance. (see MDL-67673 and MDL-64600 for more details).&lt;br /&gt;
&lt;br /&gt;
While 99% of existing tests will work without modification with PHPUnit 8.5, you will get a &#039;&#039;&#039;good number of deprecation warnings&#039;&#039;&#039; (&amp;quot;W&amp;quot; in the tests output) that &#039;&#039;&#039;should be replaced by their new counterparts as soon as possible&#039;&#039;&#039;, because all those warnings will become errors with next PHPUnit upgrade.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 8.5, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2019/02/help-my-tests-stopped-working A good article] explaining all the main changes in the release.&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-8.html PHPUnit 8 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/130104cf796a88dd1547dc5beb8bd555c2deb55e/ChangeLog-8.0.md Detailed changelog of the release].&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/8.5/ Official PHPUnit manual].&lt;br /&gt;
* A good summary of all the &#039;&#039;&#039;changes and replacements to perform&#039;&#039;&#039; is available in the [https://github.com/moodle/moodle/blob/6594c54b2eef62499d304bfa0939999e3a14246e/lib/upgrade.txt#L5-L37 lib/upgrade.txt] file. With main points being:&lt;br /&gt;
** Support for PHP 7.0 dropped (because all template methods (&amp;lt;tt&amp;gt;setUp()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tearDown()&amp;lt;/tt&amp;gt;..) now require to return void. This will mostly impact 3rd-part plugins that were still running the same tests against old branches of Moodle with PHP 7.0 support.&lt;br /&gt;
** &amp;lt;tt&amp;gt;PHPUnit/DBUnit&amp;lt;/tt&amp;gt; has been removed are replaced by a lightweight alternative.&lt;br /&gt;
** Deprecations, deprecations, deprecations. Lots of them in often used assertions (&amp;lt;tt&amp;gt;assertContains()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;assertEquals()&amp;lt;/tt&amp;gt;...) and also &amp;lt;tt&amp;gt;@expectedExceptionXXX&amp;lt;/tt&amp;gt; annotations. Again, note that all them will become errors with PHPUnit 9.&lt;br /&gt;
* Finally, it&#039;s also a good idea to [https://github.com/moodle/moodle/compare/5903054...b13ec3c browse the changes associated with the issue], hopefully with useful enough explanations in the commit messages.&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.7 and up (PHPUnit 7.5)=&lt;br /&gt;
{{Moodle 3.7}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.7, &#039;&#039;&#039;PHPUnit was upgraded to 7.5&#039;&#039;&#039; (from 6.x being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.7 (7.1, 7.2 and 7.3). (see MDL-65204 and linked issues for more details). While internally [https://phpunit.de/announcements/phpunit-7.html a lot of things changed with PHPUnit 7] (PHP 7.1-isms, typed signatures, void returns, assertEquals() changes), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 7, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://phpunit.de/announcements/phpunit-7.html  PHPUnit 7 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/520723129e2b3fc1dc4c0953e43c9d40e1ecb352/ChangeLog-7.5.md Detailed changelog of the release], paying special attention to the added, deprecated, changed and deleted sections.&lt;br /&gt;
* [https://phpunit.readthedocs.io/en/7.5/ Official PHPUnit manual].&lt;br /&gt;
* Changes performed into core, mainly: new, stricter, signatures ([https://github.com/moodle/moodle/commit/26218b7 26218b7]) and assertEquals() changes, specially important when comparing strings, now performed using strict (===) equals ([https://github.com/moodle/moodle/commit/85f47ba 85f47ba]).&lt;br /&gt;
=Upgrading unit tests to work with Moodle 3.4 and up (PHPUnit 6)=&lt;br /&gt;
{{Moodle 3.4}}&lt;br /&gt;
&lt;br /&gt;
With Moodle 3.4, &#039;&#039;&#039;PHPUnit was upgraded to 6.4&#039;&#039;&#039; (from 5.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.4 (7.0, 7.1 and 7.2). (see MDL-60611 and linked issues for more details). While internally [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues a lot of things changed with PHPUnit 6] (namespaced classes being the more noticeable), thanks to our &#039;&#039;&#039;wrapping layer&#039;&#039;&#039; (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.&lt;br /&gt;
&lt;br /&gt;
Still, in &#039;&#039;&#039;some cases, it will impossible to maintain compatibility&#039;&#039;&#039; of tests between old (pre 3.4) tests and new ones, especially &#039;&#039;&#039;when direct use of any phpunit class is performed&#039;&#039;&#039;. Luckily, both GitHub Actions and CI tests will detect this situation and it shouldn&#039;t be hard to keep all supported branches in core passing ok. Plugins may be trickier, if the same branch is attempting to work against multiple core branches and they are using some phpunit class directly.&lt;br /&gt;
&lt;br /&gt;
To find more information about the changes coming with PHPUnit 6, it&#039;s recommended to read the following resources:&lt;br /&gt;
* [https://thephp.cc/news/2017/02/migrating-to-phpunit-6 A very good mini-guide] showing all the important changes.&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-6.0.0#backwards-compatibility-issues PHPUnit 6 release Announcement].&lt;br /&gt;
* [https://github.com/sebastianbergmann/phpunit/blob/9d0c024d2099531442d862b66b0ad7cf35ed8e78/ChangeLog-6.0.md Detailed changelog of the release], paying special attention to the changed and deleted sections.&lt;br /&gt;
* Changes performed into core, mainly: namespace class renaming ([https://github.com/moodle/moodle/commit/801a372dadb6e11c8781547603e3f0a59ce5638f 801a372]) and deprecated stuff ([https://github.com/moodle/moodle/commit/796e48a58bf18533bdca423fff7949ab119101c4 796e48a])&lt;br /&gt;
=See also=&lt;br /&gt;
* [[PHPUnit integration]]&lt;br /&gt;
* [[PHPUnit]]&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63849</id>
		<title>Process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63849"/>
		<updated>2023-03-24T11:02:54Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/process}}&lt;br /&gt;
This document summarises the various development processes used in developing Moodle. There are four main processes that overlap.&lt;br /&gt;
==Integration workflow in the tracker==&lt;br /&gt;
The Moodle tracker keeps track of the status of all bug fixes and new features. &lt;br /&gt;
&lt;br /&gt;
We use a workflow that ensures that new code receives multiple reviews by different people before it is included into the core Moodle code.&lt;br /&gt;
&lt;br /&gt;
[[Image:Workflow.jpg]]&lt;br /&gt;
&lt;br /&gt;
A number of roles make this work:&lt;br /&gt;
===Users===&lt;br /&gt;
Users report bugs and make feature requests directly in the tracker, by creating new issues with a summary and a description.&lt;br /&gt;
===Developers===&lt;br /&gt;
Developers work on the issues in the tracker to specify solutions and write code that implements these solutions. They will often ask other developers to &amp;quot;peer review&amp;quot; their code in the early stages to avoid problems later on.&lt;br /&gt;
&lt;br /&gt;
While many of the developers work for Moodle.com, a large number are part of the global development community around Moodle. If you&#039;re interested in becoming a recognised developer, see [[Tracker_guide#Tracker_groups_and_permissions|Tracker groups and permissions]].&lt;br /&gt;
===CiBoT===&lt;br /&gt;
CiBoT is not a person but a bot who monitors the tracker and performs the [[Automated code review]] when issue is submitted for Peer review or when developer added &#039;&#039;cime&#039;&#039; label.&lt;br /&gt;
===Component leads===&lt;br /&gt;
[https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page Component leads] are developers with some responsibility for particular components (plugins or modules) in Moodle. They have authority to decide that a particular fix is suitable and complete enough to be considered for integration in Moodle core and should be called upon to complete peer reviews for code in their components. Note that, apart from that, every component also has some [[Component Leads|HQ Component leads]] that will specifically work on associated issues, triaging, monitoring, reviewing, fixing them.&lt;br /&gt;
&lt;br /&gt;
===Component leads reviewers===&lt;br /&gt;
Component Lead Reviewers are Component Leads who have the added responsibility of performing a second and final review of a selection of issues within their component.&lt;br /&gt;
After reviewing the code, it is sent to the integration team to be pulled without further review.&lt;br /&gt;
&lt;br /&gt;
===Integrators===&lt;br /&gt;
From Monday to Thursday, the integration team (a small team of senior developers employed by Moodle HQ) conducts a code-level review of all issues in the integration queue. This is often called the &amp;quot;pull&amp;quot; process. If the fix is judged appropriate they will integrate the code into our git integration repository for further testing and it gets added to the testing queue.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and send it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
During each week the testers look at all the issues in the testing queue, trying each fix and feature to make sure that it does actually fix the problem it was supposed to, and that there are no regressions in the web version and the Moodle mobile app.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and integrators may remove it from the integration repository and push it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
See [[Testing of integrated issues]] for more details.&lt;br /&gt;
&lt;br /&gt;
===Production maintainers===&lt;br /&gt;
On Thursday each week, production maintainers merge all the issues that passed testing into the git production repository, and it becomes available for use on production systems via git and download packages.&lt;br /&gt;
==Stable maintenance cycles==&lt;br /&gt;
Moodle releases regular updates of the stable version of the software to fix bugs and other issues. Releases like 2.2.1, 2.2.2, 2.2.3 etc only include fixes based on the latest major release (2.2) and never any significant new features or database changes.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are teams of developers using the [http://www.scrum.org/ Scrum framework] to work on these issues (as well as new features for [[#Major_release_cycles|major releases]]). &lt;br /&gt;
&lt;br /&gt;
===Minor release (point release) timing===&lt;br /&gt;
After [[#Major_release_cycles|major releases]] there will be minor releases.&lt;br /&gt;
* x.x.1 will occur approximately two months after each major release (eg. 2.x).&lt;br /&gt;
* There will then be another point release every two months after that.&lt;br /&gt;
See the [[Releases#General_release_calendar|General release calendar]] for details.&lt;br /&gt;
&lt;br /&gt;
===Issue triage===&lt;br /&gt;
[[Bug_triage|Issue triage]] involves evaluating new issues, making sure that they are recorded correctly. One of the most important jobs triagers do is to identify issues that should be fixed in the stable branch. These are set with a priority ranging from &amp;quot;Trivial&amp;quot; up to &amp;quot;Blocker&amp;quot; and other features are checked.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are currently teams working on stable issues (mostly bugs reported by users) and improvements and new features (Partners, Moodle Association, user suggestions and Martin Dougiamas).&lt;br /&gt;
&lt;br /&gt;
===Scrum===&lt;br /&gt;
At Moodle HQ, every three weeks, the stable team takes a number of the most urgent issues from the backlog to work on during a period known as a &#039;&#039;sprint&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
At the start of a sprint there is a period of planning and estimation. All issues on the backlog are given a relative rank that is based on issue features including priority, security, Partner interest, patches and votes. Issues are given a relative size in Story Points and these points are summed to allow the teams to determine how many issues they can work on in the sprint.&lt;br /&gt;
&lt;br /&gt;
During the sprint, the team meets daily to discuss solutions and progress, as well as to organise testing and peer reviews of code. The team has a &#039;&#039;Scrum master&#039;&#039; to help everyone stay organised, to &amp;quot;unblock&amp;quot; any barriers to progress and to protect the team from distracting influences (mostly people attempting to add to the developers&#039; workloads) during the sprint. The teams&#039; work is documented publicly in the tracker.&lt;br /&gt;
&lt;br /&gt;
Whenever a solution for an issue is finished, it is submitted to the standard integration workflow process described above.&lt;br /&gt;
&lt;br /&gt;
==Major release cycles==&lt;br /&gt;
Since Moodle 2.0, we have a policy of release major versions (eg 2.1, 2.2) every six months in May and November. See the [[Releases#General_release_calendar|General release calendar]] for more details.&lt;br /&gt;
&lt;br /&gt;
Each release can be different, but generally the cycles work as follows.&lt;br /&gt;
===Define roadmap===&lt;br /&gt;
The roadmap is prioritised based on user research, stakeholder inputs, community wishes, third-party developments and important issues within the existing code. &lt;br /&gt;
&lt;br /&gt;
Sometimes new features might be based on earlier features, sometimes they may be something developed by a third party that needs to be evaluated and sometimes it might be something completely new.&lt;br /&gt;
===Planning and development===&lt;br /&gt;
The product teams together with UX, employed at Moodle HQ, work on specifications of major new features throughout the cycle, specifying projects ahead of development time.&lt;br /&gt;
&lt;br /&gt;
The process of [[#New_feature_development|new feature development]] is described below. When specifications are in place, new code is developed during sprints, where designs and implementation are iterated as required, and goes through the standard weekly integration workflow described above.&lt;br /&gt;
===Testing===&lt;br /&gt;
During development, as new code is integrated, automated testing conducted at the [[PHPUnit|code]] and [[Acceptance_testing|interface]] levels, to make sure there are no regressions caused by new features.&lt;br /&gt;
&lt;br /&gt;
In the last month before the release, a feature freeze is called (no new features can be added) and volunteer testers from the Moodle community perform manual QA testing of Moodle features. The current set of functional tests is listed in MDLQA-1. The list of tests is extended as new features are added, though we&#039;re also trying to reduce the number as more automated [[Acceptance_testing|acceptance tests]] are developed.&lt;br /&gt;
&lt;br /&gt;
There is also a set of tests for manually testing any major theme changes - MDLQA-11592.&lt;br /&gt;
&lt;br /&gt;
For more details, see [[Testing]].&lt;br /&gt;
===Sprints===&lt;br /&gt;
At Moodle HQ, development takes place in sprints. The sprints are two or three-week periods during which developers to focus on a fixed list of issues. For example, sprints can be arranged within each release cycle as shown in the diagram below.&lt;br /&gt;
===Events during cycle===&lt;br /&gt;
During each cycle there are a periods and events that occur between and around sprints.&lt;br /&gt;
&lt;br /&gt;
[[Image:Dev sprint calendar.png|800px]]&lt;br /&gt;
; &#039;&#039;&#039;Planning and bug fixing&#039;&#039;&#039;&lt;br /&gt;
: A period during which the Roadmap is explored, specs are written and prototypes are created. Regressions in the recent release are fixed as they arise.&lt;br /&gt;
; &#039;&#039;&#039;End sync period&#039;&#039;&#039;&lt;br /&gt;
: During the [[Integration Review#On-sync period|on-sync period]], the recent release and master versions are kept synchronised. No new code is added during this period, which ensures regressions are fixed rapidly. This also allows for planning and provides relief for developers after a release.&lt;br /&gt;
; &#039;&#039;&#039;Personal projects&#039;&#039;&#039;&lt;br /&gt;
: Affecting full-time HQ developers only, this period allows for individual creations to be explored and provides a break from sprints.&lt;br /&gt;
; &#039;&#039;&#039;Code freeze&#039;&#039;&#039;&lt;br /&gt;
: A point after which no new code (only fixes to existing code) is accepted until beyond the release. This stabilisation allows for QA testing.&lt;br /&gt;
; &#039;&#039;&#039;QA, bug fixing, continuous integration&#039;&#039;&#039;&lt;br /&gt;
: A period after the code freeze where quality assurance testing takes place. No new code is added, which means developers are able to respond rapidly to bugs found. Integration becomes [[Integration Review#During continuous integration/Freeze/QA period|continuous]], meaning that failed QA tests can be re-run within days rather than having to wait for the weekly release.&lt;br /&gt;
; &#039;&#039;&#039;Release candidate&#039;&#039;&#039;&lt;br /&gt;
: A point prior to the full release where a candidate is made public for wider testing.&lt;br /&gt;
==New feature development==&lt;br /&gt;
Major new features in Moodle usually should go through the following process.&lt;br /&gt;
===Specification===&lt;br /&gt;
The User Experience (UX) team members create detailed wireframes and features and goals for the new feature, based on iterative user research, design sprints, user testing and co-design as part of the product team. &lt;br /&gt;
&lt;br /&gt;
For bigger features there should be a clear overall vision for the outcomes that are to achieved. During implementation design may continue to iterate based on new findings.&lt;br /&gt;
&lt;br /&gt;
Developers create a detailed spec (here in the developer docs) outlining their goals for the development and their design for meeting those goals. &lt;br /&gt;
&lt;br /&gt;
Developers should also create an issue in the tracker (linking to your docs) to keep track of the project status.&lt;br /&gt;
===Community consultation===&lt;br /&gt;
Get the community involved in looking at the spec to see if it meets their needs and to get further feedback. Please post in the [http://moodle.org/mod/forum/view.php?id=8052 Future major features forum] on moodle.org. You could also blog/tweet about it etc.&lt;br /&gt;
&lt;br /&gt;
Community developers proposing a new feature will want to talk with HQ core developers to make sure the ideas make sense, and possibly get some review on database design, architecture and so on.&lt;br /&gt;
===Develop the code using Git===&lt;br /&gt;
Develop your code on an open Git repository, like github.com. That enables people to see your code and to help you as it develops. Testers and early adopters also have the opportunity to try it early in the process and give you more valuable feedback.&lt;br /&gt;
&lt;br /&gt;
Coverage with automated tests ([[PHPUnit]] or [[Behat|Behat_integration]]) is mandatory for new features.&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
You need to fill in the information about your public git repository and which branches the fixes are on. Make sure you are listed as Assignee.&lt;br /&gt;
&lt;br /&gt;
This would be a good time to fill in the testing instructions (read the [[Testing instructions guide|instructions guide]]) for how to verify your fix is correct. You may also wish to add a comment in the bug.&lt;br /&gt;
&lt;br /&gt;
Component leads should put issues, which affect code in their components, up for peer review to allow interested parties to provide feedback. However, if it is not reviewed in a week, a component lead may send the issue to integration. If integrators consider that the issue has not been given proper chance for peer review (e.g. is extremely large or complex...) it can be decided to move the issue back in the process.&lt;br /&gt;
&lt;br /&gt;
All other developers, including people who are component leads but working outside their component, should have their issues peer reviewed before they are sent to integration.&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [http://tracker.moodle.org/browse/MDL#selectedTab=com.atlassian.jira.plugin.system.project%3Acomponents-panel component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
&lt;br /&gt;
===Submit the code for integration===&lt;br /&gt;
The developer is responsible for acting on the feedback from the peer reviewer. If changes have been made and the developer is satisfied that this has accommodated the feedback from the peer reviewer, then the developer can submit the issue for integration. If there have been significant changes after the peer review, or if the peer reviewer has raised concerns about the approach taken, then the developer should offer the issue up for peer review again, most often to the same peer reviewer, but not necessarily.&lt;br /&gt;
&lt;br /&gt;
Submitting an issue to integration is much the same as for any Moodle code. In some cases the Component Lead may perform a Component Lead Review instead of the integration team. See [[Integration Review]] and the information about the integration workflow above.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug==&lt;br /&gt;
Bug fixes, and minor features or enhancements should go through the following process. (The only exception is English language string typo fixes or suggested improvements, which may be contributed to the en_fix language pack on the [http://lang.moodle.org/ Moodle translation site].)&lt;br /&gt;
===Make sure there is a tracker issue===&lt;br /&gt;
Every change must have an issue in the tracker. If you are fixing a bug, there is probably one there already, but if not, create one. [[Tracker tips|Tips for searching tracker]].&lt;br /&gt;
===Decide which branches the fix is required on===&lt;br /&gt;
Bugs should normally be fixed on all the supported stable branches that are affected. New features should just go into master, but sometimes minor enhancements are made on the most recent stable branch.&lt;br /&gt;
===Develop your change using git===&lt;br /&gt;
Develop your fix and push the change to an open git repository, for example on github.com. See also [[Git for developers]]&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
&lt;br /&gt;
You will need to push one commit for each branch the fix needs to be applied to. Often people use branch names like MDL-12345-31_brief_name so it is clear what each branch is. [http://kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick] can help with replicating the fix onto different branches.&lt;br /&gt;
&lt;br /&gt;
Consider setting up [https://moodledev.io/general/development/tools/gha GitHub Actions integration] with your repository so tests will be automatically run for you whenever you push work on your fix.&lt;br /&gt;
&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Once your fix is done, it should be submitted for a peer review.&lt;br /&gt;
&lt;br /&gt;
The following information is necessary for this:&lt;br /&gt;
* Information about your public git repository&lt;br /&gt;
** repository URL&lt;br /&gt;
** branch name(s)&lt;br /&gt;
** diff URL&lt;br /&gt;
* [[Testing instructions guide|Testing instructions]] for how to verify your fix is correct.&lt;br /&gt;
If you have never contributed to Moodle and don&#039;t see a button &amp;quot;Request peer review&amp;quot;, just comment on the issue with the above information. The component lead or another user with sufficient privileges will then send the issue up for peer review for you.&lt;br /&gt;
&lt;br /&gt;
After your first fix is integrated you will be added to developers group and will be able to send issues for peer review yourself. In this case make sure you are listed as Assignee and click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve set up [https://moodledev.io/general/development/tools/gha GitHub Actions integration], the issue will automatically show the GitHub Actions build status for the branch(es) you&#039;ve submitted for peer review.&lt;br /&gt;
&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
===Submit your code for integration===&lt;br /&gt;
It will then be reviewed the following week by one of the integration team and either integrated or rejected. Once integrated, the fix will be tested, and then included in the next weekly release. For details see [[Integration Review]].&lt;br /&gt;
==Security issues==&lt;br /&gt;
Issues identified as [[Security|security issues]] are resolved in a slightly different way, in order to achieve responsible disclosure as described in [[Moodle security procedures]].&lt;br /&gt;
* Security issues should be labelled as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; in order control visibility of the issue.&lt;br /&gt;
** An issue reported with a security level of &amp;quot;Could be a security issue&amp;quot; should be evaluated as soon as possible and either set as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; or the security level should be set to &amp;quot;None&amp;quot;.&lt;br /&gt;
* Solutions to security issues should not:&lt;br /&gt;
** be made available in public repositories.&lt;br /&gt;
*** If a developer has shared a solution as Git branches via Github, they should be asked to provide the solutions as [[How_to_create_a_patch|stand-alone patches]] attached to the issue and to [[#How to remove a branch from Github|remove the solution from Github]].&lt;br /&gt;
** contain details about the security problem in the commit message.&lt;br /&gt;
*** Instead use generic terms like, &amp;quot;improve&amp;quot;, &amp;quot;better handling of&amp;quot; ..&lt;br /&gt;
* The solution will not be integrated until the week before a [[Process#Stable_maintenance_cycles|minor release]] following the normal [[Release process|Release process]]. In short, the issue will be incorporated into the integration version, rebased, tested and made ready for release as a normal issue would, but not until as late as possible.&lt;br /&gt;
* Details of security issues will be shared with registered admins with the minor release.&lt;br /&gt;
* Details of security issues will not be publicly announced until one week after a minor release to allow admins to update.&lt;br /&gt;
Note that not all the labelled (minor) security issues are always handled following the procedure above. It&#039;s possible that, after discussion, it&#039;s decided a given issue is not a real Moodle security problem (say external disclosures/potential attacks using Moodle as vector, not as target, discussions revealing some private details...). Those issues will be processed as normal issues, generating the needed user documentation if necessary and will be part of the habitual weekly releases.&lt;br /&gt;
====How to remove a branch from Github====&lt;br /&gt;
To remove a branch from Github, you can use the following command.&lt;br /&gt;
 git push github :remote_branch&lt;br /&gt;
Where &#039;&#039;remote_branch&#039;&#039; is the name of your remote branch, for example &#039;wip-mdl-1234&#039;. This effectively replaces the remote branch with nothing, removing the remote branch, but leaving the branch intact in your local Git repository. Please note that its likely that your commit will still exist on github due to the nature of git, so its best to avoid doing this in the first place.&lt;br /&gt;
==Policy issues==&lt;br /&gt;
Occasionally within Moodle we run into policy issues where a high-level decision needs to be made about how things are to be done.&lt;br /&gt;
&lt;br /&gt;
In these cases the process is as follows:&lt;br /&gt;
* Create an issue in the tracker with a [https://tracker.moodle.org/browse/MDL/component/12733 Policy component] and put &amp;quot;POLICY:&amp;quot; as a prefix on the summary.&lt;br /&gt;
* In the description describe the problem clearly as well as all the options. If it&#039;s long then make a page here in Moodle Dev Docs and link to it.&lt;br /&gt;
* Do not use this issue for code. If there are issues that depend on this policy decision, then add tracker links to them as dependencies.&lt;br /&gt;
* Feel free to encourage people to come and talk about the policy to support various points of view. The more evidence we have (from everyone in the community) the better.&lt;br /&gt;
Some time has been scheduled in the weekly Moodle HQ meeting to look at Policy issues and try to make decisions on them. We discuss all the evidence and try to achieve a high amount of consensus. Deadlocked issues can be resolved by a decision from Martin Dougiamas (this is rarely needed).&lt;br /&gt;
&lt;br /&gt;
Decisions will be posted on the issue and that issue will be closed, allowing any dependent issues to continue to integration (or not). Decisions are final and bribes hardly ever work.&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
* [[Deprecation]]&lt;br /&gt;
* [http://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=11350 Integration dashboard]&lt;br /&gt;
Walks-though of the process for contributors:&lt;br /&gt;
* By Dan Poltawski, Integrator: http://www.slideshare.net/poltawski/how-to-guarantee-your-change-is-integrated-to-moodle-core, https://www.youtube.com/watch?v=836WtnM2YpM&lt;br /&gt;
* By Tim Hunt, contributor: http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html and https://www.youtube.com/watch?v=gPPA3h7OGQU and https://youtu.be/Hu8ne0NCRAg?t=11659&lt;br /&gt;
[[Category:Processes]]&lt;br /&gt;
[[Category:Quality Assurance]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Integration_Review&amp;diff=63848</id>
		<title>Integration Review</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Integration_Review&amp;diff=63848"/>
		<updated>2023-03-24T11:02:06Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/process/integration}}&lt;br /&gt;
==Purpose==&lt;br /&gt;
&lt;br /&gt;
The purpose of the integration review is to:&lt;br /&gt;
* Ensure consistent quality across the codebase&lt;br /&gt;
* Ensure that pedagogical aims of Moodle are at the forefront of any change&lt;br /&gt;
* Take into consideration the holistic view of moodle, looking at the impact beyond where the original developer was focused&lt;br /&gt;
* Provide guidance and feedback to developers, helping them learn and improve &lt;br /&gt;
* Consider &#039;&#039;&#039;other perspectives&#039;&#039;&#039; of other users perhaps not considered by original developers e.g.&lt;br /&gt;
** Teachers&lt;br /&gt;
** Students&lt;br /&gt;
** Administrators&lt;br /&gt;
** The Moodle mobile app&lt;br /&gt;
**Third-party developers&lt;br /&gt;
&lt;br /&gt;
== Integration Principles ==&lt;br /&gt;
&lt;br /&gt;
Integration (non-technical but philosophical) principles (4-5 words determining if something has to be integrated/backported or no):&lt;br /&gt;
&lt;br /&gt;
# safety: if something does not look safe, stable, it won&#039;t land. Be conservative.&lt;br /&gt;
# security: all security issues, if not breaking principle (1) will be integrated/backported to all security-supported versions.&lt;br /&gt;
# community: Anything not useful for the community (or against it) won&#039;t be integrated/backported. We can measure the community as 10%HQ, 10%Partners, 10%Core developers, 20%Admins, 20%Teachers, 30%Students - not exact science, just one approximation, you know). Question yourself how the change will affect those groups and ensure positives are bigger always (only affected groups count). All community issues, if not breaking principles (1) and (2) will be integrated.&lt;br /&gt;
# typology:  bug fixes will be always integrated/backported to all the supported braches if none of the principles (1), (2) and (3) are violated. Also, partially-unsupported branches can receive some if they are important enough. Improvements and new features go, exclusively, to master only, that&#039;s the main reason for short release periods. We *must* not make exceptions to this.&lt;br /&gt;
# priority: issues will be &amp;quot;ordered down&amp;quot; by priority down (where priority is a [https://tracker.moodle.org/issues/?filter=14000 mix of various factors], dynamic). And will be integrated in that order. If something has to be delayed, better if it is low priority. Once again, nothing here can break any of the previous principles.&lt;br /&gt;
# tests: unit tests and acceptance tests will backported as much as possible without breaking (1) and (2). New features required to implement tests will be backported if the API is 100% backwards compatible. &lt;br /&gt;
If all the principles are fulfilled, the answer for &amp;quot;should I integrate this?&amp;quot; is, &amp;quot;yes, please!&amp;quot;&lt;br /&gt;
(apart from technical findings, of course, that can lead to the issue being not integrated/reopened at last, these principles are 100% philosophical)&lt;br /&gt;
&lt;br /&gt;
==Component Lead Review Process==&lt;br /&gt;
&lt;br /&gt;
Please see the [[Component_Lead_Review|Component Lead Review documentation]] for further information on the CLR process.&lt;br /&gt;
&lt;br /&gt;
==Integration Review Process==&lt;br /&gt;
&lt;br /&gt;
# Run automated pre-checks against the continuous integration server. (In future this can be automated and also moved into a publicly accessible domain.)&lt;br /&gt;
# Final code review, much like the peer review, except that this is the final check. To include&lt;br /&gt;
## Takes place in-situ (integrated) to examine the impact to other integrated issues&lt;br /&gt;
## Checking against the coding guidelines - syntax/whitespace&lt;br /&gt;
## Moodleisms - using the built-in API functions where appropriate&lt;br /&gt;
## Cross-DB compatibility &lt;br /&gt;
## Security&lt;br /&gt;
# Check purpose - the patch needs to fix the issue reported.&lt;br /&gt;
# Verify target branches are appropriated. They must match 100% the rules defined for [[#Backporting|backporting issues]].&lt;br /&gt;
# Ensure backwards compatibility is maintained. As a starting point backwards compatibility must always be maintained. Where backwards compatibility is affected it should be:&lt;br /&gt;
## Well discussed with evidence of justification&lt;br /&gt;
## Documented and communicated to the community &lt;br /&gt;
# Ensure backwards compatibility with the Moodle mobile app. Especially in areas where the Moodle app uses pre-rendered content from the site (like Quiz or Lesson)&lt;br /&gt;
# Verify that components are correct and check the right people have been involved (e.g. component maintainers)&lt;br /&gt;
# For fundamental changes, check that a thread has been started in an appropriate forum, and other Moodlers, given enough time to comment.&lt;br /&gt;
# Tests - must be written to guide tester to verify the fix is working.&lt;br /&gt;
## Unit test - very much preferred if applicable&lt;br /&gt;
## at end of Wednesday, ensure testing is going to complete as expected. else take other actions (speak to test manager)&lt;br /&gt;
# Performance - we have to look at maintaining optimum code here, as far as simple patches that can affect performance. (simple optimisations)&lt;br /&gt;
# Scalability - if master only - we&#039;re looking far future, stable branches may not be lucky to get such improvements.&lt;br /&gt;
# git authorship is correct vs committer + credits due are mentioned + email addresses&lt;br /&gt;
# Documentation / PHP Doc / readability&lt;br /&gt;
# [[Tracker issue labels]] which might need adding. Particularly:&lt;br /&gt;
## docs_required / dev_docs_required / release_notes: About which type of documentation is required for the issue.&lt;br /&gt;
## ui_change / api_change: About the implications of the change.&lt;br /&gt;
## unit_test_required / acceptance_test_required / qa_test_required: About the need to cover the issue with some test.&lt;br /&gt;
## affects_mobileapp / affects_workplace / affects_moodlecloud: About issues that may affect other Moodle products and services&lt;br /&gt;
# [[Tracker issue versions]] review. Particularly:&lt;br /&gt;
## Fixed Version after integration - is the versions that the issue is patched for. (A rule here: [[Tracker issue versions#Some general and simple rules|&amp;quot;or stables or master&amp;quot;]]).&lt;br /&gt;
## Remove any &amp;quot;Must fix for X.Y&amp;quot; version once the issue is integrated.&lt;br /&gt;
# Whenever any of the points above or any other detail require extra information or action to be done by the assignee, and the integrator considers that they can be fixed without needing to discard/reopen, the issue will be sent to &amp;quot;Waiting for feedback&amp;quot; with all the details to complete. Once everything has been fulfilled, always within a reasonable amount of time (still to decide), the issue will be sent back to integration by the assignee.&lt;br /&gt;
# Assign the tester.&lt;br /&gt;
## Don&#039;t forget to update the weight in the testers sheet&lt;br /&gt;
&lt;br /&gt;
==Schedule==&lt;br /&gt;
===In normal periods ===&lt;br /&gt;
The integrators adhere to the following schedule: (links here should convert the times into your local timezone)&lt;br /&gt;
&lt;br /&gt;
All the flow of issues to current integration is automatically controlled by the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job that keeps the current queue fed with issues, moves important ones and priotitises long awaiting issues. Issues are picked in strict integration order.&lt;br /&gt;
&lt;br /&gt;
* Monday to Thursday until [http://time.unitarium.com/utc/4 12:00 (UTC+8)]: Integration and [[Testing of integrated issues#The testing process|Testing]] happen. Note that 24h before the cutoff it&#039;s possible to pick issues out of order towards queues reduction.&lt;br /&gt;
* Thursday after 12:00 (UTC+8): Integrators duties during this time are to monitor, facilitate and &#039;problem solve&#039; the testing process.&lt;br /&gt;
* Friday: Testing should be completed before (the sooner the better) 12:00 (UTC+8) at which time remaining testing failures will be reverted/rewritten and reopened. The release process follows.&lt;br /&gt;
* Friday after 12:00 (UTC+8):: Should be kept free from integration. Integration systems are maintained during this time.&lt;br /&gt;
&lt;br /&gt;
Note that under the strict schedule above, it is specially important &#039;&#039;&#039;to be as responsive as possible&#039;&#039;&#039;, both when the issue is being integrated and when [[Testing_of_integrated_issues#Expectation_from_tester|testing]]. Any significant delay by any of the actors involved will result in the issue being moved out from current integration.&lt;br /&gt;
&lt;br /&gt;
=== During continuous integration/Freeze/QA period ===&lt;br /&gt;
During the continuous integration period (last 6 weeks before release) the integration team are continuously focused on producing regular builds of master to facilitate QA and fast fixes to issues identified.&lt;br /&gt;
&lt;br /&gt;
* Throughout:&lt;br /&gt;
** Issues are picked on a one by one basis, prioritising [https://docs.moodle.org/dev/QA_testing#Resetting_tests QA blockers] and master regressions (MUST FIX) issues.&lt;br /&gt;
** After freeze (usually 5 weeks before release) any non bug fix issues are given the &#039;&#039;integration_held&#039;&#039; label and are explicitly not picked for integration. Still, anybody is able to add a reasoned &#039;&#039;unhold_requested&#039;&#039; label to those issues in order to get them unblocked by the development managers. Note this does not guarantee the issue to land before release, but just gives it a chance to be integrated like any other issue.&lt;br /&gt;
** Also, coming together with freeze, all the flow of issues to current integration is automatically controlled by the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job that keeps the current queue fed with issues, moves important ones, holds new features and other niceties. Issues are picked in strict integration order.&lt;br /&gt;
** Our goal is to achieve &#039;releaseability&#039; throughout, so we stop integrating to ensure a release happens&lt;br /&gt;
&lt;br /&gt;
So, basically, once under continuous integration, we do organize work as follows:&lt;br /&gt;
* Continuous officially begins. Everybody is on integration. Until end of on-sync period.&lt;br /&gt;
* Monday: Integration and [[Testing of integrated issues#Differences in test process during continuous integration periods|testing]] happens.&lt;br /&gt;
* Tuesday: Integration happens until [http://time.unitarium.com/utc/4 12:00 (UTC+8)], [[Testing of integrated issues#Differences in test process during continuous integration periods|afterwards we try to achieve 100% &#039;Test Passed&#039;]] and stop integrating any untested changes until a master release is produced.&lt;br /&gt;
* Wednesday: [Assuming a master release has been rolled] Integration and testing continues&lt;br /&gt;
* Thursday: Integration and testing continues&lt;br /&gt;
* Friday: Integration happens until 12:00 (UTC+8), afterwards we try to achieve 100% &#039;Test Passed&#039; and stop integrating any untested changes until a master release is produced. Note that 24h before the cutoff it&#039;s possible to pick issues out of order towards queues reduction.&lt;br /&gt;
&lt;br /&gt;
Note: along this period we always release as many stable weeklies, both supported (always) and security only (when there are changes), as master rolls (on-demand, beta, rc) happen (see MDLSITE-3470). Note that those tags are not simply tags but they come with some important implications, aiming to stability, safety and clarity. Integrators will try to remain loyal to them, be warned:&lt;br /&gt;
&lt;br /&gt;
* Once beta is released... new features or improvements &amp;quot;unrelated&amp;quot; with the release will be really harder to be accepted. A +4 from developer managers (normally +3 is enough) will be needed to proceed with the issue. Integrators vote will be, always, -1.&lt;br /&gt;
* Once rc are released... new features or improvements &amp;quot;unrelated&amp;quot; with the release are forbidden. No unhold voting, no managers. Simply forbidden.&lt;br /&gt;
* Last week before release, only &amp;quot;related&amp;quot; issues will be picked for integration. Everything else (bug fixes included) are kept out (given the &amp;quot;integration_held&amp;quot; label) if unrelated, at very least until after release. No distractions.&lt;br /&gt;
Definition: &amp;quot;related&amp;quot;: said to be a followup of required/planned to release OR a direct (and recent) regression caused by a bug fix OR a security issue.&lt;br /&gt;
&lt;br /&gt;
=== On-sync period ===&lt;br /&gt;
Immediately after a major release and for a short period (right now, 2 weeks, matching 1st HQ sprint duration), the integration team is under the named on-sync period.&lt;br /&gt;
&lt;br /&gt;
At all effects, it&#039;s a normal period (see above), and weeklies are produced for supported stable branches and also for master. But with one important rule/goal:&lt;br /&gt;
&lt;br /&gt;
* We must keep the latest stable branch and master 100% on-sync, specifically about versions and upgrade steps. Some well-known exceptions to this are: &#039;&#039;backup.class.php&#039;&#039;, &#039;&#039;config.php&#039;&#039; (&#039;&#039;$release&#039;&#039;, &#039;&#039;$branch&#039;&#039;, &#039;&#039;$maturity&#039;&#039; and comments only, never &#039;&#039;$version&#039;&#039; !), &#039;&#039;install/lang/xx&#039;&#039; files (the new stable branch for install lang files is created 2w after the release).&lt;br /&gt;
&lt;br /&gt;
This simple, but important constraint, is there to facilitate the integration of impeding bugs, needing urgent resolution, and by keeping them the same, we guarantee that any stable or master fix will apply without problems to both branches. Of course, in order to achieve the rule, these must be also observed along the period:&lt;br /&gt;
&lt;br /&gt;
* We continuously perform diffs between the latest stable and master, controlling that we are on-sync. Any non-authorised difference is cleaned (rewritten). Whenever a latest stable branch is missing in the issue (it&#039;s optional over the period), we automatically cherry pick the changes straight from master.&lt;br /&gt;
* Both improvements and new features (and, in general, everything leading to divergence) are held until the on-sync period ends.&lt;br /&gt;
&lt;br /&gt;
Last, but not less important, a second goal for this on-sync period is:&lt;br /&gt;
&lt;br /&gt;
* The environmental requirements &#039;&#039;&#039;for next major version&#039;&#039;&#039; [[Release process#2_weeks_after|must be agreed and resolved so they can land to master]] early in the process, remaining defined and stable over the next, 6 months of, development cycle.&lt;br /&gt;
&lt;br /&gt;
As part of the standard [https://docs.moodle.org/dev/Release_process Moodle release process], at the beginning of the on-sync period, we &amp;quot;unhold&amp;quot; all bugs that were held during the last week before the release because they were unrelated to the release. At the end of the onsync period we &amp;quot;unhold&amp;quot; all new features that were submitted after the code freeze for the the release.&lt;br /&gt;
&lt;br /&gt;
== Backporting ==&lt;br /&gt;
&lt;br /&gt;
Whilst we&#039;d all like all Moodle users to be using our latest and greatest code, there is a balance to strike between improving our software and maintaining stability (both in terms of regressions, but also training and documentation materials). Large amounts of change on the stable branches make the lives difficult for institutions to manage upgrades between point releases.&lt;br /&gt;
&lt;br /&gt;
==== General policy ====&lt;br /&gt;
Our general policy is as follows:&lt;br /&gt;
&lt;br /&gt;
* Bug fixes will be backported to all (and only to) supported stable branches. &lt;br /&gt;
** When fixing a bug, please provide a fix for all supported stable branches. &lt;br /&gt;
** If a fix doesn&#039;t make sense to be backported to every branch, please make it clear in the issue.&lt;br /&gt;
* Improvements or new features will only land in master.&lt;br /&gt;
&lt;br /&gt;
==== Process for requesting a non bug-fix backport ====&lt;br /&gt;
Improvements or new features can be requested to be backported to the stable branches. We urge developers to consider this request carefully. In recent years, Moodle has moved to a short and predicatable time based release schedule and we use a very effective distributed source control system. Both of these process changes should ensure that a change not being backported to the stable branches is not as problematic as it may have used to be. &lt;br /&gt;
&lt;br /&gt;
Should you feel that a new feature or improvement needs backporting, please follow this process:&lt;br /&gt;
&lt;br /&gt;
# File a new issue.&lt;br /&gt;
# Set the issue title using our backport template guide.  (i.e. &amp;quot;Fix forum alignment (backport of MDL-99999)&amp;quot;) - see [https://docs.moodle.org/dev/Tracker_guide#Tracker_fields Tracker_guide]&lt;br /&gt;
# Link the original issue using link type &amp;quot;Will help resolve&amp;quot;.&lt;br /&gt;
# You should include clear rationale for the request to backport&lt;br /&gt;
&lt;br /&gt;
The integration team will process backport requests, with the following guidelines:&lt;br /&gt;
# The integration team will together consider each request individually considering the needs of the community (influenced by forum posts, moodle partners, nagging developers etc).&lt;br /&gt;
# Backports will happen not earlier than 3 weeks and not later than 2 months after the request was performed.&lt;br /&gt;
# Rationale will be given for rejection&lt;br /&gt;
&lt;br /&gt;
If the backport request is approved, please follow the usual development process to submit the feature or improvement on earlier branches. Just to be clear, this means using the new bug number. So, even if the fix you are back-porting cherry-picks cleanly, you will need to amend the commit comment to use the new MDL-XXXXX number. It would be good practice to also add a line like &amp;quot;This is a backport of MDL-YYYYY.&amp;quot; in the amended commit comment. You can probably copy the testing instructions from the original issue. If so, make it clear you done this by saying something like &amp;quot;Copied from MDL-66327:&amp;quot;. Of course, if you can improve the instructions, feel free to edit. MDL-66614 and MDL-66327 are probably a reasonably good example fo what should be done.&lt;br /&gt;
&lt;br /&gt;
==== Polite note about bug classification ====&lt;br /&gt;
Many issues can be appropiately classified as borderline bugfix/improvements. We politely request that developers do not try and &#039;game the system&#039; by clasifying their improvements as bugs intentionally. If your fix is in a grey area, please state your case for it being a bug fix clearly. The integration team will use their discretion where necessary.&lt;br /&gt;
&lt;br /&gt;
==== Backport fixes to unsupported branches ====&lt;br /&gt;
* Given the [[#General policy|general policy]] above, only supported stable branches are candidates normally.&lt;br /&gt;
* Also security, privacy, dataloss and regressions caused by any of the previous issue types are accepted to be fixed into security-only supported branches. Note this doesn&#039;t include [[Tracker issue labels|&amp;quot;security_benefit&amp;quot; labelled issues]].&lt;br /&gt;
* Apart from the previous, issues required to keep the testing infrastructure working and passing (gha, behat, phpunit, random failures, new steps availability...) will also be accepted when possible into security-only branches.&lt;br /&gt;
* Finally, backport to unsupported branches only will happen when the issue is a &#039;&#039;&#039;direct regression caused by a bug fix&#039;&#039;&#039; introduced by the very latest releases. This applies to both security-only and out-of-support branches.&lt;br /&gt;
&lt;br /&gt;
A new weekly release will be performed including all the cases above, but  [[Process#Security issues|security issues that follow its own special process]] and are released bi-monthly.&lt;br /&gt;
&lt;br /&gt;
== Fixing issues identified during integration review/ testing ==&lt;br /&gt;
&lt;br /&gt;
When a branch has been merged by an integrator, it is important that you do not modify the existing history of your branch (e.g. by amending or squashing your commits) and instead add new commits on top. If you modify the history of your branch, it makes it extremely difficult for the integrator to merge your changes (and see the differences).&lt;br /&gt;
&lt;br /&gt;
As a general rule, this means that if your issue has entered the &#039;in integration review&#039; stage of the development process, please only add new commits on top of your existing commits. There are circumstances when your issue will be &#039;in integration review&#039; but not merged (and thus possible to squash changes) but if in any doubt, please add new commits and ask the integrator to squash your changes for you.&lt;br /&gt;
&lt;br /&gt;
== Commit squashing ==&lt;br /&gt;
&lt;br /&gt;
The Integration team will sometimes recommend squashing commits when things do not look natural (and may offer to do this for you), especially when there are &amp;quot;fix-commits&amp;quot; in the history happening before integration. But [https://moodle.org/local/chatlogs/index.php?conversationid=13987#c489485 our policy] is &amp;quot;if you want your history of commits to look like bad, it&#039;s your history&amp;quot;. You will not be forced to squash your changes. You should pay close attention to https://docs.moodle.org/dev/Coding_style#Git_commits and intend to  &amp;quot;Tell a perfect, cleaned up version of the history. As if the code was written perfectly first time.&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Category: Processes]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Behat_integration&amp;diff=63847</id>
		<title>Behat integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Behat_integration&amp;diff=63847"/>
		<updated>2023-03-24T11:01:08Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/tools/behat/}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This page describes the internals of Behat and the integration with Moodle. For the functional description, how to install it, run the suite and add more features, see [[Acceptance_testing]].&lt;br /&gt;
&lt;br /&gt;
Behat is a framework for behavior driven development (BDD) which allows us to specify Moodle functionalities (aka features) as a human-readable list of steps. It parses these steps to executable actions to simulate user interaction against headless browsers (without java script support, only curl-kind requests) or user simulation tools like Selenium, which interacts with browsers and allows JavaScript events simulation.&lt;br /&gt;
== Objective ==&lt;br /&gt;
The aim of this integration is to allow Moodle components to have its own set of features and step definitions. This allows us to periodically execute sets of tests to detect regressions and Moodle features in different environments (browsers, DBs engines, web servers...). The Moodle QA tests will be progressively rewritten according to this format to run automatically.&lt;br /&gt;
== How Behat works ==&lt;br /&gt;
This section aims to explain the basics about BDD and Behat and a quick view of how Behat internally works from the CLI command execution to the results output.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that all those examples are not necessarily real nor part of the suite, they are meant to help understand the concepts, see [[Acceptance_testing]] for real examples&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some terms used:&lt;br /&gt;
* &#039;&#039;&#039;Features&#039;&#039;&#039;: Human-readable list of scenarios that describes a feature&lt;br /&gt;
  @auth&lt;br /&gt;
  &#039;&#039;&#039;Feature&#039;&#039;&#039;: Login&lt;br /&gt;
    In order to login&lt;br /&gt;
    As a moodle user&lt;br /&gt;
    I need to be able to validate the username and password against moodle&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an existing user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an non-existing user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Invalid login&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Human-readable list of steps to describe an expected behaviour&lt;br /&gt;
  &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an existing user&lt;br /&gt;
    Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
    When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I fill in &amp;quot;password&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
    Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Steps&#039;&#039;&#039;: Human-readable sentences that describes an action. There are 3 types of steps, &amp;quot;Given&amp;quot; describing the initial context, &amp;quot;When&amp;quot; the event that provokes a change and &amp;quot;Then&amp;quot; where the outcomes should be asserted.&lt;br /&gt;
  I click on the &amp;quot;Add user&amp;quot; button&lt;br /&gt;
* &#039;&#039;&#039;Steps definitions&#039;&#039;&#039;: PHP methods referenced by steps when matching it&#039;s regular expression. The @Given, @When and @Then tags are descriptive and they are not taken into account when matching steps with steps definitions. The regular expressions placeholders are returned to the PHP method as arguments so methods can use them to tell the browser which button (for example) they want to click.&lt;br /&gt;
  /**&lt;br /&gt;
   * @When /^I click on the &amp;quot;(.*)&amp;quot; button$/&lt;br /&gt;
   */&lt;br /&gt;
  public function i_click_on_the_button($button) {&lt;br /&gt;
    // Simulates the user interaction (see Mink description below for more info)&lt;br /&gt;
    $this-&amp;gt;getSession()-&amp;gt;getPage()-&amp;gt;pressButton($button);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
* &#039;&#039;&#039;Behat&#039;&#039;&#039;: PHP framework and CLI application that wraps the whole process of features files loading + features files parsing + execution of actions in the browser + results output (http://behat.org/)&lt;br /&gt;
* &#039;&#039;&#039;Gherkin&#039;&#039;&#039;: Human-readable language used to define features that can be parsed and translated into PHP methods. For more info, it&#039;s the same language used by Cucumber, the BDD Ruby framework (https://github.com/cucumber/cucumber/wiki/Gherkin)&lt;br /&gt;
* &#039;&#039;&#039;Context&#039;&#039;&#039;: In Behat scope a context is a PHP class that groups steps definitions (as methods)&lt;br /&gt;
* &#039;&#039;&#039;Mink&#039;&#039;&#039;: Is the component which interacts with browsers, simulating a real user interaction. It allows us to write PHP code (or use the available PHP methods) to send requests to the different browsers APIs through a common interface or extend it to allow browser-specific actions. The supported browsers includes Selenium, Selenium2, Sahi... http://mink.behat.org/&lt;br /&gt;
* &#039;&#039;&#039;Selenium 2&#039;&#039;&#039;: Web browser automation tool, applications like Mink can communicate with it through a RESTful API (http://code.google.com/p/selenium/wiki/JsonWireProtocol) to execute actions simulating user interaction.&lt;br /&gt;
* &#039;&#039;&#039;Selector type&#039;&#039;&#039;: Related with &#039;&#039;&#039;locator&#039;&#039;&#039;, is a way to select a node inside the page DOM, more info in https://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps&lt;br /&gt;
* &#039;&#039;&#039;Locator&#039;&#039;&#039;: Is what we are looking for inside the page DOM, it completely depends on the associated selector type, a few examples of it:&lt;br /&gt;
** Selector type = &amp;quot;link&amp;quot;, Locator = &amp;quot;Link text&amp;quot;&lt;br /&gt;
** Selector type = &amp;quot;field&amp;quot;, Locator = &amp;quot;Field legend text&amp;quot;&lt;br /&gt;
** Selector type = &amp;quot;css&amp;quot;, Locator = &amp;quot;.css-class #id&amp;quot;&lt;br /&gt;
** Selector type = &amp;quot;xpath&amp;quot;, Locator = &amp;quot;//input[@id=&#039;id-value&#039;]&amp;quot;&lt;br /&gt;
All this components are written in PHP, open sourced and packaged in a single and extensible framework.&lt;br /&gt;
=== Quick view of the whole process ===&lt;br /&gt;
# Behat CLI execution&lt;br /&gt;
#* Behat application initialization and loading of arguments (features files to execute, output format...)&lt;br /&gt;
#* Reads the Behat config file (browser servers are specified here)&lt;br /&gt;
#* Extensions overrides management&lt;br /&gt;
#* Gherkin initialization&lt;br /&gt;
# Features files selection&lt;br /&gt;
#* According to the arguments Gherkin looks for .features files&lt;br /&gt;
#** It can use different features loaders (single file, a directory, the default directory...)&lt;br /&gt;
#** The framework can be extended to allow multiple folders loading&lt;br /&gt;
# Features parsing (Gherkin)&lt;br /&gt;
#* Loops through the loaded features files looking for scenarios&lt;br /&gt;
#* Gets the list of steps of each scenario&lt;br /&gt;
#* There are hooks at different levels (https://docs.behat.org/en/latest/user_guide/context/hooks.html)&lt;br /&gt;
# Steps parsing (Gherkin)&lt;br /&gt;
#* Gherkin looks in the available steps definitions for a regular expression that matches the step text&lt;br /&gt;
# Step definition execution&lt;br /&gt;
#* The step definition code is executed&lt;br /&gt;
#* Steps definitions most of the time uses the Mink component to communicate with the browser API sending requests like &amp;quot;click on that button&amp;quot; or &amp;quot;go to XXX page&amp;quot;&lt;br /&gt;
# Scenario outcomes&lt;br /&gt;
#* The scenario counts as failed if an exception is thrown when executing a step definition (for example trying to click a non-existing button)&lt;br /&gt;
#* The scenario counts as passed if no exception is thrown during it&#039;s steps execution&lt;br /&gt;
# Finishing CLI execution&lt;br /&gt;
#* A summary with all the scenario results is displayed&lt;br /&gt;
#* It accepts different output formats (like JUnitXML) to it&#039;s execution in continuous integration systems (http://docs.behat.org/guides/6.cli.html#format-options)&lt;br /&gt;
== Moodle integration ==&lt;br /&gt;
It follows the approach chosen with PHPUnit:&lt;br /&gt;
* It comes disabled by default, Behat is not included within Moodle and it has to be installed separately with the composer installer&lt;br /&gt;
* Moodle components (subsystems and plugins) can have a tests/behat/ folder&lt;br /&gt;
* The scenarios are executed in a test environment, the production database and dataroot are not affected by the tests modifications&lt;br /&gt;
* The scenarios specifies their own fixtures and it&#039;s execution is isolated from other scenarios and features, resetting the test database and the test dataroot before each scenario&lt;br /&gt;
* Moodle lists the features files and steps definitions of it&#039;s components in a behat.yml file, similar to the phpunit.xml manifest&lt;br /&gt;
* A basic behat.yml.dist config file has been included&lt;br /&gt;
=== Alternative environment ===&lt;br /&gt;
Acceptance testing implies interaction with the browser like real users does, so it requires the site to be accessible via URL. The Moodle integration creates a new moodle site installation in parallel to the production one to run the tests in a sandbox without affecting the production environment, switching the regular $CFG-&amp;gt;wwwroot, $CFG-&amp;gt;dataroot and $CFG-&amp;gt;prefix to alternatives, which should be only accessible from localhost or internal networks. Info about how to run the tests in https://docs.moodle.org/dev/Acceptance_testing#Running_tests. &lt;br /&gt;
&lt;br /&gt;
This default configuration is useful when developing in a local host, but to run the tests automatically with Jenkins, GHA, other CI systems or with saucelabs we provide a few extra settings. More info in https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage&lt;br /&gt;
&lt;br /&gt;
All the behat CLI utilities we provide within the Moodle codebase (admin/tool/behat/cli/*) are using $CFG-&amp;gt;behat_wwwroot, $CFG-&amp;gt;behat_prefix and $CFG-&amp;gt;behat_dataroot instead of $CFG-&amp;gt;wwwroot, $CFG-&amp;gt;prefix and $CFG-&amp;gt;dataroot, this scripts are self-contained, but as we are accessing through a browser, we also need to switch the whole Moodle instance to test mode. For this there are two requirements:&lt;br /&gt;
* Test mode is enabled if&lt;br /&gt;
** &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039; or &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039; has been executed&lt;br /&gt;
* Test mode is requested if&lt;br /&gt;
** The vendor/bin/behat command is running, we know it because we hook the Behat process before the tests begins to run and we require moodle config.php after it&lt;br /&gt;
** We set $CFG-&amp;gt;behat_wwwroot in config.php and we are accessing the moodle instance through it&lt;br /&gt;
The unique $CFG-&amp;gt;behat_wwwroot prevents unintended execution of acceptance tests on production sites.&lt;br /&gt;
&lt;br /&gt;
=== Javascript ===&lt;br /&gt;
There are two types of tests depending on if their scenario needs a real browser capable of execute Javascript or if they can run in a headless browser.&lt;br /&gt;
* Tests with Javascript requires interaction with a browser through a user simulation tool like Selenium or ZombieJS to be executed; see http://mink.behat.org/#different-browsers-drivers for all available drivers&lt;br /&gt;
* Test that does not requires Javascript are faster to run but can not test rich applications like Moodle&lt;br /&gt;
In most of the cases a Javascript test would be more appropriate because most of the users uses Javascript-capable browsers, non-Javascript tests can be useful to ensure that Moodle maintains its functionality without Javascript enabled and to ensure there are no big issues, regressions or exceptions in general.&lt;br /&gt;
=== Admin tool &amp;quot;Acceptance testing&amp;quot; ===&lt;br /&gt;
There is an admin tool to run and ease the creation of acceptance tests. &lt;br /&gt;
* Web interface: The web interface allows you to list and filter the available steps definitions, a non-technical user can use this interface to write new features (admin/tool/behat/index.php)&lt;br /&gt;
* CLI: Command to enable and disable the test environment and to update the behat.yml file with the system tests and steps definitions (admin/tool/behat/cli/util.php and admin/tool/behat/cli/init.php for a quick start)&lt;br /&gt;
[[File:Acceptance_testing_UI_2.5.png]]&lt;br /&gt;
=== Available steps to create tests ===&lt;br /&gt;
There are behat libraries with tons of steps definitions to run all sort of processes and interactions with the browser, some of them overlaps Moodle-specific libraries and tests writers can be confused not only by this also by the amount of steps and vague or too technical steps descriptions. Moodle provides a set of steps definitions written in a common format to make tests writers life easier. New steps definitions must follow this guidelines: https://docs.moodle.org/dev/Acceptance_testing#Adding_steps_definitions&lt;br /&gt;
=== Behat extension ===&lt;br /&gt;
A new Behat extension (https://github.com/moodlehq/moodle-behat-extension) has been created to maintain Behat and its dependencies as they comes from upstream.&lt;br /&gt;
&lt;br /&gt;
The aim of this extension is:&lt;br /&gt;
* Load features from multiple folders (Moodle subsystems and plugins)&lt;br /&gt;
* Load steps definitions from multiple folders and add them as subcontexts (Moodle subsystems and plugins)&lt;br /&gt;
* Return the available steps definitions in a more human-readable format without regexps&lt;br /&gt;
* Look for exceptions, debugging() calls, PHP error messages and other backtraces in Moodle&#039;s output&lt;br /&gt;
* Extend the Selenium2 behat driver to allow extra Selenium capabilities&lt;br /&gt;
* Add a new formatter method based on progress (the moodle default one) to display info about the moodle site being tested&lt;br /&gt;
All the other particularities of this integration can managed playing with different Behat config parameters.&lt;br /&gt;
[[Category:Behat]]&lt;br /&gt;
[[es:Behat]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=63846</id>
		<title>Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=63846"/>
		<updated>2023-03-24T10:59:34Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is for helping you get started on Moodle development with Git. For further details of Git, see [[:Category:Git]].&lt;br /&gt;
&lt;br /&gt;
== General workflow ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A reasonable knowledge of the Git basics is a good idea before you start to use it for development. If you are new to Git, you are encouraged to go to &#039;See also&#039; for some more general reading.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[image:git-pushpull-model.png|right|thumb|400px|Moodle development workflow with Git]]&lt;br /&gt;
Detailed explanation of the workflow can be found in the [[Process]] page. In short, the Moodle development with Git looks like this:&lt;br /&gt;
&lt;br /&gt;
* You as the contributor commit changes into your personal repository at your computer&lt;br /&gt;
* You push the changes into your public repository and publish links to your changes in the Moodle Tracker&lt;br /&gt;
* You request a peer review of your code from another developer&lt;br /&gt;
* When peer reviewer is happy they submit issue for integration&lt;br /&gt;
* Moodle integrators pull the changes from your public repository and if they like them, they put them into Moodle integration repository&lt;br /&gt;
* The integrated change is tested and finally pushed into Moodle production repository&lt;br /&gt;
* You update your local repository with all changes from the production repository and the next cycle may start again&lt;br /&gt;
&lt;br /&gt;
This workflow runs in roughly weekly cycles. The integration happens on Monday and Tuesday and the testing on Wednesday. On Thursday (or Friday if testing takes too long), the production repository moodle.git is usually updated with changes from the last development week.&lt;br /&gt;
&lt;br /&gt;
Most Moodle developers have their public repositories hosted at [http://github.com/ Github]. Alternatively you may want to try [http://gitorious.org Gitorious] or the legendary [http://repo.or.cz repo.or.cz]. In the examples in this guide we assume you&#039;ll set up your public repository at Github.&lt;br /&gt;
&lt;br /&gt;
When you first register on tracker you can not assign issues to yourself or send them for peer review. You will be added to the developers group after your first bug fix is integrated. Before that just comment on the issue with a link to your branch and component lead or another developer will send issue for peer review for you.&lt;br /&gt;
&lt;br /&gt;
== Installing Git on your computer ==&lt;br /&gt;
&lt;br /&gt;
Install Git on your computer. Most Linux distributions have Git available as a package to install. On Debian/Ubuntu, type &#039;&#039;&#039;&#039;sudo apt-get install git&#039;&#039;&#039;&#039; on the terminal. If you are on Mac, [http://code.google.com/p/git-osx-installer/ git-osx-installer] installs it in a few clicks. &lt;br /&gt;
&lt;br /&gt;
Immediately after the installation, set your name and contact e-mail. The name and e-mail will become part of your commits and they can&#039;t be changed later once your commits are accepted into the Moodle code. Therefore we ask contributors to use their real names written in capital letters, eg &amp;quot;John Smith&amp;quot; and not &amp;quot;john smith&amp;quot; or even &amp;quot;john5677&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email yourmail@domain.tld&lt;br /&gt;
&lt;br /&gt;
Unless you are the repository maintainer, it is wise to set your Git to not push changes in file permissions:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.filemode false&lt;br /&gt;
&lt;br /&gt;
Also, it&#039;s recommended to verify that the your git installation is not performing any transformation between LFs and CRLFs. All Moodle &#039;&#039;&#039;uses only LFs&#039;&#039;&#039; and you should &#039;&#039;&#039;fetch/edit and push&#039;&#039;&#039; it that way (may need to configure your editor/IDE too). Note that having any &amp;quot;magic&amp;quot; enabled is known to cause [[Common unit test problems#The_test_file_.22evolution.test.22_should_not_contain_section_named_.22.5Blots_of_content.5D.22|problems with unit tests]] execution. So we recommend you to set:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.autocrlf false&lt;br /&gt;
&lt;br /&gt;
== Setting-up the public repository ==&lt;br /&gt;
&lt;br /&gt;
1. Go to [http://github.com/ Github] and create an account.&lt;br /&gt;
&lt;br /&gt;
2. Go to the [http://github.com/moodle/moodle official Moodle Github repository] and click on the Fork button. You now have your own Github Moodle repository.&lt;br /&gt;
&lt;br /&gt;
3. Now you need to set up your SSH public key, so you can push to your Github Moodle repository from your local Moodle repository. On Mac you can go on this [http://help.github.com/mac-key-setup/ Github help page]. If you are on another system, go to your Github administration page, to the section SSH Public Keys, and you should see a link to a help page. Done? Good! That was the most difficult part!&lt;br /&gt;
&lt;br /&gt;
4. If you want, you can set up [https://moodledev.io/general/development/tools/gha GitHub Actions integration] with your GitHub repository so that when you push your code, and it will automatically run a suite of tests for you against your changes. This way you can quickly catch issues without having to set up a testing environment locally (and before you share your code with other Moodle developers!).&lt;br /&gt;
&lt;br /&gt;
== Setting-up the local repository at your computer  ==&lt;br /&gt;
&lt;br /&gt;
Create a local clone repository of your Github repository. In a terminal:&lt;br /&gt;
&lt;br /&gt;
    git clone git://github.com/YOUR_GITHUB_USERNAME/moodle.git LOCALDIR&lt;br /&gt;
&lt;br /&gt;
    (or:  git clone git@github.com:YOUR_GITHUB_USERNAME/moodle.git LOCALDIR)&lt;br /&gt;
&lt;br /&gt;
This command does several jobs for you. It creates a new folder, initializes an empty Git repository in it, sets your Github repository as the remote repository called &#039;origin&#039; and makes a local checkout of the branch &#039;master&#039; from it. The important point to remember now is that your Github repository is aliased as &#039;origin&#039; for your local clone.&lt;br /&gt;
&lt;br /&gt;
Note that the format of the URL here is important. In the first example, the URL starts &amp;quot;git://github.com&amp;quot; and this will give read-only access to the repository at github.com. If you use this URL, the &amp;quot;git push origin&amp;quot; command that appears later in this document will not work. Therefore, if you want to be able to update the &amp;quot;origin&amp;quot; repository, you should use the URL that starts &amp;quot;git@github.com&amp;quot;, i.e. the second of the two &amp;quot;git clone&amp;quot; commands given above. This will give you read and write access to the repository on github.com.&lt;br /&gt;
&lt;br /&gt;
== Keeping your public repository up-to-date ==&lt;br /&gt;
&lt;br /&gt;
[[image:git-sync-github.png|right|thumb|400px|Fetching changes from upstream and pushing them to github]]&lt;br /&gt;
Your fork at Github is not updated automatically. To keep it synced with the upstream Moodle repository, you have to fetch the recent changes from the official moodle.git and push them to your public repository. To avoid problems with this it is strongly recommended that you never modify the standard Moodle branches. &#039;&#039;Remember: never commit directly into master and MOODLE_xx_STABLE branches.&#039;&#039; In other words, always create topic branches to work on. In Gitspeak, the master branch and MOODLE_xx_STABLE branches should be always fast-forwardable.&lt;br /&gt;
&lt;br /&gt;
To keep your public repository up-to-date, we will register remote repository git://git.moodle.org/moodle.git under &#039;upstream&#039; alias. Then we create a script to be run regularly that fetches changes from the upstream repository and pushes them to your public repository. Note that this procedure will not affect your local working directory.&lt;br /&gt;
&lt;br /&gt;
To register the upstream remote:&lt;br /&gt;
&lt;br /&gt;
    cd moodle&lt;br /&gt;
    git remote add upstream git://git.moodle.org/moodle.git&lt;br /&gt;
&lt;br /&gt;
The following commands can be used to keep the standard Moodle branches at your Github repository synced with the upstream repository. You may wish to store them in a script so that you can run it every week after the upstream repository is updated.&lt;br /&gt;
&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 git fetch upstream&lt;br /&gt;
 for BRANCH in MOODLE_{19..39}_STABLE MOODLE_{310..311}_STABLE MOODLE_{400..401}_STABLE master; do&lt;br /&gt;
     git push origin refs/remotes/upstream/$BRANCH:refs/heads/$BRANCH&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The git-fetch command does not modify your current working dir (your checkout). It just downloads all recent changes from a remote repository and stores them into so called remote-tracking branches. The git-push command takes these remote-tracking branches from upstream and pushes them to Github under the same name. Understanding this fully requires a bit knowledge of Git internals - see gitrevisions(7) man page.&lt;br /&gt;
&lt;br /&gt;
Note there is no need to switch the local branch during this. You can even execute this via cron at your machine. Just note that the upstream repository updates typically just once a week.&lt;br /&gt;
&lt;br /&gt;
=== New branches ===&lt;br /&gt;
&lt;br /&gt;
Occasionally, moodle.org will create a new branch that does not exist in your public (e.g. Github.com) repository. If you try to push this new branch, you will see an error such as the following:&lt;br /&gt;
&lt;br /&gt;
    error: unable to push to unqualified destination: MOODLE_99_STABLE&lt;br /&gt;
    The destination refspec neither matches an existing ref on the remote&lt;br /&gt;
    nor begins with refs/, and we are unable to guess a prefix based on the source ref.&lt;br /&gt;
    error: failed to push some refs to &#039;git@github.com:YOUR_GITHUB_USERNAME/moodle.git&#039;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;quot;MOODLE_99_STABLE&amp;quot;, is the name of the new branch that does not exist in your public repository. To fix the error, you need to create the new branch on your public repository, using the following commands, replacing &amp;quot;MOODLE_99_STABLE&amp;quot; with the name of the new branch you wish to create:&lt;br /&gt;
&lt;br /&gt;
    git checkout MOODLE_99_STABLE&lt;br /&gt;
    git push origin MOODLE_99_STABLE:MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
The above code will create a new copy of the &amp;quot;MOODLE_99_STABLE&amp;quot; branch in your local repository. If you do not need to keep a local copy of the new branch - and probably you do not need it, you then can remove it from your local repository as follows:&lt;br /&gt;
&lt;br /&gt;
    git checkout master&lt;br /&gt;
    git branch -D MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
== Preparing a patch ==&lt;br /&gt;
&lt;br /&gt;
As said earlier at this page, you never work on standard Moodle branches directly. Every time you are going to edit something, switch to a local branch. Fork the local branch off the standard branch you think it should be merged to. So if you are working on a patch for 1.9 or 2.0, fork the branch off MOODLE_19_STABLE or MOODLE_20_STABLE, respectively. Patches for the next [[Moodle versions|major version]] should be based on the master branch.&lt;br /&gt;
&lt;br /&gt;
    git checkout -b MDL-xxxxx-master_brief_name origin/master&lt;br /&gt;
&lt;br /&gt;
Note that if you forget to specify the starting point, the branch is based on the currently checked-out branch. It may not be what you want. It is recommended to always specify the starting point.&lt;br /&gt;
&lt;br /&gt;
To check the current branch, run&lt;br /&gt;
&lt;br /&gt;
    git branch&lt;br /&gt;
&lt;br /&gt;
The current branch is highlighted.&lt;br /&gt;
&lt;br /&gt;
Now go and fix the issue with your favorite IDE. Check the status of the files, view the change to be committed and finally commit the change:&lt;br /&gt;
&lt;br /&gt;
    vim filename.php&lt;br /&gt;
    git status&lt;br /&gt;
    git diff&lt;br /&gt;
    git commit -a&lt;br /&gt;
&lt;br /&gt;
For the commit message, please do respect the guidelines given on in the article [[Coding style#Git_commits|Coding_style]].&lt;br /&gt;
&lt;br /&gt;
Note that this is safe as the commit is recorded just locally, nothing is sent to any server yet (as it would in CVS). To see history of the commits, use&lt;br /&gt;
&lt;br /&gt;
    git log&lt;br /&gt;
&lt;br /&gt;
Once your local branch contains the change (note that it may consists of several patches) and you are happy with it, publish the branch at your public repository:&lt;br /&gt;
&lt;br /&gt;
    git push origin MDL-xxxxx-master_brief_name&lt;br /&gt;
&lt;br /&gt;
Now as your branch is published, you can ask Moodle core developers to review it and eventually integrate it into the standard Moodle repository.&lt;br /&gt;
&lt;br /&gt;
=== Changing commit message, reordering and squashing commits ===&lt;br /&gt;
&lt;br /&gt;
It often happens that you made a mistake in your patch or in the commit message and helpful CiBot pointed it out for you. You can &amp;quot;rewrite the history&amp;quot; and change the existing commits.&lt;br /&gt;
&lt;br /&gt;
Option 1. Reset all the changes in the branch and commit again. &lt;br /&gt;
&lt;br /&gt;
    git reset --mixed origin/master&lt;br /&gt;
&lt;br /&gt;
Now all your changes are still present but all commits on top of &amp;quot;master&amp;quot; branch are gone. You can create a new commit&lt;br /&gt;
&lt;br /&gt;
Option 2. Discover &#039;&#039;&#039;git rebase --interactive&#039;&#039;&#039; - this is a powerful tool to change the sequence of commit, change the commit messages, squash commits, etc. We will not cover it here, there are many articles in the Internet about it, for example: https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History.&lt;br /&gt;
&lt;br /&gt;
Whatever option you chose, you have &amp;quot;rewritten the history&amp;quot; and you can not simply push the changes to github again because they would need to overwrite the commits that were already pushed. If you try &amp;quot;git push MDL-xxxxx-master_brief_name&amp;quot; you will get an error message suggesting you to force push. &lt;br /&gt;
To force push the changed commits use:&lt;br /&gt;
&lt;br /&gt;
    git push -f origin MDL-xxxxx-master_brief_name&lt;br /&gt;
&lt;br /&gt;
If an error occurs because you are still using the git protocol (read only), use this command : &lt;br /&gt;
&lt;br /&gt;
    git remote set-url origin https://github.com/&amp;lt;user.name&amp;gt;/moodle.git&lt;br /&gt;
&lt;br /&gt;
A prompt will ask for your credentials, if you previously setup your SSH public key you can also use this one : &lt;br /&gt;
&lt;br /&gt;
    git remote set-url origin git@github.com:&amp;lt;user.name&amp;gt;/moodle.git&lt;br /&gt;
&lt;br /&gt;
=== Checking if a branch has already been merged ===&lt;br /&gt;
&lt;br /&gt;
After some time contributing to Moodle you would have a lot of branches both in your local repository and in your public repository. To prune their list and delete those that were accepted by upstream, use the following&lt;br /&gt;
&lt;br /&gt;
    git fetch upstream                                      (1)&lt;br /&gt;
    git branch --merged upstream/master                     (2)&lt;br /&gt;
    git branch --merged upstream/MOODLE_20_STABLE           (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) fetches the changes from your upstream repository at git.moodle.org (remember that git-fetch does not modify your working dir so it is safe to run it whenever). Command (2) and (3) print all branches that are merged into the upstream master branch and MOODLE_20_STABLE branch, respectively. To delete these local branches, use&lt;br /&gt;
&lt;br /&gt;
    git branch -d MDL-xxxxx-master_accepted_branch&lt;br /&gt;
&lt;br /&gt;
The similar approach can be used to check the branches published at your origin repository at github.com&lt;br /&gt;
&lt;br /&gt;
    git fetch origin                                        (1)&lt;br /&gt;
    git fetch upstream&lt;br /&gt;
    git branch -r --merged upstream/master                  (2)&lt;br /&gt;
    git branch -r --merged upstream/MOODLE_20_STABLE        (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) makes sure that you have all your branches from github.com recorded as the remote tracking branch locally. Commands (2) and (3) work the same as in the previous example but they list remote tracking branches only ([http://www.kernel.org/pub/software/scm/git/docs/git-branch.html see -r param]). To delete a branch at github.com, use&lt;br /&gt;
&lt;br /&gt;
    git push origin :MDL-xxxxx-master_branch_to_delete&lt;br /&gt;
&lt;br /&gt;
This syntax may look weird to you. However it is pretty logical. The general syntax of the git-push command is&lt;br /&gt;
&lt;br /&gt;
    git push &amp;lt;repository&amp;gt; &amp;lt;source ref&amp;gt;:&amp;lt;target ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so deleting a remote branch can be understood as pushing an &amp;quot;empty (null) reference&amp;quot; to it.&lt;br /&gt;
&lt;br /&gt;
== Peer-reviewing someone else&#039;s code ==&lt;br /&gt;
&lt;br /&gt;
To review a branch that someone else pushed into their public repository, you do not need to register a new remote (unless you work with such repository frequently, of course). Let us imagine your friend Alice pushed a work-in-progress branch called &#039;wip-feature&#039; into her Github repository and asked you to review it. You need to know the read-only address of the repository and the name of the branch.&lt;br /&gt;
&lt;br /&gt;
    git fetch git://github.com/alice/moodle.git wip-feature&lt;br /&gt;
&lt;br /&gt;
This will download all required data and will keep the pointer to the tip of the wip-feature branch in a local symbolic reference FETCH_HEAD. To see what&#039;s there on that branch, use&lt;br /&gt;
&lt;br /&gt;
    git log -p FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see how a particular file looks at Alice&#039;s branch&lt;br /&gt;
&lt;br /&gt;
    git show FETCH_HEAD:admin/blocks.php&lt;br /&gt;
&lt;br /&gt;
To create a new local branch called &#039;alice-wip-feature&#039; containing the work by Alice, use&lt;br /&gt;
&lt;br /&gt;
    git checkout -b alice-wip-feature FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To merge Alice&#039;s work into your current branch:&lt;br /&gt;
&lt;br /&gt;
    git merge FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see what would be merged into the current branch without actually modifying anything:&lt;br /&gt;
&lt;br /&gt;
    git diff ...FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
Once you are all set and reviewing code, this [[Peer_reviewing_checklist|checklist]] should prove to be useful.&lt;br /&gt;
&lt;br /&gt;
== Rebasing a branch ==&lt;br /&gt;
&lt;br /&gt;
Rebasing is a process when you cut off the branch from its current start point and transplant it to another point. Let us assume the following history exists:&lt;br /&gt;
&lt;br /&gt;
          A---B---C topic&lt;br /&gt;
         /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
From this point, the result of the command:&lt;br /&gt;
&lt;br /&gt;
    git rebase master topic&lt;br /&gt;
&lt;br /&gt;
would be:&lt;br /&gt;
&lt;br /&gt;
                  A&#039;--B&#039;--C&#039; topic&lt;br /&gt;
                 /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
and would end with &#039;topic&#039; being your current branch.&lt;br /&gt;
&lt;br /&gt;
You may be asked to rebase your branch submitted for the integration if the submitted branch was based on an outdated commit. The typical case is if you create a new branch as a fork off the upstream master branch on Tuesday. Then on Wednesday, the upstream master branch grows as all changes from the last integration cycle are merged to it. To make diff easy on Github for next weekly pull request review, you want to rebase your branch against the updated master.&lt;br /&gt;
&lt;br /&gt;
    git rebase master MDL-xxxxx-master_topic_branch&lt;br /&gt;
&lt;br /&gt;
Note that rebasing effectively rewrites the history of the branch. &#039;&#039;&#039;Do not rebase the branch if there is a chance that somebody has already forked it and based their own branch on it.&#039;&#039;&#039; For this reason, many Git tutorials discourage from rebasing any branch that has been published. However in Moodle, all branches submitted for integration are potential subject of rebase (even though we try to not to do it often) and you should not base your own branches on them.&lt;br /&gt;
&lt;br /&gt;
=== Conflicts during rebase ===&lt;br /&gt;
&lt;br /&gt;
During the rebase procedure, conflicts may appear. git-status commands reports the conflicted files. Explore them carefully and fix them in your editor (like you would do with CVS). Then add the files with &#039;git add&#039; command and continue.&lt;br /&gt;
&lt;br /&gt;
    vim conflicted.php&lt;br /&gt;
    git add conflicted.php&lt;br /&gt;
    git rebase --continue&lt;br /&gt;
&lt;br /&gt;
== Applying changes from one branch to another ==&lt;br /&gt;
&lt;br /&gt;
Most bugs are fixed at a stable branch (like MOODLE_20_STABLE) and the fix must be prepared for other branches, too (like MOODLE_21_STABLE and the main development branch - master). In Moodle, we do not merge stable branches into the master one. So usually the contributor prepares at least two branches - with the fix for the stable branch(es) and with the fix for the master branch.&lt;br /&gt;
&lt;br /&gt;
If you have a patch prepared on a local branch (let us say MDL-xxxxx-20_brief_name), it is possible to re-apply it to another branch.&lt;br /&gt;
&lt;br /&gt;
=== Cherry-picking a single commit ===&lt;br /&gt;
&lt;br /&gt;
Let us have two local Git repositories ~/public_html/moodle21 containing local installation of Moodle 2.1 and ~/public_html/moodledev with the local installation of most recent development version of Moodle. They both use your public repository at github.com as the origin. You have a branch in moodle21 called MDL-xxxxx-21_topic that was forked off MOODLE_21_STABLE. It contains one commit. Now you want to re-apply this commit to a branch MDL-xxxxx-master_topic in moodledev.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxxx-master_topic origin/master    (1)&lt;br /&gt;
    git fetch ../moodle21 MDL-xxxxx-21_topic                (2)&lt;br /&gt;
    git cherry-pick FETCH_HEAD                              (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) creates new local branch forked off the master. The command (2) fetches all data needed to re-apply the topic branch and stores the pointer to the tip of that branch to FETCH_HEAD symbolic reference. The command (3) picks the tip of the branch (the top-most commit on it) and tries to apply it on the current branch.&lt;br /&gt;
There is also a variant of the cherry-pick command that supports multiple commits, shortly (see its man page for details): &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ git cherry-pick A^..B&amp;lt;/syntaxhighlight&amp;gt; if you want to include from A - see &#039;&#039;&#039;^&#039;&#039;&#039; - to B, A should be older than B. We will use another approach for cherry-picking multiple commits.&lt;br /&gt;
&lt;br /&gt;
=== Applying a set of patches ===&lt;br /&gt;
&lt;br /&gt;
If the branch MDL-xxxxx-21_topic from the previous example consists of several commits, it may be easier to use git-format-patch and git-am combo to re-apply the whole set of patches (aka patchset). Firstly you will export all commits from the topic branch to files.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodle21&lt;br /&gt;
    mkdir .patches&lt;br /&gt;
    git format-patch -o .patches MOODLE_21_STABLE..MDL-xxxxx-21_topic         (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) takes all commits from the topic branch that are not in MOODLE_21_STABLE and exports them one by one to the output directory .patches. Look at the generated files. They contain the patch itself (in diff format) and additional information about the commit. You could eg send these files by email to a friend of yours for peer-review. We will use them in another repository.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxxx-master_topic origin/master&lt;br /&gt;
    git am -3 ../moodle21/.patches/*                        (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) applies all the files from the .patches directory. When a patch does not apply cleanly, the command tries fall back on 3-way merge (see the -3 parameter). If conflicts occur during the procedure, you can either deal with them and then use `git am --continue` or abort the whole procedure with `git am --abort`.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Git tips]]&lt;br /&gt;
&lt;br /&gt;
; Moodle forum discussions&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=168094 GIT help needed]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=165236 Best way to manage CONTRIB code with GIT]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167063 Handy Git tip for tracking 3rd-party modules and plugins]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167730 Moodle Git repositories]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=183409 Git help!! I don&#039;t understand rebase enough...]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=217617 add MOODLE_24_STABLE to github.com repository]&lt;br /&gt;
&lt;br /&gt;
; External resources &lt;br /&gt;
* [https://mirrors.edge.kernel.org/pub/software/scm/git/docs/giteveryday.html Everyday GIT With 20 Commands Or So]&lt;br /&gt;
* [https://git-scm.com/book/en/v2 &#039;Pro Git&#039; complete book]&lt;br /&gt;
* [http://vimeo.com/14629850 Getting git by Scott Chacon] - an recording of an excellent 1-hour presentation that introducing git, including a simple introduction to what is going on under the hood.&lt;br /&gt;
* [http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html Tim Hunt&#039;s blog: Fixing a bug in Moodle core: the mechanics]&lt;br /&gt;
* [https://github.com/k88hudson/git-flight-rules/blob/master/README.md#flight-rules-for-git Flight rules for Git]&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発者用Git]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63845</id>
		<title>Process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63845"/>
		<updated>2023-03-24T10:58:19Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/process}}&lt;br /&gt;
This document summarises the various development processes used in developing Moodle. There are four main processes that overlap.&lt;br /&gt;
==Integration workflow in the tracker==&lt;br /&gt;
The Moodle tracker keeps track of the status of all bug fixes and new features. &lt;br /&gt;
&lt;br /&gt;
We use a workflow that ensures that new code receives multiple reviews by different people before it is included into the core Moodle code.&lt;br /&gt;
&lt;br /&gt;
[[Image:Workflow.jpg]]&lt;br /&gt;
&lt;br /&gt;
A number of roles make this work:&lt;br /&gt;
===Users===&lt;br /&gt;
Users report bugs and make feature requests directly in the tracker, by creating new issues with a summary and a description.&lt;br /&gt;
===Developers===&lt;br /&gt;
Developers work on the issues in the tracker to specify solutions and write code that implements these solutions. They will often ask other developers to &amp;quot;peer review&amp;quot; their code in the early stages to avoid problems later on.&lt;br /&gt;
&lt;br /&gt;
While many of the developers work for Moodle.com, a large number are part of the global development community around Moodle. If you&#039;re interested in becoming a recognised developer, see [[Tracker_guide#Tracker_groups_and_permissions|Tracker groups and permissions]].&lt;br /&gt;
===CiBoT===&lt;br /&gt;
CiBoT is not a person but a bot who monitors the tracker and performs the [[Automated code review]] when issue is submitted for Peer review or when developer added &#039;&#039;cime&#039;&#039; label.&lt;br /&gt;
===Component leads===&lt;br /&gt;
[https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page Component leads] are developers with some responsibility for particular components (plugins or modules) in Moodle. They have authority to decide that a particular fix is suitable and complete enough to be considered for integration in Moodle core and should be called upon to complete peer reviews for code in their components. Note that, apart from that, every component also has some [[Component Leads|HQ Component leads]] that will specifically work on associated issues, triaging, monitoring, reviewing, fixing them.&lt;br /&gt;
&lt;br /&gt;
===Component leads reviewers===&lt;br /&gt;
Component Lead Reviewers are Component Leads who have the added responsibility of performing a second and final review of a selection of issues within their component.&lt;br /&gt;
After reviewing the code, it is sent to the integration team to be pulled without further review.&lt;br /&gt;
&lt;br /&gt;
===Integrators===&lt;br /&gt;
From Monday to Thursday, the integration team (a small team of senior developers employed by Moodle HQ) conducts a code-level review of all issues in the integration queue. This is often called the &amp;quot;pull&amp;quot; process. If the fix is judged appropriate they will integrate the code into our git integration repository for further testing and it gets added to the testing queue.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and send it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
During each week the testers look at all the issues in the testing queue, trying each fix and feature to make sure that it does actually fix the problem it was supposed to, and that there are no regressions in the web version and the Moodle mobile app.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and integrators may remove it from the integration repository and push it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
See [[Testing of integrated issues]] for more details.&lt;br /&gt;
&lt;br /&gt;
===Production maintainers===&lt;br /&gt;
On Thursday each week, production maintainers merge all the issues that passed testing into the git production repository, and it becomes available for use on production systems via git and download packages.&lt;br /&gt;
==Stable maintenance cycles==&lt;br /&gt;
Moodle releases regular updates of the stable version of the software to fix bugs and other issues. Releases like 2.2.1, 2.2.2, 2.2.3 etc only include fixes based on the latest major release (2.2) and never any significant new features or database changes.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are teams of developers using the [http://www.scrum.org/ Scrum framework] to work on these issues (as well as new features for [[#Major_release_cycles|major releases]]). &lt;br /&gt;
&lt;br /&gt;
===Minor release (point release) timing===&lt;br /&gt;
After [[#Major_release_cycles|major releases]] there will be minor releases.&lt;br /&gt;
* x.x.1 will occur approximately two months after each major release (eg. 2.x).&lt;br /&gt;
* There will then be another point release every two months after that.&lt;br /&gt;
See the [[Releases#General_release_calendar|General release calendar]] for details.&lt;br /&gt;
&lt;br /&gt;
===Issue triage===&lt;br /&gt;
[[Bug_triage|Issue triage]] involves evaluating new issues, making sure that they are recorded correctly. One of the most important jobs triagers do is to identify issues that should be fixed in the stable branch. These are set with a priority ranging from &amp;quot;Trivial&amp;quot; up to &amp;quot;Blocker&amp;quot; and other features are checked.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are currently teams working on stable issues (mostly bugs reported by users) and improvements and new features (Partners, Moodle Association, user suggestions and Martin Dougiamas).&lt;br /&gt;
&lt;br /&gt;
===Scrum===&lt;br /&gt;
At Moodle HQ, every three weeks, the stable team takes a number of the most urgent issues from the backlog to work on during a period known as a &#039;&#039;sprint&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
At the start of a sprint there is a period of planning and estimation. All issues on the backlog are given a relative rank that is based on issue features including priority, security, Partner interest, patches and votes. Issues are given a relative size in Story Points and these points are summed to allow the teams to determine how many issues they can work on in the sprint.&lt;br /&gt;
&lt;br /&gt;
During the sprint, the team meets daily to discuss solutions and progress, as well as to organise testing and peer reviews of code. The team has a &#039;&#039;Scrum master&#039;&#039; to help everyone stay organised, to &amp;quot;unblock&amp;quot; any barriers to progress and to protect the team from distracting influences (mostly people attempting to add to the developers&#039; workloads) during the sprint. The teams&#039; work is documented publicly in the tracker.&lt;br /&gt;
&lt;br /&gt;
Whenever a solution for an issue is finished, it is submitted to the standard integration workflow process described above.&lt;br /&gt;
&lt;br /&gt;
==Major release cycles==&lt;br /&gt;
Since Moodle 2.0, we have a policy of release major versions (eg 2.1, 2.2) every six months in May and November. See the [[Releases#General_release_calendar|General release calendar]] for more details.&lt;br /&gt;
&lt;br /&gt;
Each release can be different, but generally the cycles work as follows.&lt;br /&gt;
===Define roadmap===&lt;br /&gt;
The roadmap is prioritised based on user research, stakeholder inputs, community wishes, third-party developments and important issues within the existing code. &lt;br /&gt;
&lt;br /&gt;
Sometimes new features might be based on earlier features, sometimes they may be something developed by a third party that needs to be evaluated and sometimes it might be something completely new.&lt;br /&gt;
===Planning and development===&lt;br /&gt;
The product teams together with UX, employed at Moodle HQ, work on specifications of major new features throughout the cycle, specifying projects ahead of development time.&lt;br /&gt;
&lt;br /&gt;
The process of [[#New_feature_development|new feature development]] is described below. When specifications are in place, new code is developed during sprints, where designs and implementation are iterated as required, and goes through the standard weekly integration workflow described above.&lt;br /&gt;
===Testing===&lt;br /&gt;
During development, as new code is integrated, automated testing conducted at the [[PHPUnit|code]] and [[Acceptance_testing|interface]] levels, to make sure there are no regressions caused by new features.&lt;br /&gt;
&lt;br /&gt;
In the last month before the release, a feature freeze is called (no new features can be added) and volunteer testers from the Moodle community perform manual QA testing of Moodle features. The current set of functional tests is listed in MDLQA-1. The list of tests is extended as new features are added, though we&#039;re also trying to reduce the number as more automated [[Acceptance_testing|acceptance tests]] are developed.&lt;br /&gt;
&lt;br /&gt;
There is also a set of tests for manually testing any major theme changes - MDLQA-11592.&lt;br /&gt;
&lt;br /&gt;
For more details, see [[Testing]].&lt;br /&gt;
===Sprints===&lt;br /&gt;
At Moodle HQ, development takes place in sprints. The sprints are two or three-week periods during which developers to focus on a fixed list of issues. For example, sprints can be arranged within each release cycle as shown in the diagram below.&lt;br /&gt;
===Events during cycle===&lt;br /&gt;
During each cycle there are a periods and events that occur between and around sprints.&lt;br /&gt;
&lt;br /&gt;
[[Image:Dev sprint calendar.png|800px]]&lt;br /&gt;
; &#039;&#039;&#039;Planning and bug fixing&#039;&#039;&#039;&lt;br /&gt;
: A period during which the Roadmap is explored, specs are written and prototypes are created. Regressions in the recent release are fixed as they arise.&lt;br /&gt;
; &#039;&#039;&#039;End sync period&#039;&#039;&#039;&lt;br /&gt;
: During the [[Integration Review#On-sync period|on-sync period]], the recent release and master versions are kept synchronised. No new code is added during this period, which ensures regressions are fixed rapidly. This also allows for planning and provides relief for developers after a release.&lt;br /&gt;
; &#039;&#039;&#039;Personal projects&#039;&#039;&#039;&lt;br /&gt;
: Affecting full-time HQ developers only, this period allows for individual creations to be explored and provides a break from sprints.&lt;br /&gt;
; &#039;&#039;&#039;Code freeze&#039;&#039;&#039;&lt;br /&gt;
: A point after which no new code (only fixes to existing code) is accepted until beyond the release. This stabilisation allows for QA testing.&lt;br /&gt;
; &#039;&#039;&#039;QA, bug fixing, continuous integration&#039;&#039;&#039;&lt;br /&gt;
: A period after the code freeze where quality assurance testing takes place. No new code is added, which means developers are able to respond rapidly to bugs found. Integration becomes [[Integration Review#During continuous integration/Freeze/QA period|continuous]], meaning that failed QA tests can be re-run within days rather than having to wait for the weekly release.&lt;br /&gt;
; &#039;&#039;&#039;Release candidate&#039;&#039;&#039;&lt;br /&gt;
: A point prior to the full release where a candidate is made public for wider testing.&lt;br /&gt;
==New feature development==&lt;br /&gt;
Major new features in Moodle usually should go through the following process.&lt;br /&gt;
===Specification===&lt;br /&gt;
The User Experience (UX) team members create detailed wireframes and features and goals for the new feature, based on iterative user research, design sprints, user testing and co-design as part of the product team. &lt;br /&gt;
&lt;br /&gt;
For bigger features there should be a clear overall vision for the outcomes that are to achieved. During implementation design may continue to iterate based on new findings.&lt;br /&gt;
&lt;br /&gt;
Developers create a detailed spec (here in the developer docs) outlining their goals for the development and their design for meeting those goals. &lt;br /&gt;
&lt;br /&gt;
Developers should also create an issue in the tracker (linking to your docs) to keep track of the project status.&lt;br /&gt;
===Community consultation===&lt;br /&gt;
Get the community involved in looking at the spec to see if it meets their needs and to get further feedback. Please post in the [http://moodle.org/mod/forum/view.php?id=8052 Future major features forum] on moodle.org. You could also blog/tweet about it etc.&lt;br /&gt;
&lt;br /&gt;
Community developers proposing a new feature will want to talk with HQ core developers to make sure the ideas make sense, and possibly get some review on database design, architecture and so on.&lt;br /&gt;
===Develop the code using Git===&lt;br /&gt;
Develop your code on an open Git repository, like github.com. That enables people to see your code and to help you as it develops. Testers and early adopters also have the opportunity to try it early in the process and give you more valuable feedback.&lt;br /&gt;
&lt;br /&gt;
Coverage with automated tests ([[PHPUnit]] or [[Behat|Behat_integration]]) is mandatory for new features.&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
You need to fill in the information about your public git repository and which branches the fixes are on. Make sure you are listed as Assignee.&lt;br /&gt;
&lt;br /&gt;
This would be a good time to fill in the testing instructions (read the [[Testing instructions guide|instructions guide]]) for how to verify your fix is correct. You may also wish to add a comment in the bug.&lt;br /&gt;
&lt;br /&gt;
Component leads should put issues, which affect code in their components, up for peer review to allow interested parties to provide feedback. However, if it is not reviewed in a week, a component lead may send the issue to integration. If integrators consider that the issue has not been given proper chance for peer review (e.g. is extremely large or complex...) it can be decided to move the issue back in the process.&lt;br /&gt;
&lt;br /&gt;
All other developers, including people who are component leads but working outside their component, should have their issues peer reviewed before they are sent to integration.&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [http://tracker.moodle.org/browse/MDL#selectedTab=com.atlassian.jira.plugin.system.project%3Acomponents-panel component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
&lt;br /&gt;
===Submit the code for integration===&lt;br /&gt;
The developer is responsible for acting on the feedback from the peer reviewer. If changes have been made and the developer is satisfied that this has accommodated the feedback from the peer reviewer, then the developer can submit the issue for integration. If there have been significant changes after the peer review, or if the peer reviewer has raised concerns about the approach taken, then the developer should offer the issue up for peer review again, most often to the same peer reviewer, but not necessarily.&lt;br /&gt;
&lt;br /&gt;
Submitting an issue to integration is much the same as for any Moodle code. In some cases the Component Lead may perform a Component Lead Review instead of the integration team. See [[Integration Review]] and the information about the integration workflow above.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug==&lt;br /&gt;
Bug fixes, and minor features or enhancements should go through the following process. (The only exception is English language string typo fixes or suggested improvements, which may be contributed to the en_fix language pack on the [http://lang.moodle.org/ Moodle translation site].)&lt;br /&gt;
===Make sure there is a tracker issue===&lt;br /&gt;
Every change must have an issue in the tracker. If you are fixing a bug, there is probably one there already, but if not, create one. [[Tracker tips|Tips for searching tracker]].&lt;br /&gt;
===Decide which branches the fix is required on===&lt;br /&gt;
Bugs should normally be fixed on all the supported stable branches that are affected. New features should just go into master, but sometimes minor enhancements are made on the most recent stable branch.&lt;br /&gt;
===Develop your change using git===&lt;br /&gt;
Develop your fix and push the change to an open git repository, for example on github.com. See also [[Git for developers]]&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
&lt;br /&gt;
You will need to push one commit for each branch the fix needs to be applied to. Often people use branch names like MDL-12345-31_brief_name so it is clear what each branch is. [http://kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick] can help with replicating the fix onto different branches.&lt;br /&gt;
&lt;br /&gt;
Consider setting up [https://moodledev.io/general/development/tools/gha GitHub Actions integration] with your repository so tests will be automatically run for you whenever you push work on your fix.&lt;br /&gt;
&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Once your fix is done, it should be submitted for a peer review.&lt;br /&gt;
&lt;br /&gt;
The following information is necessary for this:&lt;br /&gt;
* Information about your public git repository&lt;br /&gt;
** repository URL&lt;br /&gt;
** branch name(s)&lt;br /&gt;
** diff URL&lt;br /&gt;
* [[Testing instructions guide|Testing instructions]] for how to verify your fix is correct.&lt;br /&gt;
If you have never contributed to Moodle and don&#039;t see a button &amp;quot;Request peer review&amp;quot;, just comment on the issue with the above information. The component lead or another user with sufficient privileges will then send the issue up for peer review for you.&lt;br /&gt;
&lt;br /&gt;
After your first fix is integrated you will be added to developers group and will be able to send issues for peer review yourself. In this case make sure you are listed as Assignee and click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve set up [https://moodledev.io/general/development/tools/gha GitHub Actions integration], the issue will automatically show the Travis build status for the branch(es) you&#039;ve submitted for peer review.&lt;br /&gt;
&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
===Submit your code for integration===&lt;br /&gt;
It will then be reviewed the following week by one of the integration team and either integrated or rejected. Once integrated, the fix will be tested, and then included in the next weekly release. For details see [[Integration Review]].&lt;br /&gt;
==Security issues==&lt;br /&gt;
Issues identified as [[Security|security issues]] are resolved in a slightly different way, in order to achieve responsible disclosure as described in [[Moodle security procedures]].&lt;br /&gt;
* Security issues should be labelled as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; in order control visibility of the issue.&lt;br /&gt;
** An issue reported with a security level of &amp;quot;Could be a security issue&amp;quot; should be evaluated as soon as possible and either set as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; or the security level should be set to &amp;quot;None&amp;quot;.&lt;br /&gt;
* Solutions to security issues should not:&lt;br /&gt;
** be made available in public repositories.&lt;br /&gt;
*** If a developer has shared a solution as Git branches via Github, they should be asked to provide the solutions as [[How_to_create_a_patch|stand-alone patches]] attached to the issue and to [[#How to remove a branch from Github|remove the solution from Github]].&lt;br /&gt;
** contain details about the security problem in the commit message.&lt;br /&gt;
*** Instead use generic terms like, &amp;quot;improve&amp;quot;, &amp;quot;better handling of&amp;quot; ..&lt;br /&gt;
* The solution will not be integrated until the week before a [[Process#Stable_maintenance_cycles|minor release]] following the normal [[Release process|Release process]]. In short, the issue will be incorporated into the integration version, rebased, tested and made ready for release as a normal issue would, but not until as late as possible.&lt;br /&gt;
* Details of security issues will be shared with registered admins with the minor release.&lt;br /&gt;
* Details of security issues will not be publicly announced until one week after a minor release to allow admins to update.&lt;br /&gt;
Note that not all the labelled (minor) security issues are always handled following the procedure above. It&#039;s possible that, after discussion, it&#039;s decided a given issue is not a real Moodle security problem (say external disclosures/potential attacks using Moodle as vector, not as target, discussions revealing some private details...). Those issues will be processed as normal issues, generating the needed user documentation if necessary and will be part of the habitual weekly releases.&lt;br /&gt;
====How to remove a branch from Github====&lt;br /&gt;
To remove a branch from Github, you can use the following command.&lt;br /&gt;
 git push github :remote_branch&lt;br /&gt;
Where &#039;&#039;remote_branch&#039;&#039; is the name of your remote branch, for example &#039;wip-mdl-1234&#039;. This effectively replaces the remote branch with nothing, removing the remote branch, but leaving the branch intact in your local Git repository. Please note that its likely that your commit will still exist on github due to the nature of git, so its best to avoid doing this in the first place.&lt;br /&gt;
==Policy issues==&lt;br /&gt;
Occasionally within Moodle we run into policy issues where a high-level decision needs to be made about how things are to be done.&lt;br /&gt;
&lt;br /&gt;
In these cases the process is as follows:&lt;br /&gt;
* Create an issue in the tracker with a [https://tracker.moodle.org/browse/MDL/component/12733 Policy component] and put &amp;quot;POLICY:&amp;quot; as a prefix on the summary.&lt;br /&gt;
* In the description describe the problem clearly as well as all the options. If it&#039;s long then make a page here in Moodle Dev Docs and link to it.&lt;br /&gt;
* Do not use this issue for code. If there are issues that depend on this policy decision, then add tracker links to them as dependencies.&lt;br /&gt;
* Feel free to encourage people to come and talk about the policy to support various points of view. The more evidence we have (from everyone in the community) the better.&lt;br /&gt;
Some time has been scheduled in the weekly Moodle HQ meeting to look at Policy issues and try to make decisions on them. We discuss all the evidence and try to achieve a high amount of consensus. Deadlocked issues can be resolved by a decision from Martin Dougiamas (this is rarely needed).&lt;br /&gt;
&lt;br /&gt;
Decisions will be posted on the issue and that issue will be closed, allowing any dependent issues to continue to integration (or not). Decisions are final and bribes hardly ever work.&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
* [[Deprecation]]&lt;br /&gt;
* [http://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=11350 Integration dashboard]&lt;br /&gt;
Walks-though of the process for contributors:&lt;br /&gt;
* By Dan Poltawski, Integrator: http://www.slideshare.net/poltawski/how-to-guarantee-your-change-is-integrated-to-moodle-core, https://www.youtube.com/watch?v=836WtnM2YpM&lt;br /&gt;
* By Tim Hunt, contributor: http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html and https://www.youtube.com/watch?v=gPPA3h7OGQU and https://youtu.be/Hu8ne0NCRAg?t=11659&lt;br /&gt;
[[Category:Processes]]&lt;br /&gt;
[[Category:Quality Assurance]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63844</id>
		<title>Process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Process&amp;diff=63844"/>
		<updated>2023-03-24T10:57:16Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/development/process}}&lt;br /&gt;
This document summarises the various development processes used in developing Moodle. There are four main processes that overlap.&lt;br /&gt;
==Integration workflow in the tracker==&lt;br /&gt;
The Moodle tracker keeps track of the status of all bug fixes and new features. &lt;br /&gt;
&lt;br /&gt;
We use a workflow that ensures that new code receives multiple reviews by different people before it is included into the core Moodle code.&lt;br /&gt;
&lt;br /&gt;
[[Image:Workflow.jpg]]&lt;br /&gt;
&lt;br /&gt;
A number of roles make this work:&lt;br /&gt;
===Users===&lt;br /&gt;
Users report bugs and make feature requests directly in the tracker, by creating new issues with a summary and a description.&lt;br /&gt;
===Developers===&lt;br /&gt;
Developers work on the issues in the tracker to specify solutions and write code that implements these solutions. They will often ask other developers to &amp;quot;peer review&amp;quot; their code in the early stages to avoid problems later on.&lt;br /&gt;
&lt;br /&gt;
While many of the developers work for Moodle.com, a large number are part of the global development community around Moodle. If you&#039;re interested in becoming a recognised developer, see [[Tracker_guide#Tracker_groups_and_permissions|Tracker groups and permissions]].&lt;br /&gt;
===CiBoT===&lt;br /&gt;
CiBoT is not a person but a bot who monitors the tracker and performs the [[Automated code review]] when issue is submitted for Peer review or when developer added &#039;&#039;cime&#039;&#039; label.&lt;br /&gt;
===Component leads===&lt;br /&gt;
[https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page Component leads] are developers with some responsibility for particular components (plugins or modules) in Moodle. They have authority to decide that a particular fix is suitable and complete enough to be considered for integration in Moodle core and should be called upon to complete peer reviews for code in their components. Note that, apart from that, every component also has some [[Component Leads|HQ Component leads]] that will specifically work on associated issues, triaging, monitoring, reviewing, fixing them.&lt;br /&gt;
&lt;br /&gt;
===Component leads reviewers===&lt;br /&gt;
Component Lead Reviewers are Component Leads who have the added responsibility of performing a second and final review of a selection of issues within their component.&lt;br /&gt;
After reviewing the code, it is sent to the integration team to be pulled without further review.&lt;br /&gt;
&lt;br /&gt;
===Integrators===&lt;br /&gt;
From Monday to Thursday, the integration team (a small team of senior developers employed by Moodle HQ) conducts a code-level review of all issues in the integration queue. This is often called the &amp;quot;pull&amp;quot; process. If the fix is judged appropriate they will integrate the code into our git integration repository for further testing and it gets added to the testing queue.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and send it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
During each week the testers look at all the issues in the testing queue, trying each fix and feature to make sure that it does actually fix the problem it was supposed to, and that there are no regressions in the web version and the Moodle mobile app.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and integrators may remove it from the integration repository and push it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
See [[Testing of integrated issues]] for more details.&lt;br /&gt;
&lt;br /&gt;
===Production maintainers===&lt;br /&gt;
On Thursday each week, production maintainers merge all the issues that passed testing into the git production repository, and it becomes available for use on production systems via git and download packages.&lt;br /&gt;
==Stable maintenance cycles==&lt;br /&gt;
Moodle releases regular updates of the stable version of the software to fix bugs and other issues. Releases like 2.2.1, 2.2.2, 2.2.3 etc only include fixes based on the latest major release (2.2) and never any significant new features or database changes.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are teams of developers using the [http://www.scrum.org/ Scrum framework] to work on these issues (as well as new features for [[#Major_release_cycles|major releases]]). &lt;br /&gt;
&lt;br /&gt;
===Minor release (point release) timing===&lt;br /&gt;
After [[#Major_release_cycles|major releases]] there will be minor releases.&lt;br /&gt;
* x.x.1 will occur approximately two months after each major release (eg. 2.x).&lt;br /&gt;
* There will then be another point release every two months after that.&lt;br /&gt;
See the [[Releases#General_release_calendar|General release calendar]] for details.&lt;br /&gt;
&lt;br /&gt;
===Issue triage===&lt;br /&gt;
[[Bug_triage|Issue triage]] involves evaluating new issues, making sure that they are recorded correctly. One of the most important jobs triagers do is to identify issues that should be fixed in the stable branch. These are set with a priority ranging from &amp;quot;Trivial&amp;quot; up to &amp;quot;Blocker&amp;quot; and other features are checked.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are currently teams working on stable issues (mostly bugs reported by users) and improvements and new features (Partners, Moodle Association, user suggestions and Martin Dougiamas).&lt;br /&gt;
&lt;br /&gt;
===Scrum===&lt;br /&gt;
At Moodle HQ, every three weeks, the stable team takes a number of the most urgent issues from the backlog to work on during a period known as a &#039;&#039;sprint&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
At the start of a sprint there is a period of planning and estimation. All issues on the backlog are given a relative rank that is based on issue features including priority, security, Partner interest, patches and votes. Issues are given a relative size in Story Points and these points are summed to allow the teams to determine how many issues they can work on in the sprint.&lt;br /&gt;
&lt;br /&gt;
During the sprint, the team meets daily to discuss solutions and progress, as well as to organise testing and peer reviews of code. The team has a &#039;&#039;Scrum master&#039;&#039; to help everyone stay organised, to &amp;quot;unblock&amp;quot; any barriers to progress and to protect the team from distracting influences (mostly people attempting to add to the developers&#039; workloads) during the sprint. The teams&#039; work is documented publicly in the tracker.&lt;br /&gt;
&lt;br /&gt;
Whenever a solution for an issue is finished, it is submitted to the standard integration workflow process described above.&lt;br /&gt;
&lt;br /&gt;
==Major release cycles==&lt;br /&gt;
Since Moodle 2.0, we have a policy of release major versions (eg 2.1, 2.2) every six months in May and November. See the [[Releases#General_release_calendar|General release calendar]] for more details.&lt;br /&gt;
&lt;br /&gt;
Each release can be different, but generally the cycles work as follows.&lt;br /&gt;
===Define roadmap===&lt;br /&gt;
The roadmap is prioritised based on user research, stakeholder inputs, community wishes, third-party developments and important issues within the existing code. &lt;br /&gt;
&lt;br /&gt;
Sometimes new features might be based on earlier features, sometimes they may be something developed by a third party that needs to be evaluated and sometimes it might be something completely new.&lt;br /&gt;
===Planning and development===&lt;br /&gt;
The product teams together with UX, employed at Moodle HQ, work on specifications of major new features throughout the cycle, specifying projects ahead of development time.&lt;br /&gt;
&lt;br /&gt;
The process of [[#New_feature_development|new feature development]] is described below. When specifications are in place, new code is developed during sprints, where designs and implementation are iterated as required, and goes through the standard weekly integration workflow described above.&lt;br /&gt;
===Testing===&lt;br /&gt;
During development, as new code is integrated, automated testing conducted at the [[PHPUnit|code]] and [[Acceptance_testing|interface]] levels, to make sure there are no regressions caused by new features.&lt;br /&gt;
&lt;br /&gt;
In the last month before the release, a feature freeze is called (no new features can be added) and volunteer testers from the Moodle community perform manual QA testing of Moodle features. The current set of functional tests is listed in MDLQA-1. The list of tests is extended as new features are added, though we&#039;re also trying to reduce the number as more automated [[Acceptance_testing|acceptance tests]] are developed.&lt;br /&gt;
&lt;br /&gt;
There is also a set of tests for manually testing any major theme changes - MDLQA-11592.&lt;br /&gt;
&lt;br /&gt;
For more details, see [[Testing]].&lt;br /&gt;
===Sprints===&lt;br /&gt;
At Moodle HQ, development takes place in sprints. The sprints are two or three-week periods during which developers to focus on a fixed list of issues. For example, sprints can be arranged within each release cycle as shown in the diagram below.&lt;br /&gt;
===Events during cycle===&lt;br /&gt;
During each cycle there are a periods and events that occur between and around sprints.&lt;br /&gt;
&lt;br /&gt;
[[Image:Dev sprint calendar.png|800px]]&lt;br /&gt;
; &#039;&#039;&#039;Planning and bug fixing&#039;&#039;&#039;&lt;br /&gt;
: A period during which the Roadmap is explored, specs are written and prototypes are created. Regressions in the recent release are fixed as they arise.&lt;br /&gt;
; &#039;&#039;&#039;End sync period&#039;&#039;&#039;&lt;br /&gt;
: During the [[Integration Review#On-sync period|on-sync period]], the recent release and master versions are kept synchronised. No new code is added during this period, which ensures regressions are fixed rapidly. This also allows for planning and provides relief for developers after a release.&lt;br /&gt;
; &#039;&#039;&#039;Personal projects&#039;&#039;&#039;&lt;br /&gt;
: Affecting full-time HQ developers only, this period allows for individual creations to be explored and provides a break from sprints.&lt;br /&gt;
; &#039;&#039;&#039;Code freeze&#039;&#039;&#039;&lt;br /&gt;
: A point after which no new code (only fixes to existing code) is accepted until beyond the release. This stabilisation allows for QA testing.&lt;br /&gt;
; &#039;&#039;&#039;QA, bug fixing, continuous integration&#039;&#039;&#039;&lt;br /&gt;
: A period after the code freeze where quality assurance testing takes place. No new code is added, which means developers are able to respond rapidly to bugs found. Integration becomes [[Integration Review#During continuous integration/Freeze/QA period|continuous]], meaning that failed QA tests can be re-run within days rather than having to wait for the weekly release.&lt;br /&gt;
; &#039;&#039;&#039;Release candidate&#039;&#039;&#039;&lt;br /&gt;
: A point prior to the full release where a candidate is made public for wider testing.&lt;br /&gt;
==New feature development==&lt;br /&gt;
Major new features in Moodle usually should go through the following process.&lt;br /&gt;
===Specification===&lt;br /&gt;
The User Experience (UX) team members create detailed wireframes and features and goals for the new feature, based on iterative user research, design sprints, user testing and co-design as part of the product team. &lt;br /&gt;
&lt;br /&gt;
For bigger features there should be a clear overall vision for the outcomes that are to achieved. During implementation design may continue to iterate based on new findings.&lt;br /&gt;
&lt;br /&gt;
Developers create a detailed spec (here in the developer docs) outlining their goals for the development and their design for meeting those goals. &lt;br /&gt;
&lt;br /&gt;
Developers should also create an issue in the tracker (linking to your docs) to keep track of the project status.&lt;br /&gt;
===Community consultation===&lt;br /&gt;
Get the community involved in looking at the spec to see if it meets their needs and to get further feedback. Please post in the [http://moodle.org/mod/forum/view.php?id=8052 Future major features forum] on moodle.org. You could also blog/tweet about it etc.&lt;br /&gt;
&lt;br /&gt;
Community developers proposing a new feature will want to talk with HQ core developers to make sure the ideas make sense, and possibly get some review on database design, architecture and so on.&lt;br /&gt;
===Develop the code using Git===&lt;br /&gt;
Develop your code on an open Git repository, like github.com. That enables people to see your code and to help you as it develops. Testers and early adopters also have the opportunity to try it early in the process and give you more valuable feedback.&lt;br /&gt;
&lt;br /&gt;
Coverage with automated tests ([[PHPUnit]] or [[Behat|Behat_integration]]) is mandatory for new features.&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
You need to fill in the information about your public git repository and which branches the fixes are on. Make sure you are listed as Assignee.&lt;br /&gt;
&lt;br /&gt;
This would be a good time to fill in the testing instructions (read the [[Testing instructions guide|instructions guide]]) for how to verify your fix is correct. You may also wish to add a comment in the bug.&lt;br /&gt;
&lt;br /&gt;
Component leads should put issues, which affect code in their components, up for peer review to allow interested parties to provide feedback. However, if it is not reviewed in a week, a component lead may send the issue to integration. If integrators consider that the issue has not been given proper chance for peer review (e.g. is extremely large or complex...) it can be decided to move the issue back in the process.&lt;br /&gt;
&lt;br /&gt;
All other developers, including people who are component leads but working outside their component, should have their issues peer reviewed before they are sent to integration.&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [http://tracker.moodle.org/browse/MDL#selectedTab=com.atlassian.jira.plugin.system.project%3Acomponents-panel component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
&lt;br /&gt;
===Submit the code for integration===&lt;br /&gt;
The developer is responsible for acting on the feedback from the peer reviewer. If changes have been made and the developer is satisfied that this has accommodated the feedback from the peer reviewer, then the developer can submit the issue for integration. If there have been significant changes after the peer review, or if the peer reviewer has raised concerns about the approach taken, then the developer should offer the issue up for peer review again, most often to the same peer reviewer, but not necessarily.&lt;br /&gt;
&lt;br /&gt;
Submitting an issue to integration is much the same as for any Moodle code. In some cases the Component Lead may perform a Component Lead Review instead of the integration team. See [[Integration Review]] and the information about the integration workflow above.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug==&lt;br /&gt;
Bug fixes, and minor features or enhancements should go through the following process. (The only exception is English language string typo fixes or suggested improvements, which may be contributed to the en_fix language pack on the [http://lang.moodle.org/ Moodle translation site].)&lt;br /&gt;
===Make sure there is a tracker issue===&lt;br /&gt;
Every change must have an issue in the tracker. If you are fixing a bug, there is probably one there already, but if not, create one. [[Tracker tips|Tips for searching tracker]].&lt;br /&gt;
===Decide which branches the fix is required on===&lt;br /&gt;
Bugs should normally be fixed on all the supported stable branches that are affected. New features should just go into master, but sometimes minor enhancements are made on the most recent stable branch.&lt;br /&gt;
===Develop your change using git===&lt;br /&gt;
Develop your fix and push the change to an open git repository, for example on github.com. See also [[Git for developers]]&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
&lt;br /&gt;
You will need to push one commit for each branch the fix needs to be applied to. Often people use branch names like MDL-12345-31_brief_name so it is clear what each branch is. [http://kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick] can help with replicating the fix onto different branches.&lt;br /&gt;
&lt;br /&gt;
Consider setting up [https://moodledev.io/general/development/tools/gha GitHub Actions integration] with your repository so tests will be automatically run for you whenever you push work on your fix.&lt;br /&gt;
&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
Once your fix is done, it should be submitted for a peer review.&lt;br /&gt;
&lt;br /&gt;
The following information is necessary for this:&lt;br /&gt;
* Information about your public git repository&lt;br /&gt;
** repository URL&lt;br /&gt;
** branch name(s)&lt;br /&gt;
** diff URL&lt;br /&gt;
* [[Testing instructions guide|Testing instructions]] for how to verify your fix is correct.&lt;br /&gt;
If you have never contributed to Moodle and don&#039;t see a button &amp;quot;Request peer review&amp;quot;, just comment on the issue with the above information. The component lead or another user with sufficient privileges will then send the issue up for peer review for you.&lt;br /&gt;
&lt;br /&gt;
After your first fix is integrated you will be added to developers group and will be able to send issues for peer review yourself. In this case make sure you are listed as Assignee and click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve set up [[Travis integration]], the issue will automatically show the Travis build status for the branch(es) you&#039;ve submitted for peer review.&lt;br /&gt;
===Peer review===&lt;br /&gt;
The [https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
===Submit your code for integration===&lt;br /&gt;
It will then be reviewed the following week by one of the integration team and either integrated or rejected. Once integrated, the fix will be tested, and then included in the next weekly release. For details see [[Integration Review]].&lt;br /&gt;
==Security issues==&lt;br /&gt;
Issues identified as [[Security|security issues]] are resolved in a slightly different way, in order to achieve responsible disclosure as described in [[Moodle security procedures]].&lt;br /&gt;
* Security issues should be labelled as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; in order control visibility of the issue.&lt;br /&gt;
** An issue reported with a security level of &amp;quot;Could be a security issue&amp;quot; should be evaluated as soon as possible and either set as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; or the security level should be set to &amp;quot;None&amp;quot;.&lt;br /&gt;
* Solutions to security issues should not:&lt;br /&gt;
** be made available in public repositories.&lt;br /&gt;
*** If a developer has shared a solution as Git branches via Github, they should be asked to provide the solutions as [[How_to_create_a_patch|stand-alone patches]] attached to the issue and to [[#How to remove a branch from Github|remove the solution from Github]].&lt;br /&gt;
** contain details about the security problem in the commit message.&lt;br /&gt;
*** Instead use generic terms like, &amp;quot;improve&amp;quot;, &amp;quot;better handling of&amp;quot; ..&lt;br /&gt;
* The solution will not be integrated until the week before a [[Process#Stable_maintenance_cycles|minor release]] following the normal [[Release process|Release process]]. In short, the issue will be incorporated into the integration version, rebased, tested and made ready for release as a normal issue would, but not until as late as possible.&lt;br /&gt;
* Details of security issues will be shared with registered admins with the minor release.&lt;br /&gt;
* Details of security issues will not be publicly announced until one week after a minor release to allow admins to update.&lt;br /&gt;
Note that not all the labelled (minor) security issues are always handled following the procedure above. It&#039;s possible that, after discussion, it&#039;s decided a given issue is not a real Moodle security problem (say external disclosures/potential attacks using Moodle as vector, not as target, discussions revealing some private details...). Those issues will be processed as normal issues, generating the needed user documentation if necessary and will be part of the habitual weekly releases.&lt;br /&gt;
====How to remove a branch from Github====&lt;br /&gt;
To remove a branch from Github, you can use the following command.&lt;br /&gt;
 git push github :remote_branch&lt;br /&gt;
Where &#039;&#039;remote_branch&#039;&#039; is the name of your remote branch, for example &#039;wip-mdl-1234&#039;. This effectively replaces the remote branch with nothing, removing the remote branch, but leaving the branch intact in your local Git repository. Please note that its likely that your commit will still exist on github due to the nature of git, so its best to avoid doing this in the first place.&lt;br /&gt;
==Policy issues==&lt;br /&gt;
Occasionally within Moodle we run into policy issues where a high-level decision needs to be made about how things are to be done.&lt;br /&gt;
&lt;br /&gt;
In these cases the process is as follows:&lt;br /&gt;
* Create an issue in the tracker with a [https://tracker.moodle.org/browse/MDL/component/12733 Policy component] and put &amp;quot;POLICY:&amp;quot; as a prefix on the summary.&lt;br /&gt;
* In the description describe the problem clearly as well as all the options. If it&#039;s long then make a page here in Moodle Dev Docs and link to it.&lt;br /&gt;
* Do not use this issue for code. If there are issues that depend on this policy decision, then add tracker links to them as dependencies.&lt;br /&gt;
* Feel free to encourage people to come and talk about the policy to support various points of view. The more evidence we have (from everyone in the community) the better.&lt;br /&gt;
Some time has been scheduled in the weekly Moodle HQ meeting to look at Policy issues and try to make decisions on them. We discuss all the evidence and try to achieve a high amount of consensus. Deadlocked issues can be resolved by a decision from Martin Dougiamas (this is rarely needed).&lt;br /&gt;
&lt;br /&gt;
Decisions will be posted on the issue and that issue will be closed, allowing any dependent issues to continue to integration (or not). Decisions are final and bribes hardly ever work.&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
* [[Deprecation]]&lt;br /&gt;
* [http://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=11350 Integration dashboard]&lt;br /&gt;
Walks-though of the process for contributors:&lt;br /&gt;
* By Dan Poltawski, Integrator: http://www.slideshare.net/poltawski/how-to-guarantee-your-change-is-integrated-to-moodle-core, https://www.youtube.com/watch?v=836WtnM2YpM&lt;br /&gt;
* By Tim Hunt, contributor: http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html and https://www.youtube.com/watch?v=gPPA3h7OGQU and https://youtu.be/Hu8ne0NCRAg?t=11659&lt;br /&gt;
[[Category:Processes]]&lt;br /&gt;
[[Category:Quality Assurance]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Travis_integration&amp;diff=63843</id>
		<title>Travis integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Travis_integration&amp;diff=63843"/>
		<updated>2023-03-24T10:50:00Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Part of MDLSITE-7135 - document the removal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}&lt;br /&gt;
&lt;br /&gt;
Given the two notes below, you probably don&#039;t want to read this page. [[Github actions integration]] is much more likely to be what you want.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;Since March 24th 2023, for Moodle 4.2dev and up, support for Travis CI in core has been completely removed. It&#039;s recommended to use the (enabled by default) [https://moodledev.io/general/development/tools/gha GitHub Actions integration] instead. More information can be found at:&lt;br /&gt;
* Policy issue with the agreement: MDLSITE-7135&lt;br /&gt;
* Moodle issue with the removal: MDL-77714&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;Travis [https://mailchi.mp/3d439eeb1098/travis-ciorg-is-moving-to-travis-cicom has announced] that &#039;&#039;&#039;travis-ci.org will be closed down completely on December 31st 2020&#039;&#039;&#039;, with travis-ci.com becoming the unified place for all projects. More information can be found at:&lt;br /&gt;
* [https://docs.travis-ci.com/user/migrate/open-source-repository-migration Migrating repositories to travis-ci.com]&lt;br /&gt;
* Moodle Tracker: MDLSITE-6246&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;Travis [https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing has announced], November 2, 2020, that &#039;&#039;&#039;travis-ci.com won&#039;t be (unlimitedly) free anymore&#039;&#039;&#039;, with everybody getting some credits (processing time) once and, after using them, you must change to some of their (paid) plans. Few weeks later, November 24, 2020, [https://blog.travis-ci.com/oss-announcement they have published an update] specifically for Open Source. There, they recommend to contact them &#039;&#039;&amp;quot;for anything relating with your open source account&amp;quot;&#039;&#039;. Up to you!&lt;br /&gt;
More information can be found at:&lt;br /&gt;
* Moodle Tracker: MDL-70265&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Moodle core ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Moodle is regularly tested against a matrix of Databases, PHP Versions, and operating systems, however many developers do not have the resources available to run on many of these combinations before pushing an issue for integration as they are time-consuming to both set up and to run.&lt;br /&gt;
&lt;br /&gt;
There are many Continuous Integration tools available to developers, and Travis-CI is just one of those available to the Open Source community.&lt;br /&gt;
&lt;br /&gt;
Since version 3.0, Moodle includes a Travis configuration file in its repository. This configuration file configures and controls a Travis build across a matrix of testing environments. This allows developers pushing patches to Moodle to have their code unit tested before it reaches integration. The hope is that the availability of this integration should reduce the number of unit test failures seen during Integration.&lt;br /&gt;
&lt;br /&gt;
Note: Moodle HQ uses the Jenkins CI platform and this should be seen as the [https://ci.moodle.org/ canonical CI server for Moodle]. The Travis integration aims is to provide early warning to developers of any issues with their code.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
Travis-CI is available and is usually configured to run automatically when pushing code, but it must be configured before first use.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this documentation, it is assumed that you are pushing to a public Moodle repository on GitHub. Other integrations are supported, but the service available from Travis is only available to public repositories.&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
&lt;br /&gt;
# [https://travis-ci.com/auth Sign in to Travis CI] using your GitHub account&lt;br /&gt;
# Once you’re signed in, and the initial synchronisation of your GitHub repositories has completed, go to your [https://travis-ci.com/profile profile page]&lt;br /&gt;
# Enable Travis CI for your clone of the Moodle repository [[File:moodle-travis-enable.png]]&lt;br /&gt;
# Click on the cog icon to configure the Integration&lt;br /&gt;
# Ensure that &amp;quot;Build pushed branches&amp;quot; is enabled [[File:moodle-travis-settings-2020.png]]&lt;br /&gt;
# Email notifications will be sent by default to the committer and the commit author. If you want to turn off email notifications for this repository, you can define an environment variable with name MOODLE_EMAIL and &amp;quot;no&amp;quot; as value.&lt;br /&gt;
# By default, the following jobs will be executed for each branch sent to github:&lt;br /&gt;
## GRUNT: 1 job that will check that all your javascript and scss has been properly built (see [[Grunt]]) and is part of the patch.&lt;br /&gt;
## CITESTS: 1 job that will perform a lightweight linting of your branch.&lt;br /&gt;
## PHPUNIT: 1 job that will run all the unit tests on your branch (using the lowest PHP version supported by the branch and PostgreSQL as database).&lt;br /&gt;
# If you want to change those defaults, you can use the following environment variables:&lt;br /&gt;
## MOODLE_DATABASE: With value &amp;quot;mysqli&amp;quot; to switch your runs to that database. With value &amp;quot;all&amp;quot; to run both PostgreSQL and MySQL unit tests.&lt;br /&gt;
## MOODLE_PHP: With value &amp;quot;all&amp;quot;, to run the unit tests both with the lowest and the highest PHP versions supported by the branch.&lt;br /&gt;
Note that adding more jobs will increase the time needed (and the credits consumed) for processing each branch, so be careful picking your fav configuration.&lt;br /&gt;
[[File:environment_variables.png|Define an environment variable]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How do I start a build? ===&lt;br /&gt;
&lt;br /&gt;
It won&#039;t build immediately after setup. Builds start automatically when you push a change.&lt;br /&gt;
&lt;br /&gt;
== Moodle plugins ==&lt;br /&gt;
&lt;br /&gt;
See [https://moodlehq.github.io/moodle-plugin-ci/ Moodle Plugin CI repository] for setup instructions.&lt;br /&gt;
&lt;br /&gt;
Related discussions:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=323384 Adding Travis CI support into your plugin]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=389744 Recent Travis-CI issues with plugins]&lt;br /&gt;
&lt;br /&gt;
=== Ignoring files and folders ===&lt;br /&gt;
&lt;br /&gt;
For some of the code analysis tools, it is important to ignore some files within the plugin because they might not be fixable, like a third party library. The all code analysis commands in this project ignore files and directories listed in the thirdpartylibs.xml plugin file. See https://docs.moodle.org/dev/Plugin_files#thirdpartylibs.xml for more info.&lt;br /&gt;
&lt;br /&gt;
==== Ignoring files ====&lt;br /&gt;
&lt;br /&gt;
Specifically for the codechecker command, you can ignore a single line, a section of a file or the whole file by using specific PHP comments. For details see this [[CodeSniffer]] wiki page.&lt;br /&gt;
In addition, you can ignore additional files by defining IGNORE_PATHS and/or IGNORE_NAMES environment variables in your .travis.yml file. These environment variables wont work for Grunt tasks, but will for everything else. Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
env:&lt;br /&gt;
 global:&lt;br /&gt;
  - MOODLE_BRANCH=MOODLE_35_STABLE&lt;br /&gt;
  - IGNORE_PATHS=vendor/widget,javascript/min-lib.js&lt;br /&gt;
  - IGNORE_NAMES=*-m.js,bad_lib.php&lt;br /&gt;
 matrix:&lt;br /&gt;
  - DB=pgsql&lt;br /&gt;
  - DB=mysqli&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Both environment variables take a CSV value. For IGNORE_PATHS, it takes relative file paths to ignore. File paths can be a simple string like foo/bar or a regular expression like /^foo\/bar/. For IGNORE_NAMES, it takes file names to ignore. File names can be a simple string like foo.php, a glob like *.php or a regular expression like /\.php$/.&lt;br /&gt;
&lt;br /&gt;
If you need to specify ignore paths for a specific command, then you can define additional environment variables. The variable names are the same as above, but prefixed with COMMANDNAME_. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
env:&lt;br /&gt;
 global:&lt;br /&gt;
  - MOODLE_BRANCH=MOODLE_35_STABLE&lt;br /&gt;
  - IGNORE_PATHS=vendor/widget,javascript/min-lib.js&lt;br /&gt;
  - IGNORE_NAMES=*-m.js,bad_lib.php&lt;br /&gt;
  - PHPUNIT_IGNORE_PATHS=$IGNORE_PATHS,cli&lt;br /&gt;
 matrix:&lt;br /&gt;
  - DB=pgsql&lt;br /&gt;
  - DB=mysqli&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In the above example, we are adding the cli path to our ignore paths for the PHPUnit command (this is also how you can ignore files for code coverage). Please note that this is a complete override and there is no merging with IGNORE_PATHS and IGNORE_NAMES. So, in the above, the PHPUnit command would not ignore the file names defined in IGNORE_NAMES.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Github actions integration]]: For information about the, also supported, integration with GitHub Actions.&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer tools]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Template:XMLRPC_Note_Moodle_4.1&amp;diff=63770</id>
		<title>Template:XMLRPC Note Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Template:XMLRPC_Note_Moodle_4.1&amp;diff=63770"/>
		<updated>2023-01-02T10:35:46Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Template note to be added to various user docs pages about the move of webservice_xmlrpc out from core in Moodle 4.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|The installation of the &#039;&#039;&#039;XMLRPC PHP extension&#039;&#039;&#039; is not needed for Moodle 4.1 core anymore. All [[MNet]] features continue working exactly the same, but using a PHP library instead (see MDL-76055 for details).&lt;br /&gt;
If you were using the &#039;&#039;&#039;webservice_xmlrpc&#039;&#039;&#039; plugin for integrations with other systems, be warned that it has been removed from core for Moodle 4.1 (see MDL-76052 for details). It&#039;s now available @ https://github.com/moodlehq/moodle-webservice_xmlrpc and has been also published in the [https://moodle.org/plugins/webservice_xmlrpc Plugins directory]. Note that, if you want to continue using this plugin, then you will need, &#039;&#039;&#039;before starting the upgrade process&#039;&#039;&#039;, to:&lt;br /&gt;
# Install the &#039;&#039;&#039;XMLRPC PHP extension&#039;&#039;&#039;, the webservice requires it.&lt;br /&gt;
# Install the &#039;&#039;&#039;webservice_xmlrpc plugin&#039;&#039;&#039;, from the links in the previous paragraph, into the &amp;lt;tt&amp;gt;webservice/xmlrpc&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Then, and only then, start the upgrade process.}}&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Web_service_API_functions&amp;diff=63769</id>
		<title>Web service API functions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Web_service_API_functions&amp;diff=63769"/>
		<updated>2023-01-02T10:34:50Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Note about Moodle 4.1 and XMLRPC extension/webservice added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_3.11}}&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Color meaning&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#D4FFDF;&amp;quot;  | Implemented&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#ffdead;&amp;quot;  | Must be implemented&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#ffdfcd;&amp;quot;  | Suggested&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Web service protocols==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Name !! Moodle Ver. !!  class=&amp;quot;unsortable&amp;quot; |Description !!  class=&amp;quot;unsortable&amp;quot; |CORS  !! |Issue&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#D4FFDF;&amp;quot;  | REST (returning XML) || style=&amp;quot;background:#D4FFDF;&amp;quot;  | 2.0 || style=&amp;quot;background:#D4FFDF;&amp;quot;  | XML data accessed through a REST API (not restful) || Supported (3.0 and onwards) || &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#D4FFDF;&amp;quot;  | REST (returning JSON) || style=&amp;quot;background:#D4FFDF;&amp;quot;  | 2.2 || style=&amp;quot;background:#D4FFDF;&amp;quot;  | JSON data accessed through a REST API (not restful) || Supported (3.0 and onwards)|| MDL-29242&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#ffdfcd;&amp;quot;  | REST (returning JSONP) || style=&amp;quot;background:#ffdfcd;&amp;quot;  | 2.X || style=&amp;quot;background:#ffdfcd;&amp;quot;  | Would be very useful for client-side JavaScript ||  Not supported || MDL-29913&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#ffdfcd;&amp;quot;  |  JSON || style=&amp;quot;background:#ffdfcd;&amp;quot;  | 2.X || style=&amp;quot;background:#ffdfcd;&amp;quot;  | JSON server receives a JSON encoded params and return JSON encoded values. ||  Not supported || MDL-21341&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#ffdead;&amp;quot;  | SOAP|| style=&amp;quot;background:#ffdead;&amp;quot;  | 2.0 || style=&amp;quot;background:#ffdead;&amp;quot;  | Very important for interoperating with Java and .Net applications. There was a partial implementation JAVA/.Net in Moodle 2.0, but it does not work for anything but the most trivial functions.  It is fully working with PHP clients.||  Not supported || MDL-20804, MDL-28988, MDL-28989&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#D4FFDF;&amp;quot;  | XMLRPC|| style=&amp;quot;background:#D4FFDF;&amp;quot;  | 2.0 || style=&amp;quot;background:#D4FFDF;&amp;quot;  | XML remote-procedure call. {{Template:XMLRPC Note Moodle 4.1}} ||  Not supported || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Web service functions==&lt;br /&gt;
&lt;br /&gt;
=== Naming convention ===&lt;br /&gt;
&lt;br /&gt;
All functions should be named as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;{fullcomponent}_{methodname}&amp;lt;/tt&amp;gt; - example: &amp;lt;tt&amp;gt;core_user_get_user_preferences&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;{fullcomponent}&amp;lt;/tt&amp;gt; is the full [[Frankenstyle|frankenstyle]] name or the component such as &amp;lt;tt&amp;gt;core_user&amp;lt;/tt&amp;gt; here&lt;br /&gt;
* &amp;lt;tt&amp;gt;{methodname}&amp;lt;/tt&amp;gt; is the name of the method in the form of &amp;lt;tt&amp;gt;{verb}_{noun}&amp;lt;/tt&amp;gt; such as &amp;lt;tt&amp;gt;get_user_preferences&amp;lt;/tt&amp;gt; here&lt;br /&gt;
** &amp;lt;tt&amp;gt;{verb}&amp;lt;/tt&amp;gt; - preferably one of &amp;lt;tt&amp;gt;get, create, delete, update&amp;lt;/tt&amp;gt; or eventually other that well describes the action&lt;br /&gt;
** &amp;lt;tt&amp;gt;{noun}&amp;lt;/tt&amp;gt; - moodle objects, usually plural such as &amp;lt;tt&amp;gt;user_preferences&amp;lt;/tt&amp;gt; here, or e.g. &amp;lt;tt&amp;gt;posts, discussions, users, courses&amp;lt;/tt&amp;gt; etc.&lt;br /&gt;
&lt;br /&gt;
This naming convention has been in place since Moodle 2.2. See MDL-29106 for more details.&lt;br /&gt;
&lt;br /&gt;
=== Core web service functions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
!Area!! Name !! Introduced in !! class=&amp;quot;unsortable&amp;quot; |Description !!  Available AJAX !! Login required !! Services&lt;br /&gt;
|-&lt;br /&gt;
| \core_user\search_identity || core_user_search_identity || 3.11 || Return list of users identities matching the given criteria in their name or other identity fields. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| auth_email || auth_email_get_signup_settings ||    3.2    ||    Get the signup required settings and profile fields.    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| auth_email || auth_email_signup_user ||    3.2    ||    Adds a new user (pendingto be confirmed) in the site.    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| block_recentlyaccesseditems || block_recentlyaccesseditems_get_recent_items ||  3.6  ||  List of items a user has accessed most recently.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| block_starredcourses || block_starredcourses_get_starred_courses ||  3.6  ||  Get users starred courses.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core\record_userfeedback_action || core_create_userfeedback_action_record || 3.9 || Record the action that the user takes in the user feedback notification for future use. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_confirm_user ||    3.2    ||    Confirm a user account.    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_is_age_digital_consent_verification_enabled || 3.5 || Checks if age digital consent verification is enabled.   || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_is_minor ||  3.5 || Requests a check if a user is a digital minor. || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_request_password_reset ||  3.4  ||  Requests a password reset.  || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_request_password_reset ||  3.4  ||  Requests a password reset.  || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_resend_confirmation_email ||  3.6  ||  Resend confirmation email.  || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_auth || core_auth_resend_confirmation_email ||  3.6  ||  Resend confirmation email.  || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_backup || core_backup_get_async_backup_links_backup ||  3.7  ||  Gets the data to use when updating the status table row in the UI for when an async backup completes.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_backup || core_backup_get_async_backup_links_restore ||  3.7  ||  Gets the data to use when updating the status table row in the UI for when an async restore completes.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_backup || core_backup_get_async_backup_progress ||  3.7  ||  Get the progress of an Asyncronhous backup.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_backup || core_backup_get_copy_progress || 3.9 || Gets the progress of course copy operations. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_backup || core_backup_submit_copy_form || 3.9 || Handles ajax submission of course copy form. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_badges || core_badges_get_user_badges ||     3.1     ||     Returns the list of badges awarded to a user.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_block || core_block_get_course_blocks ||   3.3   ||   Returns blocks information for a course.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_block || core_block_get_dashboard_blocks ||  3.6  ||  Returns blocks information for the given user dashboard.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_block\fetch_addable_blocks || core_block_fetch_addable_blocks || 3.11 || Returns all addable blocks in a given page. ||  Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_blog || core_blog_get_entries ||  3.6  ||  Returns blog entries.  || Yes || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_blog || core_blog_view_entries ||  3.6  ||  Trigger the blog_entries_viewed event.  || Yes || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_create_calendar_events ||     2.5     ||     Create calendar events     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_delete_calendar_events ||     2.5     ||     Delete calendar events     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_action_events_by_course ||   3.3   ||   Get calendar action events by course   || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_action_events_by_courses ||   3.3   ||   Get calendar action events by courses   || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_action_events_by_timesort ||   3.3   ||   Get calendar action events by tiemsort   || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_allowed_event_types ||  3.7  ||  Get the type of events a user can create in the given course.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_access_information ||  3.7  ||  Convenience function to retrieve some permissions/access information for the given course calendar.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_day_view ||  3.4  ||  Fetch the day view data for a calendar  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_event_by_id ||  3.4  ||  Get calendar event by id  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_events ||     2.5     ||     Get calendar events     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_monthly_view ||  3.4  ||  Fetch the monthly view data for a calendar  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_calendar_upcoming_view ||  3.4  ||  Fetch the upcoming view data for a calendar  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_get_timestamps ||  3.8  ||  Fetch unix timestamps for given date times.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_submit_create_update_form ||  3.4  ||  Submit form data for event form  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar || core_calendar_update_event_start_day ||  3.4  ||  Update the start day (but not time) for an event.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_calendar\export\token || core_calendar_get_calendar_export_token || 3.10 || Return the auth token required for exporting a calendar. ||  No || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_add_cohort_members ||     2.4     ||    Add members to cohort     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_create_cohorts ||     2.4     ||    Create cohorts     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_delete_cohort_members ||     2.4     ||    Delete members from cohort     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_delete_cohorts ||     2.4     ||    Delete cohorts     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_get_cohort_members ||     2.4     ||    Get cohort members     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_get_cohorts ||     2.4     ||    Get cohorts     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_search_cohorts ||  3.4  ||  Search for cohorts.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_cohort || core_cohort_update_cohorts ||     2.4     ||    Update cohorts     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_comment || core_comment_add_comments ||  3.8  ||  Adds a comment or comments.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_comment || core_comment_delete_comments ||  3.8  ||  Deletes a comment or comments.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_comment || core_comment_get_comments ||     2.9     ||    Return all the comments for an specific component, context.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_add_competency_to_course ||     3.1     ||     Add competency to a course     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_add_competency_to_plan ||     3.1     ||     Add a competency to a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_add_competency_to_template ||     3.1     ||     Add competency to a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_add_related_competency ||     3.1     ||     Create a relationship between competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_approve_plan ||     3.1     ||     Approve a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_competency_framework_viewed ||     3.1     ||     Notify a competency framework as being viewed     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_competency_viewed ||     3.1     ||     Report a competency as being viewed     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_complete_plan ||     3.1     ||     Complete a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_competencies ||     3.1     ||     Count the competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_competencies_in_course ||     3.1     ||     Count competencies in a course     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_competencies_in_template ||     3.1     ||     Count the competencies in a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_competency_frameworks ||     3.1     ||     Count the competency frameworks     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_course_module_competencies ||  3.8  ||  Count the competencies in a course module  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_courses_using_competency ||     3.1     ||     Count courses using a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_templates ||     3.1     ||     Count templates     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_count_templates_using_competency ||     3.1     ||     Count templates using a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_create_competency ||     3.1     ||     Create a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_create_competency_framework ||     3.1     ||     Create a competency framework     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_create_plan ||     3.1     ||     Create a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_create_template ||     3.1     ||     Create a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_create_user_evidence_competency ||     3.1     ||     Link an evidence of prior learning with a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_competency ||     3.1     ||     Delete a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_competency_framework ||     3.1     ||     Delete a competency framework     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_evidence ||     3.1     ||     Delete an evidence     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_plan ||     3.1     ||     Delete a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_template ||     3.1     ||     Delete a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_user_evidence ||     3.1     ||     Delete an evidence of prior learning     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_delete_user_evidence_competency ||     3.1     ||     Remove a link between an evidence of prior learning and a user&#039;s competency      || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_duplicate_competency_framework ||     3.1     ||     Duplicate a competency framework     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_duplicate_template ||     3.1     ||     Duplicate a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_get_scale_values ||     3.1     ||     Get the values for a scale     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_grade_competency ||     3.1     ||     Rate a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_grade_competency_in_course ||     3.1     ||     Rate a user&#039;s competency in a course     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_grade_competency_in_plan ||     3.1     ||     Rate a user&#039;s competency in a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_competencies ||     3.1     ||     List competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_competencies_in_template ||     3.1     ||     List the competencies of a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_competency_frameworks ||     3.1     ||     List the competency frameworks     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_course_competencies ||     3.1     ||     List the competencies in a course     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_course_module_competencies ||  3.8  ||  List the competencies in a course module  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_plan_competencies ||     3.1     ||     List a learning plan&#039;s competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_templates ||     3.1     ||     List templates     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_templates_using_competency ||     3.1     ||     List templates using a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_list_user_plans ||     3.1     ||     List a user&#039;s learning plans     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_move_down_competency ||     3.1     ||     Move a competency down in its branch     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_move_up_competency ||     3.1     ||     Move a competency up in its branch     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_plan_cancel_review_request ||     3.1     ||     Cancel the review request of a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_plan_request_review ||     3.1     ||     Request the review of a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_plan_start_review ||     3.1     ||     Start the review of a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_plan_stop_review ||     3.1     ||     Stop the review of a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_read_competency ||     3.1     ||     Fetch a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_read_competency_framework ||     3.1     ||     Fetch a competency framework     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_read_plan ||     3.1     ||     Fetch a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_read_template ||     3.1     ||     Fetch a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_read_user_evidence ||     3.1     ||     Fetch an evidence of prior learning     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_remove_competency_from_course ||     3.1     ||     Remove competency from a course     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_remove_competency_from_plan ||     3.1     ||     Remove a competency from a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_remove_competency_from_template ||     3.1     ||     Remove competency from template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_remove_related_competency ||     3.1     ||     Remove a relationship between competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_reopen_plan ||     3.1     ||     Reopen a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_reorder_course_competency ||     3.1     ||     Reorder competencies in a course     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_reorder_plan_competency ||     3.1     ||     Reopen a competency in a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_reorder_template_competency ||     3.1     ||     Reorder competencies in a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_request_review_of_user_evidence_linked_competencies ||     3.1     ||     Request the review of the user&#039;s competencies linked to an evidence of prior learning     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_search_competencies ||     3.1     ||     Search for competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_set_course_competency_ruleoutcome ||     3.1     ||     Set the rule of course competencies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_set_parent_competency ||     3.1     ||     Relocate a competency to another parent     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_template_has_related_data ||     3.1     ||     Check whether a template has related data     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_template_viewed ||     3.1     ||     Report a template as being viewed     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_unapprove_plan ||     3.1     ||     Unapprove a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_unlink_plan_from_template ||     3.1     ||     Unlink a learning plan from a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_update_competency ||     3.1     ||     Update a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_update_competency_framework ||     3.1     ||     Update a competency framework     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_update_course_competency_settings ||     3.1     ||     Update the course competency settings     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_update_plan ||     3.1     ||     Update a learning plan     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_update_template ||     3.1     ||     Update a template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_cancel_review_request ||     3.1     ||     Cancel the review request of a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_plan_viewed ||     3.1     ||     Report the archive of user&#039;s competency as being viewed      || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_request_review ||     3.1     ||     Request the review of a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_start_review ||     3.1     ||     Start the review of a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_stop_review ||     3.1     ||     Stop the review of a user&#039;s competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_viewed ||     3.1     ||     Report a user&#039;s competency as being viewed     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_viewed_in_course ||     3.1     ||     Report a user&#039;s competency as being viewed from a course     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_competency || core_competency_user_competency_viewed_in_plan ||     3.1     ||     Report a user&#039;s competency as being viewed from a learning plan     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_completion || core_completion_get_activities_completion_status ||     2.9     ||    Return the activities completion status for a user in a course.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_completion || core_completion_get_course_completion_status ||     2.9     ||    Returns course completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_completion || core_completion_mark_course_self_completed ||     3.0     ||     Update the course completion status for the current user (if course self-completion is enabled).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_completion || core_completion_override_activity_completion_status ||  3.4  ||  Update completion status for a user in an activity by overriding it.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_completion || core_completion_update_activity_completion_status_manually ||     2.9     ||    Update completion status for the current user in an activity, only for activities with manual tracking.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_contentbank\delete_content || core_contentbank_delete_content || 3.9 || Delete a content from the content bank. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_contentbank\rename_content || core_contentbank_rename_content || 3.9 || Rename a content in the content bank. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_contentbank\set_content_visibility || core_contentbank_set_content_visibility || 3.11 || Set the visibility of a content in the content bank. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_add_content_item_to_user_favourites || 3.9 || Adds a content item (activity, resource or their subtypes) to the favourites for the user. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_check_updates ||    3.2    ||    Check if there is updates affecting the user for the given course and contexts.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_create_categories ||     2.3     ||     create categories     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_create_courses ||     2.0     ||     Create new courses     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_delete_categories ||     2.3     ||     delete categories     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_delete_courses ||     2.3     ||     delete courses     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_delete_modules ||     2.5     ||    Deletes all specified module instances     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_duplicate_course ||     2.3     ||     duplicate a course     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_edit_module ||   3.3   ||   Performs an action on course module (change visibility, duplicate, delete, etc.)   || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_edit_section ||   3.3   ||   Performs an action on course section (change visibility, set marker, delete)   || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_activities_overview ||    3.2    ||    Return activities overview for the given courses.    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_activity_chooser_footer || 3.9 || Fetch the data for the activity chooser footer. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_categories ||     2.3     ||     get categories     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_contents ||     2.2     ||     get course content (modules + web service file urls)     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_course_content_items || 3.9 || Fetch all the content items (activities, resources and their subtypes) for the activity picker ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_course_module ||     3.0     ||     Return information about a course module.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_course_module_by_instance ||     3.0     ||     Return information about a given module name and instance id.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_courses ||     2.0     ||     Return course details     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_courses_by_field ||    3.2    ||    Get courses matching a specific field (id/s, shortname, idnumber, category)    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_enrolled_courses_by_timeline_classification ||  3.6  ||  List of enrolled courses for the given timeline classification (past, inprogress, or future).  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_enrolled_users_by_cmid ||  3.8  ||  List users by course module id &amp;amp; filter by group id.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_module ||   3.3   ||   Returns html with one activity module on course page   || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_recent_courses ||  3.6  ||  List of courses a user has accessed most recently.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_updates_since ||   3.3   ||   Check if there are updates affecting the user for the given course since the given time stamp.   || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_user_administration_options ||    3.2    ||    Return a list of administration options in a set of courses that are avaialable or not for the current                            user.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_get_user_navigation_options ||    3.2    ||    Return a list of navigation options in a set of courses that are avaialable or not for the current user.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_import_course ||     2.4     ||     Import course data from a course into another course. Does not include any user data.     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_remove_content_item_from_user_favourites || 3.9 || Removes a content item (activity, resource or their subtypes) from the favourites for the user. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_search_courses ||     3.0     ||     Search courses by (name, module, block, tag).     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_set_favourite_courses ||  3.6  ||  Add a list of courses to the list of favourite courses.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_toggle_activity_recommendation || 3.9 || Adds or removes an activity as a recommendation in the activity chooser. ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_update_categories ||     2.3     ||     update categories     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_update_courses ||     2.5     ||     Update courses.     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_course || core_course_view_course ||     2.9     ||    Log that the course was viewed     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_create_category ||  3.7  ||  Creates a new category  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_delete_category ||  3.7  ||  Deletes a category  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_delete_field ||  3.7  ||  Deletes an entry  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_move_category ||  3.7  ||  Drag and drop categories  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_move_field ||  3.7  ||  Drag and drop  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_customfield || core_customfield_reload_template ||  3.7  ||  Reloads template  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_edit_user_enrolment ||  3.4  ||  External function that updates a given user enrolment  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_get_course_enrolment_methods ||    3.0    ||    Get the list of course enrolment methods    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_get_enrolled_users ||     2.1     ||     Get enrolled users by course id     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_get_enrolled_users_with_capability ||     2.4     ||     For each course and capability specified, return a list of the users that are enrolled in the course and have that capability     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_get_potential_users ||  3.4  ||  Get the list of potential users to enrol  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_get_users_courses ||     2.0     ||     get list of course ids that a user is enrolled in (if you are allowed to see that)     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_search_users ||  3.8  ||  Search within the list of course participants  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_submit_user_enrolment_form ||  3.7  ||  Submit form data for enrolment form  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_enrol || core_enrol_unenrol_user_enrolment ||  3.4  ||  External function that unenrols a given user enrolment  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_fetch || core_fetch_notifications ||     3.1     ||     Return a list of notifications for the current session     || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_files || core_files_get_files ||     2.0     ||     browse moodle files     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_files || core_files_upload ||     2.2     ||     upload a file to moodle     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_files\delete\draft || core_files_delete_draft_files || 3.10 || Delete the indicated files (or directories) from a user draft file area. ||  No || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_files\get\unused_draft || core_files_get_unused_draft_itemid || 3.11 || Generate a new draft itemid for the current user. ||  No || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_filters || core_filters_get_available_in_context ||  3.4  ||  Returns the filters available in the given contexts.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_form || core_form_get_filetypes_browser_data ||  3.4  ||  Provides data for the filetypes element browser.  || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_form\dynamic_form || core_form_dynamic_form || 3.11 || Process submission of a dynamic (modal) form ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_get || core_get_component_strings ||     2.4     ||     Return all raw strings (with {$a-&amp;gt;xxx}) for a specific component - similar to core get_component_strings() call     || Yes || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_get || core_get_fragment ||     3.1     ||     Return a fragment for inclusion, such as a JavaScript page.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_get || core_get_string ||     2.4     ||     Return a translated string - similar to core get_string() call     || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_get || core_get_strings ||     2.4     ||     Return some translated strings - like several core get_string() calls     || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_get || core_get_user_dates ||   3.3   ||   Return formatted timestamps   || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grade || core_grade_update_grades ||     2.7     ||     Update a grade item and associated student grades.    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_create_gradecategory || 3.10 || Create a grade category inside a course gradebook. ||  No || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_get_grades ||     2.7     ||     Returns student course total grade and grades for activities. This function does not return category or manual items. This function is suitable for managers or teachers not students.    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_grader_gradingpanel_point_fetch ||  3.8  ||  Fetch the data required to display the grader grading panel for simple grading, creating the grade item if required  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_grader_gradingpanel_point_store ||  3.8  ||  Store the data required to display the grader grading panel for simple grading  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_grader_gradingpanel_scale_fetch ||  3.8  ||  Fetch the data required to display the grader grading panel for scale-based grading, creating the grade item if required  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_grades || core_grades_grader_gradingpanel_scale_store ||  3.8  ||  Store the data required to display the grader grading panel for scale-based grading  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_grades\create_gradecategories || core_grades_create_gradecategories || 3.11 || Create grade categories inside a course gradebook. ||  No || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grading || core_grading_get_definitions ||     2.6     ||     Returns grading definitions for the course module ids and areaname provided as parameters. An optionall activeonly parameter can be provided so that only the active grading method is returned.    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grading || core_grading_get_gradingform_instances ||     2.6     ||     Returns the instances and fillings for the requested definition id. An optional since parameter allows the number of records returned to be reduced so that only those with a timemodified value &amp;gt;= since are returned    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_grading || core_grading_save_definitions ||     2.8     ||    Accepts an array of areas as a parameter. The areas contain grading definitions with criteria for inserting and updating    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_add_group_members ||     2.0     ||     Adds group members     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_assign_grouping ||     2.3     ||     assign groups from groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_create_groupings ||     2.3     ||     create groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_create_groups ||     2.0     ||     Creates new groups     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_delete_group_members ||     2.0     ||     Deletes group members     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_delete_groupings ||     2.3     ||     delete groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_delete_groups ||     2.0     ||     Deletes all specified groups     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_activity_allowed_groups ||     3.0     ||     Gets a list of groups that the user is allowed to access within the specified activity.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_activity_groupmode ||     3.0     ||     Returns effective groupmode used in a given activity.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_course_groupings ||     2.3     ||     get all groupings in specified course     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_course_groups ||     2.0     ||     Returns all groups in specified course     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_course_user_groups ||     2.9     ||    Returns all groups in specified course for the specified user.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_group_members ||     2.0     ||     Returns group members     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_groupings ||     2.3     ||     get groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_get_groups ||      2.0     ||     Returns group details.     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_unassign_grouping ||     2.3     ||     unassign groups from groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_update_groupings ||     2.3     ||     update groupings     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_group || core_group_update_groups ||  3.6  ||  Updates existing groups.  || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_h5p || core_h5p_get_trusted_h5p_file ||  3.8  ||  Get the H5P file cleaned for Mobile App.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_block_contacts ||     2.5     ||     Block contacts     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_block_user ||  3.6  ||  Blocks a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_confirm_contact_request ||  3.6  ||  Confirms a contact request  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_create_contact_request ||  3.6  ||  Creates a contact request  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_create_contacts ||     2.5     ||     Add contacts to the contact list     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_contacts ||    3.2    ||    Retrieve the template data for the contact list    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_conversations ||    3.2    ||    Retrieve the template data for the conversation list    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_get_most_recent_message ||    3.2    ||    Retrieve the template data for the most recent message    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_get_profile ||    3.2    ||    Retrieve the template data for the users\&#039;s profile    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_messages ||    3.2    ||    Retrieve the template data for the messages    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_search_messages ||    3.2    ||    Retrieve the template data for searching for messages    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_search_users ||    3.2    ||    Retrieve the template data for searching for people    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_data_for_messagearea_search_users_in_course ||    3.2    ||    Retrieve the template data for searching for people in a course    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_decline_contact_request ||  3.6  ||  Declines a contact request  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_delete_contacts ||     2.5     ||     Remove contacts from the contact list     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_delete_conversation ||    3.2    ||    Deletes a conversation.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_delete_conversations_by_id ||  3.6  ||  Deletes a list of conversations.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_delete_message ||     3.1     ||     Deletes a message.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_delete_message_for_all_users ||  3.7  ||  Deletes a message for all users.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_blocked_users ||     2.9     ||    Retrieve a list of users blocked     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_contact_requests ||  3.6  ||  Returns contact requests for a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_contacts ||     2.5     ||     Retrieve the contact list     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversation ||  3.6  ||  Retrieve a conversation for a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversation_between_users ||  3.6  ||  Retrieve a conversation for a user between another user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversation_counts ||  3.6  ||  Retrieve a list of conversation counts, indexed by type.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversation_members ||  3.6  ||  Retrieve a list of members in a conversation  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversation_messages ||  3.6  ||  Retrieve the conversation messages and relevant member information  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_conversations ||  3.6  ||  Retrieve a list of conversations for a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_member_info ||  3.6  ||  Retrieve a user message profiles  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_message_processor ||    3.2    ||    Get a message processor    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_messages ||     2.8     ||    Retrieve a list of messages sent and received by a user (conversations, notifications or both)     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_received_contact_requests_count ||  3.6  ||  Gets the number of received contact requests  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_self_conversation ||  3.7  ||  Retrieve a self-conversation for a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_unread_conversations_count ||    3.2    ||    Retrieve the count of unread conversations for a given user    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_user_contacts ||  3.6  ||  Retrieve the contact list  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_user_message_preferences ||    3.2    ||    Get the message preferences for a given user.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_get_user_notification_preferences ||    3.2    ||    Get the notification preferences for a given user.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mark_all_conversation_messages_as_read ||  3.6  ||  Mark all conversation messages as read for a given user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mark_all_messages_as_read ||    3.2    ||    Mark all messages as read for a given user    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mark_all_notifications_as_read ||    3.2    ||    Mark all notifications as read for a given user    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mark_message_read ||     2.9     ||    Mark a single message as read, trigger message_viewed event.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mark_notification_read ||  3.5  ||  Mark a single notification as read, trigger notification_viewed event.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_message_processor_config_form ||    3.2    ||    Process the message processor config form    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_message_search_users ||  3.6  ||  Retrieve the data for searching for people  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_mute_conversations ||  3.7  ||  Mutes a list of conversations  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_search_contacts ||     2.5     ||     Search for contacts     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_send_instant_messages ||     2.1     ||     Send instant messages     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_send_messages_to_conversation ||  3.6  ||  Send messages to an existing conversation between users  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_set_favourite_conversations ||  3.6  ||  Mark a conversation or group of conversations as favourites/starred conversations.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_unblock_contacts ||     2.5     ||     Unblock contacts     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_unblock_user ||  3.6  ||  Unblocks a user  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_unmute_conversations ||  3.7  ||  Unmutes a list of conversations  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_message || core_message_unset_favourite_conversations ||  3.6  ||  Unset a conversation or group of conversations as favourites/starred conversations.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_create_notes ||     2.1     ||     Create notes     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_delete_notes ||     2.5     ||     Delete Notes     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_get_course_notes ||     2.9     ||    Returns all notes in specified course (or site) for the specified user.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_get_notes ||     2.5     ||     Retrieve Notes     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_update_notes ||     2.5     ||     Update Notes     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_notes || core_notes_view_notes ||     2.9     ||    Simulates the web interface view of notes/index.php: trigger events.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_output || core_output_load_fontawesome_icon_map ||   3.3   ||   Load the mapping of names to icons   || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_output || core_output_load_template ||    3.0    ||    Load a template for a renderable    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| core_payment\get_available_gateways || core_payment_get_available_gateways || 3.10 || Get the list of payment gateways that support the given component/area ||  Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_question || core_question_get_random_question_summaries ||  3.5  ||  Get the random question set for a criteria  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_question || core_question_submit_tags_form ||  3.5  ||  Update the question tags.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_question || core_question_update_flag ||     3.1     ||     Update the flag state of a question attempt.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_rating || core_rating_add_rating ||    3.2    ||    Rates an item.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_rating || core_rating_get_item_ratings ||     2.9     ||    Retrieve all the ratings for an item.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_role || core_role_assign_roles ||     2.0     ||     Manual role assignments     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_role || core_role_unassign_roles ||     2.0     ||     Manual role unassignments     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_search || core_search_get_relevant_users ||  3.5  ||  Gets relevant users for a search request.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_session || core_session_time_remaining ||  3.8  ||  Count the seconds remaining in this session  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_session || core_session_touch ||  3.8  ||  Keep the users session alive  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_table\dynamic\get || core_table_get_dynamic_table_content || 3.9 || Get the dynamic table content raw html ||  Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tag_areas ||  3.7  ||  Retrieves existing tag areas.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tag_cloud ||  3.7  ||  Retrieves a tag cloud for the given collection and/or query search.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tag_collections ||  3.7  ||  Retrieves existing tag collections.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tagindex ||     3.1     ||     Gets tag index page for one tag and one tag area     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tagindex_per_area ||  3.7  ||  Gets tag index page per different areas.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_get_tags ||    3.0    ||    Gets tags by their ids    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_tag || core_tag_update_tags ||    3.0    ||    Updates tags    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_update || core_update_inplace_editable ||     3.1     ||     Generic service to update title     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_add_user_device ||     2.6     ||    Store mobile user devices information for PUSH Notifications.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_add_user_private_files ||    2.6    ||    Copy files from a draft area to users private files area.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_agree_site_policy ||    3.2    ||    Agree the site policy for the current user.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_create_users ||     2.0     ||     Create users - admin function     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_delete_users ||     2.0     ||     Delete users - admin function     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_course_user_profiles ||     2.1     ||     Get course user profiles by id     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_private_files_info ||  3.4  ||  Returns general information about files in the user private files area.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_user_preferences ||    3.2    ||    Return user preferences.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_users ||     2.5     ||     Search users. - If you want to get multiple users for one specific field, use core_user_get_users_by_field(), it&#039;s designed for this purpose and it should be faster.     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_users_by_field ||     2.5     ||     Retrieve users information for a specified unique field - If you want to do a user search, use core_user_get_users()     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_get_users_by_id ||     2.0     ||     Get users by id     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_remove_user_device ||     2.9     ||    Remove a user device from the Moodle database.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_set_user_preferences ||    3.2    ||    Set user preferences.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_update_picture ||    3.2    ||    Update or delete the user picture in the site    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_update_user_preferences ||    3.2    ||    Update a user\&#039;s preferences    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_update_users ||     2.0     ||     Update users     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_view_user_list ||     2.9     ||    Simulates the web-interface view of user/index.php (triggering events).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_user || core_user_view_user_profile ||     2.9     ||    Simulates the web-interface view of user/view.php and user/profile.php (triggering events).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_webservice || core_webservice_get_site_info ||     2.1     ||     Return some site info / user info / list web service functions     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| core_xapi\post_statement || core_xapi_statement_post || 3.9 || Post an xAPI statement. ||  Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| enrol_guest || enrol_guest_get_instance_info ||     3.1     ||     Return guest enrolment instance information.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| enrol_manual || enrol_manual_enrol_users ||     2.0     ||     Manual enrol users     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| enrol_manual || enrol_manual_unenrol_users ||    3.0    ||    Manual unenrol users    || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| enrol_self || enrol_self_enrol_user ||     3.0     ||     Self enrol the current user in the given course.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| enrol_self || enrol_self_get_instance_info ||    3.0    ||    self enrolment instance information.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradereport_overview || gradereport_overview_get_course_grades ||    3.2    ||    Get the given user courses final grades    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradereport_overview || gradereport_overview_view_grade_report ||    3.2    ||    Trigger the report view event    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradereport_user || gradereport_user_get_grade_items ||    3.2    ||    Returns the complete list of grade items for users in a course    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradereport_user || gradereport_user_get_grades_table ||     2.9     ||    Get the user/s report grades table for a course     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradereport_user || gradereport_user_view_grade_report ||     2.9     ||    Trigger the grade_report_viewed event when a user view his grade report (this web service will be initially used by the mobile app so information can be logged in the Moodle side when a user see the same page in the app).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| gradingform_guide || gradingform_guide_grader_gradingpanel_fetch ||  3.8  ||  Fetch the data required to display the grader grading panel, creating the grade item if required  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| gradingform_guide || gradingform_guide_grader_gradingpanel_store ||  3.8  ||  Store the grading data for a user from the grader grading panel.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| gradingform_rubric || gradingform_rubric_grader_gradingpanel_fetch ||  3.8  ||  Fetch the data required to display the grader grading panel, creating the grade item if required  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| gradingform_rubric || gradingform_rubric_grader_gradingpanel_store ||  3.8  ||  Store the grading data for a user from the grader grading panel.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| local_mobile || local_mobile_get_plugin_settings ||  3.4  ||  Retrieve the plugin settings.  || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| message_airnotifier || message_airnotifier_are_notification_preferences_configured ||    2.7    ||    Check if the users have notification preferences configured yet    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| message_airnotifier || message_airnotifier_enable_device ||    3.2    ||    Enables or disables a registered user device so it can receive Push notifications    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| message_airnotifier || message_airnotifier_get_user_devices ||    3.2    ||    Return the list of mobile devices that are registered in Moodle for the given user    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| message_airnotifier || message_airnotifier_is_system_configured ||    2.7    ||    Check whether the airnotifier settings have been configured    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| message_popup || message_popup_get_popup_notifications ||    3.2    ||    Retrieve a list of popup notifications for a user    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| message_popup || message_popup_get_unread_popup_notification_count ||    3.2    ||    Retrieve the count of unread popup notifications for a given user    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_copy_previous_attempt ||     2.6     ||     Copy a students previous attempt to a new attempt.     || No || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_assignments ||     2.4     ||     Returns the courses and assignments for the users capability     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_grades ||     2.4     ||     Returns grades from the assignment     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_participant ||     3.1     ||     Get a participant for an assignment, with some summary info about their submissions.    || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_submission_status ||     3.1     ||     Returns information about an assignment submission status for a given user.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_submissions ||     2.5     ||     Returns the submissions for assignments     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_user_flags ||     2.6     ||     Returns the user_flags for assignments     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_get_user_mappings ||     2.6     ||     Returns the user_mappings for assignments     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_list_participants ||     3.1     ||     List the participants for a single assignment, with some summary info about their submissions.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_lock_submissions ||     2.6     ||     Prevent students from making changes to a list of submissions     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_reveal_identities ||     2.6     ||     Reveal the identities for a blind marking assignment     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_revert_submissions_to_draft ||     2.6     ||     Reverts the list of submissions to draft status     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_save_grade ||     2.6     ||     Save a grade update for a single student.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_save_grades ||     2.7     ||     Save grade updates for one or more students.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_save_submission ||     2.6     ||     Update the current students submission     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_save_user_extensions ||     2.6     ||     Save a list of assignment extensions     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_set_user_flags ||     2.6     ||     Sets the specified user_flags for an assignment     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_submit_for_grading ||     2.6     ||     Submit the current students assignment for grading     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_submit_grading_form ||     3.1     ||     Submit the grading form data via ajax     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_unlock_submissions ||     2.6     ||     Allow students to make changes to a list of submissions     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_view_assign ||    3.2    ||    Update the module completion status.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_view_grading_table ||    3.0    ||    Trigger the grading_table_viewed event.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_assign || mod_assign_view_submission_status ||     3.1     ||     Trigger the submission status viewed event.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_book || mod_book_get_books_by_courses ||     3.0     ||     Returns a list of book instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_book || mod_book_view_book ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_get_chat_latest_messages ||     3.0     ||     Get the latest messages from the given chat sessio.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_get_chat_users ||     3.0     ||     Get the list of users in the given chat session.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_get_chats_by_courses ||     3.0     ||     Returns a list of chat instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_get_session_messages ||  3.5  ||  Retrieves messages of the given chat session.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_get_sessions ||  3.5  ||  Retrieves chat sessions for a given chat.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_login_user ||     3.0     ||     Log a user into a chat room in the given chat.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_send_chat_message ||     3.0     ||     Send a message on the given chat session.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_chat || mod_chat_view_chat ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_delete_choice_responses ||     3.0     ||     Delete the given submitted responses in a choice.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_get_choice_options ||     3.0     ||     Retrieve options for a specific choice.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_get_choice_results ||     3.0     ||     Retrieve users results for a given choice.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_get_choices_by_courses ||     3.0     ||     Returns a list of choice instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_submit_choice_response ||     3.0     ||     Submit responses to a specific choice item.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_choice || mod_choice_view_choice ||     3.0     ||     Trigger the course module viewed event and update the module completion status..     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_add_entry ||   3.3   ||   Adds a new entry.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_approve_entry ||   3.3   ||   Approves or unapproves an entry.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_delete_entry ||   3.3   ||   Deletes an entry.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_get_data_access_information ||   3.3   ||   Return access information for a given database.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_get_databases_by_courses ||     2.9     ||    Returns a list of database instances in a provided set of courses, if no courses are provided then all the database instances the user has access to will be returned.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_get_entries ||   3.3   ||   Return the complete list of entries of the given database.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_get_entry ||   3.3   ||   Return one entry record from the database, including contents optionally.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_get_fields ||   3.3   ||   Return the list of configured fields for the given database.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_search_entries ||   3.3   ||   Search for entries in the given database.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_update_entry ||   3.3   ||   Updates an existing entry.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_data || mod_data_view_database ||   3.3   ||   Simulate the view.php web interface data: trigger events, completion, etc...   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_analysis ||   3.3   ||   Retrieves the feedback analysis.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_current_completed_tmp ||   3.3   ||   Returns the temporary completion record for the current user.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_feedback_access_information ||   3.3   ||   Return access information for a given feedback.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_feedbacks_by_courses ||   3.3   ||   Returns a list of feedbacks in a provided list of courses, if no list is provided all feedbacks that                            the user can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_finished_responses ||   3.3   ||   Retrieves responses from the last finished attempt.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_items ||   3.3   ||   Returns the items (questions) in the given feedback.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_last_completed ||   3.3   ||   Retrieves the last completion record for the current user.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_non_respondents ||   3.3   ||   Retrieves a list of students who didn\&#039;t submit the feedback.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_page_items ||   3.3   ||   Get a single feedback page items.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_responses_analysis ||   3.3   ||   Return the feedback user responses analysis.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_get_unfinished_responses ||   3.3   ||   Retrieves responses from the current unfinished attempt.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_launch_feedback ||   3.3   ||   Starts or continues a feedback submission.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_process_page ||   3.3   ||   Process a jump between pages.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_feedback || mod_feedback_view_feedback ||   3.3   ||   Trigger the course module viewed event and update the module completion status.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_folder || mod_folder_get_folders_by_courses ||   3.3   ||   Returns a list of folders in a provided list of courses, if no list is provided all folders that                            the user can view will be returned. Please note that this WS is not returning the folder contents.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_folder || mod_folder_view_folder ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_add_discussion ||     3.0     ||     Add a new discussion into an existing forum.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_add_discussion_post ||     3.0     ||     Create new posts into an existing discussion.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_can_add_discussion ||     3.1     ||     Check if the current user can add discussions in the given forum (and optionally for the given group).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_delete_post ||  3.8  ||  Deletes a post or a discussion completely when the post is the discussion topic.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_discussion_post ||  3.8  ||  Get a particular discussion post.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_discussion_posts ||  3.7  ||  Returns a list of forum posts for a discussion.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_discussion_posts_by_userid ||  3.8  ||  Returns a list of forum posts for a discussion for a user.  || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_forum_access_information ||  3.7  ||  Return capabilities information for a given forum.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_forum_discussion_posts ||     2.7     ||    Returns a list of forum posts for a discussion.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_forum_discussions ||  3.7  ||  Returns a list of forum discussions optionally sorted and paginated.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_forum_discussions_paginated ||     2.8     ||    Returns a list of forum discussions optionally sorted and paginated.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_get_forums_by_courses ||     2.5     ||     Returns a list of forum instances in a provided set of courses, if no courses are provided then all the forum instances the user has access to will be returned.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_prepare_draft_area_for_post ||  3.8  ||  Prepares a draft area for editing a post.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_set_lock_state ||  3.7  ||  Set the lock state for the discussion  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_set_pin_state ||  3.7  ||  Set the pin state  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_set_subscription_state ||  3.7  ||  Set the subscription state  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_toggle_favourite_state ||  3.7  ||  Toggle the favourite state  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_update_discussion_post ||  3.8  ||  Updates a post or a discussion topic post.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_view_forum ||     2.9     ||    Trigger the course_module_viewed event when a user view a forum (this web service will be initially used by the mobile app so information can be logged in the Moodle side when a user see the same page in the app).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_forum || mod_forum_view_forum_discussion ||     2.9     ||    Trigger the discussion_viewed event when a user view a forum discussion (this web service will be initially used by the mobile app so information can be logged in the Moodle side when a user see the same page in the app).     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_add_entry ||    3.2    ||    Add a new entry to a given glossary    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_authors ||     3.1     ||     Get the authors in a glossary     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_categories ||     3.1     ||     Get a glossary&#039;s categories     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_author ||     3.1     ||     Get entries using author filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_author_id ||     3.1     ||     Get entries using author ID filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_category ||     3.1     ||     Get entries using category filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_date ||     3.1     ||     Get entries using date filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_letter ||     3.1     ||     Get entries using letter filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_search ||     3.1     ||     Get entries matching a search query     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_by_term ||     3.1     ||     Get entries using term filtering     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entries_to_approve ||     3.1     ||     Get entries to be approved     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_entry_by_id ||     3.1     ||     Get an entry by ID     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_get_glossaries_by_courses ||     3.1     ||     Get the glossaries in courses     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_view_entry ||     3.1     ||     Notify that a glossary entry was viewed     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_glossary || mod_glossary_view_glossary ||     3.1     ||     Notify that a glossary was viewed     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_imscp || mod_imscp_get_imscps_by_courses ||     3.0     ||     Returns a list of imscp instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_imscp || mod_imscp_view_imscp ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_label || mod_label_get_labels_by_courses ||   3.3   ||   Returns a list of labels in a provided list of courses, if no list is provided all labels that the user                            can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_finish_attempt ||   3.3   ||   Finishes the current attempt.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_attempts_overview ||   3.3   ||   Get a list of all the attempts made by users in a lesson.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_content_pages_viewed ||   3.3   ||   Return the list of content pages viewed by a user during a lesson attempt.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_lesson ||   3.3   ||   Return information of a given lesson.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_lesson_access_information ||   3.3   ||   Return access information for a given lesson.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_lessons_by_courses ||   3.3   ||   Returns a list of lessons in a provided list of courses,                            if no list is provided all lessons that the user can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_page_data ||   3.3   ||   Return information of a given page, including its contents.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_pages ||   3.3   ||   Return the list of pages in a lesson (based on the user permissions).   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_pages_possible_jumps ||   3.3   ||   Return all the possible jumps for the pages in a given lesson.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_questions_attempts ||   3.3   ||   Return the list of questions attempts in a given lesson.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_user_attempt ||   3.3   ||   Return information about the given user attempt (including answers).   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_user_attempt_grade ||   3.3   ||   Return grade information in the attempt for a given user.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_user_grade ||   3.3   ||   Return the final grade in the lesson for the given user.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_get_user_timers ||   3.3   ||   Return the timers in the current lesson for the given user.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_launch_attempt ||   3.3   ||   Starts a new attempt or continues an existing one.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_process_page ||   3.3   ||   Processes page responses.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lesson || mod_lesson_view_lesson ||   3.3   ||   Trigger the course module viewed event and update the module completion status.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_create_tool_proxy ||     3.1     ||     Create a tool proxy     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_create_tool_type ||     3.1     ||     Create a tool type     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_delete_tool_proxy ||     3.1     ||     Delete a tool proxy     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_delete_tool_type ||     3.1     ||     Delete a tool type     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_get_ltis_by_courses ||     3.0     ||     Returns a list of lti instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_get_tool_launch_data ||     3.0     ||     Return the launch data for a given external tool.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_get_tool_proxies ||     3.1     ||     Get a list of the tool proxies     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_get_tool_proxy_registration_request ||     3.1     ||     Get a registration request for a tool proxy     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_get_tool_types ||     3.1     ||     Get a list of the tool types     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_is_cartridge ||     3.1     ||     Determine if the given url is for a cartridge     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_update_tool_type ||     3.1     ||     Update a tool type     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| mod_lti || mod_lti_view_lti ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_page || mod_page_get_pages_by_courses ||   3.3   ||   Returns a list of pages in a provided list of courses, if no list is provided all pages that the user                            can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_page || mod_page_view_page ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_attempt_access_information ||     3.1     ||     Return access information for a given attempt in a quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_attempt_data ||     3.1     ||     Returns information for the given attempt page for a quiz attempt in progress.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_attempt_review ||     3.1     ||     Returns review information for the given finished attempt, can be used by users or teachers.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_attempt_summary ||     3.1     ||     Returns a summary of a quiz attempt before it is submitted.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_combined_review_options ||     3.1     ||     Combines the review options from a number of different quiz attempts.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_quiz_access_information ||     3.1     ||     Return access information for a given quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_quiz_feedback_for_grade ||     3.1     ||     Get the feedback text that should be show to a student who got the given grade in the given quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_quiz_required_qtypes ||     3.1     ||     Return the potential question types that would be required for a given quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_quizzes_by_courses ||     3.1     ||     Returns a list of quizzes in a provided list of courses, if no list is provided all quizzes that the user can view will be returned.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_user_attempts ||     3.1     ||     Return a list of attempts for the given quiz and user.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_get_user_best_grade ||     3.1     ||     Get the best current grade for the given user on a quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_process_attempt ||     3.1     ||     Process responses during an attempt at a quiz and also deals with attempts finishing.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_save_attempt ||     3.1     ||     Processes save requests during the quiz.This function is intended for the quiz auto-save feature.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_start_attempt ||     3.1     ||     Starts a new attempt at a quiz.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_view_attempt ||     3.1     ||     Trigger the attempt viewed event.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_view_attempt_review ||     3.1     ||     Trigger the attempt reviewed event.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_view_attempt_summary ||     3.1     ||     Trigger the attempt summary viewed event.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_quiz || mod_quiz_view_quiz ||     3.1     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_resource || mod_resource_get_resources_by_courses ||   3.3   ||   Returns a list of files in a provided list of courses, if no list is provided all files that                            the user can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_resource || mod_resource_view_resource ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorm_access_information ||  3.7  ||  Return capabilities information for a given scorm.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorm_attempt_count ||     3.0     ||     Return the number of attempts done by a user in the given SCORM.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorm_sco_tracks ||     3.0     ||     Retrieves SCO tracking data for the given user id and attempt number.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorm_scoes ||     3.0     ||     Returns a list containing all the scoes data related to the given scorm id.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorm_user_data ||     3.0     ||     Retrieves user tracking and SCO data and default SCORM values.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_get_scorms_by_courses ||     3.0     ||     Returns a list of scorm instances in a provided set of courses.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_insert_scorm_tracks ||     3.0     ||     Saves a scorm tracking record.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_launch_sco ||     3.1     ||     Trigger the SCO launched event.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_scorm || mod_scorm_view_scorm ||     3.0     ||     Trigger the course module viewed event and update the module completion status..     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_survey || mod_survey_get_questions ||    3.0    ||    Get the complete list of questions for the survey, including subquestions.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_survey || mod_survey_get_surveys_by_courses ||    3.0    ||    Returns a list of survey instances in a provided set of courses, if no courses are provided then all the survey instances the user has access to will be returned.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_survey || mod_survey_submit_answers ||    3.0    ||    Submit the answers for a given survey.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_survey || mod_survey_view_survey ||    3.0    ||    Trigger the course module viewed event and update the module completion status.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_url || mod_url_get_urls_by_courses ||   3.3   ||   Returns a list of urls in a provided list of courses, if no list is provided all urls that the user                            can view will be returned.   || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_url || mod_url_view_url ||     3.0     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_edit_page ||     3.1     ||     Save the contents of a page.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_page_contents ||     3.1     ||     Returns the contents of a page.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_page_for_editing ||     3.1     ||     Locks and retrieves info of page-section to be edited.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_subwiki_files ||     3.1     ||     Returns the list of files for a specific subwiki.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_subwiki_pages ||     3.1     ||     Returns the list of pages for a specific subwiki.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_subwikis ||     3.1     ||     Returns the list of subwikis the user can see in a specific wiki.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_get_wikis_by_courses ||     3.1     ||     Returns a list of wiki instances in a provided set of courses, if no courses are provided then all the wiki instances the user has access to will be returned.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_new_page ||     3.1     ||     Create a new page in a subwiki.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_view_page ||     3.1     ||     Trigger the page viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_wiki || mod_wiki_view_wiki ||     3.1     ||     Trigger the course module viewed event and update the module completion status.     || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_add_submission ||  3.4  ||  Add a new submission to a given workshop.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_delete_submission ||  3.4  ||  Deletes the given submission.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_evaluate_assessment ||  3.4  ||  Evaluates an assessment (used by teachers for provide feedback to the reviewer).  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_evaluate_submission ||  3.4  ||  Evaluates a submission (used by teachers for provide feedback or override the submission grade).  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_assessment ||  3.4  ||  Retrieves the given assessment.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_assessment_form_definition ||  3.4  ||  Retrieves the assessment form definition.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_grades ||  3.4  ||  Returns the assessment and submission grade for the given user.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_grades_report ||  3.4  ||  Retrieves the assessment grades report.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_reviewer_assessments ||  3.4  ||  Retrieves all the assessments reviewed by the given user.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_submission ||  3.4  ||  Retrieves the given submission.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_submission_assessments ||  3.4  ||  Retrieves all the assessments of the given submission.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_submissions ||  3.4  ||  Retrieves all the workshop submissions or the one done by the given user (except example submissions).  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_user_plan ||  3.4  ||  Return the planner information for the given user.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_workshop_access_information ||  3.4  ||  Return access information for a given workshop.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_get_workshops_by_courses ||  3.4  ||  Returns a list of workshops in a provided list of courses, if no list is provided all workshops that                            the user can view will be returned.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_update_assessment ||  3.4  ||  Add information to an allocated assessment.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_update_submission ||  3.4  ||  Update the given submission.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_view_submission ||  3.4  ||  Trigger the submission viewed event.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| mod_workshop || mod_workshop_view_workshop ||  3.4  ||  Trigger the course module viewed event and update the module completion status.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| report_competency || report_competency_data_for_report ||     3.1     ||     Load the data for the competency report in a course.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| report_insights || report_insights_action_executed ||  3.8  ||  Stores an action executed over a group of predictions.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| report_insights || report_insights_set_fixed_prediction ||  3.4  ||  Flags a prediction as fixed.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| report_insights || report_insights_set_notuseful_prediction ||  3.4  ||  Flags the prediction as not useful.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_analytics || tool_analytics_potential_contexts ||  3.8  ||  Retrieve the list of potential contexts for a model.  || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_competencies_manage_page ||     3.1     ||     Load the data for the competencies manage page template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_competency_frameworks_manage_page ||     3.1     ||     Load the data for the competency frameworks manage page template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_competency_summary ||     3.1     ||     Load competency data for summary template.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_course_competencies_page ||     3.1     ||     Load the data for the course competencies page template.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_plan_page ||     3.1     ||     Load the data for the plan page template.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_plans_page ||     3.1     ||     Load the data for the plans page template     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_related_competencies_section ||     3.1     ||     Load the data for the related competencies template.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_template_competencies_page ||     3.1     ||     Load the data for the template competencies page template.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_templates_manage_page ||     3.1     ||     Load the data for the learning plan templates manage page template     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_user_competency_summary ||     3.1     ||     Load a summary of a user competency.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_user_competency_summary_in_course ||     3.1     ||     Load a summary of a user competency.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_user_competency_summary_in_plan ||     3.1     ||     Load a summary of a user competency.     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_user_evidence_list_page ||     3.1     ||     Load the data for the user evidence list page template     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_data_for_user_evidence_page ||     3.1     ||     Load the data for the user evidence page template     || Yes || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_list_courses_using_competency ||     3.1     ||     List the courses using a competency     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_search_cohorts ||     3.1     ||     Search for cohorts.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_lp || tool_lp_search_users ||     3.1     ||     Search for users.     || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_call_external_functions ||  3.7  ||  Call multiple external functions and return all responses.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_get_autologin_key ||    3.2    ||    Creates an auto-login key for the current user.                            Is created only in https sites and is restricted by time and ip address.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_get_config ||    3.2    ||    Returns a list of the site configurations, filtering by section.    || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_get_content ||  3.5  ||  Returns a piece of content to be displayed in the Mobile app.  || No || Yes || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_get_plugins_supporting_mobile ||     3.1     ||     Returns a list of Moodle plugins supporting the mobile app.     || Yes || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_mobile || tool_mobile_get_public_config ||    3.2    ||    Returns a list of the site public settings, those not requiring authentication.    || Yes || No || moodle_mobile_app&lt;br /&gt;
|-&lt;br /&gt;
| tool_templatelibrary || tool_templatelibrary_list_templates ||    3.0    ||    List/search templates by component.    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_templatelibrary || tool_templatelibrary_load_canonical_template ||    3.0    ||    Load a canonical template by name (not the theme overidden one).    || Yes || No ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_usertours || tool_usertours_complete_tour ||    3.2    ||    Mark the specified tour as completed for the current user    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_usertours || tool_usertours_fetch_and_start_tour ||    3.2    ||    Fetch the specified tour    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_usertours || tool_usertours_reset_tour ||    3.2    ||    Remove the specified tour    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_usertours || tool_usertours_step_shown ||    3.2    ||    Mark the specified step as completed for the current user    || Yes || Yes ||&lt;br /&gt;
|-&lt;br /&gt;
| tool_xmldb || tool_xmldb_invoke_move_action ||  3.6  ||  moves element up/down  || Yes || Yes ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is the list of the integrated core functions. To see the roadmap, see to the tracker issue in the section bellow.&lt;br /&gt;
&lt;br /&gt;
New Web Services entries are automatically generated for each new major version via this script: https://github.com/moodlehq/moodlemobile-scripts/blob/master/ws-documenter.php&lt;br /&gt;
&amp;lt;F2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Roadmap===&lt;br /&gt;
Tracker issue: MDL-29934&lt;br /&gt;
&lt;br /&gt;
= See also =&lt;br /&gt;
* [[Web services API Changes]]&lt;br /&gt;
* [[How to contribute a web service function to core]]&lt;br /&gt;
* [[Web services|Web services developer documentation]]&lt;br /&gt;
* [[:en:Web services|Web services user documentation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Services]]&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Core_plugins_review_for_Moodle_4.0&amp;diff=63669</id>
		<title>Core plugins review for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Core_plugins_review_for_Moodle_4.0&amp;diff=63669"/>
		<updated>2022-10-21T21:28:50Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: just adding a few details in case somebody searches the docs looking for plugin removal information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Core plugins review&lt;br /&gt;
|state = Completed&lt;br /&gt;
|tracker = MDL-72046 (epic)&lt;br /&gt;
|discussion = [https://moodle.org/mod/forum/discuss.php?d=426053 Moodle core plugins review]&lt;br /&gt;
|assignee = Sara Arjona&lt;br /&gt;
}}&lt;br /&gt;
{{Template:Moodle 4.0}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
This project is about reviewing the plugins in core Moodle LMS with the aim of removing any which are no longer or hardly used, and if appropriate, adding them to the Moodle plugins directory.&lt;br /&gt;
==Plugins to be deleted from core==&lt;br /&gt;
The following plugins will be deleted from core but not put in the plugins directory because the technology is discontinued.&lt;br /&gt;
* WebCT question import/export format (qformat_webct)&lt;br /&gt;
* Examview question import/export format (qformat_examview)&lt;br /&gt;
* Flash animation media player (media_swf)&lt;br /&gt;
* VideoJS Flash plugin&lt;br /&gt;
* Picasa repository (repository_picasa)&lt;br /&gt;
* Picasa portfolio (portfolio_picasa)&lt;br /&gt;
* Microsoft OneDrive (legacy)	(repository_skydrive)&lt;br /&gt;
==Plugins to be removed from core and added to the plugins directory==&lt;br /&gt;
Plugins which have been removed from core and added to the plugins directory will initially be listed with Moodle HQ as maintainer while we seek new maintainers via the [[Plugins adoption programme]].&lt;br /&gt;
* Word censorship filter (filter_censor)&lt;br /&gt;
* Health center admin tool (tool_health)&lt;br /&gt;
* Jabber notification (message_jabber)&lt;br /&gt;
* Quiz results block (block_quiz_results)&lt;br /&gt;
* Box repository (repository_boxnet)&lt;br /&gt;
* Box portfolio (portfolio_boxnet)&lt;br /&gt;
Note the plugins can be added to the Plugins directory only once the target version 4.0 is registered there, which happens on beta release.&lt;br /&gt;
&lt;br /&gt;
==Plugins we are thinking about removing from core in the future and adding to the plugins directory==&lt;br /&gt;
We still need to decide which of the following plugins should be removed from core and added to the plugins directory. It will be done in MDL-73136 (epic). Please let us know your thoughts by posting in the discussion on moodle.org [https://moodle.org/mod/forum/discuss.php?d=426053 Moodle core plugins review]. We will collate all your feedback and review what to do with each plugin.&lt;br /&gt;
* Algebra notation filter (filter_algebra)&lt;br /&gt;
* Assignment 2.2 module (mod_assignment): MDL-72350&lt;br /&gt;
* Equella repository (repository_equella)&lt;br /&gt;
* Flickr block (block_tag_flickr): MDL-72614 &lt;br /&gt;
* Flickr portfolio (portfolio_flickr): MDL-72614  &lt;br /&gt;
* Flickr repository (repository_flickr): MDL-72614  &lt;br /&gt;
* Flickr public repository (repository_flickr_public): MDL-72614  &lt;br /&gt;
* HTML tidy filter (filter_tidy)&lt;br /&gt;
* Legacy course files repository (repository_coursefiles)&lt;br /&gt;
* Mahara ePortfolio (portfolio_mahara)&lt;br /&gt;
* Merlot.org repository (repository_merlot)&lt;br /&gt;
* Survey activity (mod_survey)&lt;br /&gt;
* URL downloader repository (repository_url)&lt;br /&gt;
== How will these plugins be removed from core? ==&lt;br /&gt;
* The plugin folder (for instance, question/format/webct/ for qformat_webct), will be completely removed from Moodle core. IMPORTANT: if you want to keep any of the plugins removed from core in your Moodle site, you will need to download and copy the plugin folder to the right place BEFORE running the upgrading process.&lt;br /&gt;
* Each plugin will be removed from the standard_plugins_list() method and added to the is_deleted_standard_plugin() method (both placed in lib/classes/plugin_manager.php).&lt;br /&gt;
[[File:jabber tobedeleted.png|center|thumb|The plugins will be marked as &amp;quot;To be deleted&amp;quot; if their code is not placed again in the Moodle folder.]]&lt;br /&gt;
* The upgrading steps will be added to lib/db/upgrade.php, to remove, when it applies, specific:&lt;br /&gt;
** DB tables (drop table statements).&lt;br /&gt;
** settings, using unset_all_config_for_plugin().&lt;br /&gt;
** capabilities, using capabilities_cleanup().&lt;br /&gt;
** ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The plugins data will be removed only if the plugins files are not present anymore in the code. So, if a site wants to keep any of the plugins removed from core, they should download and copy the plugin folder to the right place (as they use to do with third-party plugins) BEFORE running the upgrading process.&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_4.0_release_notes&amp;diff=63507</id>
		<title>Moodle 4.0 release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_4.0_release_notes&amp;diff=63507"/>
		<updated>2022-07-07T17:11:01Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: updating the requirements, no matter the page is blocked/migrated coz this is still visited lots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/releases/4.0}}&lt;br /&gt;
[[Releases]] &amp;gt; {{FULLPAGENAME}}&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Release date: 19 April 2022&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is [https://tracker.moodle.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=project+%3D+mdl+AND+resolution+%3D+fixed+AND+fixVersion+in+%28%224.0%22%29+ORDER+BY+priority+DESC&amp;amp;runQuery=true&amp;amp;clear=true the full list of fixed issues in 4.0].&lt;br /&gt;
&lt;br /&gt;
See our [https://docs.moodle.org/400/en/New_features New features] page in the user documentation for an introduction to Moodle 4.0 with screenshots.&lt;br /&gt;
{{MediaPlayer | url = https://www.youtube.com/watch?v=sZxZ_YzsD_w&amp;amp;list=PLxcO_MFWQBDcI0BezfCOW8QRfJw6FblRn&amp;amp;ab_channel=Moodle | desc = Moodle 4.0 new features}}&lt;br /&gt;
&lt;br /&gt;
If you are upgrading from a previous version, please see [[:en:Upgrading|Upgrading]] in the user docs.&lt;br /&gt;
==Server requirements==&lt;br /&gt;
These are just the minimum supported versions. We recommend keeping all of your software and operating systems up-to-date.&lt;br /&gt;
* Moodle upgrade: Moodle 3.6 or later&lt;br /&gt;
* PHP version: minimum PHP 7.3.0 &#039;&#039;Note: minimum PHP version has increased since Moodle 3.10&#039;&#039;. PHP 7.4.x and 8.0.x are supported too. See [[Moodle and PHP]] for details.&lt;br /&gt;
* PHP extension &#039;&#039;&#039;sodium&#039;&#039;&#039; is recommended. It will be required in Moodle 4.2. For further details, see [https://docs.moodle.org/311/en/Environment_-_PHP_extension_sodium Environment - PHP extension sodium].&lt;br /&gt;
* PHP extension &#039;&#039;&#039;exif&#039;&#039;&#039; is recommended.&lt;br /&gt;
* PHP setting &#039;&#039;&#039;max_input_vars&#039;&#039;&#039; is recommended to be &amp;gt;= 5000 for PHP 7.x installations. It&#039;s a requirement for PHP 8.x installations. For further details, see [https://docs.moodle.org/311/en/Environment_-_max_input_vars Environment - max input vars].&lt;br /&gt;
=== Database requirements ===&lt;br /&gt;
Moodle supports the following database servers. Again, version numbers are just the minimum supported version. We recommend running the latest stable version of any software.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Database&lt;br /&gt;
! Minimum version&lt;br /&gt;
! Recommended&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.postgresql.org/ PostgreSQL]&lt;br /&gt;
| 10 (increased since Moodle 3.11)  &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mysql.com/ MySQL]&lt;br /&gt;
| 5.7 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [https://mariadb.org/ MariaDB]&lt;br /&gt;
| 10.2.29 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microsoft.com/en-us/server-cloud/products/sql-server/ Microsoft SQL Server]&lt;br /&gt;
| 2017 (increased since Moodle 3.10)&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.oracle.com/us/products/database/overview/index.html Oracle Database]&lt;br /&gt;
| 11.2&lt;br /&gt;
| Latest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Client requirements==&lt;br /&gt;
=== Browser support ===&lt;br /&gt;
Moodle is compatible with any standards compliant web browser. We regularly test Moodle with the following browsers:&lt;br /&gt;
&lt;br /&gt;
Desktop:&lt;br /&gt;
* Chrome&lt;br /&gt;
* Firefox&lt;br /&gt;
* Safari&lt;br /&gt;
* Edge&lt;br /&gt;
&#039;&#039;Note: Moodle 4.0 does NOT support Internet Explorer 11.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Safari 7 and below has known compatibility issues with Moodle 4.0.&lt;br /&gt;
&lt;br /&gt;
Mobile:&lt;br /&gt;
* MobileSafari&lt;br /&gt;
* Google Chrome&lt;br /&gt;
For the best experience and optimum security, we recommend that you keep your browser up to date.&lt;br /&gt;
==Major UX improvements==&lt;br /&gt;
===Navigation improvements===&lt;br /&gt;
* MDL-70208 - Implement frontend functionality for primary navigation&lt;br /&gt;
* MDL-70207 - Implement backend functionality for primary navigation&lt;br /&gt;
* MDL-70202 - Implement frontend functionality for secondary navigation&lt;br /&gt;
* MDL-70198 - Implement backend functionality for secondary navigation&lt;br /&gt;
* MDL-70196 - Create a module based navigation bar&lt;br /&gt;
* MDL-72352 - Ensure that secondary navigation is backwards compatible&lt;br /&gt;
* MDL-73462 - Course and category management secondary and tertiary navigation&lt;br /&gt;
* MDL-71977 - Define the secondary navigation nodes that should be always displayed in the more menu in the module context&lt;br /&gt;
* MDL-71901 - Allow plugins to define their own secondary nav ordering&lt;br /&gt;
* MDL-70844 - Update the secondary navigation view to send site administration information in tab form&lt;br /&gt;
* MDL-72396 - Allow easy setting of the active tab for navigation views&lt;br /&gt;
* MDL-71912 - Implement tertiary navigation for plugins (also see MDL-71913, MDL-71914 and MDL-71914)&lt;br /&gt;
* MDL-73863 - Tertiary navigation in course completion&lt;br /&gt;
* MDL-72875 - Add tertiary navigation to the participants page&lt;br /&gt;
* MDL-72904 - Add tertiary navigation to the badges pages&lt;br /&gt;
* MDL-72873 - Add tertiary navigation to the gradebook&lt;br /&gt;
* MDL-72094 - Update the course reports page styling and functionality&lt;br /&gt;
* MDL-71083 - Move the user menu in the top bar into the primary navigation menu in the mobile view&lt;br /&gt;
* MDL-73393 - Ensure that existing third party themes still work with latest navigation changes&lt;br /&gt;
* MDL-71943 - Dynamic (AJAX) tabs in Moodle LMS&lt;br /&gt;
* MDL-72090 - Convert course admin pages from link farms to dropdowns&lt;br /&gt;
* MDL-72413 - Move the activity modules title, description, and activity completion into a standard module API&lt;br /&gt;
* MDL-72736 - Remove section navigation on one section per page&lt;br /&gt;
* MDL-72834 - Move the calendar link into the user menu&lt;br /&gt;
* MDL-72450 - Remove the next and previous activity links from all activity modules in Boost&lt;br /&gt;
* MDL-71148 - Combine both the custom menu &amp;amp; primary navigation renderers&lt;br /&gt;
* MDL-71683 - Update language menu to move from the top navigation into the user menu when logged in&lt;br /&gt;
* MDL-72005 - Update the context_header in Boost to move the breadcrumb to the top&lt;br /&gt;
===Course index===&lt;br /&gt;
* MDL-71209 - Create the new course index list&lt;br /&gt;
* MDL-72660 - Add activity completion indicators to the course index&lt;br /&gt;
* MDL-71228 - Implement drag and drop option for sections and activities in the course index&lt;br /&gt;
* MDL-71211 - Keep the status of the course index collapsed and expanded sections per user and course&lt;br /&gt;
* MDL-71795 - Course index on activity view page&lt;br /&gt;
* MDL-71828 - Implement section links&#039; behaviour in course index&lt;br /&gt;
* MDL-71664 - Enable drag &amp;amp; drop from course index to course content and vice versa&lt;br /&gt;
* MDL-72463 - Add &#039;highlighted&#039; label to course index&lt;br /&gt;
* MDL-71727 - Sync course index and course content when an element is dragged&lt;br /&gt;
* MDL-72897 - Mark the current section in the course index&lt;br /&gt;
* MDL-73340 - Open course index by default first time a user access the course&lt;br /&gt;
* MDL-73310 - Show the course index on all pages within a course&lt;br /&gt;
===Course experience===&lt;br /&gt;
* MDL-71037 - Sections are now collapsible for Topics and Weekly course formats&lt;br /&gt;
* MDL-71691 - Created a new activity UI component&lt;br /&gt;
* MDL-71689 - Improvements to add activity and add section design&lt;br /&gt;
* MDL-71663 - Created a new &amp;quot;move&amp;quot; option in the sections and activity cog menu in the course editor&lt;br /&gt;
* MDL-71779 - Made &#039;Add a new topic/week&#039; option client side on Topics and Weekly formats&lt;br /&gt;
* MDL-72311 - Proceed straight to course content when creating a new course&lt;br /&gt;
* MDL-71863 - Created core_courseformat subsystem&lt;br /&gt;
* MDL-72578 - Moved activity UI component to output classes and templates&lt;br /&gt;
* MDL-73343 - New quick access to create a new course from My courses page when there is no course available&lt;br /&gt;
===My Courses page and overview block===&lt;br /&gt;
* MDL-70801 - Implement &amp;quot;My courses&amp;quot; page&lt;br /&gt;
* MDL-58579 - Allow searching / filtering of courses in myoverview&lt;br /&gt;
* MDL-73231 - Provide option of having My courses as defaulthomepage&lt;br /&gt;
===Timeline block===&lt;br /&gt;
* MDL-72276 - Update timeline block dropdowns to display current selection&lt;br /&gt;
* MDL-72277 - Improve the layout and usability of the items in the timeline block&lt;br /&gt;
* MDL-73068 - Only display courses in the timeline block if they contain events&lt;br /&gt;
* MDL-72295 - Add text search to the timeline block&lt;br /&gt;
* MDL-72594 - Improve displaying of overdue items in the timeline block&lt;br /&gt;
* MDL-72603 - Replace timeline block pagination with &amp;quot;show more&amp;quot; lazy loading&lt;br /&gt;
* MDL-72543 - Change the display of the event names of the items on the timeline block&lt;br /&gt;
===Calendar usability===&lt;br /&gt;
* MDL-71817 - Render the calendar in the calendar block in month view&lt;br /&gt;
* MDL-72237 - Limit number of events shown per day in calendar month view&lt;br /&gt;
* MDL-71810 - Add a current date indicator and make calendar block responsive when switching between small and large views&lt;br /&gt;
* MDL-71808 - Move the import calendar form to its own page&lt;br /&gt;
* MDL-72045 - Improve help information provided on the calendar export page&lt;br /&gt;
* MDL-71790 - Revamp the manage subscriptions page&lt;br /&gt;
* MDL-71788 - Make it easier to copy the export URL&lt;br /&gt;
* MDL-71775 - Add footer links to the calendar block&lt;br /&gt;
* MDL-72810 - Remove 3-month calendar view&lt;br /&gt;
===Dashboard===&lt;br /&gt;
* MDL-72092 - Arrange blocks between My courses &amp;amp; My dashboard&lt;br /&gt;
* MDL-73114 - Display a title in the dashboard page&lt;br /&gt;
* MDL-71964 - Welcome message for users&lt;br /&gt;
* MDL-73233 - Provide option to disable the Dashboard&lt;br /&gt;
* MDL-72116 - Remove some of the default blocks from the Dashboard&lt;br /&gt;
===User tours===&lt;br /&gt;
* MDL-61674 - Allow user tours to be created using the Atto text editor&lt;br /&gt;
* MDL-72385 - Improve and simplify design of user tours&lt;br /&gt;
* MDL-71938 - Display number of steps in a user tour&lt;br /&gt;
* MDL-72783 - Add new user tours&lt;br /&gt;
* MDL-72781 - Remove previous user tours&lt;br /&gt;
* MDL-72557 - Implement customisable confirmation button for single step user tours&lt;br /&gt;
* MDL-71931 - Update user tours to emit events&lt;br /&gt;
===Other usability and user experience improvements===&lt;br /&gt;
* MDL-69371 - Redesign the Moodle login page (also see MDL-72928)&lt;br /&gt;
* MDL-71457 - Update the Moodle activity icons&lt;br /&gt;
* MDL-71963 - Turn confirmation page into modals&lt;br /&gt;
* MDL-71965 - New footer&lt;br /&gt;
* MDL-71456 - Create page drawers for the block and course index areas&lt;br /&gt;
* MDL-72095 - Set a main container width of Boost pages&lt;br /&gt;
* MDL-71610 - Move the turn editing on button into the navbar&lt;br /&gt;
* MDL-72305 - Show user initials as a placeholder for the user profile picture&lt;br /&gt;
* MDL-72278 - Fake blocks now in drawer are made visible on first visit&lt;br /&gt;
* MDL-72454 - Removal of back to top link&lt;br /&gt;
* MDL-72088 - Update styling across top level pages&lt;br /&gt;
* MDL-70888 - Update the layouts in Boost theme&lt;br /&gt;
* MDL-71292 - Update the page header and include course image / activity icon&lt;br /&gt;
* MDL-73608 - Provide a contact form which sends to the site support email and replace mailto link in footer&lt;br /&gt;
* MDL-73935 - Improved flexibility of site support form and consistency of site support info provided in Moodle&lt;br /&gt;
* MDL-61564 - Allow multiple cohort selection in cohort enrolment&lt;br /&gt;
* MDL-66539 - Better handling of link names and URLs with Atto&lt;br /&gt;
* MDL-73797 - Dialogues now have the action button on the right&lt;br /&gt;
* MDL-60917 - Add highest ranked results section to global search&lt;br /&gt;
* MDL-73917 - Notification preferences page improvements&lt;br /&gt;
* MDL-72500 - Easier to find a specific component in event list report&lt;br /&gt;
* MDL-32103 - Course completion is instant for activity based completion criteria (single user completions only)&lt;br /&gt;
==Other major features==&lt;br /&gt;
===Report builder integration (from Moodle Workplace)===&lt;br /&gt;
* MDL-70795 - Implement functionality for creating custom reports&lt;br /&gt;
* MDL-70794 - Implement functionality for creating system reports&lt;br /&gt;
* MDL-72588 - Implement custom report audiences&lt;br /&gt;
* MDL-72598 - Implement custom report schedules&lt;br /&gt;
* MDL-73598 - Allow Custom Reports to be disabled by site admin&lt;br /&gt;
* MDL-72280 - Create &amp;quot;Courses&amp;quot; custom report source&lt;br /&gt;
* MDL-73069 - Report condition to limit returned data to current user&lt;br /&gt;
* MDL-73180 - Improve definitions of previous/next relative date filters&lt;br /&gt;
* MDL-72662 - Implement relative date options in the Reportbuilder date filter&lt;br /&gt;
* MDL-72172 - Create &amp;quot;Cohort members&amp;quot; custom report source&lt;br /&gt;
* MDL-72962 - Format editable report elements (column, filters, etc)&lt;br /&gt;
* MDL-72826 - Custom report option to display unique row values&lt;br /&gt;
* MDL-71153 - Convert task logs report to a system report&lt;br /&gt;
* MDL-71070 - Convert configuration changes report to a system report&lt;br /&gt;
===BigBlueButton integration===&lt;br /&gt;
* MDL-70658 - Integrate the BigBlueButton plugin into Moodle LMS&lt;br /&gt;
===Quiz and Questions===&lt;br /&gt;
* MDL-71516 - Create new plugin type - Qbank (for the full list of qbank plugins added to core, see MDL-70329)&lt;br /&gt;
* MDL-71679 - Update mod_quiz for new question bank&lt;br /&gt;
* MDL-71636 - Add a columnsortorder settings page &lt;br /&gt;
* MDL-71696 - Add question versions&lt;br /&gt;
* MDL-72076 - Question bank bulk action UI&lt;br /&gt;
* MDL-72553 - Add custom fields to questions&lt;br /&gt;
* MDL-52206 - Move &amp;quot;Require passing grade&amp;quot; completion option to core&lt;br /&gt;
* MDL-52456 - Add notification message for students after questions have been manually graded&lt;br /&gt;
* MDL-71984 - Add logging to quiz auto-save, process_attempt and redo_question&lt;br /&gt;
* MDL-73337 - Log editing quizzes in detail&lt;br /&gt;
* MDL-73699 - Question status UI/UX update&lt;br /&gt;
* MDL-72448 - Add qbank_history to core&lt;br /&gt;
* MDL-71614 - Add qbank_previewquestion to core&lt;br /&gt;
===Update LTI tool provider feature to support 1.3===&lt;br /&gt;
* MDL-69543 - Update tool to support 1.3 OAuth2/OIDC launch flow&lt;br /&gt;
* MDL-71371 - Provide upgrade path for 1.1 preconfigured tools&lt;br /&gt;
* MDL-72745 - Provide account provisioning options for LTI Advantage launches&lt;br /&gt;
* MDL-69547 - Update tool enrolment code so that a user is automatically created and enrolled when launching via 1.3&lt;br /&gt;
* MDL-69545 - Update user sync task to support 1.3 messages&lt;br /&gt;
* MDL-69544 - Update grade sync task to support 1.3 messages&lt;br /&gt;
* MDL-72288 - Update library and model code to support issuer and clientid uniqueness on registrations&lt;br /&gt;
* MDL-69862 - Add dynamic registration support to the tool&lt;br /&gt;
* MDL-70354 - Return line item information during content selection&lt;br /&gt;
===Assignment===&lt;br /&gt;
* MDL-68913 - Per attempt timing now available in assignments&lt;br /&gt;
===Admin configuration presets===&lt;br /&gt;
* MDL-72112 - Integrate admin_presets third-party plugin in Moodle LMS&lt;br /&gt;
* MDL-73145 - Add a $CFG setting to define the preset to be installed&lt;br /&gt;
* MDL-72114 - Include pre-installed admin presets&lt;br /&gt;
* MDL-72113 - Add feature to import/export plugins visibility from Admin presets tool&lt;br /&gt;
* MDL-73394 - Store the latest site admin preset applied&lt;br /&gt;
===Content bank and H5P===&lt;br /&gt;
* MDL-68394 - Integrate mod_h5pactivity with recent activity plugins&lt;br /&gt;
* MDL-72099 - Add navigation by contexts in the content bank&lt;br /&gt;
* MDL-71885 - Inline editing H5P content for mod_h5pactivity&lt;br /&gt;
* MDL-71956 - Inline editing H5P content anywhere&lt;br /&gt;
===Badges===&lt;br /&gt;
* MDL-72141 - Simplifying the external badge page&lt;br /&gt;
===Accessibility improvements===&lt;br /&gt;
* MDL-67853 - Remove online-offline options on notifications&lt;br /&gt;
* MDL-72078 - Give users an indication that they encountered an editor&lt;br /&gt;
* MDL-71604 - Move the screen reader helper button to the first row&lt;br /&gt;
* MDL-72896 - Make html_tables responsive by default&lt;br /&gt;
==Other Highlights==&lt;br /&gt;
===Functional changes===&lt;br /&gt;
* MDL-70456 - Add custom user field support to all places that display user identity [0,Minor] Improvement  &lt;br /&gt;
* MDL-73342 - Disable some blocks by default (such as feedback, RSS and self-completion)&lt;br /&gt;
* MDL-70905 - Updated media default width/height to use 16:9&lt;br /&gt;
* MDL-72118 - Rename &amp;quot;HTML block&amp;quot; to the more easily understood &amp;quot;Text block&amp;quot; &lt;br /&gt;
* MDL-72706 - Change default value of &amp;quot;Hidden sections&amp;quot; course format setting&lt;br /&gt;
* MDL-72115 - Rename &amp;quot;Miscellaneous&amp;quot; category to &amp;quot;Category 1&amp;quot;&lt;br /&gt;
* MDL-72119 - Make “Enable xxxxx” features consistent (hide menus for disabled features)&lt;br /&gt;
===For administrators===&lt;br /&gt;
* MDL-71347 - Add a filter to &amp;quot;browse list of users&amp;quot; for date of user account creation&lt;br /&gt;
* MDL-72031 - Separate out max_time for audio and video files in Atto/RecordRTC&lt;br /&gt;
* MDL-71515 - Improve the test outgoing mail configuration admin page&lt;br /&gt;
* MDL-67686 - Add more filters to task log (/admin/tasklogs.php)&lt;br /&gt;
* MDL-72984 - Ensure support email address is mandatory&lt;br /&gt;
* MDL-73592 - MoodleNet integration now enabled by default&lt;br /&gt;
* MDL-71621 - Parent role cannot edit custom fields in child profile&lt;br /&gt;
* MDL-73918 - Allow admins to change the page width using custom SCSS&lt;br /&gt;
* MDL-71927 - Logs and question attempt history now show time to the second, to help investigate issues&lt;br /&gt;
* MDL-71466 - Custom user field support: Admin role screens (check permissions, assign)&lt;br /&gt;
* MDL-72619 - Provide admin page to view cache size estimates&lt;br /&gt;
* MDL-67822 - New check_database_schema performance check&lt;br /&gt;
* MDL-70271 - Dropbox token and Permission Updates&lt;br /&gt;
* MDL-58395 - LDAP auth sync now skip and report problematic user accounts&lt;br /&gt;
* MDL-72251 - Tasks admin UI now shows time to nearest second&lt;br /&gt;
===Mobile===&lt;br /&gt;
* MDL-67807 - Return concurrent sessions information to apply concurrent login limit in the mobile app&lt;br /&gt;
* MDL-69555 - Make duration of QR login and auto-login time between requests configurable&lt;br /&gt;
* MDL-73794 - Update the footer in the mobile view&lt;br /&gt;
===Performance===&lt;br /&gt;
* MDL-72596 - Caching: Track cache I/O size in perfdebug&lt;br /&gt;
* MDL-69088 - Make file cache store purges instant with a safe and async purge&lt;br /&gt;
* MDL-68164 - Additional caching of pg_field_type postgres field metadata&lt;br /&gt;
* MDL-63983 - Improve the performance of non-contact searches in messaging when site-wide messaging is disabled (default)&lt;br /&gt;
* MDL-71014 - Cache the siteidentifier and site contextid in local cache&lt;br /&gt;
* MDL-72328 - Add TTL support for Redis caches&lt;br /&gt;
* MDL-72837 - Cache API should support versioned data&lt;br /&gt;
==Security improvements==&lt;br /&gt;
* MDL-56873 - Set more secure defaults for the cURL allow/deny lists&lt;br /&gt;
* MDL-66776 - Send notifications when new devices are used to log in into the site&lt;br /&gt;
* MDL-71627 - Add check API for anti virus and optionally remove admin notifications&lt;br /&gt;
* MDL-71806 - Improved the UX of the Moodle security report&lt;br /&gt;
* MDL-71176 - New password and change forms should have autocomplete=&amp;quot;new-password&amp;quot;&lt;br /&gt;
==For developers==&lt;br /&gt;
* MDL-61460 - Introduce the UI components library&lt;br /&gt;
* MDL-74229 - Add navigation node keys to allow themers to hide navigation tabs&lt;br /&gt;
* MDL-74235 - Rename the icons for activities to allow support of multiple icons for multiple versions&lt;br /&gt;
* MDL-74033 - Allow full customisation of the primary navigation&lt;br /&gt;
* MDL-72779 - Set more than one value on a persistent at the same time&lt;br /&gt;
* MDL-70862 - Implement a new callback to extend gradebook plugininfo&lt;br /&gt;
* MDL-72289 - Allow callers to customise the rendered icon of inplace editable elements&lt;br /&gt;
* MDL-73347 - Allow themes to define un-addable blocks&lt;br /&gt;
* MDL-46778 - Allow use a separate DB configuration (not just prefix) for Behat similar to PHPUnit&lt;br /&gt;
* MDL-73270 - Warn where XMLRPC is currently in use&lt;br /&gt;
* MDL-67228 - Tool_replace maturity set&lt;br /&gt;
===Web service additions and updates===&lt;br /&gt;
* MDL-71135 - Create core_course_get_state web service&lt;br /&gt;
* MDL-71165 - Create core_course_update_course web service&lt;br /&gt;
===Core plugins removed===&lt;br /&gt;
* MDL-71473 - Jabber removed as a standard notification plugin&lt;br /&gt;
* MDL-58939 - Picasa repository and portfolio removed from core&lt;br /&gt;
* MDL-72335 - Tool_health removed from core&lt;br /&gt;
* MDL-72615 - Boxnet plugins removed from core&lt;br /&gt;
* MDL-72616 - Quiz results block removed from core&lt;br /&gt;
* MDL-72348 - Microsoft OneDrive (legacy) repository (repository_skydrive) removed from core&lt;br /&gt;
* MDL-72347 - Word censorship filter (filter_censor) removed from core&lt;br /&gt;
* MDL-72407 - VideoJS Flash plugin removed from core&lt;br /&gt;
* MDL-72042 - Flash animation media player removed from core&lt;br /&gt;
* MDL-72041 - WebCT question import format removed from core&lt;br /&gt;
* MDL-72517 - Examview question import format removed from core&lt;br /&gt;
===Deprecations===&lt;br /&gt;
* MDL-53544 - Typo3 library removed&lt;br /&gt;
* MDL-72004 - Quiz 4.0 Class renaming and deprecation&lt;br /&gt;
* MDL-73756 - Deprecate $modinfo param to completion_info::get_data()&lt;br /&gt;
* MDL-65799 - Phase 2 of deprecation of functions in lib/deprecatedlib.php initially deprecated in 3.8&lt;br /&gt;
* MDL-71175 - Deprecate some plagiarism functions that are not used, or have replacements&lt;br /&gt;
* MDL-66266 - Remove deprecated functions in messages/classes/api.php&lt;br /&gt;
* MDL-72098 - deprecate grade_grade::insert method that just calls its parent&lt;br /&gt;
* MDL-72433 - Final deprecation of get_grades() in lib/classes/grades_external.php&lt;br /&gt;
* MDL-71476 - Remove mysql_engine.php&lt;br /&gt;
* MDL-65252 - Final deprecations of forum_count_replies and get_forum_discussion_posts&lt;br /&gt;
* MDL-67412 - Remove deprecated functions in lib/setuplib.php &lt;br /&gt;
* MDL-65801 - Remove strings deprecated in 3.8&lt;br /&gt;
===Component API updates===&lt;br /&gt;
* admin/tool/generator/upgrade.txt&lt;br /&gt;
* admin/tool/log/upgrade.txt&lt;br /&gt;
* admin/tool/mobile/upgrade.txt&lt;br /&gt;
* admin/tool/upgrade.txt&lt;br /&gt;
* admin/tool/usertours/upgrade.txt&lt;br /&gt;
* admin/upgrade.txt&lt;br /&gt;
* analytics/upgrade.txt&lt;br /&gt;
* auth/shibboleth/upgrade.txt&lt;br /&gt;
* availability/upgrade.txt&lt;br /&gt;
* backup/upgrade.txt&lt;br /&gt;
* badges/upgrade.txt&lt;br /&gt;
* blocks/section_links/upgrade.txt&lt;br /&gt;
* blocks/tag_youtube/upgrade.txt&lt;br /&gt;
* blocks/timeline/upgrade.txt&lt;br /&gt;
* blocks/upgrade.txt&lt;br /&gt;
* cache/upgrade.txt&lt;br /&gt;
* calendar/upgrade.txt&lt;br /&gt;
* completion/upgrade.txt&lt;br /&gt;
* contentbank/upgrade.txt&lt;br /&gt;
* course/format/upgrade.txt&lt;br /&gt;
* course/upgrade.txt&lt;br /&gt;
* customfield/upgrade.txt&lt;br /&gt;
* dataformat/upgrade.txt&lt;br /&gt;
* enrol/database/upgrade.txt&lt;br /&gt;
* enrol/upgrade.txt&lt;br /&gt;
* filter/upgrade.txt&lt;br /&gt;
* grade/grading/form/upgrade.txt&lt;br /&gt;
* grade/upgrade.txt&lt;br /&gt;
* group/upgrade.txt&lt;br /&gt;
* h5p/upgrade.txt&lt;br /&gt;
* lib/upgrade.txt&lt;br /&gt;
* media/upgrade.txt&lt;br /&gt;
* message/upgrade.txt&lt;br /&gt;
* mod/assign/upgrade.txt&lt;br /&gt;
* mod/book/upgrade.txt&lt;br /&gt;
* mod/feedback/upgrade.txt&lt;br /&gt;
* mod/forum/upgrade.txt&lt;br /&gt;
* mod/glossary/upgrade.txt&lt;br /&gt;
* mod/h5pactivity/upgrade.txt&lt;br /&gt;
* mod/lesson/upgrade.txt&lt;br /&gt;
* mod/lti/upgrade.txt&lt;br /&gt;
* mod/page/upgrade.txt&lt;br /&gt;
* mod/quiz/upgrade.txt&lt;br /&gt;
* mod/resource/upgrade.txt&lt;br /&gt;
* mod/scorm/upgrade.txt&lt;br /&gt;
* mod/upgrade.txt&lt;br /&gt;
* mod/url/upgrade.txt&lt;br /&gt;
* mod/wiki/upgrade.txt&lt;br /&gt;
* mod/workshop/upgrade.txt&lt;br /&gt;
* my/upgrade.txt&lt;br /&gt;
* payment/upgrade.txt&lt;br /&gt;
* plagiarism/upgrade.txt&lt;br /&gt;
* portfolio/upgrade.txt&lt;br /&gt;
* question/bank/upgrade.txt&lt;br /&gt;
* question/behaviour/upgrade.txt&lt;br /&gt;
* question/engine/upgrade.txt&lt;br /&gt;
* question/format/upgrade.txt&lt;br /&gt;
* question/type/multichoice/upgrade.txt&lt;br /&gt;
* question/type/upgrade.txt&lt;br /&gt;
* question/upgrade.txt&lt;br /&gt;
* report/eventlist/upgrade.txt&lt;br /&gt;
* report/upgrade.txt&lt;br /&gt;
* repository/upgrade.txt&lt;br /&gt;
* search/upgrade.txt&lt;br /&gt;
* theme/upgrade.txt&lt;br /&gt;
* user/upgrade.txt&lt;br /&gt;
* webservice/upgrade.txt&lt;br /&gt;
 &lt;br /&gt;
==See also==&lt;br /&gt;
*[[Moodle 3.11 release notes]]&lt;br /&gt;
 &lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Moodle 4.0]]&lt;br /&gt;
 &lt;br /&gt;
[[fr:Notes de version de Moodle 4.0]]&lt;br /&gt;
[[es:Notas de Moodle 4.0]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_3.11_release_notes&amp;diff=63506</id>
		<title>Moodle 3.11 release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_3.11_release_notes&amp;diff=63506"/>
		<updated>2022-07-07T17:10:00Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: updating the requirements, no matter the page is blocked/migrated coz this is still visited lots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/general/releases/3.11}}&lt;br /&gt;
[[Releases]] &amp;gt; {{FULLPAGENAME}}&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Release date: 17 May 2021&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is [https://tracker.moodle.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=project+%3D+mdl+AND+resolution+%3D+fixed+AND+fixVersion+in+%28%223.11%22%29+ORDER+BY+priority+DESC&amp;amp;runQuery=true&amp;amp;clear=true the full list of fixed issues in 3.11].&lt;br /&gt;
&lt;br /&gt;
See our [https://docs.moodle.org/311/en/New_features New features page] in the user documentation for an introduction to Moodle 3.11 with screenshots.&lt;br /&gt;
&lt;br /&gt;
If you are upgrading from a previous version, please see [[:en:Upgrading|Upgrading]] in the user docs.&lt;br /&gt;
==Server requirements==&lt;br /&gt;
These are just the minimum supported versions. We recommend keeping all of your software and operating systems up-to-date.&lt;br /&gt;
* Moodle upgrade: Moodle 3.6 or later&lt;br /&gt;
* PHP version: minimum PHP 7.3.0 &#039;&#039;Note: minimum PHP version has increased since Moodle 3.10&#039;&#039;. PHP 7.4.x and 8.0.x are supported too. See [[Moodle and PHP]] for details.&lt;br /&gt;
* PHP extension &#039;&#039;&#039;sodium&#039;&#039;&#039; is recommended. It will be required in Moodle 4.2. For further details, see [https://docs.moodle.org/311/en/Environment_-_PHP_extension_sodium Environment - PHP extension sodium].&lt;br /&gt;
* PHP setting &#039;&#039;&#039;max_input_vars&#039;&#039;&#039; is recommended to be &amp;gt;= 5000 for PHP 7.x installations. It&#039;s a requirement for PHP 8.x installations. For further details, see [https://docs.moodle.org/311/en/Environment_-_max_input_vars Environment - max input vars].&lt;br /&gt;
=== Database requirements ===&lt;br /&gt;
Moodle supports the following database servers. Again, version numbers are just the minimum supported version. We recommend running the latest stable version of any software.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Database&lt;br /&gt;
! Minimum version&lt;br /&gt;
! Recommended&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.postgresql.org/ PostgreSQL]&lt;br /&gt;
| 9.6  &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mysql.com/ MySQL]&lt;br /&gt;
| 5.7 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [https://mariadb.org/ MariaDB]&lt;br /&gt;
| 10.2.29 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microsoft.com/en-us/server-cloud/products/sql-server/ Microsoft SQL Server]&lt;br /&gt;
| 2017 (increased since Moodle 3.10)&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.oracle.com/us/products/database/overview/index.html Oracle Database]&lt;br /&gt;
| 11.2&lt;br /&gt;
| Latest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Client requirements==&lt;br /&gt;
=== Browser support ===&lt;br /&gt;
Moodle is compatible with any standards compliant web browser. We regularly test Moodle with the following browsers:&lt;br /&gt;
&lt;br /&gt;
Desktop:&lt;br /&gt;
* Chrome&lt;br /&gt;
* Firefox&lt;br /&gt;
* Safari&lt;br /&gt;
* Edge&lt;br /&gt;
&#039;&#039;Note: Moodle 3.10 and above do NOT support Internet Explorer 11.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Safari 7 and below has known compatibility issues with Moodle 3.10 and above.&lt;br /&gt;
&lt;br /&gt;
Mobile:&lt;br /&gt;
* MobileSafari&lt;br /&gt;
* Google Chrome&lt;br /&gt;
For the best experience and optimum security, we recommend that you keep your browser up to date. https://www.whatsmybrowser.org/&lt;br /&gt;
==Warnings==&lt;br /&gt;
* If you have a site running on MariaDB / MySQL with many users, you may experience database issues after the upgrade step 2021042100. The upgrade attempts to drop several columns from the user table (&amp;quot;icq&amp;quot;, &amp;quot;skype&amp;quot; and others) once they were converted to new user profile fields (MDL-28452). These ALTER TABLE queries typically require copying all the rows into a new tablespace and rebuilding all indexes. Which may eventually lead to time-outs and &#039;&#039;&amp;quot;MySQL server has gone away&amp;quot;&#039;&#039; errors. It should be enough and safe to simply wait for the query to finish on the DB server (you may need to monitor currently running queries there) and then re-run the upgrade until the upgrade step 2021042100.01 finishes successfully.&lt;br /&gt;
==Major features==&lt;br /&gt;
===Improve student activity completion===&lt;br /&gt;
* MDL-71189 - Define sort ordering for completion conditions&lt;br /&gt;
* MDL-70821 - Update the course homepage to display the activity information&lt;br /&gt;
* MDL-70818 - Implement the activity dates functionality for each activity and output them in view.php&lt;br /&gt;
* MDL-70815 - Create a base class for fetching a user&#039;s activity completion details&lt;br /&gt;
* MDL-70816 - Create a base class for fetching an activity&#039;s dates that are relevant for a given user&lt;br /&gt;
* MDL-70820 - Implement the completion details functionality for each activity plugins output them in view.php - Part 1&lt;br /&gt;
* MDL-70935 - Implement the completion details functionality for each activity plugins output them in view.php - Part 2&lt;br /&gt;
* MDL-71235 - Review and update existing web services to return the new fields and exported information from activities&lt;br /&gt;
* MDL-71288 - Activity completion fallback for third party plugins&lt;br /&gt;
* MDL-71163 - Remove duplicate activity dates&lt;br /&gt;
* MDL-71144 - Deprecate the *_get_completion_state() callbacks&lt;br /&gt;
* MDL-71234 - Create user tours for the activity information output component&lt;br /&gt;
===Brickfield accessibility toolkit===&lt;br /&gt;
* MDL-69863 - Brickfield Education Labs accessibility toolkit core integration&lt;br /&gt;
===Badges===&lt;br /&gt;
* MDL-71117 - Make Moodle OBv2.1 implementation compliant &lt;br /&gt;
* MDL-70689 - Add new &amp;quot;IMS OBv2.1&amp;quot; OAuth 2 service&lt;br /&gt;
* MDL-70911 - Remove &amp;quot;Backpack settings&amp;quot; site administration page and improve UI&lt;br /&gt;
* MDL-63961 - Improve resolution of badge image sent to external backpacks and used when duplicating badges&lt;br /&gt;
===Content bank and H5P===&lt;br /&gt;
* MDL-69331 - Add ability to disable specified H5P content types&lt;br /&gt;
* MDL-66769 - Create a task to clean up unused H5P content&lt;br /&gt;
* MDL-70429 - Set the default returntype to reference in repository_contentbank&lt;br /&gt;
* MDL-67999 - Update content bank upload button to open file picker in a popup instead of new page&lt;br /&gt;
* MDL-69762 - Option to make a content bank item unlisted&lt;br /&gt;
* MDL-70408 - Open H5P file from H5P activity when it was added as a reference&lt;br /&gt;
* MDL-70438 - Content bank should provide info on the number of places where content is used and warn you when deleting&lt;br /&gt;
===Assignment===&lt;br /&gt;
* MDL-52420 - Assignment comments should be also saved when clicking &#039;save changes&#039; in the assignment grader page&lt;br /&gt;
* MDL-68533 - Allow mod_assign download all assignments to be streamed&lt;br /&gt;
* MDL-67702 - Assignment name filter preference should only affect current assignment&#039;s view&lt;br /&gt;
* MDL-70038 - Implement Poppler pdftoppm compatibility for faster assignment submission PDF to PNG conversion&lt;br /&gt;
* MDL-69631 - Add &#039;Draft&#039; filter to assignment grading table&lt;br /&gt;
===Quiz and questions===&lt;br /&gt;
* MDL-32226 - Add Plagiarism support to essay questions&lt;br /&gt;
* MDL-70895 - Questions: Default options when creating a question&lt;br /&gt;
* MDL-71262 - Add default options for essay question type&lt;br /&gt;
* MDL-71225 - Add default options for ddimageortext, ddmarker and match question types&lt;br /&gt;
* MDL-71181 - Display pass grade on quiz front page&lt;br /&gt;
* MDL-68597 - Add optional min/max word count limits to Essay question type&lt;br /&gt;
* MDL-69735 - Read-only view of quiz settings overrides&lt;br /&gt;
* MDL-70134 - Improve manual grading of quiz essay answers - web page format&lt;br /&gt;
* MDL-66600 - Manual grading of automatically graded questions: show computer grading&lt;br /&gt;
* MDL-71205 - Add default options for numerical question type using user-preferences&lt;br /&gt;
* MDL-70562 - In a newly created quiz, prevent &amp;quot;Edit quiz&amp;quot; and &amp;quot;Back to the course&amp;quot; buttons sticking together&lt;br /&gt;
* MDL-70266 - Quiz override screens should show user identity fields&lt;br /&gt;
* MDL-71030 - Quiz review: name the person who made each change in the question response history (if not the student)&lt;br /&gt;
===Accessibility improvements===&lt;br /&gt;
* MDL-69474 - Improve accessibility of profile images&lt;br /&gt;
* MDL-71089 - Make it possible to style toast notifications&lt;br /&gt;
===Usability improvements===&lt;br /&gt;
* MDL-70817 - Create an output component that displays an activity&#039;s information for a user&lt;br /&gt;
* MDL-48594 - More filtering options on Activity Completion Report&lt;br /&gt;
* MDL-65856 - UX Review of session expired timeout modal&lt;br /&gt;
* MDL-65135 - Add year to messaging conversation date headings, if not the current year&lt;br /&gt;
* MDL-51287 - Show confirmation when profile changes are saved&lt;br /&gt;
* MDL-70565 - Add ability to search country field on Participants page&lt;br /&gt;
* MDL-69145 - Default the participants page filtering to &amp;quot;ALL&amp;quot;&lt;br /&gt;
* MDL-57831 - Improve notification preferences on/off buttons so they fit better with non-English strings&lt;br /&gt;
* MDL-71254 - OAuth2: Display login errors on the login page&lt;br /&gt;
* MDL-67028 - LTI: Support Course dates substitution parameters&lt;br /&gt;
* MDL-70753 - Create landing page for the reports link in the secondary navigation&lt;br /&gt;
* MDL-71403 - Update message preferences of a user as admin to use consistent toggle icons&lt;br /&gt;
* MDL-71064 - Add support for keyboard hotkeys in VideoJS&lt;br /&gt;
* MDL-69878 - Always show the close button on the message drawer&lt;br /&gt;
==Other highlights==&lt;br /&gt;
===Functional changes===&lt;br /&gt;
* MDL-28452 - Convert user profile fields for messaging/networking into custom profile fields&lt;br /&gt;
* MDL-58673 - Enable playbackrates for videojs&lt;br /&gt;
* MDL-45242 - Allow user profile fields to be specified as user identity fields - New code is backwards-compatible, but report code should be updated.&lt;br /&gt;
* MDL-66431 - Remove &amp;quot;Enable activity chooser&amp;quot; user preference&lt;br /&gt;
* MDL-61768 - Update Google Drive repository to allow Shared drive files&lt;br /&gt;
* MDL-63381 - Option to not include permissions overrides when importing or restoring a backup&lt;br /&gt;
* MDL-71190 - Backup and Restore lastaccess to course&lt;br /&gt;
* MDL-48269 - Remove option to hide a group picture&lt;br /&gt;
* MDL-71118 - Differentiate between grade as a noun and grade as a verb in the UI texts&lt;br /&gt;
* MDL-71186 - Add custom user field support to group management screens&lt;br /&gt;
* MDL-69773 - Add an option to display section names in Section link block&lt;br /&gt;
===For administrators===&lt;br /&gt;
* MDL-70722 - Move Microsoft, Facebook and NextCloud OAuth2 services to new, reorganised architecture&lt;br /&gt;
* MDL-42382 - Add a &amp;quot;Replace filter&amp;quot; option on the admin browse users page&lt;br /&gt;
* MDL-65843 - Ability to force cron scheduled task definitions in config.php (schedule and disabled)&lt;br /&gt;
* MDL-70536 - Create a CLI script to reset user dashboards&lt;br /&gt;
* MDL-67748 - Improve the web services tokens management to allow searching and filtering &lt;br /&gt;
* MDL-69460 - Check for removed files before CLI upgrade&lt;br /&gt;
* MDL-70828 - Add ability to switch off session lock debugging&lt;br /&gt;
* MDL-70583 - Implement a renderer for progress_bar in cli output&lt;br /&gt;
* MDL-68010 - Allow disabled tasks to be run from the GUI&lt;br /&gt;
* MDL-71017 - Add the ability to configure OAuth2 services for login only; add login display name&lt;br /&gt;
* MDL-70269 - Update the ClamAV default behaviour when an error occurs&lt;br /&gt;
* MDL-70500 - Use Dynamic Registration to allow Tools to update to LTI Advantage&lt;br /&gt;
* MDL-70287 - Payment service consumers should be able to specify url after payment&lt;br /&gt;
* MDL-70158 - Make it easier to find a specific component in template library&lt;br /&gt;
* MDL-70632 - Allow searching of available language packs&lt;br /&gt;
* MDL-70362 - Add showdebugging and showsql options to admin/cli/uninstall_plugins.php&lt;br /&gt;
* MDL-69898 - Config change event should link to config change report&lt;br /&gt;
* MDL-70159 - Sort capabilities in capability overview tool&lt;br /&gt;
===Mobile===&lt;br /&gt;
* MDL-71273 - Add a new option in Moodle app &amp;quot;Disabled features&amp;quot; for preventing the new LTI launch in the app&lt;br /&gt;
* MDL-65983 - Include option for testing Push notifications in a site&lt;br /&gt;
===Performance===&lt;br /&gt;
* MDL-68481 - mod/folder/download_folder.php should be a streaming zip download&lt;br /&gt;
* MDL-70444 - Make my_reset_page_for_all_users for dashboards more robust&lt;br /&gt;
* MDL-68052 - Implement cleanup of analytics_indicator_calc stores table&lt;br /&gt;
* MDL-71044 - Extend the &#039;backup_cleanup_task&#039; scheduled task to remove old files&lt;br /&gt;
* MDL-66667 - Cache course image in the course_summary_exporter&lt;br /&gt;
* MDL-69121 - Allow redis session store to use zip or zStd for compression like redis MUC&lt;br /&gt;
* MDL-70107 - Running a scheduled task in the GUI should unlock the session&lt;br /&gt;
* MDL-27193 - Eliminate DB queries in mod/glossary/settings.php &lt;br /&gt;
* MDL-70608 - Update language pack installs / updates to run asynchronously to avoid timeouts when multiple are used&lt;br /&gt;
==Security improvements==&lt;br /&gt;
* MDL-65818 - Provide admin setting type for secure data (passwords/tokens)&lt;br /&gt;
* MDL-64865 - Add logging when auth config is automatically changed due to config/filesystem mismatch&lt;br /&gt;
* MDL-69333 - Reduce ability to fingerprint a server with a htaccess-dist / nginx file / docs&lt;br /&gt;
* MDL-69522 - Allow antivirus scanners to specify the message to the user&lt;br /&gt;
* MDL-67882 - Log changes to the message notifications settings&lt;br /&gt;
* MDL-70649 - Allow plugins to augment the cURL security helper via callback&lt;br /&gt;
* MDL-70735 - Reduce information disclosure from TCPDF version&lt;br /&gt;
* MDL-70766 - Log changes to auth plugin settings in config log&lt;br /&gt;
* MDL-70439 - Display user email address visibility settings on their own profile&lt;br /&gt;
==For developers==&lt;br /&gt;
The PHPUnit upgrade will almost certainly break your tests. See [[Writing PHPUnit tests#Upgrading unit tests to work with Moodle 3.11 and up .28PHPUnit 9.5.29]]&lt;br /&gt;
* MDL-52817 - New sql_group_concat db method&lt;br /&gt;
* MDL-64554 - Add module for displaying moodleform in a modal window&lt;br /&gt;
* MDL-71036 - Upgrade PHPUnit to 9.5.x&lt;br /&gt;
* MDL-68608 - Improve the readonly session debugging message&lt;br /&gt;
* MDL-71012 - HTTP 503 Service Not Available is returned by exceptions and should be 500 instead&lt;br /&gt;
* MDL-70311 - Upgrade boost to use Bootstrap latest version&lt;br /&gt;
* MDL-69202 - Restore backup: add getter method for oldmoduleid&lt;br /&gt;
* MDL-70055 - Support large number of SQL-IN parameters in Postgres&lt;br /&gt;
* MDL-70142 - Preserve form data when purging individual caches&lt;br /&gt;
* MDL-71099 - Move user_fields from core to core_user&lt;br /&gt;
===Web service additions and updates===&lt;br /&gt;
* MDL-69869 - Add ability for &amp;quot;get enrolled users&amp;quot; web service to be filtered by suspended users&lt;br /&gt;
* MDL-70128 - Create a new endpoint (script) to retrieve draft files from web services&lt;br /&gt;
* MDL-68853 - Create web service to trigger report_viewed event for H5P activities&lt;br /&gt;
* MDL-69259 - Create H5P activity web service to get the list of students that attempted an activity&lt;br /&gt;
* MDL-70387 - New web service core_files_get_unused_draft_itemid&lt;br /&gt;
* MDL-71492 - Return quiz pass grade via web services&lt;br /&gt;
* MDL-70037 - Update mod_forum_get_discussion_posts web service to return the last_modified attribute&lt;br /&gt;
* MDL-71031 - Batch create API for grade categories&lt;br /&gt;
* MDL-71169 - All new external functions implementation classes should use &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; as the method name, in which case the &amp;lt;tt&amp;gt;methodname&amp;lt;/tt&amp;gt; property should not be specified in db/services.php file&lt;br /&gt;
===Deprecations===&lt;br /&gt;
* MDL-69792 - Deprecate unused backpack js functions&lt;br /&gt;
* MDL-66138 - Deprecate get_forum_discussions_paginated webservice&lt;br /&gt;
* MDL-65319 - Phase 2 of deprecation of functions in lib/deprecatedlib.php initially deprecated in 3.7&lt;br /&gt;
* MDL-65284 - Final deprecation for analytics methods deprecated in MDL-64783&lt;br /&gt;
* MDL-65215 - Final deprecation of i_dock_block()&lt;br /&gt;
* MDL-65186 - Final deprecation of \core_analytics\manager::add_builtin_models()&lt;br /&gt;
* MDL-65086 - get_enabled_time_splitting_methods final deprecation&lt;br /&gt;
* MDL-64982 - Final deprecation of behat_base::TIMEOUT and related constants&lt;br /&gt;
* MDL-64866 - Remove message/defaultoutputs.php and final deprecation of admin_page_manageqbehaviours class&lt;br /&gt;
* MDL-64776 - Final deprecation of booktool_print_get_toc()&lt;br /&gt;
* MDL-63266 - Final deprecation of enrol/database/cli/sync.php&lt;br /&gt;
===Component API updates===&lt;br /&gt;
* admin/upgrade.txt&lt;br /&gt;
* analytics/upgrade.txt&lt;br /&gt;
* auth/shibboleth/upgrade.txt&lt;br /&gt;
* backup/upgrade.txt&lt;br /&gt;
* badges/upgrade.txt&lt;br /&gt;
* blocks/section_links/upgrade.txt&lt;br /&gt;
* blocks/tag_youtube/upgrade.txt&lt;br /&gt;
* completion/upgrade.txt&lt;br /&gt;
* contentbank/upgrade.txt&lt;br /&gt;
* course/upgrade.txt&lt;br /&gt;
* customfield/upgrade.txt&lt;br /&gt;
* enrol/database/upgrade.txt&lt;br /&gt;
* enrol/upgrade.txt&lt;br /&gt;
* group/upgrade.txt&lt;br /&gt;
* h5p/upgrade.txt&lt;br /&gt;
* lib/upgrade.txt&lt;br /&gt;
* mod/book/upgrade.txt&lt;br /&gt;
* mod/feedback/upgrade.txt&lt;br /&gt;
* mod/forum/upgrade.txt&lt;br /&gt;
* mod/h5pactivity/upgrade.txt&lt;br /&gt;
* mod/quiz/upgrade.txt&lt;br /&gt;
* payment/upgrade.txt&lt;br /&gt;
* plagiarism/upgrade.txt&lt;br /&gt;
* question/type/upgrade.txt&lt;br /&gt;
* report/upgrade.txt&lt;br /&gt;
* repository/upgrade.txt&lt;br /&gt;
* theme/upgrade.txt&lt;br /&gt;
* user/upgrade.txt&lt;br /&gt;
* webservice/upgrade.txt&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Moodle 3.10 release notes]]&lt;br /&gt;
 &lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Moodle 3.11]]&lt;br /&gt;
 &lt;br /&gt;
[[fr:Notes de mise à jour de Moodle 3.11]]&lt;br /&gt;
[[es:Notas de Moodle 3.11]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_and_PHP&amp;diff=63505</id>
		<title>Moodle and PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_and_PHP&amp;diff=63505"/>
		<updated>2022-07-07T11:04:12Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: php80 supported since 3.11.8, 4.0.2 and up. And php74 min version for 4.1 and up.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;New PHP versions are [https://www.php.net/supported-versions.php released every year] and come with important improvements and changes compared with previous versions. Moodle tries to support them as soon as possible, always matching them with our own [https://docs.moodle.org/dev/Releases#Version_support scheduled release plans].&lt;br /&gt;
&lt;br /&gt;
This page contains the current status of support for every PHP version and Moodle versions. For details, follow also the epic links below that combine all the changes that were made in Moodle to ensure PHP compatibility. &#039;&#039;(Note: you must be logged in to tracker to see issues in Epics)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MDL-50565 - &#039;&#039;&#039;PHP 7.0 can be used with Moodle 3.0.1, Moodle 3.1 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.4. See [[Moodle and PHP 7.0 details]] for details.&lt;br /&gt;
&lt;br /&gt;
MDL-55120 - &#039;&#039;&#039;PHP 7.1 can be used with Moodle 3.2 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.7.&lt;br /&gt;
&lt;br /&gt;
MDL-60279 - &#039;&#039;&#039;PHP 7.2 can be used with Moodle 3.4 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.9.&lt;br /&gt;
&lt;br /&gt;
MDL-63420 - &#039;&#039;&#039;PHP 7.3 can be used with Moodle 3.6.4, Moodle 3.7 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.11.&lt;br /&gt;
&lt;br /&gt;
MDL-66260 - &#039;&#039;&#039;PHP 7.4 can be used with Moodle 3.8.3, Moodle 3.9 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 4.1.&lt;br /&gt;
&lt;br /&gt;
MDL-70745 - &#039;&#039;&#039;PHP 8.0 can be used with Moodle 3.11.8, Moodle 4.0.2 and later releases.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MDL-73016 - &#039;&#039;&#039;PHP 8.1 support is being implemented for Moodle 4.1 and later releases. Hence it&#039;s still incomplete and only for development purposes&#039;&#039;&#039;&lt;br /&gt;
[[fr:Moodle et PHP]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63357</id>
		<title>Github actions integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63357"/>
		<updated>2022-06-21T15:09:54Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: just-just out&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Moodle core ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Moodle is regularly tested against a matrix of Databases, PHP Versions, and operating systems, however many developers do not have the resources available to run on many of these combinations before pushing an issue for integration as they are time-consuming to both set up and to run.&lt;br /&gt;
&lt;br /&gt;
There are many Continuous Integration tools available to developers, and [https://github.com/features/actions GitHub Actions] (usually named simply &amp;quot;GHA&amp;quot;) is just one of those available to the Open Source community.&lt;br /&gt;
&lt;br /&gt;
Since November 2020 (Moodle 3.5.16 and up), Moodle includes a GitHub Actions configuration file in its repository. This configuration file configures and controls a GitHub build across a matrix of testing environments. This allows developers pushing patches to Moodle to have their code unit tested before it reaches integration. The hope is that the availability of this integration should reduce the number of unit test failures seen during Integration.&lt;br /&gt;
&lt;br /&gt;
Note: Moodle HQ uses the Jenkins CI platform and this should be seen as the [https://ci.moodle.org/ canonical CI server for Moodle]. The GitHub Actions integration aims is to provide early warning to developers of any issues with their code.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
GitHub Actions are available and enabled by default for all public repositories @ GitHub. You can enable or disable them going to your moodle.git clone page, then settings tab -&amp;gt; actions . Please use the &amp;quot;Allow all&amp;quot; option as far as the integration reuses actions from different sources.&lt;br /&gt;
&lt;br /&gt;
[[File:enable_disable_github_actions.png|Enabling and disabling GitHub Actions for your repos]]&lt;br /&gt;
&lt;br /&gt;
For the purpose of this documentation, it is assumed that you are pushing to a public Moodle repository on GitHub. Other integrations are supported, but the service available from GitHub Actions is only available to github public repositories.&lt;br /&gt;
&lt;br /&gt;
=== How do I start a build? ===&lt;br /&gt;
&lt;br /&gt;
Whenever you push a change to any branch in your repository... a build will be queued and executed. You can see how all your builds are progressing by visiting your moodle.git clone page at GitHub, then selecting the actions tab. From there you can filter by branch, by status, access to every build, see failures, relaunch jobs...&lt;br /&gt;
&lt;br /&gt;
[[File:actions_dashboard.png|GitHub Actions &amp;quot;dashboard&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
You will receive notifications (by email or web) whenever a build finish (can be configured from your account notification settings). Also, if your branches match the branch names in any issue in the Tracker, you will get there the corresponding pass/fail badges [[File:github_passing.png|GitHub passing badge]]. Clicking on them you will access straight to the job details @ GitHub.&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all, pretty nice, simple and effective.&lt;br /&gt;
&lt;br /&gt;
=== How do I configure the PHPUnit executions ===&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.11.8 and 4.0.2, it&#039;s possible to configure the PHPUnit executions by creating a [https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository GitHub repository secret] named &amp;lt;code&amp;gt;phpunit_options&amp;lt;/code&amp;gt;. Just setup its value to the options that you want to pass to PHPUnit and they will come into effect for all runs. For a list of [https://phpunit.readthedocs.io/en/9.5/textui.html#command-line-options PHPUnit available options] use the &amp;lt;code&amp;gt;vendor/bin/phpunit --help&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
== Moodle plugins ==&lt;br /&gt;
&lt;br /&gt;
See [https://moodlehq.github.io/moodle-plugin-ci/#github-actions the instructions in the Moodle Plugin CI repository].&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Travis integration]]: For information about the, also supported, integration with Travis CI facilities.&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer tools]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63356</id>
		<title>Github actions integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63356"/>
		<updated>2022-06-21T15:09:00Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Add &amp;quot;GHA&amp;quot; abbreviation to the description.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Moodle core ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Moodle is regularly tested against a matrix of Databases, PHP Versions, and operating systems, however many developers do not have the resources available to run on many of these combinations before pushing an issue for integration as they are time-consuming to both set up and to run.&lt;br /&gt;
&lt;br /&gt;
There are many Continuous Integration tools available to developers, and [https://github.com/features/actions GitHub Actions] (usually named just GHA) is just one of those available to the Open Source community.&lt;br /&gt;
&lt;br /&gt;
Since November 2020 (Moodle 3.5.16 and up), Moodle includes a GitHub Actions configuration file in its repository. This configuration file configures and controls a GitHub build across a matrix of testing environments. This allows developers pushing patches to Moodle to have their code unit tested before it reaches integration. The hope is that the availability of this integration should reduce the number of unit test failures seen during Integration.&lt;br /&gt;
&lt;br /&gt;
Note: Moodle HQ uses the Jenkins CI platform and this should be seen as the [https://ci.moodle.org/ canonical CI server for Moodle]. The GitHub Actions integration aims is to provide early warning to developers of any issues with their code.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
GitHub Actions are available and enabled by default for all public repositories @ GitHub. You can enable or disable them going to your moodle.git clone page, then settings tab -&amp;gt; actions . Please use the &amp;quot;Allow all&amp;quot; option as far as the integration reuses actions from different sources.&lt;br /&gt;
&lt;br /&gt;
[[File:enable_disable_github_actions.png|Enabling and disabling GitHub Actions for your repos]]&lt;br /&gt;
&lt;br /&gt;
For the purpose of this documentation, it is assumed that you are pushing to a public Moodle repository on GitHub. Other integrations are supported, but the service available from GitHub Actions is only available to github public repositories.&lt;br /&gt;
&lt;br /&gt;
=== How do I start a build? ===&lt;br /&gt;
&lt;br /&gt;
Whenever you push a change to any branch in your repository... a build will be queued and executed. You can see how all your builds are progressing by visiting your moodle.git clone page at GitHub, then selecting the actions tab. From there you can filter by branch, by status, access to every build, see failures, relaunch jobs...&lt;br /&gt;
&lt;br /&gt;
[[File:actions_dashboard.png|GitHub Actions &amp;quot;dashboard&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
You will receive notifications (by email or web) whenever a build finish (can be configured from your account notification settings). Also, if your branches match the branch names in any issue in the Tracker, you will get there the corresponding pass/fail badges [[File:github_passing.png|GitHub passing badge]]. Clicking on them you will access straight to the job details @ GitHub.&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all, pretty nice, simple and effective.&lt;br /&gt;
&lt;br /&gt;
=== How do I configure the PHPUnit executions ===&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.11.8 and 4.0.2, it&#039;s possible to configure the PHPUnit executions by creating a [https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository GitHub repository secret] named &amp;lt;code&amp;gt;phpunit_options&amp;lt;/code&amp;gt;. Just setup its value to the options that you want to pass to PHPUnit and they will come into effect for all runs. For a list of [https://phpunit.readthedocs.io/en/9.5/textui.html#command-line-options PHPUnit available options] use the &amp;lt;code&amp;gt;vendor/bin/phpunit --help&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
== Moodle plugins ==&lt;br /&gt;
&lt;br /&gt;
See [https://moodlehq.github.io/moodle-plugin-ci/#github-actions the instructions in the Moodle Plugin CI repository].&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Travis integration]]: For information about the, also supported, integration with Travis CI facilities.&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer tools]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63355</id>
		<title>Github actions integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Github_actions_integration&amp;diff=63355"/>
		<updated>2022-06-21T15:07:32Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Document the availability of phpunit_options for GHA runs (3.11.8, 4.0.2 and up)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Moodle core ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Moodle is regularly tested against a matrix of Databases, PHP Versions, and operating systems, however many developers do not have the resources available to run on many of these combinations before pushing an issue for integration as they are time-consuming to both set up and to run.&lt;br /&gt;
&lt;br /&gt;
There are many Continuous Integration tools available to developers, and [https://github.com/features/actions GitHub Actions] is just one of those available to the Open Source community.&lt;br /&gt;
&lt;br /&gt;
Since November 2020 (Moodle 3.5.16 and up), Moodle includes a GitHub Actions configuration file in its repository. This configuration file configures and controls a GitHub build across a matrix of testing environments. This allows developers pushing patches to Moodle to have their code unit tested before it reaches integration. The hope is that the availability of this integration should reduce the number of unit test failures seen during Integration.&lt;br /&gt;
&lt;br /&gt;
Note: Moodle HQ uses the Jenkins CI platform and this should be seen as the [https://ci.moodle.org/ canonical CI server for Moodle]. The GitHub Actions integration aims is to provide early warning to developers of any issues with their code.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
GitHub Actions are available and enabled by default for all public repositories @ GitHub. You can enable or disable them going to your moodle.git clone page, then settings tab -&amp;gt; actions . Please use the &amp;quot;Allow all&amp;quot; option as far as the integration reuses actions from different sources.&lt;br /&gt;
&lt;br /&gt;
[[File:enable_disable_github_actions.png|Enabling and disabling GitHub Actions for your repos]]&lt;br /&gt;
&lt;br /&gt;
For the purpose of this documentation, it is assumed that you are pushing to a public Moodle repository on GitHub. Other integrations are supported, but the service available from GitHub Actions is only available to github public repositories.&lt;br /&gt;
&lt;br /&gt;
=== How do I start a build? ===&lt;br /&gt;
&lt;br /&gt;
Whenever you push a change to any branch in your repository... a build will be queued and executed. You can see how all your builds are progressing by visiting your moodle.git clone page at GitHub, then selecting the actions tab. From there you can filter by branch, by status, access to every build, see failures, relaunch jobs...&lt;br /&gt;
&lt;br /&gt;
[[File:actions_dashboard.png|GitHub Actions &amp;quot;dashboard&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
You will receive notifications (by email or web) whenever a build finish (can be configured from your account notification settings). Also, if your branches match the branch names in any issue in the Tracker, you will get there the corresponding pass/fail badges [[File:github_passing.png|GitHub passing badge]]. Clicking on them you will access straight to the job details @ GitHub.&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all, pretty nice, simple and effective.&lt;br /&gt;
&lt;br /&gt;
=== How do I configure the PHPUnit executions ===&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.11.8 and 4.0.2, it&#039;s possible to configure the PHPUnit executions by creating a [https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository GitHub repository secret] named &amp;lt;code&amp;gt;phpunit_options&amp;lt;/code&amp;gt;. Just setup its value to the options that you want to pass to PHPUnit and they will come into effect for all runs. For a list of [https://phpunit.readthedocs.io/en/9.5/textui.html#command-line-options PHPUnit available options] use the &amp;lt;code&amp;gt;vendor/bin/phpunit --help&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
== Moodle plugins ==&lt;br /&gt;
&lt;br /&gt;
See [https://moodlehq.github.io/moodle-plugin-ci/#github-actions the instructions in the Moodle Plugin CI repository].&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Travis integration]]: For information about the, also supported, integration with Travis CI facilities.&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer tools]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=63285</id>
		<title>Javascript Modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=63285"/>
		<updated>2022-06-08T16:59:03Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: /* Install NVM and Node */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
= Javascript Modules =&lt;br /&gt;
== What is a Javascript module and why do I care? ==&lt;br /&gt;
A Javascript module is nothing more than a collection of Javascript code that can be used (reliably) from other pieces of Javascript. &lt;br /&gt;
== Why should I package my code as a module? ==&lt;br /&gt;
By packaging your code as a module you break your code up into smaller reusable pieces. This is good because:&lt;br /&gt;
&lt;br /&gt;
a) Each smaller piece is simpler to understand / debug&lt;br /&gt;
&lt;br /&gt;
b) Each smaller piece is simpler to test&lt;br /&gt;
&lt;br /&gt;
c) You can re-use common code instead of duplicating it&lt;br /&gt;
= How do I write a Javascript module in Moodle? =&lt;br /&gt;
Since version 2.9, Moodle supports Javascript modules written using the Asynchronous Module Definition ([https://github.com/amdjs/amdjs-api/wiki/AMD AMD]) API. This is a standard API for creating Javascript modules and you will find many useful third party libraries that are already using this format. &lt;br /&gt;
&lt;br /&gt;
To edit or create an AMD module in Moodle you need to do a couple of things. &lt;br /&gt;
&lt;br /&gt;
Since version 3.8, Moodle supports [https://github.com/lukehoban/es6features#readme ECMAScript 2015 features] (aka ES6) in a cross browser compatible way thanks to [https://babeljs.io/ Babel JS]. In order to achieve the compatibility with older browsers Babel will compile the newer ES6 features back into ES5 Javascript. Unfortunately this means that in order for your Javascript changes to show in the browser they must be compiled by running [[Grunt]], even with the cachejs config setting set to false (i.e. &amp;quot;Development mode&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Note that, for Moodle 3.10 and up (see MDLSITE-6130), any new Javascript module &#039;&#039;&#039;must&#039;&#039;&#039; be written on ES6.&lt;br /&gt;
== Install NVM and Node ==&lt;br /&gt;
The recommended way of installing NodeJS is via the [https://github.com/nvm-sh/nvm Node Version Manager], or NVM. NVM allows you to have several different versions of NodeJS installed at and in-use at any once on your computer. Supported versions of Moodle all use version {{NodeJSExactVersion}} of NodeJS.&lt;br /&gt;
&lt;br /&gt;
For Linux and Mac, follow https://github.com/nvm-sh/nvm#installing-and-updating&lt;br /&gt;
&lt;br /&gt;
For Windows, use https://github.com/coreybutler/nvm-windows/releases -- Note! NVM 1.1.7 for Windows has bugs. You should upgrade to at least 1.1.9.)&lt;br /&gt;
&lt;br /&gt;
Confirm it is working (version below in on Linux, and probably not current):&lt;br /&gt;
 $ nvm --version&lt;br /&gt;
 0.35.3&lt;br /&gt;
After you have installed &#039;&#039;&#039;nvm&#039;&#039;&#039;, you should install the correct version of NodeJS by running the following commands from your Moodle directory:&lt;br /&gt;
 nvm install&lt;br /&gt;
 nvm use&lt;br /&gt;
If your primary use of NodeJS is for Moodle then we recommend that you set NodeJS version {{NodeJSExactVersion}} as your default version. You can do this by running:&lt;br /&gt;
 nvm alias default {{NodeJSExactVersion}}&lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
The AMD modules in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[[grunt]]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment.&lt;br /&gt;
&lt;br /&gt;
Once this is done, you can run the the following commands from your Moodle directory:&lt;br /&gt;
 npm install&lt;br /&gt;
&#039;&#039;&#039;This may mention vulnerabilities, that&#039;s fine and doesn&#039;t apply.&#039;&#039;&#039;&lt;br /&gt;
 npm install -g grunt-cli&lt;br /&gt;
Troubleshooting: on Mac, if you get weird errors, try running &amp;lt;code&amp;gt;sudo xcode-select --reset&amp;lt;/code&amp;gt;. And, this probably means that you need to have Xcode or simlar build tools installed and resonably up to date.&lt;br /&gt;
== Development mode (Moodle v2.9 to v3.7)  ==&lt;br /&gt;
To avoid having to constantly run grunt, make sure you set the following in your config.php&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Prevent JS caching&lt;br /&gt;
$CFG-&amp;gt;cachejs = false;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Moodle will now run your module from the amd/src module. Don&#039;t forget to switch this off and run &#039;grunt&#039; before deploying the new version!&lt;br /&gt;
&lt;br /&gt;
In this mode - if you get a strange message in your javascript console like &amp;quot;No define call for core/first&amp;quot; it means you have a syntax error in the javascript you are developing.&lt;br /&gt;
Or, &amp;quot;No define call for theme_XXX/loader&amp;quot; as you are probably missing the &#039;src&#039; folder with relevant JS files. which might happen when you turn debugging ON on a theme that was bought, without &#039;src&#039; folder :-(&lt;br /&gt;
== Development mode (Moodle v3.8 and above)  ==&lt;br /&gt;
All Javascript code is now compiled using Babel which means Moodle will only ever serve minified Javascript to the browser, even in development mode. However in development mode Moodle will also send the browser the corresponding source map files for each of the Javascript modules. The source map files will tell the browser how to map the minified source code back to the unminified original source code so that the original source files will be displayed in the sources section of the browser&#039;s development tools.&lt;br /&gt;
&lt;br /&gt;
While in development mode each of the Javascript modules will appear in the browser&#039;s source tree as separate modules (no more giant first.js file!) and they will also be loaded with individual network requests (this is a compromise we had to make thanks to some browser bugs with source map files).&lt;br /&gt;
&lt;br /&gt;
To enable development mode set the &#039;&#039;&#039;cachejs&#039;&#039;&#039; config value to &#039;&#039;&#039;false&#039;&#039;&#039; in the admin settings or directly in your config.php file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Prevent JS caching&lt;br /&gt;
$CFG-&amp;gt;cachejs = false;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Since all Javascript must now be compiled you must run [[Grunt]] in order for you changes to appear in the browser. However rather than running Grunt manually each time on either the whole project or each file you modified, it is recommended that you just run the &#039;&#039;&#039;grunt watch&#039;&#039;&#039; task at the root of your Moodle directory. The grunt watch task will listen for changes to the Javascript files in the Moodle directory and will automatically lint and compile only the file that is changed after each change is detected. This removes the need to manually run grunt after each change.&lt;br /&gt;
== Development mode (Moodle v3.10 and above)  ==&lt;br /&gt;
All the above for Moodle 3.8 and up applies, plus (see MDLSITE-6130), any new Javascript module must be written on ES6.&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
You can run grunt in your plugin&#039;s &#039;amd&#039; directory and it will only operate on your modules. If you&#039;re having problems or just want to check your work it is worth running for the &#039;lint&#039; feature. This can find basic problems. This sub-directory support wont work on Windows unfortunately but there is an alternative: Run grunt from the top directory with the --root=path/to/dir to limit execution to a sub-directory.&lt;br /&gt;
&lt;br /&gt;
See [[Grunt#Running_grunt]] for more details of specific grunt commands which can be used.&lt;br /&gt;
&lt;br /&gt;
If you get the error message&lt;br /&gt;
 /usr/bin/env: node: No such file or directory&lt;br /&gt;
Then see the thread https://github.com/nodejs/node-v0.x-archive/issues/3911&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 14.04 this fixed it for me:&lt;br /&gt;
 sudo ln -fs /usr/bin/nodejs /usr/local/bin/node&lt;br /&gt;
Note: Once you have run grunt and built your code, you will then need to purge Moodle caches otherwise the changes made to your minified files may not be picked up by Moodle.&lt;br /&gt;
== ES6 Modules (Moodle v3.8 and above) ==&lt;br /&gt;
In addition to AMD module syntax Moodle now supports the [https://github.com/lukehoban/es6features#modules ES6 syntax] for writing Javascript modules. All modules (defined using either syntax) are compatible with one another. Behind the scenes the ES6 module syntax is converted into an AMD syntax as part of the Babel compiling process.&lt;br /&gt;
&lt;br /&gt;
Note that, for Moodle 3.10 and up (see MDLSITE-6130), any new Javascript module must be written on ES6.&lt;br /&gt;
&lt;br /&gt;
The call from a PHP file takes the same format&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;myplugin/myfile&#039;,&#039;init&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And a minimal ES6 file will work with &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
export const init = () =&amp;gt; {&lt;br /&gt;
    window.console.log(&#039;we have been started&#039;);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Export default ===&lt;br /&gt;
There is one slight difference between the ES6 definition for exporting modules and the RequireJS (AMD) definition.&lt;br /&gt;
&lt;br /&gt;
ES6 allows you to export a “default” value which is actually no different to exporting a named value where the name is “default”. Unfortunately, RequireJS allows for unnamed default exports (e.g. you can do &amp;quot;return SomeClass;&amp;quot;) which can be imported by just requiring them in other AMD modules.&lt;br /&gt;
&lt;br /&gt;
That’s a bit confusing, get to the point! Well, it basically means that in Moodle you won’t be able to write an ES6 module that exports both a default and named exports, e.g. &amp;quot;export default function() {...}&amp;quot; and &amp;quot;export const FOO = &#039;bar&#039;&amp;quot; in the same module. The export default will simply override all other exports in that module.&lt;br /&gt;
=== Inline Javascript ===&lt;br /&gt;
Another important note is that ES6 support is only for stand alone Javascript files because it relies on the compilation from Babel and Grunt. That means any inline Javascript (either in PHP or in Mustache templates) won&#039;t support the ES6 features. Instead it would be best to keep the inline Javascript as minimal as possible and only use it to load a stand alone Javascript module.&lt;br /&gt;
== Minimum (getting started) module for plugins ==&lt;br /&gt;
This shows the absolute minimum module you need to get started adding modules to your plugins. It&#039;s actually quite simple...&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Put this file in path/to/plugin/amd/src&lt;br /&gt;
// You can call it anything you like&lt;br /&gt;
&lt;br /&gt;
export const init = () =&amp;gt; {&lt;br /&gt;
    document.addEventListener(&#039;change&#039;, e =&amp;gt; {&lt;br /&gt;
        const someNode = e.target.closest(&#039;.someclass&#039;);&lt;br /&gt;
        if (someNode) {&lt;br /&gt;
            alert(&#039;It changed!&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For older versions of Moodle prior to 3.8, you will need to use the legacy ES5 format instead:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
define([], function() {&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function() {&lt;br /&gt;
            document.addEventListener(&#039;change&#039;, function(e) {&lt;br /&gt;
                var someNode = e.target.closest(&#039;.someclass&#039;);&lt;br /&gt;
                if (someNode) {&lt;br /&gt;
                    alert(&#039;It changed!&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This code passes the jquery module into our function (parameter $). There are a number of other useful modules available in Moodle, some of which you&#039;ll probably need in a practical application. See [[Useful_core_Javascript_modules]]. Simply list them in both the define() first parameter and the function callback. E.g.,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import jQuery from &#039;jquery&#039;; // We recommend that you strongly consider whether you really need jQuery. It is typically not needed in modern code.&lt;br /&gt;
import * as Str from &#039;core/str&#039;;&lt;br /&gt;
import Ajax from &#039;core/ajax&#039;;&lt;br /&gt;
&lt;br /&gt;
export const init = config =&amp;gt; {&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The idea here is that we will run the &#039;init&#039; function from our (PHP) code to set things up. This is called from PHP like this...&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;frankenstyle_path/your_js_filename&#039;, &#039;init&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Don&#039;t forget to supply the complete &#039;[[Frankenstyle]]&#039; path. The .js is not needed. &lt;br /&gt;
&lt;br /&gt;
js_call_amd takes a third parameter which is an &#039;&#039;array&#039;&#039; of parameters. These will translate to individual parameters in the &#039;init&#039; function call. For example...&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;block_iomad_company_admin/department_select&#039;, &#039;init&#039;, array($first, $last));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
...calls&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
export const init = (first, last) {&lt;br /&gt;
    window.console.log(`The first name was &#039;${first}&#039; and the last name was &#039;${last}&#039;`);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
A more comprehensive explanation follows...&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; I am a Javascript Module ==&lt;br /&gt;
Lets now create a simple Javascript module so we can see how to lay things out. &lt;br /&gt;
&lt;br /&gt;
Each Javascript module is contained in a single source file in the &amp;lt;componentdir&amp;gt;/amd/src folder. The final name of the module is taken from the file name and the component name. E.g. block_overview/amd/src/helloworld.js would be a module named &amp;quot;block_overview/helloworld&amp;quot;. the name of the module is important when you want to call it from somewhere else in the code. &lt;br /&gt;
&lt;br /&gt;
After running grunt - the minified Javascript files are stored in the &amp;lt;componentdir&amp;gt;/amd/build folder. The javascript files are renamed to show that they are minified (helloworld.js becomes helloworld.min.js). &lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add the built files (the ones in amd/build) to your git commits, or in production no-one will see your changes. &lt;br /&gt;
&lt;br /&gt;
Lets create a simple module now:&lt;br /&gt;
&lt;br /&gt;
blocks/overview/amd/src/helloworld.js&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Standard license block omitted.&lt;br /&gt;
/*&lt;br /&gt;
 * @module     block_overview/helloworld&lt;br /&gt;
 * @copyright  2015 Someone cool&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
import * as Str from &#039;core/str&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Reveal all of the hidden notes.&lt;br /&gt;
 */&lt;br /&gt;
const showAllNotes = () =&amp;gt; {&lt;br /&gt;
    document.querySelectorAll(&#039;.note.hidden&#039;).map(note =&amp;gt; note.removeClass(&#039;hidden&#039;));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Hide all of the notes.&lt;br /&gt;
 */&lt;br /&gt;
const hideAllNotes = () =&amp;gt; document.querySelectorAll(&#039;.note&#039;).map(note =&amp;gt; note.addClass(&#039;hidden&#039;));&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Return a personalised, formal, greeting.&lt;br /&gt;
 *&lt;br /&gt;
 * @param   {String} name The name of the person to greet&lt;br /&gt;
 * @returns {Promise}&lt;br /&gt;
 */&lt;br /&gt;
export const formal = name =&amp;gt; Str.get_string(&#039;formallygreet&#039;, &#039;block_overview&#039;, name);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Return a personalised, informal, greeting.&lt;br /&gt;
 *&lt;br /&gt;
 * @param   {String} name The name of the person to greet&lt;br /&gt;
 * @returns {Promise}&lt;br /&gt;
 */&lt;br /&gt;
export const informal = name =&amp;gt; {&lt;br /&gt;
    return Str.get_string(&#039;informallygreet&#039;, &#039;block_overview&#039;, name);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
It&#039;s important to note tha tonly functions which are exported will be callable from outside the module. These are part of the public API.&lt;br /&gt;
== Loading modules dynamically ==&lt;br /&gt;
What do you do if you don&#039;t know in advance which modules will be required? In a limited number of situations you may not know the modules that you need until you call them. You can make use of dynamic imports to import them when you know what they are. Note: This is not the recommended approach in most cases.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
export const showTheThing = thingToShow =&amp;gt; {&lt;br /&gt;
    // Load the module for this thing.&lt;br /&gt;
    import(`local_examples/local/types/type_${thingToShow.modname}`)&lt;br /&gt;
    .then(thingModule =&amp;gt; {&lt;br /&gt;
        window.console.log(`The ${thingToShow.modname} is now available under thingModule within this scope`);&lt;br /&gt;
&lt;br /&gt;
        return thingModule;&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Including an external javascript/jquery library ==&lt;br /&gt;
If you want to include a javascript / jquery library downloaded from the internet you can do so as follows:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning: if the library you download, supports AMD but is already &amp;quot;named&amp;quot; you will not be able to include it directly&#039;&#039;&#039;&lt;br /&gt;
e.g. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// DO NOT DO THIS - IT DOES NOT WORK IN MOODLE&lt;br /&gt;
define(&amp;quot;typeahead.js&amp;quot;, *[ &amp;quot;jquery&amp;quot; ], function(a0) {&lt;br /&gt;
    return factory(a0);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
will not work, as moodle injects it&#039;s own define name when loading the library.&lt;br /&gt;
&lt;br /&gt;
If the library is in AMD format and has a define:&lt;br /&gt;
e.g. i want to include the jquery final countdown timer on my page ( hilios.github.io/jQuery.countdown/ )&lt;br /&gt;
* download the module in both normal and minified versions&lt;br /&gt;
* place the modules in your moodle install e.g. your custom theme dir, or plugin dir&lt;br /&gt;
* /theme/mytheme/amd/src/jquery.countdown.js&lt;br /&gt;
you can now include the module and initialise it (there are multiple ways to do this)&lt;br /&gt;
php:&lt;br /&gt;
&lt;br /&gt;
1. Create your own AMD module and initialise it:&lt;br /&gt;
&lt;br /&gt;
In your PHP file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_call_amd(&#039;theme_mytheme/countdowntimer&#039;, &#039;init&#039;, $params);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Javascript module:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// /theme/mytheme/amd/src/countdowntimer.js&lt;br /&gt;
import Countdown from &#039;theme_mytheme/jquery.countdown&#039;);&lt;br /&gt;
import $ from &#039;jquery&#039;;&lt;br /&gt;
&lt;br /&gt;
export const init = params =&amp;gt; {&lt;br /&gt;
    $(&#039;#clock&#039;).countdown(params.targetItem, event =&amp;gt; {&lt;br /&gt;
             $(event.target).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
2. Call your Javascript module from your template:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// /theme/mytheme/templates/countdowntimer.mustache&lt;br /&gt;
&amp;lt;span id=&amp;quot;theme_mytheme-clock-{{uniqid}}&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;theme_mytheme/countdowntimer&#039;], function(myModule) {&lt;br /&gt;
    myModule.init({&lt;br /&gt;
        targetItem: &#039;theme_mytheme-clock-{{uniqid}}&#039;&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note: If you feel that you need to work around MDL-62468, then you should probably be putting the data into the DOM in your template via data Attributes, or loading it via a Web Service.&lt;br /&gt;
&lt;br /&gt;
Another example of adding a 3rd-party library to a Moodle plugin (by Ruslan Kabalin)&lt;br /&gt;
&lt;br /&gt;
If you want use https://github.com/R-TEK/colr_pickr in your plugin but this module isn&#039;t RequireJS-compatible.&lt;br /&gt;
&lt;br /&gt;
You need to configure requirejs in your plugin to use third-party library:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$config = [&#039;paths&#039; =&amp;gt; [&#039;colorpicker&#039; =&amp;gt; &#039;CDN or local path...&#039;]];&lt;br /&gt;
$requirejs = &#039;require.config(&#039; . json_encode($config) . &#039;)&#039;;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_amd_inline($requirejs);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Then in your JS module in the plugin:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
define([colorpicker], function(ColorPicker) {&lt;br /&gt;
    const button = document.getElementById(&#039;my_picker&#039;);&lt;br /&gt;
    let picker = new ColorPicker(button, &#039;#ff0000&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And another example of using https://github.com/itsjavi/bootstrap-colorpicker (that has a [[jQuery]] dependency) with native ES6 JS:&lt;br /&gt;
 NOTE: It is advised to move away from [[jQuery]] related plugins, as Moodle core is moving away from jQuery.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import ColourPicker from &#039;local_myplugin/bootstrap-colorpicker&#039;;&lt;br /&gt;
&lt;br /&gt;
const myElement = document.querySelector(&#039;.myelement&#039;);&lt;br /&gt;
const picker = new ColourPicker(myElement);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Embedding AMD code in a page ==&lt;br /&gt;
So you have created lots of cool Javascript modules. Great. How do we actually call them? Any javascript code that calls an AMD module must execute AFTER the requirejs module loader has finished loading. We have provided a function &amp;quot;js_call_amd&amp;quot; that will call a single function from an AMD module with parameters. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_call_amd($modulename, $functionname, $params);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
that will &amp;quot;do the right thing&amp;quot; with your block of AMD code and execute it at the end of the page, after our AMD module loader has loaded.&lt;br /&gt;
Notes:&lt;br /&gt;
* the $modulename is the &#039;componentname/modulename&#039; discussed above&lt;br /&gt;
* the $functionname is the name of a public function exposed by the amd module. &lt;br /&gt;
* the $params is an array of params passed as arguments to the function. These should be simple types that can be handled by json_encode (no recursive arrays, or complex classes please). &lt;br /&gt;
* if the size of the params array is too large (&amp;gt; 1Kb), this will produce a developer warning. Do not attempt to pass large amounts of data through this function, it will pollute the page size. A preferred approach is to pass css selectors for DOM elements that contain data-attributes for any required data, or fetch data via ajax in the background.&lt;br /&gt;
AMD / JS code can also be embedded on a page via mustache templates&lt;br /&gt;
see here: https://docs.moodle.org/dev/Templates#What_if_a_template_contains_javascript.3F&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== npm-shrinkwrap.json sha1 / sha512 changes ===&lt;br /&gt;
If grunt changes all the hashes in npm-shrinkwrap.json then try this:&lt;br /&gt;
 rm -rf node_modules &amp;amp;&amp;amp; npm i&lt;br /&gt;
== But I have a mega JS file I don&#039;t want loaded on every page? ==&lt;br /&gt;
Loading all JS files at once and stuffing them in the browser cache is the right choice for MOST js files, there are probably some exceptions. For these files, you can rename the javascript file to end with the suffix &amp;quot;-lazy.js&amp;quot; which indicates that the module will not be loaded by default, it will be requested the first time it is used. There is no difference in usage for lazy loaded modules, the require() call looks exactly the same, it&#039;s just that the module name will also have the &amp;quot;-lazy&amp;quot; suffix.&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [https://assets.moodlemoot.org/sites/15/20171004085436/JavaScript-AMD-with-RequireJS-presented-by-Daniel-Roperto-Catalyst.pdf JavaScript AMD with RequireJS] presented by Daniel Roperto, Catalyst. (MoodleMOOT AU 2017)&lt;br /&gt;
* [[Useful_core_Javascript_modules]]&lt;br /&gt;
*[[Guide_to_adding_third_party_jQuery_for_AMD]] by Patrick Thibaudeau&lt;br /&gt;
*[https://moodle.org/mod/forum/discuss.php?d=378112#p1524459 How to get variables from PHP into javascript AMD modules in M3.5] Justin Hunt, on Moodle forums.&lt;br /&gt;
*MDL-67327 JavaScript issues when not following the official documentation, since Moodle 3.8&lt;br /&gt;
*[https://moodle.org/mod/forum/discuss.php?d=405829 Error from grunt watch - Moodle 3.9] Forum Discussion&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Template:NodeJSExactVersion&amp;diff=63284</id>
		<title>Template:NodeJSExactVersion</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Template:NodeJSExactVersion&amp;diff=63284"/>
		<updated>2022-06-08T16:55:43Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;v16.15.1&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_and_PHP&amp;diff=63122</id>
		<title>Moodle and PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_and_PHP&amp;diff=63122"/>
		<updated>2022-05-26T21:13:25Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Add information about php81 status&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;New PHP versions are [https://www.php.net/supported-versions.php released every year] and come with important improvements and changes compared with previous versions. Moodle tries to support them as soon as possible, always matching them with our own [https://docs.moodle.org/dev/Releases#Version_support scheduled release plans].&lt;br /&gt;
&lt;br /&gt;
This page contains the current status of support for every PHP version and Moodle versions. For details, follow also the epic links below that combine all the changes that were made in Moodle to ensure PHP compatibility. &#039;&#039;(Note: you must be logged in to tracker to see issues in Epics)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MDL-50565 - &#039;&#039;&#039;PHP 7.0 can be used with Moodle 3.0.1, Moodle 3.1 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.4. See [[Moodle and PHP 7.0 details]] for details.&lt;br /&gt;
&lt;br /&gt;
MDL-55120 - &#039;&#039;&#039;PHP 7.1 can be used with Moodle 3.2 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.7.&lt;br /&gt;
&lt;br /&gt;
MDL-60279 - &#039;&#039;&#039;PHP 7.2 can be used with Moodle 3.4 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.9.&lt;br /&gt;
&lt;br /&gt;
MDL-63420 - &#039;&#039;&#039;PHP 7.3 can be used with Moodle 3.6.4, Moodle 3.7 and later releases.&#039;&#039;&#039; It is also the &#039;&#039;&#039;minimum&#039;&#039;&#039; supported version for Moodle 3.11.&lt;br /&gt;
&lt;br /&gt;
MDL-66260 - &#039;&#039;&#039;PHP 7.4 can be used with Moodle 3.8.3, Moodle 3.9 and later releases.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MDL-70745 - &#039;&#039;&#039;PHP 8.0 support is being implemented for Moodle 3.11 and later releases. Hence it&#039;s still incomplete and only for development purposes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MDL-73016 - &#039;&#039;&#039;PHP 8.1 support is being implemented for Moodle 4.1 and later releases. Hence it&#039;s still incomplete and only for development purposes&#039;&#039;&#039;&lt;br /&gt;
[[fr:Moodle et PHP]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=62367</id>
		<title>Releases</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=62367"/>
		<updated>2022-05-09T07:34:40Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: today... it ended :-)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists all official releases of Moodle, grouped by branch in reverse chronological order.&lt;br /&gt;
==Version support==&lt;br /&gt;
From Moodle 2.6 onwards, the end of support, both general and security, happens the second Monday of May and November, observing the 12, 18... month periods, no matter if the major release date was moved or not.&lt;br /&gt;
&lt;br /&gt;
The most recent [https://en.wikipedia.org/wiki/Long-term_support long-term support release (LTS)] version is Moodle 3.9.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1px solid #dee2e6;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Version&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Release status&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Initial release&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:rgba(0, 0, 0, 0.05);&amp;quot; | General support ends&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Security support ends&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 3.9 (LTS)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#239cae; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 15 June 2020&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 10 May 2021&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 13 November 2023 (ext 6M)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 3.11&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current stable&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 17 May 2021&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 14 Nov 2022 (ext 6M)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 13 Nov 2023 (ext 12M)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |4.0&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current stable&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |19 April 2022&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |8 May 2023&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |13 November 2023&lt;br /&gt;
|-&lt;br /&gt;
|4.1 (LTS)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#9cbd50; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future stable&lt;br /&gt;
|November 2022&lt;br /&gt;
|November 2023&lt;br /&gt;
|November 2025&lt;br /&gt;
|}&lt;br /&gt;
[[Image:401_release_graph.png|alt=Release graph]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Release graph key:&amp;lt;/b&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1px solid #dee2e6;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Current stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Currently supported stable releases.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#239cae; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Current security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | Current release of versions still receiving security-only updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#9cbd50; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Future point releases receiving bug fixes, as well as security updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#316d5e; color:white; adding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |Future point releases receiving security-only updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#686566; color:white; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Past stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Previously released versions containing bug fixes, as well as security updates. Updating to a currently supported version is recommended.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#282828; color:white; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Past security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |Previously released versions containing security updates only. Updating to a currently supported version is recommended.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==General release calendar==&lt;br /&gt;
These are the target dates for releases. These dates may vary slightly due to unforeseen circumstances.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Release type&lt;br /&gt;
!Frequency&lt;br /&gt;
!Months&lt;br /&gt;
|-&lt;br /&gt;
|[[Process#Major_release_cycles|Major]] (eg. 3.x)&lt;br /&gt;
|6 monthly&lt;br /&gt;
|Second Monday of May and November&lt;br /&gt;
|-&lt;br /&gt;
|[[Process#Stable_maintenance_cycles|Minor]] (Point) (eg. 3.x.y)&lt;br /&gt;
| 2 monthly&lt;br /&gt;
|Second Monday of July, September, November, March and May.&lt;br /&gt;
Third Monday of January.&lt;br /&gt;
|}&lt;br /&gt;
All releases are preceded by a one week warning. Upcoming release dates can be found in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar] (Note, this is an iCAL link that will try to add the dates to your personal calendar. If you just want to browse the dates online, use [https://calendar.google.com/calendar/embed?src=moodle.com_p4c2oe7hsb77ltaro5qtihb5d4@group.calendar.google.com&amp;amp;pli=1 this link].).&lt;br /&gt;
&lt;br /&gt;
==Moodle 4.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 4.0&lt;br /&gt;
|19 April 2022&lt;br /&gt;
|2022041900&lt;br /&gt;
|[[Moodle 4.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/400/en/Upgrading Upgrading to 4.0]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 4.0.1&lt;br /&gt;
|9 May 2022&lt;br /&gt;
|2022041901&lt;br /&gt;
|[[Moodle 4.0.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).&lt;br /&gt;
&lt;br /&gt;
==Moodle 3.11==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11&lt;br /&gt;
|17 May 2021&lt;br /&gt;
|2021051700&lt;br /&gt;
|[[Moodle 3.11 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/311/en/Upgrading Upgrading to 3.11]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11.1&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2021051701&lt;br /&gt;
|[[Moodle 3.11.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11.2&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2021051702&lt;br /&gt;
|[[Moodle 3.11.2 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.3&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2021051703&lt;br /&gt;
|[[Moodle 3.11.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.4&lt;br /&gt;
|8 November 2021&lt;br /&gt;
|2021051704&lt;br /&gt;
|[[Moodle 3.11.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.5&lt;br /&gt;
|17 January 2022&lt;br /&gt;
|2021051705&lt;br /&gt;
|[[Moodle 3.11.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.6&lt;br /&gt;
|14 March 2022&lt;br /&gt;
|2021051706&lt;br /&gt;
|[[Moodle 3.11.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.7&lt;br /&gt;
|9 May 2022&lt;br /&gt;
|2021051707&lt;br /&gt;
|[[Moodle 3.11.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).&lt;br /&gt;
 Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).&lt;br /&gt;
&lt;br /&gt;
==Moodle 3.10==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2020110900&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 3.10 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/310/en/Upgrading Upgrading to 3.10]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.1&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2020110901&lt;br /&gt;
| [[Moodle 3.10.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.2&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2020110902&lt;br /&gt;
|[[Moodle 3.10.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10.3&lt;br /&gt;
|25 March 2021&lt;br /&gt;
|2020110903&lt;br /&gt;
|[[Moodle 3.10.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.4&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2020110904&lt;br /&gt;
|[[Moodle 3.10.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.5&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2020110905&lt;br /&gt;
|[[Moodle 3.10.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.6&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2020110906&lt;br /&gt;
|[[Moodle 3.10.6 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10.7&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2020110907&lt;br /&gt;
|[[Moodle 3.10.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.8&lt;br /&gt;
|8 November 2021&lt;br /&gt;
|2020110908&lt;br /&gt;
|[[Moodle 3.10.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.9&lt;br /&gt;
|17 January 2022&lt;br /&gt;
|2020110909&lt;br /&gt;
|[[Moodle 3.10.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.10&lt;br /&gt;
|14 March 2022&lt;br /&gt;
|2020110910&lt;br /&gt;
|[[Moodle 3.10.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.11&lt;br /&gt;
|9 May 2022&lt;br /&gt;
|2020110911&lt;br /&gt;
|[[Moodle 3.10.11 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.10.x ended 8 November 2021 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.10.x ended 9 May 2022 (18 months).&lt;br /&gt;
&lt;br /&gt;
==Moodle 3.9 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9&lt;br /&gt;
|15 June 2020&lt;br /&gt;
|2020061500&lt;br /&gt;
|[[Moodle 3.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/39/en/Upgrading Upgrading to 3.9]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.1&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2020061501&lt;br /&gt;
|[[Moodle 3.9.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.2&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2020061502&lt;br /&gt;
| [[Moodle 3.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.3&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2020061503&lt;br /&gt;
| [[Moodle 3.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.4&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2020061504&lt;br /&gt;
|[[Moodle 3.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.5&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2020061505&lt;br /&gt;
|[[Moodle 3.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.6&lt;br /&gt;
|25 March 2021&lt;br /&gt;
|2020061506&lt;br /&gt;
|[[Moodle 3.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.7&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2020061507&lt;br /&gt;
|[[Moodle 3.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9.8&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2020061508&lt;br /&gt;
|[[Moodle 3.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.9&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2020061509&lt;br /&gt;
|[[Moodle 3.9.9 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9.10&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2020061510&lt;br /&gt;
|[[Moodle 3.9.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.11&lt;br /&gt;
| 8 November 2021&lt;br /&gt;
|2020061511&lt;br /&gt;
|[[Moodle 3.9.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.12&lt;br /&gt;
| 17 January 2022&lt;br /&gt;
|2020061512&lt;br /&gt;
|[[Moodle 3.9.12 release notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.13&lt;br /&gt;
| 14 March 2022&lt;br /&gt;
|2020061513&lt;br /&gt;
|[[Moodle 3.9.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.14&lt;br /&gt;
| 9 May 2022&lt;br /&gt;
|2020061514&lt;br /&gt;
|[[Moodle 3.9.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.9.x ended 10 May 2021 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.9.x will end 13 Nov 2023 (36 months plus 6 months extension).&lt;br /&gt;
==Moodle 3.8==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8&lt;br /&gt;
|18 November 2019&lt;br /&gt;
|2019111800&lt;br /&gt;
|[[Moodle 3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/38/en/Upgrading Upgrading to 3.8]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.1&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2019111801&lt;br /&gt;
|[[Moodle 3.8.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.2&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2019111802&lt;br /&gt;
|[[Moodle 3.8.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.3&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2019111803&lt;br /&gt;
|[[Moodle 3.8.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.4&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2019111804&lt;br /&gt;
|[[Moodle 3.8.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.5&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2019111805&lt;br /&gt;
| [[Moodle 3.8.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.6&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2019111806&lt;br /&gt;
| [[Moodle 3.8.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.7&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2019111807&lt;br /&gt;
|[[Moodle 3.8.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.8&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2019111808&lt;br /&gt;
|[[Moodle 3.8.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.9&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2019111809&lt;br /&gt;
|[[Moodle 3.8.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.8.x ended 9 November 2020 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.8.x ended 10 May 2021 (18 months).&lt;br /&gt;
==Moodle 3.7==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7&lt;br /&gt;
|20 May 2019&lt;br /&gt;
|2019052000&lt;br /&gt;
|[[Moodle 3.7 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/37/en/Upgrading Upgrading to 3.7]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.1&lt;br /&gt;
|8 July 2019&lt;br /&gt;
|2019052001&lt;br /&gt;
|[[Moodle 3.7.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.2&lt;br /&gt;
|9 September 2019&lt;br /&gt;
|2019052002&lt;br /&gt;
|[[Moodle 3.7.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.3&lt;br /&gt;
|11 November 2019&lt;br /&gt;
|2019052003&lt;br /&gt;
| [[Moodle 3.7.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.4&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2019052004&lt;br /&gt;
|[[Moodle 3.7.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.5&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2019052005&lt;br /&gt;
|[[Moodle 3.7.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.6&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2019052006&lt;br /&gt;
|[[Moodle 3.7.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.7&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2019052007&lt;br /&gt;
|[[Moodle 3.7.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.8&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2019052008&lt;br /&gt;
| [[Moodle 3.7.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.9&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2019052009&lt;br /&gt;
|[[Moodle 3.7.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.7.x ended 11 May 2020 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.7.x ended 9 November 2020 (18 months).&lt;br /&gt;
==Moodle 3.6==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6&lt;br /&gt;
| 3 December 2018&lt;br /&gt;
|2018120300&lt;br /&gt;
|[[Moodle 3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/36/en/Upgrading Upgrading to 3.6]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.1&lt;br /&gt;
|5 December 2018&lt;br /&gt;
|2018120301&lt;br /&gt;
| [[Moodle 3.6.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.6.2&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2018120302&lt;br /&gt;
|[[Moodle 3.6.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.3&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2018120303&lt;br /&gt;
|[[Moodle 3.6.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.4&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2018120304&lt;br /&gt;
|[[Moodle 3.6.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.5&lt;br /&gt;
|8th July 2019&lt;br /&gt;
|2018120305&lt;br /&gt;
|[[Moodle 3.6.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.6&lt;br /&gt;
|9th September 2019&lt;br /&gt;
|2018120306&lt;br /&gt;
|[[Moodle 3.6.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.7&lt;br /&gt;
| 11th November 2019&lt;br /&gt;
|2018120307&lt;br /&gt;
|[[Moodle 3.6.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.8&lt;br /&gt;
|13th January 2020&lt;br /&gt;
|2018120308&lt;br /&gt;
|[[Moodle 3.6.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.9&lt;br /&gt;
|9th March 2020&lt;br /&gt;
|2018120309&lt;br /&gt;
| [[Moodle 3.6.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.10&lt;br /&gt;
|11th May 2020&lt;br /&gt;
|2018120310&lt;br /&gt;
|[[Moodle 3.6.10 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.6.x ended 11 November 2019 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.6.x ended 11 May 2020 (18 months).&lt;br /&gt;
==Moodle 3.5 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2018051700&lt;br /&gt;
|[[Moodle 3.5 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/35/en/Upgrading Upgrading to 3.5]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.5.1&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2018051701&lt;br /&gt;
|[[Moodle 3.5.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.2&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2018051702&lt;br /&gt;
|[[Moodle 3.5.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.3&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2018051703&lt;br /&gt;
| [[Moodle 3.5.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.5.4&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2018051704&lt;br /&gt;
|[[Moodle 3.5.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.5&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2018051705&lt;br /&gt;
|[[Moodle 3.5.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.6&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2018051706&lt;br /&gt;
|[[Moodle 3.5.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.7&lt;br /&gt;
|8 July 2019&lt;br /&gt;
|2018051707&lt;br /&gt;
|[[Moodle 3.5.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.8&lt;br /&gt;
|9 September 2019&lt;br /&gt;
|2018051708&lt;br /&gt;
|[[Moodle 3.5.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.9&lt;br /&gt;
|11 November 2019&lt;br /&gt;
|2018051709&lt;br /&gt;
|[[Moodle 3.5.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.10&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2018051710&lt;br /&gt;
| [[Moodle 3.5.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.11&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2018051711&lt;br /&gt;
|[[Moodle 3.5.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.12&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2018051712&lt;br /&gt;
| [[Moodle 3.5.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.13&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2018051713&lt;br /&gt;
|[[Moodle 3.5.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.14&lt;br /&gt;
| 14 September 2020&lt;br /&gt;
|2018051714&lt;br /&gt;
|[[Moodle 3.5.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.15&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2018051715&lt;br /&gt;
|[[Moodle 3.5.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.16&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2018051716&lt;br /&gt;
| [[Moodle 3.5.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.17&lt;br /&gt;
|8 March 2021&lt;br /&gt;
| 2018051717&lt;br /&gt;
|[[Moodle 3.5.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.18&lt;br /&gt;
| 10 May 2021&lt;br /&gt;
| 2018051718&lt;br /&gt;
|[[Moodle 3.5.18 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.5.x ended May 2019 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.5.x ended 10 May 2021 (36 months).&lt;br /&gt;
==Moodle 3.4==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2017111300&lt;br /&gt;
|[[Moodle 3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/34/en/Upgrading Upgrading to 3.4]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.1&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2017111301&lt;br /&gt;
|[[Moodle 3.4.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.2&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2017111302&lt;br /&gt;
|[[Moodle 3.4.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.3&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2017111303&lt;br /&gt;
|[[Moodle 3.4.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.4&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2017111304&lt;br /&gt;
|[[Moodle 3.4.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.5&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2017111305&lt;br /&gt;
|[[Moodle 3.4.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.6&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2017111306&lt;br /&gt;
| [[Moodle 3.4.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.7&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2017111307&lt;br /&gt;
|[[Moodle 3.4.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.8&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2017111308&lt;br /&gt;
|[[Moodle 3.4.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.9&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2017111309&lt;br /&gt;
| [[Moodle 3.4.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.4.x ended 12 November 2018 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.4.x ended 13 May 2019 (18 months).&lt;br /&gt;
==Moodle 3.3==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3&lt;br /&gt;
|15 May 2017&lt;br /&gt;
|2017051500&lt;br /&gt;
|[[Moodle 3.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/33/en/Upgrading Upgrading to 3.3]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.1&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2017051501&lt;br /&gt;
|[[Moodle 3.3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.2&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2017051502&lt;br /&gt;
|[[Moodle 3.3.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.3&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2017051503&lt;br /&gt;
| [[Moodle 3.3.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.4&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2017051504&lt;br /&gt;
|[[Moodle 3.3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.5&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2017051505&lt;br /&gt;
|[[Moodle 3.3.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.6&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2017051506&lt;br /&gt;
|[[Moodle 3.3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.7&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2017051507&lt;br /&gt;
|[[Moodle 3.3.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.8&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2017051508&lt;br /&gt;
|[[Moodle 3.3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.9&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2017051509&lt;br /&gt;
|[[Moodle 3.3.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.3.x ended 17 May 2018 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.3.x ended 12 November 2018 (18 months).&lt;br /&gt;
==Moodle 3.2==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2&lt;br /&gt;
| 5 December 2016&lt;br /&gt;
|2016120500&lt;br /&gt;
|[[Moodle 3.2 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/32/en/Upgrading Upgrading to 3.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.1&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2016120501&lt;br /&gt;
|[[Moodle 3.2.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.2&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2016120502&lt;br /&gt;
|[[Moodle 3.2.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.3&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2016120503&lt;br /&gt;
|[[Moodle 3.2.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.4&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2016120504&lt;br /&gt;
|[[Moodle 3.2.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.5&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2016120505&lt;br /&gt;
|[[Moodle 3.2.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.6&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2016120506&lt;br /&gt;
| [[Moodle 3.2.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.2.7&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2016120507&lt;br /&gt;
|[[Moodle 3.2.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.8&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2016120508&lt;br /&gt;
|[[Moodle 3.2.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.9&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2016120509&lt;br /&gt;
| [[Moodle 3.2.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.2.x ended 13 November 2017 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.2.x ended 17 May 2018 (18 months).&lt;br /&gt;
==Moodle 3.1 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1&lt;br /&gt;
|23 May 2016&lt;br /&gt;
|2016052300&lt;br /&gt;
|[[Moodle 3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/31/en/Upgrading Upgrading to 3.1]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.1&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2016052301&lt;br /&gt;
|[[Moodle 3.1.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.2&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2016052302&lt;br /&gt;
|[[Moodle 3.1.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.3&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2016052303&lt;br /&gt;
|[[Moodle 3.1.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.4&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2016052304&lt;br /&gt;
|[[Moodle 3.1.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.5&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2016052305&lt;br /&gt;
|[[Moodle 3.1.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.6&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2016052306&lt;br /&gt;
|[[Moodle 3.1.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.7&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2016052307&lt;br /&gt;
|[[Moodle 3.1.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.8&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2016052308&lt;br /&gt;
|[[Moodle 3.1.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.9&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2016052309&lt;br /&gt;
|[[Moodle 3.1.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.10&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2016052310&lt;br /&gt;
|[[Moodle 3.1.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.11&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2016052311&lt;br /&gt;
|[[Moodle 3.1.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.12&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2016052312&lt;br /&gt;
|[[Moodle 3.1.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.13&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2016052313&lt;br /&gt;
|[[Moodle 3.1.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.14&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2016052314&lt;br /&gt;
|[[Moodle 3.1.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.15&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2016052315&lt;br /&gt;
|[[Moodle 3.1.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.16&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2016052316&lt;br /&gt;
|[[Moodle 3.1.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.17&lt;br /&gt;
|11 March 2019&lt;br /&gt;
| 2016052317&lt;br /&gt;
|[[Moodle 3.1.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.18&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2016052318&lt;br /&gt;
|[[Moodle 3.1.18 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.1.x ended 8 May 2017 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.1.x ended 13 May 2019 (36 months).&lt;br /&gt;
==Moodle 3.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0&lt;br /&gt;
|16 November 2015&lt;br /&gt;
|2015111600&lt;br /&gt;
|[[Moodle 3.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/30/en/Upgrading Upgrading to 3.0]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.1&lt;br /&gt;
|21 December 2015&lt;br /&gt;
|2015111601&lt;br /&gt;
| [[Moodle 3.0.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.0.2&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2015111602&lt;br /&gt;
|[[Moodle 3.0.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.3&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2015111603&lt;br /&gt;
|[[Moodle 3.0.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.4&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2015111604&lt;br /&gt;
|[[Moodle 3.0.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.5&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2015111605&lt;br /&gt;
|[[Moodle 3.0.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.6&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2015111606&lt;br /&gt;
|[[Moodle 3.0.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.7&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2015111607&lt;br /&gt;
|[[Moodle 3.0.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.8&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2015111608&lt;br /&gt;
|[[Moodle 3.0.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.9&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2015111609&lt;br /&gt;
|[[Moodle 3.0.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.10&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2015111610&lt;br /&gt;
|[[Moodle 3.0.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.0.x ended 14 November 2016 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.0.x ended 8 May 2017 (18 months).&lt;br /&gt;
==Moodle 2.9==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9&lt;br /&gt;
| 11 May 2015&lt;br /&gt;
|2015051100&lt;br /&gt;
|[[Moodle 2.9 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/29/en/Upgrading_to_Moodle_2.9 Upgrading to 2.9]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.1&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2015051101&lt;br /&gt;
|[[Moodle 2.9.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.2&lt;br /&gt;
|14 September 2015&lt;br /&gt;
|2015051102&lt;br /&gt;
| [[Moodle 2.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.3&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2015051103&lt;br /&gt;
| [[Moodle 2.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.4&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2015051104&lt;br /&gt;
|[[Moodle 2.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.5&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2015051105&lt;br /&gt;
|[[Moodle 2.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.6&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2015051106&lt;br /&gt;
|[[Moodle 2.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.7&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2015051107&lt;br /&gt;
|[[Moodle 2.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.8&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2015051108&lt;br /&gt;
|[[Moodle 2.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.9&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2015051109&lt;br /&gt;
|[[Moodle 2.9.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.9.x ended 9 May 2016 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.9.x ended 14 November 2016 (18 months).&lt;br /&gt;
==Moodle 2.8==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2014111000&lt;br /&gt;
| [[Moodle 2.8 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/28/en/Upgrading_to_Moodle_2.8 Upgrading to 2.8]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.1&lt;br /&gt;
|13 November 2014&lt;br /&gt;
|2014111001&lt;br /&gt;
| [[Moodle 2.8.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.2&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2014111002&lt;br /&gt;
| [[Moodle 2.8.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.3&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2014111003&lt;br /&gt;
|[[Moodle 2.8.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.4&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2014111004&lt;br /&gt;
|[[Moodle 2.8.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.5&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2014111005&lt;br /&gt;
|[[Moodle 2.8.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.6&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2014111006&lt;br /&gt;
|[[Moodle 2.8.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.8.7&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2014111007&lt;br /&gt;
|[[Moodle 2.8.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.8&lt;br /&gt;
|14 September 2015&lt;br /&gt;
|2014111008&lt;br /&gt;
| [[Moodle 2.8.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.9&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2014111009&lt;br /&gt;
|[[Moodle 2.8.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.10&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2014111010&lt;br /&gt;
|[[Moodle 2.8.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.11&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2014111011&lt;br /&gt;
|[[Moodle 2.8.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.12&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2014111012&lt;br /&gt;
| [[Moodle 2.8.12 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).&lt;br /&gt;
==Moodle 2.7 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7&lt;br /&gt;
| 12 May 2014&lt;br /&gt;
|2014051200&lt;br /&gt;
|[[Moodle 2.7 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/27/en/Upgrading_to_Moodle_2.7 Upgrading to 2.7]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.7.1&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2014051201&lt;br /&gt;
|[[Moodle 2.7.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.2&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2014051202&lt;br /&gt;
|[[Moodle 2.7.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.3&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2014051203&lt;br /&gt;
| [[Moodle 2.7.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.4&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2014051204&lt;br /&gt;
| [[Moodle 2.7.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.5&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2014051205&lt;br /&gt;
|[[Moodle 2.7.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.6&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2014051206&lt;br /&gt;
|[[Moodle 2.7.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.7&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2014051207&lt;br /&gt;
|[[Moodle 2.7.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.8&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2014051208&lt;br /&gt;
|[[Moodle 2.7.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.9&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2014051209&lt;br /&gt;
|[[Moodle 2.7.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.10&lt;br /&gt;
| 14 September 2015&lt;br /&gt;
|2014051210&lt;br /&gt;
|[[Moodle 2.7.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.11&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2014051211&lt;br /&gt;
|[[Moodle 2.7.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.12&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2014051212&lt;br /&gt;
|[[Moodle 2.7.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.13&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2014051213&lt;br /&gt;
|[[Moodle 2.7.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.14&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2014051214&lt;br /&gt;
| [[Moodle 2.7.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.15&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2014051215&lt;br /&gt;
|[[Moodle 2.7.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.16&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2014051216&lt;br /&gt;
|[[Moodle 2.7.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.17&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2014051217&lt;br /&gt;
|[[Moodle 2.7.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.18&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2014051218&lt;br /&gt;
|[[Moodle 2.7.18 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.19&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2014051219&lt;br /&gt;
|[[Moodle 2.7.19 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.20&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2014051220&lt;br /&gt;
| [[Moodle 2.7.20 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.7.x ended 11 May 2015 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.7.x ended 8 May 2017 (36 months).&lt;br /&gt;
==Moodle 2.6==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6&lt;br /&gt;
|18 November 2013&lt;br /&gt;
|2013111800&lt;br /&gt;
|[[Moodle 2.6 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/26/en/Upgrading_to_Moodle_2.6 Upgrading to 2.6]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.1&lt;br /&gt;
|13 January 2014&lt;br /&gt;
| 2013111801&lt;br /&gt;
| [[Moodle 2.6.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.2&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2013111802&lt;br /&gt;
|[[Moodle 2.6.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.3&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2013111803&lt;br /&gt;
|[[Moodle 2.6.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.4&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2013111804&lt;br /&gt;
|[[Moodle 2.6.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.5&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2013111805&lt;br /&gt;
|[[Moodle 2.6.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.6&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2013111806&lt;br /&gt;
|[[Moodle 2.6.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.7&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2013111807&lt;br /&gt;
|[[Moodle 2.6.7 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.6.8&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2013111808&lt;br /&gt;
|[[Moodle 2.6.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.6.9&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2013111809&lt;br /&gt;
|[[Moodle 2.6.9 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.10&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2013111810&lt;br /&gt;
| [[Moodle 2.6.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.11&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2013111811&lt;br /&gt;
|[[Moodle 2.6.11 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.6.x ended 10 November 2014 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.6.x ended 11 May 2015 (18 months).&lt;br /&gt;
==Moodle 2.5==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5&lt;br /&gt;
| 14 May 2013&lt;br /&gt;
|2013051400&lt;br /&gt;
|[[Moodle 2.5 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/25/en/Upgrading_to_Moodle_2.5 Upgrading to 2.5]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.5.1&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2013051401&lt;br /&gt;
|[[Moodle 2.5.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.2&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2013051402&lt;br /&gt;
|[[Moodle 2.5.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.3&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2013051403&lt;br /&gt;
|[[Moodle 2.5.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.4&lt;br /&gt;
|13 January 2014&lt;br /&gt;
| 2013051404&lt;br /&gt;
| [[Moodle 2.5.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.5&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2013051405&lt;br /&gt;
|[[Moodle 2.5.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.6&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2013051406&lt;br /&gt;
|[[Moodle 2.5.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.7&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2013051407&lt;br /&gt;
|[[Moodle 2.5.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.8&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2013051408&lt;br /&gt;
|[[Moodle 2.5.8 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.5.9&lt;br /&gt;
| 10 November 2014&lt;br /&gt;
|2013051409&lt;br /&gt;
|[[Moodle 2.5.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.5.x ended May 2014 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.5.x ended 10 November 2014 (18 months).&lt;br /&gt;
==Moodle 2.4==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4&lt;br /&gt;
|3 December 2012&lt;br /&gt;
|2012120300&lt;br /&gt;
|[[Moodle 2.4 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/24/en/Upgrading_to_Moodle_2.4 Upgrading to 2.4]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4.1&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2012120301&lt;br /&gt;
|[[Moodle 2.4.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.2&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2012120302&lt;br /&gt;
|[[Moodle 2.4.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.3&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2012120303&lt;br /&gt;
|[[Moodle 2.4.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.4&lt;br /&gt;
|14 May 2013&lt;br /&gt;
|2012120304&lt;br /&gt;
|[[Moodle 2.4.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.5&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2012120305&lt;br /&gt;
|[[Moodle 2.4.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.6&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2012120306&lt;br /&gt;
|[[Moodle 2.4.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.7&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2012120307&lt;br /&gt;
| [[Moodle 2.4.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4.8&lt;br /&gt;
|13 January 2014&lt;br /&gt;
|2012120308&lt;br /&gt;
|[[Moodle 2.4.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.9&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2012120309&lt;br /&gt;
|[[Moodle 2.4.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.10&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2012120310&lt;br /&gt;
| [[Moodle 2.4.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.11&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2012120311&lt;br /&gt;
|[[Moodle 2.4.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.4.x ended December 2013 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.4.x ended June 2014 (18 months).&lt;br /&gt;
==Moodle 2.3==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3&lt;br /&gt;
|25 June 2012&lt;br /&gt;
|2012062500&lt;br /&gt;
|[[Moodle 2.3 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/23/en/Upgrading_to_Moodle_2.3 Upgrading to 2.3]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.1&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2012062501&lt;br /&gt;
|[[Moodle 2.3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.2&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2012062502&lt;br /&gt;
|[[Moodle 2.3.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.3&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2012062503&lt;br /&gt;
|[[Moodle 2.3.3 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.4&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2012062504&lt;br /&gt;
|[[Moodle 2.3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.5&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2012062505&lt;br /&gt;
|[[Moodle 2.3.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.6&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2012062506&lt;br /&gt;
|[[Moodle 2.3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.7&lt;br /&gt;
|14 May 2013&lt;br /&gt;
|2012062507&lt;br /&gt;
|[[Moodle 2.3.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.8&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2012062508&lt;br /&gt;
|[[Moodle 2.3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.9&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2012062509&lt;br /&gt;
|[[Moodle 2.3.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.10&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2012062510&lt;br /&gt;
|[[Moodle 2.3.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.11&lt;br /&gt;
|13 January 2014&lt;br /&gt;
|2012062511&lt;br /&gt;
|[[Moodle 2.3.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.3.x ended June 2013 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.3.x ended December 2013 (18 months).&lt;br /&gt;
==Moodle 2.2==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2&lt;br /&gt;
|5 December 2011&lt;br /&gt;
|2011120500&lt;br /&gt;
|[[Moodle 2.2 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/22/en/Upgrading_to_Moodle_2.2 Upgrading to 2.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.1&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011120501&lt;br /&gt;
|[[Moodle 2.2.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.2&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011120502&lt;br /&gt;
|[[Moodle 2.2.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.3&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011120503&lt;br /&gt;
|[[Moodle 2.2.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2.4&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011120504&lt;br /&gt;
|[[Moodle 2.2.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.5&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2011120505&lt;br /&gt;
|[[Moodle 2.2.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.6&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2011120506&lt;br /&gt;
| [[Moodle 2.2.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2.7&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2011120507&lt;br /&gt;
|[[Moodle 2.2.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.8&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2011120508&lt;br /&gt;
|[[Moodle 2.2.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.9&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2011120509&lt;br /&gt;
|[[Moodle 2.2.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.10&lt;br /&gt;
|14 May 2013&lt;br /&gt;
| 2011120510&lt;br /&gt;
|[[Moodle 2.2.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.11&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2011120511&lt;br /&gt;
|[[Moodle 2.2.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.2.x ended December 2012 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.2.x ended June 2013 (18 months).&lt;br /&gt;
==Moodle 2.1==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1&lt;br /&gt;
| 1 July 2011&lt;br /&gt;
|2011070100&lt;br /&gt;
|[[Moodle 2.1 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/21/en/Upgrading_to_Moodle_2.1 Upgrading to 2.1]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.1.1&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2011070101&lt;br /&gt;
| [[Moodle 2.1.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.2&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2011070102&lt;br /&gt;
|[[Moodle 2.1.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.3&lt;br /&gt;
|28 November 2011&lt;br /&gt;
|2011070103&lt;br /&gt;
|[[Moodle 2.1.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.4&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011070104&lt;br /&gt;
|[[Moodle 2.1.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.5&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011070105&lt;br /&gt;
|[[Moodle 2.1.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.6&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011070106&lt;br /&gt;
|[[Moodle 2.1.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.1.7&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011070107&lt;br /&gt;
|[[Moodle 2.1.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.8&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2011070108&lt;br /&gt;
|[[Moodle 2.1.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.9&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2011070109&lt;br /&gt;
|[[Moodle 2.1.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.10&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2011070110&lt;br /&gt;
|[[Moodle 2.1.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.1.x ended June 2012 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.1.x ended December 2012 (18 months).&lt;br /&gt;
==Moodle 2.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0&lt;br /&gt;
|24 November 2010&lt;br /&gt;
|2010112400&lt;br /&gt;
| [[Moodle 2.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/20/en/Upgrading_to_Moodle_2.0 Upgrading to 2.0]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.1&lt;br /&gt;
|25 December 2010&lt;br /&gt;
|2010122500&lt;br /&gt;
|[[Moodle 2.0.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.2&lt;br /&gt;
|21 February 2011&lt;br /&gt;
|2011022100&lt;br /&gt;
|[[Moodle 2.0.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.3&lt;br /&gt;
|5 May 2011&lt;br /&gt;
|2011033003&lt;br /&gt;
|[[Moodle 2.0.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.0.4&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2011033004&lt;br /&gt;
| [[Moodle 2.0.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.5&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2011033005&lt;br /&gt;
|[[Moodle 2.0.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.6&lt;br /&gt;
|28 November 2011&lt;br /&gt;
|2011033006&lt;br /&gt;
|[[Moodle 2.0.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.7&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011033007&lt;br /&gt;
|[[Moodle 2.0.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.8&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011033008&lt;br /&gt;
|[[Moodle 2.0.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.9&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011033009&lt;br /&gt;
|[[Moodle 2.0.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.10&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011033010&lt;br /&gt;
|[[Moodle 2.0.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.0.x ended December 2011 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.0.x ended June 2012 (18 months).&lt;br /&gt;
==Moodle 1.9==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9&lt;br /&gt;
|3 March 2008&lt;br /&gt;
|2007101509&lt;br /&gt;
|[[Moodle 1.9 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/19/en/Upgrading_to_Moodle_1.9 Upgrading to 1.9]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.1&lt;br /&gt;
|15 May 2008&lt;br /&gt;
| 2007101512&lt;br /&gt;
|[[Moodle 1.9.1 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.2&lt;br /&gt;
|11 July 2008&lt;br /&gt;
|2007101520&lt;br /&gt;
|[[Moodle 1.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.3&lt;br /&gt;
|15 October 2008&lt;br /&gt;
|2007101530&lt;br /&gt;
|[[Moodle 1.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.4&lt;br /&gt;
|28 January 2009&lt;br /&gt;
|2007101540&lt;br /&gt;
|[[Moodle 1.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.5&lt;br /&gt;
|13 May 2009&lt;br /&gt;
|2007101550&lt;br /&gt;
|[[Moodle 1.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.6&lt;br /&gt;
|21 October 2009&lt;br /&gt;
|2007101560&lt;br /&gt;
|[[Moodle 1.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.7&lt;br /&gt;
|25 November 2009&lt;br /&gt;
|2007101570&lt;br /&gt;
|[[Moodle 1.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.8&lt;br /&gt;
|25 March 2010&lt;br /&gt;
|2007101580.00&lt;br /&gt;
|[[Moodle 1.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.9&lt;br /&gt;
| 8 June 2010&lt;br /&gt;
| 2007101590.00&lt;br /&gt;
| [[Moodle 1.9.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.10&lt;br /&gt;
|25 October 2010&lt;br /&gt;
|2007101591.00&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 1.9.10 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.11&lt;br /&gt;
|21 February 2011&lt;br /&gt;
|2007101591.02&lt;br /&gt;
|[[Moodle 1.9.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.12&lt;br /&gt;
|10 May 2011&lt;br /&gt;
|2007101591.03&lt;br /&gt;
|[[Moodle 1.9.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.13&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2007101591.04&lt;br /&gt;
|[[Moodle 1.9.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.14&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2007101591.06&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 1.9.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.15&lt;br /&gt;
|28 November 2011&lt;br /&gt;
| 2007101591.07&lt;br /&gt;
| [[Moodle 1.9.15 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.16&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2007101591.10&lt;br /&gt;
|[[Moodle 1.9.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.17&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2007101591.12&lt;br /&gt;
|[[Moodle 1.9.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.18&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2007101591.16&lt;br /&gt;
|[[Moodle 1.9.18 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.19&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2007101592.00&lt;br /&gt;
|[[Moodle 1.9.19 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 1.9.x has ended June 2011 (3.5 years).&lt;br /&gt;
 Bug fixes for security issues in 1.9.x by Moodle HQ ended June 2012 (4.5 years).&lt;br /&gt;
 Bug fixes for security issues in 1.9.19+ branch by [http://catalyst.net.nz Catalyst IT] ended [http://moodle.org/mod/forum/discuss.php?d=199706 Dec 2013] (6 years).&lt;br /&gt;
==Moodle 1.8 ==&lt;br /&gt;
*[[Moodle 1.8 release notes|Moodle 1.8]] - 30 March 2007&lt;br /&gt;
*[[Moodle 1.8.1 release notes|Moodle 1.8.1]] - 14 June 2007&lt;br /&gt;
*[[Moodle 1.8.2 release notes|Moodle 1.8.2]] - 8 July 2007&lt;br /&gt;
*[[Moodle 1.8.3 release notes|Moodle 1.8.3]] - 11 October 2007&lt;br /&gt;
*[[Moodle 1.8.4 release notes|Moodle 1.8.4]] - 11 January 2008&lt;br /&gt;
*[[Moodle 1.8.5 release notes|Moodle 1.8.5]] - 8 April 2008&lt;br /&gt;
*[[Moodle 1.8.6 release notes|Moodle 1.8.6]] - 11 July 2008&lt;br /&gt;
*[[Moodle 1.8.7 release notes|Moodle 1.8.7]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.8.8 release notes|Moodle 1.8.8]] - 28 January 2009&lt;br /&gt;
*[[Moodle 1.8.9 release notes|Moodle 1.8.9]] - 15 May 2009&lt;br /&gt;
*[[Moodle 1.8.10 release notes|Moodle 1.8.10]] - 26 October 2009&lt;br /&gt;
*[[Moodle 1.8.11 release notes|Moodle 1.8.11]] - 25 November 2009&lt;br /&gt;
*[[Moodle 1.8.12 release notes|Moodle 1.8.12]] - 27 March 2010&lt;br /&gt;
*[[Moodle 1.8.13 release notes|Moodle 1.8.13]] - 8 June 2010&lt;br /&gt;
*[[Moodle 1.8.14 release notes|Moodle 1.8.14]] - 3 December 2010&lt;br /&gt;
*Support has ended&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.7==&lt;br /&gt;
*[[Moodle 1.7 release notes|Moodle 1.7]] - 7 November 2006&lt;br /&gt;
*[[Moodle 1.7.1 release notes|Moodle 1.7.1]] - 17 January 2007&lt;br /&gt;
*[[Moodle 1.7.2 release notes|Moodle 1.7.2]] - 30 March 2007&lt;br /&gt;
*[[Moodle 1.7.3 release notes|Moodle 1.7.3]] - 11 October 2007&lt;br /&gt;
*[[Moodle 1.7.4 release notes|Moodle 1.7.4]] - 11 January 2008&lt;br /&gt;
*[[Moodle 1.7.5 release notes|Moodle 1.7.5]] - 11 July 2008&lt;br /&gt;
*[[Moodle 1.7.6 release notes|Moodle 1.7.6]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.7.7 release notes|Moodle 1.7.7]] - 28 January 2009&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.6==&lt;br /&gt;
*[[Moodle 1.6 release notes|Moodle 1.6]] - 20 June 2006&lt;br /&gt;
*[[Moodle 1.6.1 release notes|Moodle 1.6.1]] - 20 July 2006&lt;br /&gt;
*[[Moodle 1.6.2 release notes|Moodle 1.6.2]] - 12 September 2006&lt;br /&gt;
*[[Moodle 1.6.3 release notes|Moodle 1.6.3]] - 10 October 2006&lt;br /&gt;
*[[Moodle 1.6.4 release notes|Moodle 1.6.4]] - 17 January 2007&lt;br /&gt;
*[[Moodle 1.6.5 release notes|Moodle 1.6.5]] - 30 March 2007&lt;br /&gt;
*Moodle 1.6.6 - 11 January 2008&lt;br /&gt;
*Moodle 1.6.7 - 11 July 2008&lt;br /&gt;
*[[Moodle 1.6.8 release notes|Moodle 1.6.8]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.6.9 release notes|Moodle 1.6.9]] - 28 January 2009&lt;br /&gt;
* Support has ended&lt;br /&gt;
==Moodle 1.5==&lt;br /&gt;
*[[Moodle 1.5 release notes|Moodle 1.5]] - 5 June 2005&lt;br /&gt;
*[[Moodle 1.5.1 release notes|Moodle 1.5.1]] - 8 July 2005&lt;br /&gt;
*[[Moodle 1.5.2 release notes|Moodle 1.5.2]] - 16 July 2005&lt;br /&gt;
*[[Moodle 1.5.3 release notes|Moodle 1.5.3]] - 11 November 2005&lt;br /&gt;
*[[Moodle 1.5.4 release notes|Moodle 1.5.4]] - 21 May 2006&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.4==&lt;br /&gt;
*Moodle 1.4 - 31 August 2004&lt;br /&gt;
*Moodle 1.4.1 - 12 September 2004&lt;br /&gt;
*Moodle 1.4.2 - 5 November 2004&lt;br /&gt;
*Moodle 1.4.3 - 21 December 2004&lt;br /&gt;
*Moodle 1.4.4 - 7 March 2005&lt;br /&gt;
*[[Moodle 1.4.5 release notes|Moodle 1.4.5]] - 7 May 2005&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.3==&lt;br /&gt;
*Moodle 1.3 - 25 May 2004&lt;br /&gt;
* Moodle 1.3.1 - 4 June 2004&lt;br /&gt;
*Moodle 1.3.2 - 9 July 2004&lt;br /&gt;
*Moodle 1.3.3 - 16 July 2004&lt;br /&gt;
* Moodle 1.3.4 - 11 August 2004&lt;br /&gt;
*Moodle 1.3.5 - 9 September 2004&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.2==&lt;br /&gt;
*Moodle 1.2 - 20 March 2004&lt;br /&gt;
*Moodle 1.2.1 - 25 March 2004&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.1==&lt;br /&gt;
*Moodle 1.1 - 29 August 2003&lt;br /&gt;
*Moodle 1.1.1 - 11 September 2003&lt;br /&gt;
*Support has ended&lt;br /&gt;
== Moodle 1.0==&lt;br /&gt;
*Moodle 1.0 - 20 August 2002&lt;br /&gt;
*Moodle 1.0.1 - 26 August 2002&lt;br /&gt;
*Moodle 1.0.2 - 2 September 2002&lt;br /&gt;
*Moodle 1.0.3 - 5 September 2002&lt;br /&gt;
*Moodle 1.0.4 - 10 September 2002&lt;br /&gt;
*Moodle 1.0.5 - 27 September 2002&lt;br /&gt;
* Moodle 1.0.6 - 26 October 2002&lt;br /&gt;
::1.0.6.1 - 6 November 2002&lt;br /&gt;
::1.0.6.2 - 11 November 2002&lt;br /&gt;
::1.0.6.3 - 14 November 2002&lt;br /&gt;
::1.0.6.4 - 25 November 2002&lt;br /&gt;
*Moodle 1.0.7 - 9 December 2002&lt;br /&gt;
*Moodle 1.0.8 - 7 January 2003&lt;br /&gt;
*Moodle 1.0.9 - 30 May 2003&lt;br /&gt;
*Support has ended&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Roadmap]] - future versions&lt;br /&gt;
*[[Moodle versions]] - an explanation of how our versions work plus version numbers for each release (for $plugin-&amp;gt;requires)&lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Core development]]&lt;br /&gt;
[[fr:Historique des versions]]&lt;br /&gt;
[[es:dev/Historia de las versiones]]&lt;br /&gt;
[[de:Versionshistorie]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62243</id>
		<title>Release process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62243"/>
		<updated>2022-05-04T07:04:36Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Added link to en_fix issues&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8 weeks prior ==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Recurring release epics review:&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure we are running latest/good behat, phpunit and nodejs (npm) versions.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm external testers daily availability from -6w to release (internally with dev manager and then, externally, with contractors). They start in just 2 weeks!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| - Move QA tests for new features in old release with automated tests from MDLQA-1 to MDLQA-5249.&lt;br /&gt;
- Remind devs:&lt;br /&gt;
* To label issues qa_test_required when a new feature/improvement is landing without automated tests. Also add a comment advising exactly what should be covered in the QA test e.g. steps 6-10 in testing instructions.&lt;br /&gt;
* The best possible lang strings land at first attempt. Given the proximity of the major release and to facilitate the work of translators and others... the sooner, the better, instead of relying on (late) en_fixes too much. &lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| - Create a &amp;quot;Must fix for X.Y&amp;quot; version in the Tracker and adjust the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Set%20integration%20priority%20to%20one/ &amp;quot;TR - Set integration priority to one&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20reopened%20out%20from%20current/ &amp;quot;TR - Move reopened out from current&amp;quot;] jobs in &#039;&#039;&#039;all CI servers&#039;&#039;&#039; to point to it.&lt;br /&gt;
- Apply the following changes to filters and dashboards:&lt;br /&gt;
*  Edit the [https://tracker.moodle.org/issues/?filter=21363 All &amp;quot;must fix&amp;quot; issues] filter used both in the release dashboard and to detect wrong uses of must-fix issues. Note that, since 3.7, this filter is fully automated and does not need edition (uses regexp to catch all must fix versions).&lt;br /&gt;
* Comment about its creation within HQ, to get people applying for it. &lt;br /&gt;
* Verify that these filters ([https://tracker.moodle.org/issues/?filter=18596 1], [https://tracker.moodle.org/issues/?filter=18594 2] and [https://tracker.moodle.org/issues/?filter=18861 3]), used in the [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard], are working ok (they should be, automatically based in the filter edited in the previous point). &lt;br /&gt;
* Rename [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard] to point to incoming release (QA part of the dashboard will not work yet)&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==7 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Full demo of new code and sign-off for internal HQ projects. Decide which projects will be completed by the code freeze.&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Check [https://tracker.moodle.org/issues/?jql=labels%20%3D%20qa_test_required%20AND%20status%20%3D%20Closed closed qa_test_required-labelled issues] and create new QA tests as required.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==6 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period Continuous Integration] period begins. Warn about it everywhere (telegram, exposed posts...).&lt;br /&gt;
Rolling (on demand, beta, rc... all them together with stable weeklies) happens often (Tuesday &amp;amp; Friday are the usual days). All the team is on integration 100% since this week and until the end of continuous.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create the next &amp;quot;X.Y+1&amp;quot; (next dev) version in the Tracker (MDL and CONTRIB), so people can move delayed stuff to next major release if needed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Warn external developers about the impending code freeze in a post to the [http://moodle.org/mod/forum/view.php?id=55 General developer forum]. ([https://moodle.org/mod/forum/discuss.php?d=225854 example])&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Let the community know [[QA testing]] starts in two weeks and how they can participate. &lt;br /&gt;
| Community Manager&lt;br /&gt;
|}&lt;br /&gt;
==5 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm the code freeze by replying to the previous warning in the [http://moodle.org/mod/forum/view.php?id=55 General developer forum].&lt;br /&gt;
| Development manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| This week, once the freeze has happened at 11:00 UTC:&lt;br /&gt;
* The [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job has to be disabled.&lt;br /&gt;
* Immediately after that, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20awaiting%20issues%20to%20current%20integration/ Move awaiting issues to current integration] job must be enabled and executed, only once, and all the candidate issues already @ integration will come to the current queue. All them did the freeze.&lt;br /&gt;
* Once run, disable the job again to avoid executing it by mistake.&lt;br /&gt;
* Once the previous job has ended, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job, in charge of managing the integration queues after freeze, will be enabled (until the end of on-sync). It performs some tasks like moving important (must fix, qa, security...) issues to the current integration queue and also keep if fed by priority when there are few issues remaining. &#039;&#039;&#039;Don&#039;t forget&#039;&#039;&#039; to configure the &amp;quot;releasedate&amp;quot; date to get it automatically holding issues the last week (instead of moving them to current integration) and also processing issues over the on-sync (after release) period.&lt;br /&gt;
Irrespectively from any automation, issues can, also, be manually picked for integration until the post-release &amp;quot;On Sync&amp;quot; period ends, usually 2 weeks after release.&lt;br /&gt;
&lt;br /&gt;
Review all the new features and improvements so, everything &amp;quot;unrelated&amp;quot; with the release, is given the &amp;quot;integration_held&amp;quot; label. That means that will be ignored unless there is an [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period unhold request process] started on them.&lt;br /&gt;
&lt;br /&gt;
Dev leaders promptly vote on held issues labelled with unhold_requested label and decide whether they can be allowed to break the freeze.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare a fresh installation of the [http://qa.moodle.net QA site] based on the beta code to make sure the site is not affected by incremental upgrade steps during the development cycle.&lt;br /&gt;
| QA Master Site Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Begin reviewing [https://lang.moodle.org/mod/forum/view.php?id=7 new and changed English language strings] ready for en_fix to be merged 2 weeks prior.&lt;br /&gt;
| English fixes lang pack maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review standards certifications (Open Badges, LTI, etc) and schedule in recertification to be performed.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==4 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Start reviewing fixed issues and add the release_notes label to all issues to be listed in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review requirements for adding user tours for new features in the upcoming release (clone of MDL-72783). Review existing tours and remove very old ones (clone of MDL-72781)&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Beta release (The Moodle release tool - mdlrelease - manages it): Release normal weeklies but with these changes in the master branch being considered all the time, until we are feature complete (can happen @ -4w - ideally - but also later):&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_BETA and $release = &#039;X.Ybeta (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-beta&amp;quot; (and MOODLE_XY_BETA as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Once the beta is available create the &amp;quot;[https://docs.google.com/spreadsheets/d/1TcMJT3o2Cnyq006lmLWrXJeNQQzyNXz2E_Vbc8ff5EE/edit?usp=sharing|Release testing matrix for X.Y.0]&amp;quot; and share it @ HQ &amp;amp; Dev. chat.&lt;br /&gt;
* (Optionally) Announce Beta release in forums (ideally once packages are available).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-72815 for the X.Y release, adding there all the debugging / PHP notices happening in the web server logs while running tests.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Release candidates release (The Moodle release tool - mdlrelease - manages it): At some points (between beta to final release) produce release candidates (Z = 1, 2, 3..), which are normal builds with the following changes:&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_RC and $release = &#039;X.YrcZ (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-rcZ&amp;quot; (and MOODLE_XY_RCZ as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Upgrade all the Moodle CI sites to recent release candidate by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Add a new version in the Plugins Directory with the version&#039;s name and the beta release version build number (https://moodle.org/plugins/admin/softwareversions.php).&lt;br /&gt;
* Any standard plugins being retired from the release can transition to Add-on (that supports this release and/or any previous ones) now.&lt;br /&gt;
* These plugins currently collect at https://moodle.org/plugins/browse.php?list=contributor&amp;amp;id=1532512&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Push any plugins to the plugins database which were previously a part of core.&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Tidy up current latest en version of Moodle Docs prior to copying it to create new version wiki as described in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new QA test cycle and post in moodle.org front page news forum about [[QA testing]].&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Invite community volunteers to start [[QA testing]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Modify [https://tracker.moodle.org/issues/?filter=11824 Current QA cycle filter] to link to the new QA test cycle&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor QA fails. Check each fail is real and if so ensure an MDL issue has been created and correctly linked and labelled.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor MDL issues created for QA fails. Add them to the &amp;quot;Must fix for X.Y&amp;quot; list and get a developer to work on the issue immediately.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the [https://tracker.moodle.org/issues/?filter=17705&amp;amp;jql=filter%20%3D%2011701%20AND%20type%20!%3D%20Bug list of features and improvements submitted before code freeze] which are awaiting integration review and decide on related QA tests to be put on hold.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==3 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ask developers to begin QA tests marked [https://tracker.moodle.org/issues/?filter=22055 external_skipped] then [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20test_server_required%20 test_server_required tests] and [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20credentials_required credentials_required tests].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new en and de Moodle Docs version wikis.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Go through all points listed under 3 weeks prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review issues with labelled with [https://tracker.moodle.org/issues/?filter=11824&amp;amp;jql=labels%20in%20%28dev_docs_required%29%20AND%20resolution%20%3D%20fixed%20ORDER%20BY%20assignee%20ASC%2C%20created%20ASC dev_docs_required], prompting assigned developers to create/update this documentation and remove this label when relevant docs are updated.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify how everything is going and, before the end of the week, decide (dev leaders &amp;amp; integrators) if there are real reasons for delaying any release. Whenever a delay is agreed, run the &#039;&#039;&amp;quot;Release delaying process&amp;quot;&#039;&#039; (doc) actions ASAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; ASAP stands for as soon as possible ;-), the delay needs to happen before the last week before release begins (there are flows changing that week requiring the decision and actions to be taken and applied earlier).&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Check the number of open QA tests. Depending on the amount of work involved, encourage HQ developers to assist from the start of the week or later in the week in order to achieve the target of 100% pass rate by the end of the week.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Create MDLSITE issue to ensure all prototype.moodle.net sites which are no longer relevant (part of release) are removed from prototype.moodle.net&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Merge [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc fixes from en_fix] pack and then integrate them.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Give Partners complete brandable Marketing pack for release including list and description of major new features.&lt;br /&gt;
| Marketing Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Label (ui_change) in the Tracker all pending issues having &#039;&#039;&#039;noticeable UI modifications&#039;&#039;&#039; and track them in the &amp;quot;[https://docs.google.com/spreadsheets/d/18xZf9OgKrndi7CwSTwjwjF_rzGYCWFuGjNNaaDVZDM4/edit?usp=sharing Late landing UI changes]&amp;quot; sheet, in order to have all the associated docs, screenshots, videos under control. The Integration and Documentation people will try to &#039;&#039;&#039;keep the sheet updated until release&#039;&#039;&#039;.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
For major releases, use (clone if needed) MDL-72836 to keep the security.txt files in all supported branches updated. For minor releases, also check the security.txt expiry dates in all security supported branches in case known release delays will result in any security.txt expiring before the next release - in that case relevant branches should also be updated.&lt;br /&gt;
| Security Officer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==1 week prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone as many filters as needed in the Tracker, modifying them to point to the new, upcoming, branch (keeping same perms, title...). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create new minor version X.Y.Z+1 in the Tracker (MDL and CONTRIB). Archive any version &amp;gt; 6 months old, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-71583 and bump all versions, requires and dependencies along all plugins in codebase to planned release dates.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [http://moodle.org/mod/forum/view.php?id=55 General Developer forum] and [https://moodleassociation.org/ MUA website].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on Twitter and other outlets.&lt;br /&gt;
| Marketing Officer&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Identify security issues that need to be integrated using the [https://tracker.moodle.org/issues/?filter=21712 security issues under integration filter] (includes held, being integrated and ready issues).&lt;br /&gt;
* Integrate from provided patches into supported branches (including branches supported only for security issues).&lt;br /&gt;
* Ensure security issues are given priority in weekly integration and testing. Note that the --weekly releases to be performed this week are 100% normal and cover the standard (supported) branches. security branches will come as part of the release process later in the week.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Collect security issues into a clone of the [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20level%20is%20not%20EMPTY%20AND%20summary%20~%20%22security%20advisories%22%20ORDER%20BY%20updated%20DESC last advisory in the list] to prepare for release of Security Advisories.&lt;br /&gt;
* Determine which security issues will be integrated.&lt;br /&gt;
* Request CVE Identifiers by emailing issue descriptions to [mailto:secalert@redhat.com secalert@redhat.com] with a message like... &amp;lt;tt&amp;gt; The following security issues have been discovered in Moodle. We request CVE Identifiers for these issues. We will be releasing the security announcements for these on moodle.org on XXX at 12noon AWST which is 04:00 UTC.&amp;lt;/tt&amp;gt; The email subject should include the characters &amp;lt;tt&amp;gt;[vs]&amp;lt;/tt&amp;gt;. The format needs to be plain text or encrypted. When granted CVE Identifiers, our issues should appear in the [http://cve.mitre.org/cve/cve.html CVE list]. More [http://oss-security.openwall.org/wiki/mailing-lists/distros instructions] are available (since 2015 we request identifiers from redhat and not from distros).&lt;br /&gt;
* Post security issues as a reply to the &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Release notes tasks:&lt;br /&gt;
* Review and complete the [[Releases|release notes]], making sure that issues have easily understandable summaries. Aim to have the release notes mostly complete on the Wednesday before release, and fully complete on the Friday, to give translators time to translate them.&lt;br /&gt;
* Ensure all issues labelled with &amp;quot;ui_change&amp;quot;, &amp;quot;api_change&amp;quot; and &amp;quot;release_notes&amp;quot; are listed as UI changes, functional changed and fixes/improvements respectively in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the following issues:&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=21363 &amp;quot;Must fix for X.Y version&amp;quot;]. Filter out unrealistic issues.&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=22350 &amp;quot;Bug issues held last week before release&amp;quot;]. Consider to request the unholding of release related/blocker ones.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| Upgrade moodle.org to beta release&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare pull requests for CI Repositories:&lt;br /&gt;
* MR1: Create a new version, with unit tests, in Jobs repository ([https://git.in.moodle.com/integration/nightlyjobs/merge_requests/24 see example from 3.11 release])&lt;br /&gt;
* MR2: Create a new symlink for the version in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/41 see example from 3.11 release])&lt;br /&gt;
* MR3: Configure CIs to skip language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/35 see example from 3.10 release])&lt;br /&gt;
* MR4: Configure CIs to stop skipping language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository for after on-sync ([https://github.com/moodlehq/moodle-ci-runner/pull/40 see example from 3.10 release]) -- Note: This change should be based on the previous and only applied when the lang packs corresponding to the version being released are available.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under 1 week prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==Releasing==&lt;br /&gt;
===Packaging===&lt;br /&gt;
This should happen immediately before the next integration cycle begins on Monday (i.e., some days after last weekly, 2 days prior to official release).&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Check list:&lt;br /&gt;
* Make sure there are no real blockers introduced in the last weekly (install / upgrade ...).&lt;br /&gt;
* Confirm that the latest [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc en_fix changes]have been generated and integrated.&lt;br /&gt;
* Verify that [https://tracker.moodle.org/issues/?jql=text%20~%20%22%2BPrepare%20%2Bsecurity%20%2Badvisories%20%2Bfriends%22%20ORDER%20BY%20updated%20DESC all security issues] have been integrated and there are not leftovers in the security area (but for delayed majors, where some security issues may have been introduced along the delay and they will be postponed to next minors).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify all unit tests and integration tests have passed (check all current CI servers in use).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Verify QA tests have passed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Timing prerequisites (don&#039;t continue with the process if not within the time window!):&lt;br /&gt;
# Latest weeklies before the minor/major releases must be done (moodle-package-extract-and-postprocess email should confirm this has happened around 09:00 Australia/Perth).&lt;br /&gt;
# Minor and major releases can be packaged at any time within the 96 hours before the automatic releasing time (Monday 09:00 Australia/Perth). And always, at very least, 4 hours before then (to allow the server to prepare all the stuff).&lt;br /&gt;
(in practice, this means that the packaging of minor/major releases must be done, assuming that weeklies were rolled normally on Thursday, between Friday 09:00 and Monday 05:00 (Australia/Perth times). Breaking any of these rules will require manual operation in the server, forcing repackaging and releasing.&lt;br /&gt;
&lt;br /&gt;
Follow the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script to generate the target minor (--type minor) and major (--type major) releases and their corresponding tags. Pay attention to the complete output of the process: permissions, svg, travis changes (only for majors)... Triple verify all changes are correct! (can use the --show option to inspect them). Follow the on-screen instructions. &lt;br /&gt;
* Push changes to integration.git (but tags).&lt;br /&gt;
For major releases, only when a new STABLE branch has been created:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script (--type back-to-dev) to move master to next X.Y+1 development version/branch. &lt;br /&gt;
* Push changes to integration.git - note this will lead to the &amp;quot;versions checker&amp;quot; failing for master, no problem, it will be fixed by the 1st cloned issue at #12 below).&lt;br /&gt;
* Configure &amp;quot;mdlrelease&amp;quot; (config.sh) to know about the new MOODLE_XY stable branch.&lt;br /&gt;
* Update the old CI server(s) by cloning all the &amp;quot;master&amp;quot; jobs to a new &amp;quot;MXY&amp;quot; view (trick: do it down-top, way easier). Don&#039;t forget to re-chain the jobs properly.&lt;br /&gt;
** Adjust &amp;quot;master&amp;quot; compare DB jobs to check for upgrade from MOODLE_XY_STABLE.&lt;br /&gt;
** Configure the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
** Run all them.&lt;br /&gt;
* Update the new CI infrastructure:&lt;br /&gt;
** MR1: Merge pull request for new version in [https://git.in.moodle.com/integration/nightlyjobs CI Jobs Repository]&lt;br /&gt;
** MR2: Merge pull request for symlink in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** MR3: Merge pull request for skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** Clone all the &amp;quot;B - master&amp;quot; jobs to a new &amp;quot;B - XY&amp;quot; view (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Clone%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
Both with minors and majors, continue with the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Once CI servers have ended and all jobs have passed, &#039;&#039;&#039;push tags&#039;&#039;&#039; and run the &#039;&#039;&#039;release.sh&#039;&#039;&#039; script to apply the changes to moodle.git.&lt;br /&gt;
* If needed configure &amp;quot;mdlrelease&amp;quot; (config.sh) to get rid of any unsupported version and adjust stable and security branches. Make a pull request with the changes.&lt;br /&gt;
* Don&#039;t forget the &amp;quot;[https://github.com/moodlehq/mdlrelease/#after-the-release After the release]&amp;quot; tasks.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;git repos updated &amp;amp; tagged&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=810 Partner forum]&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| In the [https://github.com/moodlehq/moodle-performance-comparison performance comparison repository], set the new release commit hash as $basecommit in the master branch and create a new MOODLE_XY_STABLE branch from it. ([https://github.com/moodlehq/moodle-performance-comparison/commit/7c875f03e52641f69674235a8947131d77691299 example]). Also, apply it to the current performance testing infrastructure.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Wait for the automated (every 2 hours) moodle-package to finish building for all versions. Verify the process has ended successfully (email).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
* Create new windows packager script (cloning the current master one and configuring it).&lt;br /&gt;
* Edit the stats.php script (in the moodle-local_downloadmoodleorg repository), adding the new branch to the versions. Push it. Next time the plugin is deployed (normally 1 week after release, aprox.) the stats will start showing the new branch statistics.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
* Visit the versions page and make the release, bumping all remaining open bugs to the next point release. If there is not next (end of support), clean that version from all the issues having it as &amp;quot;Fix for&amp;quot;. This must be done both for the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10011 Moodle Project] and the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10033 Plugins project].&lt;br /&gt;
* Archive all versions but the ones being released, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
* Remove from all screens the custom fields belonging to 100% unsupported branches.&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Release and archive the [https://tracker.moodle.org/issues/?jql=affectedVersion%20~%20%22must%20fix%20for*%22%20OR%20fixVersion%20~%20%22must%20fix%20for*%22 &amp;quot;Must fix for X.Y&amp;quot; versions], it must be empty to do so.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Create the new &amp;quot;Pull X.Y Branch&amp;quot; and &amp;quot;Pull X.Y Diff URL&amp;quot; custom fields and spread them to all the screens needing them (copy from previous ones). Order them properly on each screen. Re-index Tracker.&lt;br /&gt;
* In the CI server edit the [http://integration.moodle.org/view/tracker/job/Tracker%20-%20CI%20-%20Bulk%20precheck%20issues/ &amp;quot;Bulk precheck issues&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(awaiting_integration)/ &amp;quot;Pre-launch DEV jobs (awaiting_integration)&amp;quot;], [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch DEV jobs (list_of_mdsl)&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/STR%20-%20Bulk%20pre-launch%20SDEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch SDEV jobs (list_of_mdsl)&amp;quot;] jobs to make them meet the new &amp;quot;Pull X.Y Branch&amp;quot; field created. At the same time, remove from those jobs any branch belonging to 100% unsupported branches.&lt;br /&gt;
* Edit the &amp;quot;Tracker - CI - Check marked as integrated&amp;quot; job ([https://ci.moodle.org/view/Tracker/job/TR%20-%20Check%20marked%20as%20integrated/ link]) to configure the development branches (devbranches) (39, 310, 311, 400...) actually active. Normally only the branch corresponding to master, but also accepts a comma separated list when under parallel development (&amp;quot;310,400&amp;quot; or &amp;quot;311,400&amp;quot; for example). Ordered by planned release date.&lt;br /&gt;
* Check/configure (again, this may be has been already executed few steps above) the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Create the new &amp;quot;X.Y regressions&amp;quot; version to be applied to every issue found to be a recent problem introduced by the major release. These issues should get priority after release.&lt;br /&gt;
* Adjust the [https://tracker.moodle.org/issues/?filter=17528 Latest regressions] filter (requires login).&lt;br /&gt;
For all releases:&lt;br /&gt;
* Verify how the &amp;quot;X.Y regressions&amp;quot; versions [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20resolution%20%3D%20Unresolved%20AND%20affectedVersion%20in%20(versionMatches(%22.*regressions%22)) are going] (requires login) and ping Development Managers about. Package and archive them once empty.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-74509 and MDL-74510, to be resolved ASAP.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
* Create the new MOODLE_XY_STABLE and lastbased-MOODLE_XY_STABLE branches in the security repo (branching from the just created upstream MOODLE_XY_STABLE branch).&lt;br /&gt;
* Cherry pick any security commit present in the security repository&#039;s master branch to the new MOODLE_XY_STABLE branch (note that normally there should not be any, see point #1 check list above).&lt;br /&gt;
* Verify the new security jobs exist for the new branch and check it&#039;s working in all servers, keeping only enabled the public one.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Protect the MOODLE_XY_STABLE branches in github interface to prevent non-FF accidents ( MDLSITE-4183 )&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
===Release day===&lt;br /&gt;
Usually on Monday&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| The execution of &amp;quot;moodle-package-extract-and-postprocess X&amp;quot; script may be needed if the releases &#039;&#039;&#039;are not going to be published on Monday&#039;&#039;&#039; but another weekday (X is the weekday, (1-7) starting in Monday).&lt;br /&gt;
By default it happens automatically around 09:00 AM Perth/Australia time (check emails then). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify release status, download pages and windows packages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| If needed, modify the downloads cfg script (serverscripts) to decide about branches status, master visibility and windows availability. Push changes, will be autodeployed in a few minutes.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add/update the release date, build number and link on the [[Releases|Releases page]] and date in new version pages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify all registered sys admins, including security notes with CVE identifiers, using the [http://lists.moodle.org/ mailing list server].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Post about the Major release on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post about minor releases on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| New &amp;quot;X.Y+1dev&amp;quot; branch to be created in AMOS, to have master changes performed there. New install_XY_STABLE processing set up. These needs to be done anytime during the on-sync period.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify, 24h after tagging, that https://moodle.org/dev/contributions.php has been updated with new versions. If not, file an urgent mdlsite issue, crons must be running!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| For en and de Moodle Docs, update default redirects and enable email notifications.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under Day of release in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Decide the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot; and &amp;quot;QA begins&amp;quot; dates for the next X.(Y+1) major release and put them in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar]. They will be -7w, -5w and -4w before release date respectively.&lt;br /&gt;
* Update the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot;, &amp;quot;QA begins&amp;quot; and Release dates on the [[Roadmap]] page.&lt;br /&gt;
* Add events to the HQ calendar for next Major release 6-months cycle according to [[Process#Sprints|the cycle plan]]: ~4 weeks planning and regression fixing, 2 sprints, 1 personal project week, 2 sprints, 1 personal project week, 1 sprint (which should lead up to code freeze).&lt;br /&gt;
* Notify the Community Manager of new dates to be added to the moodle.org calendar.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &lt;br /&gt;
| Add calendar events in the [https://moodle.org/calendar moodle.org calendar] for coming Major and Minor releases up to the next Major release.&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update release schedule image on [[Releases#Version_support|Releases page]]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 15.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Important: This must be done &#039;&#039;&#039;once it&#039;s already release day @ UTC&#039;&#039;&#039; (aka, after Australia/Perth 08:00) or the &#039;&#039;&#039;queues manage with hold them again&#039;&#039;&#039; because it&#039;s still &amp;quot;last week before release&amp;quot;.&lt;br /&gt;
The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed &#039;&#039;&#039;only&#039;&#039;&#039; [https://tracker.moodle.org/issues/?jql=filter%3D13669%20AND%20type%20in%20(bug%2C%20task%2C%20Sub-task) from &#039;&#039;&#039;bug issues&#039;&#039;&#039; awaiting integration]; they correspond to last-week bugs that were held because of them being unrelated with the release. Now they can be processed, under on-sync rules. Standard message will be used to explain the un-hold.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==1 week after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Publish the X.Y+ packages for download.moodle.org (should be automatic once weeklies are packaged).&lt;br /&gt;
For major releases, within the on-sync period, master packages will be generated using the prerelease.sh script (--type on-sync). That guarantees XY_STABLE and master versions are kept the same. The last week, when leaving the on-sync period, master package will be generated normally (implicit --type weekly), so versions will diverge and dev can continue separately from that point.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update the version.php in git to be X.Y.Z+ during the next weekly integration process&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create a new release notes page for the next minor versions (using the [[Release notes template|release notes template]].) Add note to top of relevant version page about security support.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add all security advisories to [http://moodle.org/security Security news] and [[:Category:Release notes|release notes]] with links to security advisories&lt;br /&gt;
|| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify about publications of CVE using form: https://cveform.mitre.org/&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Upgrade moodle.org and all other Moodle community sites (next sites first, then production)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &#039;&#039;&#039;Deprecations:&#039;&#039;&#039;&lt;br /&gt;
* Create the next deprecation epic (for X.Y+1+2y) similar to MDL-74579 and add standard issues to it:&lt;br /&gt;
** Final deprecation of lib/deprecatedlib.php (like MDL-74580)&lt;br /&gt;
** Removal of deprecated Behat steps (like MDL-74581)&lt;br /&gt;
** Removal of strings (like MDL-74582) and&lt;br /&gt;
** Removal of renamed classes (MDL-74583).&lt;br /&gt;
The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Libraries:&#039;&#039;&#039;&lt;br /&gt;
* Create the next third party libraries epic for X.Y+1, similar to MDL-73715. The issue should refer to the list of [[Moodle libraries credits]]. The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it. &#039;&#039;&#039;Drag/link opened issues from the previous one&#039;&#039;&#039;, avoiding leaving unfinished stuff.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20(summary%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20OR%20summary%20~%20%22Review%20third-party%20libraries%20for%20upgrade%22)%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Once the &amp;quot;On Sync&amp;quot; period ends:&lt;br /&gt;
* Confirm that versions (XY_STABLE and master) diverged properly the last on-sync week. If not, proceed to it by manually bumping master the version to the current date @ integration.git.&lt;br /&gt;
* Disable the &amp;quot;[https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous&amp;quot;] job. It has served us well.&lt;br /&gt;
* The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed from all issues awaiting integration, so they will be, automatically (see next point), be moved to the current integration queue. Send an &amp;quot;unholding + rebase&amp;quot; message to all those issues.&lt;br /&gt;
* Enable the &amp;quot;[https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal&amp;quot;] job. It will control the queues over the coming months, until the next freeze.&lt;br /&gt;
* In the [https://ci.moodle.org/ Jenkins CI server] enable all the jobs corresponding to the new branch (B-XYZ view) that were created on packaging day.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The discussion about environmental requirements for next X.Y+1 major release (MDL-71747) will end and the issue will be resolved &#039;&#039;&#039;immediately&#039;&#039;&#039;. A new issue, about the requirements for nextthe -next X.Y+2 major release wil,l be created at the same time by cloning the previous one and dragging any non-resolved detail (due date = 3w after release).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure [https://download.moodle.org/langpack/X.Y+1/ Language pack for master (X.Y+1)] is available and merge the pull request MR4 for stop skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure release retrospectives are held for each of the LMS teams and results are actioned.&lt;br /&gt;
| Development Manager / Head of LMS&lt;br /&gt;
|}&lt;br /&gt;
==1 month after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Remove, in CI servers, all the jobs and views corresponding to branches which support has ended completely. (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Remove%20all%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Upgrade all the Moodle CI sites to recent major release by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Confirm that there isn&#039;t any remaining [https://tracker.moodle.org/issues/?filter=13669 integration_held] issue from latest release, proceeding to uhhold them immediately. Note that there may exist [https://tracker.moodle.org/issues/?filter=13669&amp;amp;jql=project%20%3D%20MDL%20AND%20labels%20in%20(integration_held)%20ORDER%20BY%20%22Integration%20priority%22%20DESC%2C%20priority%20DESC%2C%20votes%20DESC%2C%20%22Last%20comment%20date%22%20ASC other &amp;quot;held&amp;quot; issues], unrelated with latest release. This process step does not affect them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Deprecation|Deprecation process]]&lt;br /&gt;
[[Category:Processes|Release process]]&lt;br /&gt;
[[Category:Release notes|Release process]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Converters_review_2011-04&amp;diff=62241</id>
		<title>Backup 2.0 - Converters review 2011-04</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Converters_review_2011-04&amp;diff=62241"/>
		<updated>2022-05-03T19:05:58Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Backup 2.0|Backup 2.0]] &amp;gt; [[Backup 2.0 - Provide upwards compatibility of Moodle 1.9.x backups|Backup 1.9 =&amp;gt; 2.x main page]] &amp;gt; Review 2011-04&lt;br /&gt;
{{Template:WillNotMigrate}}{{Template:Backup 2.0}}{{Moodle_2.1}}&lt;br /&gt;
&lt;br /&gt;
This page summarizes the results of the review performed (on April 2011) over the code available at https://github.com/mrmark/moodle related to the implementation of a general solution for the creation and support of moodle restore converters and its first implementation as one Moodle 1.9 =&amp;gt; 2.x converter.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
* MDL-22414 - the main tracker issue for this task.&lt;br /&gt;
* [[Backup 2.0 - Provide upwards compatibility of Moodle 1.9.x backups|Backup 1.9 =&amp;gt; 2.x article]] in Moodle Docs.&lt;br /&gt;
* [http://tracker.moodle.org/secure/attachment/23241/Moodle1.9to2.0Restore.pdf PDF with initial implementation plan].&lt;br /&gt;
* [https://github.com/mrmark/moodle/compare/master...converters_wip Development branch changes] &lt;br /&gt;
&lt;br /&gt;
=== Nomenclature ===&lt;br /&gt;
&lt;br /&gt;
* The review results are shown below as one list of numbered points, briefly explained, with link to corresponding MDL-xxxx (subtask of MDL-22414), where any discussion / agreement / coding should happen.&lt;br /&gt;
* All the MDL-xxxx issue created will begin with R04xx to note they have been ignited as part of this review process and the point they correspond to.&lt;br /&gt;
* Each point below includes one short &amp;quot;status&amp;quot; message in order to know the immediate actions that must be performed on it.&lt;br /&gt;
* New points can be added to the review as long as discussion / agreement happens, if necessary.&lt;br /&gt;
&lt;br /&gt;
=== Global summary ===&lt;br /&gt;
&lt;br /&gt;
* Overall, all code seems to be in correct places and be correct code.&lt;br /&gt;
* The main infrastructure parts (base/plan/moodle1 converters and plan/task/step architectures) are ok, though their APIs would need some improvements detailed below.&lt;br /&gt;
* There are a lot of stuff missing / todo. Files, users, enrolments, plugins, tricky activities, comments, grades...&lt;br /&gt;
* We need to push-push-push (4 weeks to freeze!).&lt;br /&gt;
&lt;br /&gt;
=== The list ===&lt;br /&gt;
&lt;br /&gt;
==== Related to integration with restore_controller &amp;amp; general behavior ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0401&amp;lt;/strike&amp;gt;: status: fixed (MDL-27376) Right now, the to_moodle2_format() performs instantiation of all available converters + simple loop to get the conversions to perform. Instead, it should be possible to use exclusively static methods, returning origin format, target format and cost of the conversion, and then finding the best path or so. Note this is trivial right now but can be a useful general approach if new converters arrive (core and 3rd part).&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0402&amp;lt;/strike&amp;gt;: status: fixed (MDL-27377) The can_convert() function can be static too, passing tempdir as param. Also, the same function (or another one, mandatory) should check if all the PHP/server requirements are satisfied or no (some converters can need extra stuff available in order to be able to perform conversions).&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0403&amp;lt;/strike&amp;gt;: status: fixed. After each conversion, the original source directory is deleted and replaced by the converted one. This makes things complex to trace or perform repeated conversions and also, doesn&#039;t observe the $CFG-&amp;gt;keeptempdirectoriesonbackup completely. We should be able to keep temp stuff undeleted if desired and, perhaps too, be able to instruct the restore controller about tempdir changes.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0404&amp;lt;/strike&amp;gt;: status: fixed. Exceptions: It needs to be decided if we are going to use own converter_exception/s or restore_exception/s and use them constantly along all the code base.&lt;br /&gt;
&lt;br /&gt;
* R0405: status: to code (MDL-27379). Logging: Converters stuff must inherit / use restore_controller logging facilities.&lt;br /&gt;
&lt;br /&gt;
==== Related to the converters/moodle1 infrastructure ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0406&amp;lt;/strike&amp;gt;: status: fixed. All the parser / processor / path_elelement stuff is part of the abstract plan_converter. That stuff should be moved to moodle1_converter as far as it is highly dependent / tidied with the conversion particularities.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0407&amp;lt;/strike&amp;gt;: status: refused by David. About converters, should class names and file names match, i.e. converter.class.php =&amp;gt; moodle1_converter.class.php&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0408&amp;lt;/strike&amp;gt;: status: fixed. On restore, we have both after_restore() methods available in steps (executed when the step execution ends) and in tasks (executed when the whole plan execution ends). Do we need this duality in plan_converter, or is it enough with current one. Right now it seems that we are using a lot these methods to do the work, and process_xxx() should be used instead (together with next point).&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0409&amp;lt;/strike&amp;gt;: status: fixed. Since some weeks ago the notify_path_start/end() methods are available in the xml processor, should we start using them to call some stuff in converter, able to dispatch to start_xxxx() and end_xxxx() methods in the converter steps. It would help a lot with both starting/closing XML tags, creating and closing xml files, or any other pre/post stuff needing to be executed at certain stages.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0410&amp;lt;/strike&amp;gt;: status: fixed. The deprecated/new/renamed elements / mutate_datum stuff. Perhaps it should be moved from steps to path_elements instead, so each path element autocontains the basic transformations to be performed on data and they are applied automatically. It seems a better place for that definitions. Or, alternatively, we&#039;ll need deprecated/new/renamed/mutate_xxxx() methods, one for each path.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0411&amp;lt;/strike&amp;gt;: status: fixed. After looking current uses of the xml writer, it seems clear that we need some extra methods, able to print one tag completely, push/pop last open tag and other commodities in order to make coding easier.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0412&amp;lt;/strike&amp;gt;: status: fixed. The &amp;quot;trick&amp;quot; in the parser about dynamically modify /MOD paths seems ok (I cannot imagine another way to implement it). Similar magic will be needed for blocks and surely, the start/end implementation above will need a similar way to handle/dispatch processing.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0413&amp;lt;/strike&amp;gt;: status: fixed. Some raw accesses to the backup_ids_temp DB stuff must be modified to use helper functions. Also, the use of the table in get_context() can be really slow (text comparison). Look for some alternative.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0414&amp;lt;/strike&amp;gt;: status: fixed. The convert_file() method uses the backup_ids_temp to get sequential fileid values. It should be enough (completely safe), to use one static (in memory) generator instead. No concurrence problems at all IMO.&lt;br /&gt;
&lt;br /&gt;
* R0415: status: to code (MDL-27626, MDL-27452). Support for plugins is a must as far as at least qtypes require it. Note that question types are going to suffer one major revamp on Moodle 2.1, so their final architecture is unknown right now (different from both 1.9 and 2.0).&lt;br /&gt;
&lt;br /&gt;
* R0416: status: to code (tiny detail). In current moodle1_conversion, original_site_identifier should be generated only if there is one original identifier. Right now it saves one &amp;quot;?&amp;quot; that can lead to wrong results detecting same sites.&lt;br /&gt;
&lt;br /&gt;
==== Related to coding in general ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0417&amp;lt;/strike&amp;gt;: status: done. Copyright messages are required on each new file. It must be the standard one with GPL3 msg and MR/Mark/whatever copyright.&lt;br /&gt;
&lt;br /&gt;
* R0418: status: to code. We should have as many tests as possible, specially testing all the infrastructure stuff, in order to guarantee it continues working as expected after any refactor / modification. Right now it&#039;s practically inexistent.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;strike&amp;gt;R0419&amp;lt;/strike&amp;gt;: status: the workflow established. We need to keep the main repo for all the project &amp;quot;converters_wip&amp;quot; in sync (merged) with current moodle.git master branch in order to ensure stuff will land properly (conflicts-free) and converters will be able to use any new feature / improvement available.&lt;br /&gt;
&lt;br /&gt;
==== Related to pending &amp;amp; tricky areas ====&lt;br /&gt;
&lt;br /&gt;
* R0420: status: to code. There are a lot of areas which coding hasn&#039;t been ignited yet (surely to pending work in the list above, don&#039;t worry). Here there is a brief ordered list, annotating the ones that will be really tricky:&lt;br /&gt;
** Users and enrollments: All the users with their complete information must be saved to new users.xml file and each process_xxx() method must, continuously, be annotating needed uses in order to generate proper inforef.xml files. Enrolments will be all moved to manual ones (this needs confirmation).&lt;br /&gt;
** Workshop activity: Completely revamped in 2.0. It has proper subplugins. Upgrade code needs to be deeply analyzed and XML differences too to know how to implement it. (contact: David).&lt;br /&gt;
** Wiki activity: Also brand new in 2.0. Upgrade needs analysis and XML differences too. (contact: Dongsheng).&lt;br /&gt;
** Resource activity: Split into  file/folder/page/url activities. The structure is simple (no user data) but the split makes it really tricky. Also very file-intensive. Upgrade code needs analysis and XML differences (contact: Petr).&lt;br /&gt;
** Files: 1.9 files can had site/course files (apart from the ones &amp;quot;owned&amp;quot; by the module @ moddata). They must be annotated and moved to new files.xml &amp;amp; storage. There is some code already but is not used in the general converter helper stuff (should be moodle1 converter specific instead?).&lt;br /&gt;
** Gradebook: There are important differences between how 1.9 and 2.0 backup information is handled. Scales / outcomes / grade items need annotation in inforef.xml files and also there are new xml files designed to store specifically grades (categories, items, grades...) information. Need analysis. (contact: Andrew).&lt;br /&gt;
&lt;br /&gt;
====After review, organization====&lt;br /&gt;
&lt;br /&gt;
This section will be used to annotate any agreement / conclusion / organization for the next weeks in case the Tracker isn&#039;t enough to do so. Feel free to use it, beloved colleagues, always using the R04xx nomenclature for referencing exact stuff, plz.&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
&lt;br /&gt;
* Go back to [[Backup 2.0|Backup 2.0]] &amp;gt; [[Backup 2.0 - Provide upwards compatibility of Moodle 1.9.x backups|Backup 1.9 =&amp;gt; 2.x main page]].&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_multiple_formats&amp;diff=62240</id>
		<title>Backup 2.0 multiple formats</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_multiple_formats&amp;diff=62240"/>
		<updated>2022-05-03T19:05:25Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{Template:Backup 2.0}}{{Work in progress}}{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
One of the major goals of the [[Backup 2.0|Moodle 2.0 backup]] development is to be able to support multiple formats, both on export (backup) and import (restore), all them handled from core backup/restore code in a central and unified way.&lt;br /&gt;
&lt;br /&gt;
This document explains how those formats will work and interact with Moodle, defining responsibilities and data flow between each part.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Moodle 2.0 has one unique, &#039;&#039;&#039;documented&#039;&#039;&#039;, valid XML format. Details about it can be found in the [[Backup 2.0 XML format|Backup 2.0 XML format]] page. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;(note the page doesn&#039;t exist yet because it&#039;s one of the parts being researched in the next weeks)&amp;lt;/font&amp;gt; This will be the &#039;&#039;&#039;M20-BCK&#039;&#039;&#039; format. It&#039;s highly possible that this format will end being noticeably different from current (monolithic) format used in Moodle 1.9, although internal structures will remain pretty similar.&lt;br /&gt;
&lt;br /&gt;
Also, there is one unique, &#039;&#039;&#039;undocumented&#039;&#039;&#039; (but easily readable and understandable because it&#039;s basically one DB dump) XML format used before Moodle 2.0, let&#039;s call it the &#039;&#039;&#039;M19-BCK&#039;&#039;&#039; (from Moodle 1.9) format. It&#039;s an important format because we need to guarantee that any M19-BCK file will be properly restored in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
And then there are various formats, let&#039;s call them &#039;&#039;&#039;3RD-BCK&#039;&#039;&#039; (3rd part backup formats) that should provide Moodle with extra backup / restore abilities. Notorious examples of these formats are: Blackboard 5.5, Blackboard 6.0 (see [http://cvs.moodle.org/moodle/backup/bb/?pathrev=MOODLE_19_STABLE cvs] to see how they are working in Moodle 1.x), or the new [http://www.imsglobal.org/cc/index.html IMS CC] format. In any case, all them will work in the same way under Moodle 2.0, so let&#039;s put them under the &amp;quot;3RD-BCK&amp;quot; umbrella.&lt;br /&gt;
&lt;br /&gt;
== Restore Data Flow ==&lt;br /&gt;
&lt;br /&gt;
Here it&#039;s one general overview of how those multiple formats are supported on restore. It handles M20-BCK backups (in blue, main restore process) and both 3RD-BCK and M19-BCK formats (in green, handling other formats sub-process).&lt;br /&gt;
&lt;br /&gt;
[[Image:RestoreFormatsActivityDiagram.png|640px]]&lt;br /&gt;
&lt;br /&gt;
([[Media:RestoreFormatsActivityDiagram.dia|original file available here]] - editable with [http://projects.gnome.org/dia Dia])&lt;br /&gt;
&lt;br /&gt;
== Backup Data Flow ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Backup]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Provide_upwards_compatibility_of_Moodle_1.9.x_backups&amp;diff=62239</id>
		<title>Backup 2.0 - Provide upwards compatibility of Moodle 1.9.x backups</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Provide_upwards_compatibility_of_Moodle_1.9.x_backups&amp;diff=62239"/>
		<updated>2022-05-03T19:03:53Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
While the [[Backup 2.0 multiple formats|Backup 2.0 multiple formats]] document describes how different formats will be supported by the restore process in Moodle 2.0, it&#039;s going to be a highly complex task to perform the transformation of Moodle 1.9.x backups into the new, improved, Moodle 2.x backup format. &lt;br /&gt;
&lt;br /&gt;
Too many things have changed between both versions to be able to achieve this easily. Surely it&#039;s computable (as long as upgrade is being able to apply the correct logic, so restore will) but it is going to be handled as a separate development that will allow us to 1) be centered in the 2.0 backup/restore and 2) be free (both in mind and implementation) from any 1.9.x XML format dependency.&lt;br /&gt;
&lt;br /&gt;
=== Goals and basis ===&lt;br /&gt;
&lt;br /&gt;
* The main goal is to create one &#039;&#039;&#039;conversion&#039;&#039;&#039; tool, able to get any Moodle 1.9 backup file and convert it to one Moodle 2.0 backup file. The tool &#039;&#039;&#039;will not perform any modification&#039;&#039;&#039; in the Moodle instance where it is being executed (i.e.the tool won&#039;t import anything). Once the conversion has finished, the standard Moodle 2.0 restore functionality will perform its job.&lt;br /&gt;
* The tool will get one already-uncompressed directory containing one Moodle 1.9 backup file and will create all the needed stuff in the same directory.&lt;br /&gt;
* The tool will have one unique entry point to perform the conversion and will be able to be invoked from within Moodle 2.0 (restore, performing conversion on the fly) or standalone (from CLI interface of any sort of batch processing).&lt;br /&gt;
* The tool will be built using as much infrastructure from Moodle 2.0 as possible (xml processors, plugins, core stuff, logging, debugging...) and will be full OOP (and php, of course).&lt;br /&gt;
* Ideally the conversion will happen in only 1-pass of xml parsing.&lt;br /&gt;
* The tool will be licensed under GPL3 or later and bundled with future releases of Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Before any further analysis is highly recommended to:&lt;br /&gt;
&lt;br /&gt;
* Know as much as possible about the Moodle 2.0 backup infrastructure. Reading the [[Backup 2.0 general architecture| general architecture page]], looking at all the stuff available under the backup/moodle2 directories (each plugin has its own) and understanding how information flows and is stored.&lt;br /&gt;
* Pay special attention and understand these parts of the Moodle 2.0 backup infrastructure:&lt;br /&gt;
** XML parser: In charge of reading all the XML file and dispatching pieces to different processors (backup/util/xml/parser).&lt;br /&gt;
** XML writer: In charge of writing XML files (util/xml/xml_writer.class.php and util/xml/output)&lt;br /&gt;
** Chained loggers: To output any information about the process (backup/util/loggers).&lt;br /&gt;
** Temporary tables, to store transient information if needed.&lt;br /&gt;
&lt;br /&gt;
==== Physical differences ====&lt;br /&gt;
&lt;br /&gt;
After reading the [[Backup 2.0 general architecture| general architecture page]], it&#039;s clear that there are huge differences between the XML used in Moodle 1.9 backups and their Moodle 2.0 counterparts. Let&#039;s dissect them briefly:&lt;br /&gt;
&lt;br /&gt;
* We have changed from one unique monolithic &#039;&#039;&#039;moodle.xml&#039;&#039;&#039; file to a multiple xml files (and directories) alternative.&lt;br /&gt;
* The course, each section and each activity has its own directory.&lt;br /&gt;
* There are some top-level XML files (groups, users, files, questions, roles, scales...) acting as &amp;quot;containers&amp;quot; of information referenced from any course/section/activity (by their inforef.xml files).&lt;br /&gt;
* We have moved from uppercase tags to lowercase everywhere&lt;br /&gt;
* We are using XML attributes for some pieces of information (mainly ids).&lt;br /&gt;
* When possible (modules mainly) the old XML-tree structure has been observed.&lt;br /&gt;
&lt;br /&gt;
==== Logical differences ====&lt;br /&gt;
&lt;br /&gt;
A lot of things have changed from Moodle 1.9 to Moodle 2.0, causing a lot of modifications in the DB schema and, as backup is highly dependent of that (it&#039;s basically one representation of the DB), the information present in the physical xml files above has changed in a noticeable way too.&lt;br /&gt;
&lt;br /&gt;
One good exercise is to create one, more or less, complete test course, backup it in Moodle 1.9, upgrade the site to Moodle 2.0 and backup it again. That way you&#039;ll see where each bit of information has ended in the new format. Also is a good task, in order to understand the changes, to read all the db/upgrade.php scripts present in Moodle 2.0. They show all the modifications performed along the time.&lt;br /&gt;
&lt;br /&gt;
At this point it&#039;s important to avoid get stressed, yes, there are many differences and tons of modifications, some of them really complex. But good news is that, if the upgrade.php scripts have been able to perform the change then, for sure, it is computable and the conversion tool will be able to do the same.&lt;br /&gt;
&lt;br /&gt;
Back to the logical differences, there are some of them needing special attention since day 0 (now):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;files:&#039;&#039;&#039; Under Moodle 1.9, files were stored both in the named &amp;quot;course files&amp;quot; directory (one physical directory) and also under the &amp;quot;moddata&amp;quot; directory (files belonging to modules, like forum attachments, assignment submissions...). Under Moodle 2.0, all the files are physically stored into one file pool (a really cryptic hash-based storage solution) with one logical store in DB, with contexts, components, file areas, hashes and items. The conversion tool will need one sort of &amp;quot;file conversion tool&amp;quot; able to handle any transformation from the old to the new approach, used everywhere.&lt;br /&gt;
* &#039;&#039;&#039;roles and enrolments:&#039;&#039;&#039; Moodle 1.9 enrolments were, simply, some role assignments performed at course level. This has been changed to a more powerful (dual) structure of both role assignments and proper enrollment-plugins. The conversion toll will need to do some &amp;quot;assumptions&amp;quot; in order to convert this information. Also it&#039;s important to note that, while in Moodle 1.9 backups the complete roles were being sent to XML (with all their capabilities and friends), this doesn&#039;t&#039; happen anymore in Moodle 2.0 (where we only store basic information about them).&lt;br /&gt;
* &#039;&#039;&#039;contexts:&#039;&#039;&#039; Under Moodle 1.9, the use of contexts (the course, each activity, each user is one, unique context) was really limited (basically only used for roles and capabilities. Under Moodle 2.0, there are way more information based on contexts (files, comments, ratings, filters, blocks...). Hence we&#039;ll need to assign one context for each component in the backup to be able to associate information to it along the conversion.&lt;br /&gt;
* &#039;&#039;&#039;categories and questions:&#039;&#039;&#039; while the internal representation is pretty similar, now they are handled via standard plugins backup &amp;amp; restore in Moodle 2.0 (see question/type/xxxx/backup/moodle2) so some extra information (extra xml-levels) is required. The tool also should be handling the conversion in a plugin way, allowing other 3rd-part question types conversions to be implemented.&lt;br /&gt;
* &#039;&#039;&#039;blocks:&#039;&#039;&#039; 90% of blocks haven&#039;t any special DB representation nor need especial processing, but the rest (see, for example, the html block or the rss_client one) need custom conversion. So the tool must allow conversion of blocks also in a plugin way.&lt;br /&gt;
* &#039;&#039;&#039;activities:&#039;&#039;&#039; This is the most important part, where all the (educational POV) information resides. Of course, it must work in a plugin way. Here we&#039;ll find activities really easy to convert, because the only noticeable change has been their conversion to the new &amp;quot;files&amp;quot; (commented above). For example, the choice, glossary, forum... modules are good candidates to start with. But there are also some activities that have been completely rewritten / modified since Moodle 1.9. And they will be, without doubts, the most difficult ones to be handled by the conversion tool. Let&#039;s see some of them:&lt;br /&gt;
** &#039;&#039;&#039;resource:&#039;&#039;&#039; Under Moodle 1.9 all we had were types of resources (page, directory...) but all them being types of the (unique) resource module. Under Moodle 2.0, the the module has been split into different modules, each one with its own DB representation and unique features (file, folder, page and url). This split will need to be detected and handled specially by the conversion tool.&lt;br /&gt;
** &#039;&#039;&#039;wiki:&#039;&#039;&#039; Completely rewritten from scratch. Will need important changes both in the xml representation (100% different DB structure) and special process of all the contents (to translate from the old ewiki dialect to the new html implementation). Not to talk about binary contents that will also need special handling.&lt;br /&gt;
** &#039;&#039;&#039;workshop:&#039;&#039;&#039; Also completely rewritten from scratch. Will need important changes in the xml representation, use of subplugins and special process of some contents.&lt;br /&gt;
&lt;br /&gt;
=== Overall process ===&lt;br /&gt;
&lt;br /&gt;
Here there is one ordered list that could serve as technical/development roadmap for the analysis and implementation of the Moodle 1.9 conversion tool. Surely some (practically all) the points below can be split into smaller tasks in order to allow work to advance in parallel. Ideally all them should have one representation as subtasks of MDL-22414. Each task has one alphanumeric code to be used as reference in the future:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;A&#039;&#039;&#039;: Preliminary Tasks&lt;br /&gt;
** &#039;&#039;&#039;A1&#039;&#039;&#039;: Initial report (this document)&lt;br /&gt;
** &#039;&#039;&#039;A2&#039;&#039;&#039;: Organization / roles / actors involved&lt;br /&gt;
** &#039;&#039;&#039;A3&#039;&#039;&#039;: Initial timeline specification&lt;br /&gt;
** &#039;&#039;&#039;A4&#039;&#039;&#039;: Documentation / research / learn&lt;br /&gt;
** &#039;&#039;&#039;A5&#039;&#039;&#039;: Testing use cases, QA specifications&lt;br /&gt;
* &#039;&#039;&#039;B&#039;&#039;&#039;: Infrastructure Tasks&lt;br /&gt;
** &#039;&#039;&#039;B1&#039;&#039;&#039;: XML Parser&lt;br /&gt;
** &#039;&#039;&#039;B2&#039;&#039;&#039;: Conversion dispatcher&lt;br /&gt;
** &#039;&#039;&#039;B3&#039;&#039;&#039;: XML writer&lt;br /&gt;
** &#039;&#039;&#039;B4&#039;&#039;&#039;: Support for plugins (questions, blocks, modules...)&lt;br /&gt;
** &#039;&#039;&#039;B5&#039;&#039;&#039;: Support for subplugins (workshop, assignments...)&lt;br /&gt;
** &#039;&#039;&#039;B6&#039;&#039;&#039;: Integration with Moodle 2.0 restore, logging, output...&lt;br /&gt;
** &#039;&#039;&#039;B7&#039;&#039;&#039;: Progress review / discuss / adjust / timeline&lt;br /&gt;
* &#039;&#039;&#039;C&#039;&#039;&#039;: Conversion Development Tasks&lt;br /&gt;
** &#039;&#039;&#039;C1&#039;&#039;&#039;: Globals (files / users / groups / scales / outcomes / roles / gradebook ...)&lt;br /&gt;
** &#039;&#039;&#039;C2&#039;&#039;&#039;: Course level information&lt;br /&gt;
** &#039;&#039;&#039;C3&#039;&#039;&#039;: Section level information&lt;br /&gt;
** &#039;&#039;&#039;C4&#039;&#039;&#039;: Activity level information&lt;br /&gt;
** &#039;&#039;&#039;C5&#039;&#039;&#039;: Commons (comments / completion / filters / grades / roles /logs ...)&lt;br /&gt;
&lt;br /&gt;
===Followups===&lt;br /&gt;
&lt;br /&gt;
* [[Backup 2.0 - Converters review 2011-04|Review April 2011]]&lt;br /&gt;
* [[Backup 1.9 conversion for developers]]&lt;br /&gt;
&lt;br /&gt;
===See also===&lt;br /&gt;
&lt;br /&gt;
* MDL-22414 - the main tracker issue for this task&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Improve_XML_parsing&amp;diff=62238</id>
		<title>Backup 2.0 - Improve XML parsing</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_-_Improve_XML_parsing&amp;diff=62238"/>
		<updated>2022-05-03T19:03:40Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
[[Backup 2.0]] -&amp;gt; Improve XML parsing&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
Current (Moodle 1.x) restore uses too much memory parsing some &amp;quot;parts&amp;quot; of the XML information. We need to change current approach to one providing optimal memory usage and acceptable throughput. In this page you&#039;ll find the different alternatives researched, with their strengths and weaknesses. Finally one solution will be provided in order to be implemented in new Moodle 2.0 backup &amp;amp; restore. Also, if possible, some changes will be performed in Moodle 1.9 in order to achieve better results and solve bugs like MDL-14302, MDL-15489, MDL-9838...).&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&lt;br /&gt;
Below, you will find some information about different methods used to perform the XML parsing of one 12.5MB file, corresponding to one real quiz module with only 788 attempts and 20115 states (answers). It has been proved to be the problematic &amp;quot;part&amp;quot; in one production server using current Moodle 1.9.x (the file isn&#039;t available here for privacy matters, obviously).&lt;br /&gt;
&lt;br /&gt;
Each method, in order to be considered valid must fulfil these basic objectives:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Parse&#039;&#039;&#039; the XML file.&lt;br /&gt;
* &#039;&#039;&#039;Provide one in-memory object&#039;&#039;&#039; with all the needed info in order to be processed later by the corresponding restore plugin. &#039;&#039;Discussion of this point moved to the [[Development talk:Backup 2.0 - Improve XML parsing|talk page]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For each method, some common information bits are provided (to allow comparisons later).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039;: mnemonic to easily reference each method later in comments.&lt;br /&gt;
* &#039;&#039;&#039;file size&#039;&#039;&#039;: the size of the original XML file being parsed.&lt;br /&gt;
* &#039;&#039;&#039;memory&#039;&#039;&#039;: max memory used by PHP in the execution (provided by [http://php.net/memory_get_peak_usage memory_get_peak_usage()]).&lt;br /&gt;
* &#039;&#039;&#039;time&#039;&#039;&#039;: time required to perform the parsing to memory (measured in seconds).&lt;br /&gt;
* &#039;&#039;&#039;data size&#039;&#039;&#039;: size of the in-memory generated object (final result of the execution).&lt;br /&gt;
* &#039;&#039;&#039;data format&#039;&#039;&#039;: specifications of the in-memory generated object (xmlize compatible, custom...).&lt;br /&gt;
&lt;br /&gt;
=== Table of Results ===&lt;br /&gt;
&lt;br /&gt;
This table summarises the raw results obtained running each method, providing links to details about each of them.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! File size !! Memory !! Time !! Data size !! Format&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 0: Current behaviour (xmlize)|Method 0: Current behaviour (xmlize)]] || 12.5MB || 311.3MB || 4.8 seconds || 14MB || [[#XMLize format|xmlize]]&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 1: SimpleXML parsing + conversion to xmlize format|Method 1: SimpleXML parsing + conversion to xmlize format]] || 12.5MB || 165.8MB || 5.2 seconds || 14MB || [[#XMLize format|xmlize]]&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 2: Method 2: SimpleXML parsing, no conversion|Method 2: Method 2: SimpleXML parsing, no conversion]] || 12.5MB || 36.5MB || 0.5 seconds || 8.5MB || [[#SimpleXML format|simplexml]]&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 3: Custom SAX parser + conversion to xmlize format|Method 3: Custom SAX parser + conversion to xmlize format]] || 12.5MB || 158.3MB || 47.5 seconds || 14MB || [[#XMLize format|xmlize]]&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 4: Custom SAX parser + conversion to xmlize-reduced format|Method 4: Custom SAX parser + conversion to xmlize-reduced format]] || 12.5MB || 72MB || 51.9 seconds || 7.7MB || [[#XMLize-reduced format|xmlize-reduced]]&lt;br /&gt;
|-&lt;br /&gt;
| [[#Method 5: Custom SAX parser + conversion to custom (simple) format|Method 5: Custom SAX parser + conversion to custom (simple) format ]] || 12.5MB || 64.5MB || 15.1 seconds || 5.4MB || [[#Custom-simple format|custom-simple]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Temp Note: To avoid forgetting to talk about : &lt;br /&gt;
** Improve4memory and improve4speed&lt;br /&gt;
** SimpleXML in core (possibility to provide transformation to xmlize for easier contrib code upgrade of backup/restore.&lt;br /&gt;
** Split moodle.xml into multiple files (one for each current &amp;quot;TODO&amp;quot; - part in Moodle 1.9 + 1 per module). Some of this has been worked out/tested in MDL-18468 showing important speed benefits.&lt;br /&gt;
** With that split performed it will be easier to support different &amp;quot;envelopes&amp;quot; for the same modules (section backup/course backup/1 activity backup...).&lt;br /&gt;
** Analyse the possibility to, in a declarative way, be able to define the whole backup &amp;amp; restore process. One XML to specify the whole thing would be amazing... prospect possibilities. Different from install.xml for sure (just in case somebody is thinking about that) (see [[Development talk:Backup 2.0|talk page]]).&lt;br /&gt;
::&#039;&#039;Eloy, declarative is good, but please not XML. We need an machine-readable format that developers understand. Let&#039;s use a PHP API. Defining databases with XML that can only be edited with the built in editor sucks. We should not repeat that choice.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]] 04:53, 8 March 2009 (CDT)&lt;br /&gt;
:::&#039;&#039;Tim, I don&#039;t get the point. What exactly sucks? What is a PHP API? I think XML is the way, 100%&#039;&#039; --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 07:23, 8 March 2009 (CDT)&lt;br /&gt;
&lt;br /&gt;
::::OK, easy example, when you have to edit an XMLDB file by hand becuase the stupid XMLDB editor is buggy, you find yourself editing stuff like&lt;br /&gt;
 &amp;lt;FIELD NAME=&amp;quot;questiondecimalpoints&amp;quot; TYPE=&amp;quot;int&amp;quot; LENGTH=&amp;quot;4&amp;quot; NOTNULL=&amp;quot;true&amp;quot; UNSIGNED=&amp;quot;false&amp;quot; DEFAULT=&amp;quot;-2&amp;quot; SEQUENCE=&amp;quot;false&amp;quot; ENUM=&amp;quot;false&amp;quot; COMMENT=&amp;quot;The number of decimal digits to use when displaying question grades. -1 = use decimalpoints, otherwise a separate setting.&amp;quot; PREVIOUS=&amp;quot;decimalpoints&amp;quot; NEXT=&amp;quot;review&amp;quot;/&amp;gt;&lt;br /&gt;
::::In particular, when you are trying to edit the previous and next links (which are completely unnecessary, separate rant) your editor is scrolled so far over to the right that you cannot actually see which field you are editing the prev and next attributes of. That is my point. XML is a horrible format to edit by hand.&lt;br /&gt;
::::Instead, I would rather work with a PHP API, for example the admin settings API. That is also more flexible. With XML, you can only do the things that the XML lets you do. With PHP, where necessary, you can write PHP code to do anything necessary, in the admin settings case, that may mean making a new settings subclass, or writing some code to compute a default value to feed to a setting constructor. For backup and restore, we will need that sort of flexibility I think.--[[User:Tim Hunt|Tim Hunt]] 01:30, 10 March 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
** Allow modules to request &amp;quot;sub-parts&amp;quot; of the whole module.xml file. While we can accept each module as a whole (an load it straight to memory) some modules (quiz) are big enough to make this approach to cause problems (see MDL-15489). Should be able to request &amp;quot;different sub-parts&amp;quot; using some simple mini-API. (quiz example: &amp;quot;giveme the quiz module data&amp;quot;, or &amp;quot;iterate over the attempts in a nice loop&amp;quot;...). (see [[Development talk:Backup 2.0 - Improve XML parsing|talk page]]).&lt;br /&gt;
** Modules implementing own parser?&lt;br /&gt;
** Backport or analyse some interim solution for 1.9 quizzes.&lt;br /&gt;
&lt;br /&gt;
=== The alternatives analysed ===&lt;br /&gt;
&lt;br /&gt;
Here each of the alternatives is analysed and compared&lt;br /&gt;
&lt;br /&gt;
==== Method 0: Current behaviour (xmlize) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 311.3MB, time: 4.8 seconds, data size: 14MB, data format: xmlize format&lt;br /&gt;
&lt;br /&gt;
==== Method 1: SimpleXML parsing + conversion to xmlize format  ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 165.8MB, time: 5.2 seconds, ata size: 14MB, data format: xmlize format&lt;br /&gt;
&lt;br /&gt;
==== Method 2: SimpleXML parsing, no conversion (use simplexml as final object)  ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 36.5MB, time: 0.5 seconds, data size: 8.5MB, data format: simplexml format&lt;br /&gt;
&lt;br /&gt;
==== Method 3: Custom SAX parser + conversion to xmlize format  ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 158.3MB, time: 47.5 seconds, data size: 14MB, data format: xmlize format&lt;br /&gt;
&lt;br /&gt;
==== Method 4: Custom SAX parser + conversion to xmlize-reduced format  ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 72MB,  time: 51.9 seconds, data size: 7.7MB, data format: xmlize-reduced format&lt;br /&gt;
&lt;br /&gt;
==== Method 5: Custom SAX parser + conversion to custom (simple) format  ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: file size: 12.5MB, memory: 64.5MB, time: 15.1 seconds, data size: 5.4MB, data format: custom simple format&lt;br /&gt;
&lt;br /&gt;
== Formats ==&lt;br /&gt;
&lt;br /&gt;
In this section there are some explanations about the different object formats generated by the different methods:&lt;br /&gt;
&lt;br /&gt;
=== XMLize format ===&lt;br /&gt;
&lt;br /&gt;
=== SimpleXML format ===&lt;br /&gt;
&lt;br /&gt;
=== XMLize-reduced format ===&lt;br /&gt;
&lt;br /&gt;
=== Custom-simple format ===&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Here its&#039; the code used for the different parsing methods commented above:&lt;br /&gt;
&lt;br /&gt;
=== Method 0: Current behaviour ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$contents = file_get_contents(&#039;moodle.xml&#039;);&lt;br /&gt;
$data = xmlize($contents);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_known_problems&amp;diff=62237</id>
		<title>Backup 2.0 known problems</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_known_problems&amp;diff=62237"/>
		<updated>2022-05-03T19:03:29Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[Backup 2.0 - Improve XML parsing|Improve XML parsing]]&#039;&#039;&#039;: One of the major bottlenecks in backup and, especially, in restore reliability under Moodle 1.x has been the large amount of memory needed to handle those operations (see bugs like MDL-14302, MDL-15489, MDL-9838... and many others). While the whole XML file (moodle.xml) is parsed in a [http://en.wikipedia.org/wiki/Simple_API_for_XML SAX] way (hence, &amp;quot;streamed&amp;quot; and requiring small amounts of memory),  we use to group some XML contents into &amp;quot;parts&amp;quot; in order to delegate the operations over those &amp;quot;parts&amp;quot; to different plugins (modules, blocks...). And problems arrive when some of those &amp;quot;parts&amp;quot; are big enough and processing them with the [http://php.net/xml_parse_into_struct xml_parse_into_struct()] function and the [http://www.hansanderson.com/php/xml/ xmlize] library uses exaggerated amounts of memory (for example, to process a 12.5MB file requires 311MB of memory, crazy!). So we need to switch to an alternate method to parse those &amp;quot;parts&amp;quot; using much less memory and to build the corresponding in-memory object with one acceptable throughput (speed).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[Backup 2.0 - Provide upwards compatibility of Moodle 1.9.x backups|Upwards compatibility of Moodle 1.9.x backups]]&#039;&#039;&#039;: While the [[Backup 2.0 multiple formats|Backup 2.0 multiple formats]] document describes how different formats will be supported by the restore process in Moodle 2.0, it&#039;s going to be a highly complex task to perform the transformation of Moodle 1.9.x backups into the new, improved, Moodle 2.x backup format. Too  many things have changed between both versions to be able to achieve this easily. Surely it&#039;s computable (as long as upgrade is being able to apply the correct logic, so restore will) but it is going to be handled as a separate development that will allow us to 1) be centred in the 2.0 backup/restore and 2) be free (both in mind and implementation) from any 1.9.x XML format dependency.&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_general_architecture&amp;diff=62236</id>
		<title>Backup 2.0 general architecture</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_general_architecture&amp;diff=62236"/>
		<updated>2022-05-03T19:03:21Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
This page tries to explain briefly all the rationale behind [[Backup 2.0]]. It isn&#039;t a complete and exhaustive description of the whole thing, but a summary showing the main concepts involved.&lt;br /&gt;
&lt;br /&gt;
== Nomenclature ==&lt;br /&gt;
&lt;br /&gt;
When talking about backup, there are some basic terms that it&#039;s better to have clearly defined. Here they are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup (or restore) Type&#039;&#039;&#039;: Simply, what is being handled, and, at the time of writing this, can be: 1 activity, 1 section or 1 course.&lt;br /&gt;
* &#039;&#039;&#039;Backup Format&#039;&#039;&#039;: The &amp;quot;physical&amp;quot; representation of the information to be handled and its organization in one transferable file. The main format is, of course, the &amp;quot;moodle2&amp;quot; format (the one that guarantees the max data to be preserved when moving Moodle contents), with others in the pipeline, like the &amp;quot;imscc&amp;quot; format and friends...&lt;br /&gt;
* &#039;&#039;&#039;Interactivity&#039;&#039;&#039;: To determine if the process, once launched, requires user interaction or not. Basically an interactive backup/restore is needed in order to give the user a UI to adjust all the settings (options) before the process is launched.&lt;br /&gt;
* &#039;&#039;&#039;Execution:&#039;&#039;&#039;: To determine if the execution of the process is immediate or delayed (scheduled?). Has implications in the output of the process, logging and others.&lt;br /&gt;
* &#039;&#039;&#039;Backup Mode&#039;&#039;&#039;: Can be considered like &amp;quot;purposes&amp;quot; of the backup, and based on them, various options will be defined and locked. Think on them like some sort of presets or hardcoded rules altering the settings and process.&lt;br /&gt;
* &#039;&#039;&#039;Backup Defaults&#039;&#039;&#039;: Or how settings are configured initially, each time a backup/restore is requested. They are defined for each (backup) &#039;&#039;&#039;Type&#039;&#039;&#039; and &#039;&#039;&#039;Format&#039;&#039;&#039; and are altered depending on the &#039;&#039;&#039;Mode&#039;&#039;&#039; selected.&lt;br /&gt;
* &#039;&#039;&#039;Backup UI&#039;&#039;&#039;: The front-end displayed to the user in &#039;&#039;&#039;Interactive&#039;&#039;&#039; backups, allowing him/her to configure the backup settings. This includes any feedback from the backup system &#039;&#039;&#039;before&#039;&#039;&#039; the execution process is started. Strongly form-based.&lt;br /&gt;
* &#039;&#039;&#039;Backup Output&#039;&#039;&#039;: The front-end displayed to the user in &#039;&#039;&#039;Interactive&#039;&#039;&#039; and &#039;&#039;&#039;Immediate&#039;&#039;&#039; backups showing information &#039;&#039;&#039;after&#039;&#039;&#039; the process starts, showing any information about the different steps being executed, final status...&lt;br /&gt;
&lt;br /&gt;
== Backup ==&lt;br /&gt;
&lt;br /&gt;
=== The components ===&lt;br /&gt;
&lt;br /&gt;
These are the main components involved in backup and their main responsibilities in the process:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Controller&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/controller/ cvs]) It&#039;s the main object in the life of one backup operation. It contains all the information needed in order to be able to execute a backup successfully (you can see some more details in the next section). From the complete specs of the backup (type, mode, execution, interactivity, source...), including all the settings, logging, output options and also the whole backup plan to be executed and various steps that any backup must fulfil (load defaults, ui invocation, apply security constraints...). Everything happens in / is done by the backup controller. One important feature is that it &#039;&#039;&#039;must&#039;&#039;&#039; be 100% serializable, so all their elements (before process execution) must be also, serializable. This guarantees we can delay execution, safely storing the whole controller in DB while we &#039;&#039;&#039;avoid completely&#039;&#039;&#039; using sessions for backup transient information.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Loggers&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/loggers/ cvs]) Typical loggers chain able to log information to various places (DB, file, error_log...). With typical logging levels and so on. Should be configurable globally from admin options. Each backup controller has one chain of loggers instantiated.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Destinations&#039;&#039;&#039; ([http://cvs.moodle.org/moodle/backup/util/destinations/ cvs]) (not implemented yet!): The basic idea about backup destinations is to be able to send the final backup file to/over a variety of systems. For example, in backups of Moodle = HUB, we could be sending the backup file to the corresponding Moodle HUB, or to other repositories, or by email, or direct download... or any combination of these. For now, they only will be able to send the backup files to different file areas within Moodle, or perhaps they won&#039;t be used at all initially. To be decided.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Settings&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/settings/ cvs]) Anything altering backup behaviour must be considered to be one setting. No matter if it has visual representation in the UI or not, or if can be configured by the user or not. It&#039;s a setting. And other components in backup will rely on setting values to conditionally perform different actions. Note that each setting has one level (root, course, section, activity) and they follow somehow the observer pattern so relations and dependencies between them can be specified easily (and UI must respect them).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup UI&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/ui/ cvs]) (not implemented yet!): All the stuff that, once all the settings have been created and pre-defined (observing defaults, security and dependencies), will organize them in one usable front-end, allowing the user to interact with them, changing the final behaviour of the process.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Output&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/output/ cvs]) In charge of show information about the process, this singleton can receive requests from the backup loggers and/ or by direct invocation. Current implementation is pretty simple (just prints one list of messages, but could be extended to support progress bars and /or other commodities).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Structure&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/structure/ cvs]) The base component on top of which all the rest of backup is built. Implements one simple PHP API allowing to define (virtually) any structure suitable to be sent to xml, fetch any information (using the visitor pattern to recursively process the whole tree) from iterator and perform other operations in a transparent and consistent way. In three words, &#039;&#039;&amp;quot;the heart of backup&amp;quot;&#039;&#039; (well, they are four).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Backup Plan&#039;&#039;&#039;: ([http://cvs.moodle.org/moodle/backup/util/plan/ cvs] and [http://cvs.moodle.org/moodle/backup/moodle2/ cvs2]) The execution plan, dependent of the Type and Format of the backup. Split into tasks, each one having one or more steps. Note there are two types of steps: &#039;&#039;&#039;execution steps&#039;&#039;&#039; that only execute (custom) php code, used for anything not being XML output and &#039;&#039;&#039;structure steps&#039;&#039;&#039; that, using the &amp;quot;backup structure&amp;quot; component, are used basically to generate XML output. Note they are spread out in the moodle code, so each block and activity, for each format available, will have its own plans, tasks and steps. Also in three words, &#039;&#039;&amp;quot;backup&#039;s skeleton&amp;quot;&#039;&#039; (grrr, they are two now).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Other components&#039;&#039;&#039;: Last, some more components that are good to know about, all them being non-instantiable classes with static execution of methods:&lt;br /&gt;
** Backup checks: ([http://cvs.moodle.org/moodle/backup/util/checks/ cvs]) Various fixed checks performed by the controller. Security being the most important.&lt;br /&gt;
** Backup dbops: ([http://cvs.moodle.org/moodle/backup/util/dbops/ cvs]) Operations involving DB access must go here, not 100%, but at least to avoid &amp;quot;spaghetti code&amp;quot; in above (critical) components.&lt;br /&gt;
** Backup helper: ([http://cvs.moodle.org/moodle/backup/util/helper/ cvs]) Classes and methods not being part of other components but being used along the backup process. Some iterator implementations to help backup structures, some functions used more than 1 time...&lt;br /&gt;
** Backup factories: ([http://cvs.moodle.org/moodle/backup/util/factories/ cvs]) Some methods in charge of, dynamically, instantiate different objects along the backup process. Mainly supporting backup plans and tasks.&lt;br /&gt;
** Backup interfaces: ([http://cvs.moodle.org/moodle/backup/util/interfaces/ cvs]) Very basic interfaces to enforce the implementation of some methods in order to achieve functionalities in a consistent way (checksum-able, process-able....).&lt;br /&gt;
** Backup xml-writer: ([http://cvs.moodle.org/moodle/backup/util/xml/ cvs]) Very low level XML writer implementation, with error detection, support for memory/file output, dynamic contents transformations. Used extensively in the process to output all the XML contents.&lt;br /&gt;
** ... (note there are some more components, but they don&#039;t seem to be important enough to be introduced here).&lt;br /&gt;
&lt;br /&gt;
=== The process ===&lt;br /&gt;
&lt;br /&gt;
Any backup will go through the following steps:&lt;br /&gt;
&lt;br /&gt;
# Backup controller instantiation, that automatically&lt;br /&gt;
## Performs various checks, prepare loggers, destinations and other components&lt;br /&gt;
## Load the backup plan (so settings become available)&lt;br /&gt;
## Apply defaults to settings (based in $CFG config options and backup type/format/mode)&lt;br /&gt;
## Apply security constraints to settings (modifying settings if necessary)&lt;br /&gt;
# If the backup is interactive, looping over the next steps until finished:&lt;br /&gt;
## Save / load the controller as necessary (to make it persistent along multiple requests).&lt;br /&gt;
## Show UI (observing settings status, values and dependencies)&lt;br /&gt;
## Process UI changes&lt;br /&gt;
## Re-apply security constraints to settings (with error if something is violated)&lt;br /&gt;
# Finish UI if was used (interactive)&lt;br /&gt;
# Save the controller if execution delayed (cron will get it later - once implemented)&lt;br /&gt;
# Execute controller plan (so everything will be generated)&lt;br /&gt;
&lt;br /&gt;
So, just as an example for the impatient people, literally following the steps above, and knowing that the UI implementation and other bits are still missing, here it&#039;s your first course backup (just replace the XXs and execute it). Please ignore any output in browser / command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once(&#039;config.php&#039;);&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot . &#039;/backup/util/includes/backup_includes.php&#039;);&lt;br /&gt;
&lt;br /&gt;
$course = XX; // id of the course to backup&lt;br /&gt;
$user   = XX; // id of the user performing the backup&lt;br /&gt;
&lt;br /&gt;
$bc = new backup_controller(backup::TYPE_1COURSE, $course, backup::FORMAT_MOODLE,&lt;br /&gt;
                            backup::INTERACTIVE_YES, backup::MODE_GENERAL, $user);&lt;br /&gt;
$bc-&amp;gt;finish_ui();&lt;br /&gt;
$bc-&amp;gt;execute_plan();&lt;br /&gt;
$bc-&amp;gt;get_results();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should end with one directory under $CFG-&amp;gt;dataroot/temp/backup having the complete backup contents within it. Time to take a look to it.&lt;br /&gt;
&lt;br /&gt;
=== The results ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temp note&#039;&#039;&#039;: First of all, did I say that your execution above should be performed in one course having some forum(s)? As far as right now, forum is the only activity with backup implemented... it&#039;s a good recommendation. ;-) In the other side, all blocks, filters, comments, ratings, role assignments and overrides ... are fully supported, so use them here and there.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temp note2&#039;&#039;&#039;: There are some missing bits in the explanations below. More noticeable are questions and their categories and complete gradebook information. Will be added once decided and implemented.&lt;br /&gt;
&lt;br /&gt;
This section tries to summarize the final results of one &amp;quot;moodle2&amp;quot; format backup. As listed in the requirements of the project, we are moving from one &#039;&#039;&#039;&amp;quot;monolithic&amp;quot;&#039;&#039;&#039; moodle.xml file to one multi-file format, &#039;&#039;&#039;better structured and easier to be handled&#039;&#039;&#039; by restore. At the same time, while contents will be practically the same (as far as the xml generated) continues being one structured &amp;quot;database dump&amp;quot; one of the main visually differences is that we have, finally, moved to &#039;&#039;&#039;lowercase tag names&#039;&#039;&#039; (Moodle 1.x used to have everything uppercase). &lt;br /&gt;
&lt;br /&gt;
Also, we have introduced some &#039;&#039;&#039;new &amp;quot;references&amp;quot; files&#039;&#039;&#039; will provide information about which part of the backup is using which instances of some elements so, on restore, if we are restoring one course partially, only the &amp;quot;used&amp;quot; files / groups / users / scales ... will be restored. This was one of the major design limits in Moodle 1.x backup, where those items were restored always completely and not selectively based in that extra &amp;quot;usage&amp;quot; information.&lt;br /&gt;
&lt;br /&gt;
From an organizational point of view, folders follow the schema of available Backup Types (see above). So, in the backup generated file we are going to find, always, one of more of this folders:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;course&#039;&#039;&#039;: (present only in 1 course backups). Will contain information about the course (course.xml), role uses (assignments and overrides), comments, filters, logs and, of course, blocks (we comment about them below) and the corresponding &amp;quot;references&amp;quot; (inforef.xml) file, pointing about uses of some key components, as explained above.&lt;br /&gt;
* &#039;&#039;&#039;sections&#039;&#039;&#039; (present in 1 course and 1 section backups). Will contain &#039;&#039;&#039;one directory for each section&#039;&#039;&#039; included in backup (numbered with the section-&amp;gt;id). Each section will contain information about the section (section.xml) and its corresponding &amp;quot;references&amp;quot; file (just referencing file uses).&lt;br /&gt;
* &#039;&#039;&#039;activities&#039;&#039;&#039; (present in all backups). Will contain &#039;&#039;&#039;one directory for each activity&#039;&#039;&#039; included in backup (numbered with the cm-&amp;gt;id). Each activity will contain information about the activity (&#039;&#039;activityname&#039;&#039;.xml), its module characteristics (module.xml), role uses, filter, comments, user completion, logs, activity grade items...) and, once more, blocks and the corresponding references file.&lt;br /&gt;
&lt;br /&gt;
Special mention is necessary for the &amp;quot;blocks&amp;quot; directory (present under each course / activity dir). As far a blocks are 1st class citizens in Moodleland, they can have a lot of information associated so they have their own space in backups. It will be &#039;&#039;&#039;one directory for each block belonging to that&#039;&#039;&#039; course/activity (numbered with block_instance-&amp;gt;id). Each block directory will contain information about the block (block.xml), optionally information about the DB related to the block (&#039;&#039;blockname&#039;&#039;.xml), roles, comments and the corresponding references file.&lt;br /&gt;
&lt;br /&gt;
Finally we have to talk about the backup root directory and what we can find there:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;moodle_backup.xml&#039;&#039;&#039;: it&#039;s the root file in the backup. It contains information about the backup itself: versions, details, summary of contents and full list of settings, as configured on backup. We can consider it like the &amp;quot;map&amp;quot; that shows/describes the whole backup and it will be highly useful in the restore process.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;files.xml&#039;&#039;&#039; and &#039;&#039;&#039;&amp;quot;files&amp;quot;&#039;&#039;&#039; directory. It contains &#039;&#039;&#039;all&#039;&#039;&#039; the files used in the backup process, no matter of which course/section/activity is using them. Its internal structure is kinda similar to current moodle file storage structure, although this could diverge (safely) in the future. Of course, it&#039;s important to comment that we have all those &amp;quot;reference&amp;quot; (inforef.xml) files spread along the course/section/activity/block directories above so it will be &#039;&#039;&#039;easy to pick&#039;&#039;&#039; the needed on restore.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;other files&#039;&#039;&#039; (users, roles, scales, groups, outcomes...). All these follow the same pattern as the files.xml file above, as far as all them &#039;&#039;&#039;are merely &amp;quot;stores&amp;quot;&#039;&#039;&#039; of all the information used by any backup part. Once more, reference files will point to the required ones on restore.&lt;br /&gt;
&lt;br /&gt;
That is!&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_drop_in_ideas&amp;diff=62235</id>
		<title>Backup 2.0 drop in ideas</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_drop_in_ideas&amp;diff=62235"/>
		<updated>2022-05-03T19:03:11Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{Template:Backup 2.0}}This page collects all the ideas collected/suggested by the Community, related to [[Backup 2.0|Backup 2.0]] along the last months. They are distilled/discussed with detail in the [[Backup 2.0 requirements|requirements]] page in order to get a comprehensible list to be fulfilled in the development process. Here it&#039;s the original raw list (just numbered for easier reference):&lt;br /&gt;
&lt;br /&gt;
# Enable Backup and restore of a Course and it&#039;s related meta courses IN ONE HIT to save on adminstration time. &lt;br /&gt;
# Support incremental backups &amp;amp; restore.&lt;br /&gt;
# Support 1-activity backup.&lt;br /&gt;
# Backup/restore one topic only (not just one activity) --[[User:Samuli Karevaara|Samuli Karevaara]] 21:29, 5 March 2009 (CST)&lt;br /&gt;
# Support anonymisation of personal data on backup.&lt;br /&gt;
# Separate process and progress. &#039;&#039;(Perhaps [http://cvs.moodle.org/moodle/lib/weblib.php?r1=1.1214&amp;amp;r2=1.1215 these classes I wrote] can help)--[[User:Tim Hunt|Tim Hunt]] 19:41, 1 March 2009 (CST)&#039;&#039;&lt;br /&gt;
# XML format doesn&#039;t need to be radical different (IMO).&lt;br /&gt;
# Support restore of old (1.9 only?) backups.&lt;br /&gt;
# Hook in backup &amp;amp; restore to [[Backup 2.0 multiple formats|intercept &amp;amp; support other formats (BB, IMS-CC...)]]&lt;br /&gt;
# One code base both for manual and scheduled backup&lt;br /&gt;
# Scheduled restore&lt;br /&gt;
# Fix restore so that one can also select to restore course settings (they are currently backed up, but not restored in any restore function.)&lt;br /&gt;
# Fileless export/import (aka fix import function so that one can choose to import blocks, course settings, etc. in addition to resources/activities)&lt;br /&gt;
# Export/import over mnet&lt;br /&gt;
# OOP.&lt;br /&gt;
# Secure (don&#039;t handle non-allowed data, user matching on restore, salted passwords..)&lt;br /&gt;
# Safe (some sort of &amp;quot;rollback&amp;quot; on failure - requires to have everything annotated somewhere - backup_ids or so).&lt;br /&gt;
# file-less backups - if you have separate backups, import/export etc.&lt;br /&gt;
# Allow to backup one category of courses (at the same time, one zip per course). MDL-17187&lt;br /&gt;
# Allow to mark courses to be excluded from scheduled backup manually.&lt;br /&gt;
# Avoid anti-timeout output when not running from browser. MDL-17282&lt;br /&gt;
# Review related caps, cleaning them and adding missing bits, improving sec. consistency.&lt;br /&gt;
# Log all backups (both manual and scheduled). Improve logging in general.&lt;br /&gt;
# Separate each module&#039;s portion of XML into its own namespace.&lt;br /&gt;
# Use the namespaces to allow each module the option of validating it&#039;s XML content before processing.&lt;br /&gt;
# Roll dates: on restore or import, allow instructor to input a start date, and roll all assignment, quiz, etc. dates forward based on the new start date.&lt;br /&gt;
# Backup would need to be called when publish a course on the community hub ([https://docs.moodle.org/en/Community_hub#Publish_course course template])&lt;br /&gt;
# Metadata... to be included in backup/restore... something like: [[Metadata]]&lt;br /&gt;
# Allow backup of roles with permissions, assigns and overrides. MDL-17081&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; list items marked with ✔ have been analysed/added as development [[Backup 2.0 requirements|requirements]].&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_requirements&amp;diff=62234</id>
		<title>Backup 2.0 requirements</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_requirements&amp;diff=62234"/>
		<updated>2022-05-03T19:02:58Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
This page shows the analysis/justification/decision for all the [[Backup 2.0 drop in ideas|drop in ideas]] detected/suggested along the last months mashed up with the main goals of the project. While pinpointing all the requirements of the new Backup 2.0, also we&#039;ll be defining the main list of tasks to fulfil them.&lt;br /&gt;
&lt;br /&gt;
== RQ01:  ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Enable Backup and restore of a Course and it&#039;s related meta courses IN ONE HIT to save on adminstration time&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Meta courses are out in Moodle 2.0 and their functionality will be, somehow, replaced my the new [[Cohorts | Cohorts]] (a.k.a. site-wide groups). In any case, and as a general rule, any backup / restore operation involving more that one course is not backup / restore responsibility (i.e. the functionality is not built in there) but responsibility of newly scripts using the new backup API to do those &amp;quot;multiple operations&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== RQ02: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Support incremental backups &amp;amp; restore&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This has been a requirement since long time ago (see various discussions in the Forums). Anyway it seems that, at the end, the only way to accomplish this with certain degree of success is to use &#039;&#039;&#039;external tools&#039;&#039;&#039; to calculate the differences between two backup files and apply them in order to build the necessary final backup file to be restored. The alternative approach, to make the functionality to be available under Moodle would require time/hast stamping near all information and keeping big logs of each backup file in order to selectively know what needs to be exported / imported. Not viable.&lt;br /&gt;
&lt;br /&gt;
So, from the backup / restore perspective, there is &#039;&#039;&#039;nothing to do&#039;&#039;&#039; but to provide information in one format that makes those &amp;quot;external tools&amp;quot; to be able to handle information properly. With the current changes already performed in the backup format (where information is highly splited, that should be far easier than under Moodle 1.9).&lt;br /&gt;
&lt;br /&gt;
== RQ03: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Support 1-activity backup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Supported!&lt;br /&gt;
&lt;br /&gt;
== RQ04: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Support 1-section backup (topic/week)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Supported!&lt;br /&gt;
&lt;br /&gt;
== RQ05: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Support anonymisation of personal data on backup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Supported! Right now it&#039;s limited to anonymize user information bits (name, email...) and related info (preferences, tags, personal files...) to be exported. There are two points that could be improved:&lt;br /&gt;
&lt;br /&gt;
* Improvements to the anonymizer (MDL-22158): Make information to &amp;quot;look&amp;quot; better, using random names and so on.&lt;br /&gt;
* Be more intrusive (NOBUG): Also anonymize (replace) file submissions and friends by &amp;quot;template-blank&amp;quot; files.&lt;br /&gt;
&lt;br /&gt;
== RQ06: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Separate process and progress&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is one of the primary goals of the new subsystem. Already have two well defined points where visualization can happen (conditionally). The backup / restore UI (MDL-22142 - previous to process). And the output process (MDL-22144 - handled by output singleton). Both used only if necessary and not interfering the process itself at all. Also, logging (MDL-22143) has been separated from process and delegated to proper loggers. Finally, heartbeat information (MDL-22143 - needed to avoid browser timeouts) is also performed transparently by the process and developer doesn&#039;t need to do it manually any more.&lt;br /&gt;
&lt;br /&gt;
== RQ07: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;XML format doesn&#039;t need to be radical different&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
While the original idea (at early Moodle 2.0 planning stages) was to keep the Backup 2.0 format as similar as possible with 1.x format, finally some core changes (new [[File API|File API]]...), other requirements (like 1-activity, 1-section backups, see above...) and the need to modernize a bit the old format  (uppercase, not using attributes...), have produced this original thoughts to change. So Moodle 2.0 will debut one new format, split along multiple files for easier reference / manipulation. &lt;br /&gt;
&lt;br /&gt;
Note that contents will be basically the same, as far as contents are just &amp;quot;DB dumps&amp;quot;. They just will be more organized along different files. See the [[Backup 2.0 general architecture|general architecture]] page for more information about the new format.&lt;br /&gt;
&lt;br /&gt;
== RQ08: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Support restore of old (1.9 only?) backups&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a &#039;&#039;&#039;must&#039;&#039;&#039; requirements and will be developed once Moodle 2.0 &amp;lt;==&amp;gt; 2.0 backup / restore is completely working. It will use the mechanism described at [[Backup 2.0 multiple formats|backup multiple formats]] so the format will be intercepted and converted. In any case it&#039;s going to be a really complex task, due to the deep changes performed in Moodle 2 (new modules, files...) and is, by itself, one separated project which codebase won&#039;t interfere at all with Moodle 2.0 backup / restore (although will be executed as part of it normally).&lt;br /&gt;
&lt;br /&gt;
== RQ09: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hook in backup &amp;amp; restore to intercept &amp;amp; [[Backup 2.0 multiple formats|support other formats]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Backup will allow the generation of backup files in different formats. This is supported from core, so once the corresponding backup controller is instantiated and the corresponding format specified, everything (settings, ui, plan, tasks and steps) will be performed accordingly with that backup format.&lt;br /&gt;
&lt;br /&gt;
In the other side, restore will detect as soon as possible the format of the file, performing the necessary conversions to transform the original format detected into one suitable Moodle 2.0 backup format.&lt;br /&gt;
&lt;br /&gt;
== RQ10: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;One code base both for manual and scheduled backup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Process will be unique. This is 100% mandatory. Another thing is the &amp;quot;scheduled&amp;quot; bit of those backups and their &amp;quot;iterative&amp;quot; (multiple) characteristic. Both are out from backup process responsibilities (see [[#RQ01:|RQ01]] above). One script / cron combination will provide such functionalities while using core backup API for each of the target courses when necessary.&lt;br /&gt;
&lt;br /&gt;
== RQ11: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scheduled restore&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ12: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix restore so that one can also select to restore course settings&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ13: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fileless export/import&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ14: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Export/import over mnet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ15: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OOP&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ16: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Secure&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ17: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Safe&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ18: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;file-less backups - if you have separate backups, import/export etc.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ19: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Allow to backup one category of courses. MDL-17187&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ20: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Allow to mark courses to be excluded from scheduled backup manually&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ21: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Avoid anti-timeout output when not running from browser. MDL-17282&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ22: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Review related caps, cleaning them and adding missing bits, improving sec. consistency&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ23: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Log all backups (both manual and scheduled). Improve logging in general&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ24: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Separate each module&#039;s portion of XML into its own namespace&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ25: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Use the namespaces to allow each module the option of validating it&#039;s XML content before processing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ26: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Roll dates&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ27: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Backup would need to be called when publish a course on the community hub&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ28: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Metadata... to be included in backup/restore. Something like [[Metadata]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== RQ29: ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Allow backup of roles with permissions, assigns and overrides. MDL-17081&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0_overview&amp;diff=62233</id>
		<title>Backup 2.0 overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0_overview&amp;diff=62233"/>
		<updated>2022-05-03T19:02:47Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{obsolete}}&lt;br /&gt;
&lt;br /&gt;
== Non-functional requirements ==&lt;br /&gt;
&lt;br /&gt;
* Change format dramatically, splitting current monolithic moodle.xml into smaller pieces (1xplugin, 1xusers, 1xroles, 1x...). Working in experimental way since 1.9, proved to be great for speed (saves ~20 repeated parsings of the whole file). No dependencies from previous stuff at all.&lt;br /&gt;
* Change the current &amp;quot;xmlize&amp;quot; approach when restoring files to one new progressive_parser instead. Each part of restore will decide how it wants to receive the information and who is in charge of processing it. Great for memory.&lt;br /&gt;
* Allow 1-activity, 1-section and 1-course backup. Use different shells/envelopes for any type of backup, keeping the &amp;quot;content&amp;quot; the same.&lt;br /&gt;
* Unify all multiple backup variations (course backup, course export, silent backup, scheduled backup) into a single codebase. Same for multiple restore.&lt;br /&gt;
* Backup and restore execution function (only ONE function, the executor!!) will be &amp;quot;blind&amp;quot;: They won&#039;t perform decisions based on (changing) roles/capabilities/configuration settings any more. One master &amp;quot;backup_director&amp;quot; object will direct them once the object has performed all validations and ensured the process is executable. That director will handle/decide/instruct the executor about output/logging and everything else.&lt;br /&gt;
* Store complete information about any backup/restore performed in the site. This will include all the information for the the director (array-serialised) and the results of the executor. And obviously all the logged info cached when running.&lt;br /&gt;
* Important UI changes:&lt;br /&gt;
** UI won&#039;t make any processes! (like pre-calculating, or post-checks and friends). It will be completely separate from the &amp;quot;director&amp;quot; and the &amp;quot;executor&amp;quot;.&lt;br /&gt;
** Complete site/user defaults&lt;br /&gt;
** View the backup/restore form in &amp;quot;course&amp;quot; organisation (inline? nah for 2.0 IMO) instead of grouped by activity mode. Surely over multiple configuration &amp;quot;steps&amp;quot;.&lt;br /&gt;
** Bunch of new detail-options (restore section descriptions, overwrite course settings..., usually requested).&lt;br /&gt;
* Reuse code like crazy. Some things like the &amp;quot;id-remapping&amp;quot; on restore, the logs output, the &amp;quot;flush&amp;quot; output and so on will be central and any point of restore will be able to request that &amp;quot;services&amp;quot; or &amp;quot;utilities&amp;quot; when desired in a easy way (mini PHP-API to define things in a declarative way VS one/multiple helpful backup/restore &amp;quot;utilities&amp;quot; classes).&lt;br /&gt;
&lt;br /&gt;
== Preliminary notes ==&lt;br /&gt;
&lt;br /&gt;
=== Splitting information ===&lt;br /&gt;
&lt;br /&gt;
* All the existing/required caps define behaviour for each one.&lt;br /&gt;
* All the zones and splitter.&lt;br /&gt;
* Files backup/ restore.&lt;br /&gt;
* 1.9 =&amp;gt; 2.0 transformations.&lt;br /&gt;
* Shells, separate structure and activities/blocks.&lt;br /&gt;
* Backup by &amp;quot;context&amp;quot;. Each &amp;quot;context&amp;quot;(or inner items) will have:&lt;br /&gt;
** users&lt;br /&gt;
** groups&lt;br /&gt;
** files&lt;br /&gt;
** logs&lt;br /&gt;
** blocks&lt;br /&gt;
** role definitions&lt;br /&gt;
** role assignments&lt;br /&gt;
** role overrides&lt;br /&gt;
** completion info&lt;br /&gt;
** conditional info&lt;br /&gt;
** comments&lt;br /&gt;
** tags&lt;br /&gt;
** questions and categories&lt;br /&gt;
** gradebook: scales/outcomes and &amp;quot;activity grade items&amp;quot;.&lt;br /&gt;
** gradebook: agregations/calculations and categories.&lt;br /&gt;
** filters&lt;br /&gt;
** metadata&lt;br /&gt;
** messages&lt;br /&gt;
** events&lt;br /&gt;
** blogs&lt;br /&gt;
(alternatively, all these parts can be found at the end of the backup file, globally for all contexts)&lt;br /&gt;
&lt;br /&gt;
=== CZ Hackfest thoughts ===&lt;br /&gt;
&lt;br /&gt;
* Need stamps for users (perhaps not because of MDL-16658) and roles (like question/categories ones) to guarantee uniqueness.&lt;br /&gt;
* Need to decide about backup file names (moving from .zip to .xxx). Multiple extensions or prefixed info to &amp;quot;tell more&amp;quot; about the backup type.&lt;br /&gt;
* 1.9 =&amp;gt; 2.0 restore:&lt;br /&gt;
** Really complex, needs to mimic all current logic in upgrade.php scripts:&lt;br /&gt;
*** xml transformations --&amp;gt; relatively easy&lt;br /&gt;
*** files migration (course and moddata)&lt;br /&gt;
*** wiki, resources, workshop transformations (complex)&lt;br /&gt;
*** incoming question bank changes.&lt;br /&gt;
*** surely other stuff (comments, messages, blogs)&lt;br /&gt;
** Possible solutions:&lt;br /&gt;
*** How:&lt;br /&gt;
**** Reuse as much as possible code from upgrade scripts. Not everything is re-usable (bulk changes).&lt;br /&gt;
**** Re-implement all the logic in restore.&lt;br /&gt;
**** Forgetting about it&lt;br /&gt;
*** When:&lt;br /&gt;
**** In one step, so Moodle 2.0 will natively-on-the-fly be able to process 1.9 files. Impossible!&lt;br /&gt;
**** Keep it within Moodle, so conversion will be executed transparently immediately before restore (in the original plan at [[Backup 2.0 multiple formats]]. &lt;br /&gt;
**** Completely separate utility, so files need to be transformed before being accepted by restore.&lt;br /&gt;
**** Never&lt;br /&gt;
*** Where:&lt;br /&gt;
**** Restore everything into some duplicate tables in order to do the conversion there.&lt;br /&gt;
**** Do that into memory/some specialised tables not duplicating anything.&lt;br /&gt;
**** Nowhere&lt;br /&gt;
* Scheduled backups (it&#039;s just a &amp;quot;timed&amp;quot; backup iterator). Do we want it to continue being part of Moodle or have a separate utility. Using moodle cron or its own one?&lt;br /&gt;
* Incremental backup/restore. Is also a external thing. We provide constant &amp;quot;content&amp;quot; by separating envelopes and content, but all the &amp;quot;diff&amp;quot;, &amp;quot;patch&amp;quot; stuff is no related with Moodle at all.&lt;br /&gt;
* Structures over course level. They are a pain. Can lead to non-restorable courses or differently-behaviour courses.&lt;br /&gt;
* ... more ideas/things..&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Backup_2.0&amp;diff=62232</id>
		<title>Backup 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Backup_2.0&amp;diff=62232"/>
		<updated>2022-05-03T19:02:34Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WillNotMigrate}}{{Template:Backup 2.0}}{{Moodle_2.0}}__NOTOC__{{Work in progress}}&lt;br /&gt;
== Summary &amp;amp; Objectives ==&lt;br /&gt;
The backup &amp;amp; restore functionality has been present since Moodle 1.1 (29 August 2003, more than six years ago!) and, although it has been continuously improved and renewed, the core has remained basically the same.&lt;br /&gt;
&lt;br /&gt;
Many things have evolved since then both in Moodle and PHP-land so this project is an attempt to rework the backup &amp;amp; restore functionality in order to achieve these goals:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Modernise&#039;&#039;&#039; the code base, using actual PHP/DB techniques: OOP, exceptions, temporary DB tables, transactions... aiming to reduce the current &#039;&#039;&amp;quot;spaghetti code&amp;quot;&#039;&#039; in various places.&lt;br /&gt;
* &#039;&#039;&#039;Unify&#039;&#039;&#039; current developments, so all backup alternatives (manual, export, silent, scheduled...) will be executed by the same code base (also for restore/import of course).&lt;br /&gt;
* &#039;&#039;&#039;Improve&#039;&#039;&#039; the process, making it more reliable, being able to pre-detect wrong situations, rollback (if possible) to previous states, and apply any possible benefit both for speed (some interim in-memory caches) and memory (better parsing techniques).&lt;br /&gt;
* Improve &#039;&#039;&#039;Security&#039;&#039;&#039;, so the Moodle permissions structure will be 100% respected and any user data disclosure will be avoided, of course, whilst giving the admins the flexibility to change default behaviours by configuring them in a standard way.&lt;br /&gt;
* &#039;&#039;&#039;New features&#039;&#039;&#039; requested from the Community will be added. Things like fine grained control of various restore parts, the ability to backup not only course structures, but sections or individual activities, anonymised backups and so on will début with Moodle 2.0. See the [[Backup 2.0 requirements|requirements]] section for more info.&lt;br /&gt;
&lt;br /&gt;
== Implementation plan ==&lt;br /&gt;
&lt;br /&gt;
META bug in the Tracker: MDL-21432&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62193</id>
		<title>Release process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62193"/>
		<updated>2022-04-30T18:08:54Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Moving the requirements issue to point 2 (and removing the, not needed anymore, behat-extension point. Add point about to ensure all new jobs @ CIs are enabled.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8 weeks prior ==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Recurring release epics review:&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure we are running latest/good behat, phpunit and nodejs (npm) versions.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm external testers daily availability from -6w to release (internally with dev manager and then, externally, with contractors). They start in just 2 weeks!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| - Move QA tests for new features in old release with automated tests from MDLQA-1 to MDLQA-5249.&lt;br /&gt;
- Remind devs:&lt;br /&gt;
* To label issues qa_test_required when a new feature/improvement is landing without automated tests. Also add a comment advising exactly what should be covered in the QA test e.g. steps 6-10 in testing instructions.&lt;br /&gt;
* The best possible lang strings land at first attempt. Given the proximity of the major release and to facilitate the work of translators and others... the sooner, the better, instead of relying on (late) en_fixes too much. &lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| - Create a &amp;quot;Must fix for X.Y&amp;quot; version in the Tracker and adjust the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Set%20integration%20priority%20to%20one/ &amp;quot;TR - Set integration priority to one&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20reopened%20out%20from%20current/ &amp;quot;TR - Move reopened out from current&amp;quot;] jobs in &#039;&#039;&#039;all CI servers&#039;&#039;&#039; to point to it.&lt;br /&gt;
- Apply the following changes to filters and dashboards:&lt;br /&gt;
*  Edit the [https://tracker.moodle.org/issues/?filter=21363 All &amp;quot;must fix&amp;quot; issues] filter used both in the release dashboard and to detect wrong uses of must-fix issues. Note that, since 3.7, this filter is fully automated and does not need edition (uses regexp to catch all must fix versions).&lt;br /&gt;
* Comment about its creation within HQ, to get people applying for it. &lt;br /&gt;
* Verify that these filters ([https://tracker.moodle.org/issues/?filter=18596 1], [https://tracker.moodle.org/issues/?filter=18594 2] and [https://tracker.moodle.org/issues/?filter=18861 3]), used in the [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard], are working ok (they should be, automatically based in the filter edited in the previous point). &lt;br /&gt;
* Rename [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard] to point to incoming release (QA part of the dashboard will not work yet)&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==7 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Full demo of new code and sign-off for internal HQ projects. Decide which projects will be completed by the code freeze.&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Check [https://tracker.moodle.org/issues/?jql=labels%20%3D%20qa_test_required%20AND%20status%20%3D%20Closed closed qa_test_required-labelled issues] and create new QA tests as required.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==6 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period Continuous Integration] period begins. Warn about it everywhere (telegram, exposed posts...).&lt;br /&gt;
Rolling (on demand, beta, rc... all them together with stable weeklies) happens often (Tuesday &amp;amp; Friday are the usual days). All the team is on integration 100% since this week and until the end of continuous.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create the next &amp;quot;X.Y+1&amp;quot; (next dev) version in the Tracker (MDL and CONTRIB), so people can move delayed stuff to next major release if needed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Warn external developers about the impending code freeze in a post to the [http://moodle.org/mod/forum/view.php?id=55 General developer forum]. ([https://moodle.org/mod/forum/discuss.php?d=225854 example])&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Let the community know [[QA testing]] starts in two weeks and how they can participate. &lt;br /&gt;
| Community Manager&lt;br /&gt;
|}&lt;br /&gt;
==5 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm the code freeze by replying to the previous warning in the [http://moodle.org/mod/forum/view.php?id=55 General developer forum].&lt;br /&gt;
| Development manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| This week, once the freeze has happened at 11:00 UTC:&lt;br /&gt;
* The [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job has to be disabled.&lt;br /&gt;
* Immediately after that, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20awaiting%20issues%20to%20current%20integration/ Move awaiting issues to current integration] job must be enabled and executed, only once, and all the candidate issues already @ integration will come to the current queue. All them did the freeze.&lt;br /&gt;
* Once run, disable the job again to avoid executing it by mistake.&lt;br /&gt;
* Once the previous job has ended, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job, in charge of managing the integration queues after freeze, will be enabled (until the end of on-sync). It performs some tasks like moving important (must fix, qa, security...) issues to the current integration queue and also keep if fed by priority when there are few issues remaining. &#039;&#039;&#039;Don&#039;t forget&#039;&#039;&#039; to configure the &amp;quot;releasedate&amp;quot; date to get it automatically holding issues the last week (instead of moving them to current integration) and also processing issues over the on-sync (after release) period.&lt;br /&gt;
Irrespectively from any automation, issues can, also, be manually picked for integration until the post-release &amp;quot;On Sync&amp;quot; period ends, usually 2 weeks after release.&lt;br /&gt;
&lt;br /&gt;
Review all the new features and improvements so, everything &amp;quot;unrelated&amp;quot; with the release, is given the &amp;quot;integration_held&amp;quot; label. That means that will be ignored unless there is an [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period unhold request process] started on them.&lt;br /&gt;
&lt;br /&gt;
Dev leaders promptly vote on held issues labelled with unhold_requested label and decide whether they can be allowed to break the freeze.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare a fresh installation of the [http://qa.moodle.net QA site] based on the beta code to make sure the site is not affected by incremental upgrade steps during the development cycle.&lt;br /&gt;
| QA Master Site Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Begin reviewing [https://lang.moodle.org/mod/forum/view.php?id=7 new and changed English language strings] ready for en_fix to be merged 2 weeks prior.&lt;br /&gt;
| English fixes lang pack maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review standards certifications (Open Badges, LTI, etc) and schedule in recertification to be performed.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==4 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Start reviewing fixed issues and add the release_notes label to all issues to be listed in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review requirements for adding user tours for new features in the upcoming release (clone of MDL-72783). Review existing tours and remove very old ones (clone of MDL-72781)&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Beta release (The Moodle release tool - mdlrelease - manages it): Release normal weeklies but with these changes in the master branch being considered all the time, until we are feature complete (can happen @ -4w - ideally - but also later):&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_BETA and $release = &#039;X.Ybeta (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-beta&amp;quot; (and MOODLE_XY_BETA as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Once the beta is available create the &amp;quot;[https://docs.google.com/spreadsheets/d/1TcMJT3o2Cnyq006lmLWrXJeNQQzyNXz2E_Vbc8ff5EE/edit?usp=sharing|Release testing matrix for X.Y.0]&amp;quot; and share it @ HQ &amp;amp; Dev. chat.&lt;br /&gt;
* (Optionally) Announce Beta release in forums (ideally once packages are available).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-72815 for the X.Y release, adding there all the debugging / PHP notices happening in the web server logs while running tests.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Release candidates release (The Moodle release tool - mdlrelease - manages it): At some points (between beta to final release) produce release candidates (Z = 1, 2, 3..), which are normal builds with the following changes:&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_RC and $release = &#039;X.YrcZ (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-rcZ&amp;quot; (and MOODLE_XY_RCZ as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Upgrade all the Moodle CI sites to recent release candidate by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Add a new version in the Plugins Directory with the version&#039;s name and the beta release version build number (https://moodle.org/plugins/admin/softwareversions.php).&lt;br /&gt;
* Any standard plugins being retired from the release can transition to Add-on (that supports this release and/or any previous ones) now.&lt;br /&gt;
* These plugins currently collect at https://moodle.org/plugins/browse.php?list=contributor&amp;amp;id=1532512&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Push any plugins to the plugins database which were previously a part of core.&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Tidy up current latest en version of Moodle Docs prior to copying it to create new version wiki as described in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new QA test cycle and post in moodle.org front page news forum about [[QA testing]].&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Invite community volunteers to start [[QA testing]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Modify [https://tracker.moodle.org/issues/?filter=11824 Current QA cycle filter] to link to the new QA test cycle&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor QA fails. Check each fail is real and if so ensure an MDL issue has been created and correctly linked and labelled.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor MDL issues created for QA fails. Add them to the &amp;quot;Must fix for X.Y&amp;quot; list and get a developer to work on the issue immediately.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the [https://tracker.moodle.org/issues/?filter=17705&amp;amp;jql=filter%20%3D%2011701%20AND%20type%20!%3D%20Bug list of features and improvements submitted before code freeze] which are awaiting integration review and decide on related QA tests to be put on hold.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==3 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ask developers to begin QA tests marked [https://tracker.moodle.org/issues/?filter=22055 external_skipped] then [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20test_server_required%20 test_server_required tests] and [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20credentials_required credentials_required tests].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new en and de Moodle Docs version wikis.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Go through all points listed under 3 weeks prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review issues with labelled with [https://tracker.moodle.org/issues/?filter=11824&amp;amp;jql=labels%20in%20%28dev_docs_required%29%20AND%20resolution%20%3D%20fixed%20ORDER%20BY%20assignee%20ASC%2C%20created%20ASC dev_docs_required], prompting assigned developers to create/update this documentation and remove this label when relevant docs are updated.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify how everything is going and, before the end of the week, decide (dev leaders &amp;amp; integrators) if there are real reasons for delaying any release. Whenever a delay is agreed, run the &#039;&#039;&amp;quot;Release delaying process&amp;quot;&#039;&#039; (doc) actions ASAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; ASAP stands for as soon as possible ;-), the delay needs to happen before the last week before release begins (there are flows changing that week requiring the decision and actions to be taken and applied earlier).&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Check the number of open QA tests. Depending on the amount of work involved, encourage HQ developers to assist from the start of the week or later in the week in order to achieve the target of 100% pass rate by the end of the week.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Create MDLSITE issue to ensure all prototype.moodle.net sites which are no longer relevant (part of release) are removed from prototype.moodle.net&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Merge fixes from en_fix pack and then integrate them.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Give Partners complete brandable Marketing pack for release including list and description of major new features.&lt;br /&gt;
| Marketing Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Label (ui_change) in the Tracker all pending issues having &#039;&#039;&#039;noticeable UI modifications&#039;&#039;&#039; and track them in the &amp;quot;[https://docs.google.com/spreadsheets/d/18xZf9OgKrndi7CwSTwjwjF_rzGYCWFuGjNNaaDVZDM4/edit?usp=sharing Late landing UI changes]&amp;quot; sheet, in order to have all the associated docs, screenshots, videos under control. The Integration and Documentation people will try to &#039;&#039;&#039;keep the sheet updated until release&#039;&#039;&#039;.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
For major releases, use (clone if needed) MDL-72836 to keep the security.txt files in all supported branches updated. For minor releases, also check the security.txt expiry dates in all security supported branches in case known release delays will result in any security.txt expiring before the next release - in that case relevant branches should also be updated.&lt;br /&gt;
| Security Officer&lt;br /&gt;
|}&lt;br /&gt;
==1 week prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone as many filters as needed in the Tracker, modifying them to point to the new, upcoming, branch (keeping same perms, title...). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create new minor version X.Y.Z+1 in the Tracker (MDL and CONTRIB). Archive any version &amp;gt; 6 months old, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-71583 and bump all versions, requires and dependencies along all plugins in codebase to planned release dates.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [http://moodle.org/mod/forum/view.php?id=55 General Developer forum] and [https://moodleassociation.org/ MUA website].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on Twitter and other outlets.&lt;br /&gt;
| Marketing Officer&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Identify security issues that need to be integrated using the [https://tracker.moodle.org/issues/?filter=21712 security issues under integration filter] (includes held, being integrated and ready issues).&lt;br /&gt;
* Integrate from provided patches into supported branches (including branches supported only for security issues).&lt;br /&gt;
* Ensure security issues are given priority in weekly integration and testing. Note that the --weekly releases to be performed this week are 100% normal and cover the standard (supported) branches. security branches will come as part of the release process later in the week.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Collect security issues into a clone of the [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20level%20is%20not%20EMPTY%20AND%20summary%20~%20%22security%20advisories%22%20ORDER%20BY%20updated%20DESC last advisory in the list] to prepare for release of Security Advisories.&lt;br /&gt;
* Determine which security issues will be integrated.&lt;br /&gt;
* Request CVE Identifiers by emailing issue descriptions to [mailto:secalert@redhat.com secalert@redhat.com] with a message like... &amp;lt;tt&amp;gt; The following security issues have been discovered in Moodle. We request CVE Identifiers for these issues. We will be releasing the security announcements for these on moodle.org on XXX at 12noon AWST which is 04:00 UTC.&amp;lt;/tt&amp;gt; The email subject should include the characters &amp;lt;tt&amp;gt;[vs]&amp;lt;/tt&amp;gt;. The format needs to be plain text or encrypted. When granted CVE Identifiers, our issues should appear in the [http://cve.mitre.org/cve/cve.html CVE list]. More [http://oss-security.openwall.org/wiki/mailing-lists/distros instructions] are available (since 2015 we request identifiers from redhat and not from distros).&lt;br /&gt;
* Post security issues as a reply to the &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Release notes tasks:&lt;br /&gt;
* Review and complete the [[Releases|release notes]], making sure that issues have easily understandable summaries. Aim to have the release notes mostly complete on the Wednesday before release, and fully complete on the Friday, to give translators time to translate them.&lt;br /&gt;
* Ensure all issues labelled with &amp;quot;ui_change&amp;quot;, &amp;quot;api_change&amp;quot; and &amp;quot;release_notes&amp;quot; are listed as UI changes, functional changed and fixes/improvements respectively in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the following issues:&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=21363 &amp;quot;Must fix for X.Y version&amp;quot;]. Filter out unrealistic issues.&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=22350 &amp;quot;Bug issues held last week before release&amp;quot;]. Consider to request the unholding of release related/blocker ones.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| Upgrade moodle.org to beta release&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare pull requests for CI Repositories:&lt;br /&gt;
* MR1: Create a new version, with unit tests, in Jobs repository ([https://git.in.moodle.com/integration/nightlyjobs/merge_requests/24 see example from 3.11 release])&lt;br /&gt;
* MR2: Create a new symlink for the version in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/41 see example from 3.11 release])&lt;br /&gt;
* MR3: Configure CIs to skip language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/35 see example from 3.10 release])&lt;br /&gt;
* MR4: Configure CIs to stop skipping language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository for after on-sync ([https://github.com/moodlehq/moodle-ci-runner/pull/40 see example from 3.10 release]) -- Note: This change should be based on the previous and only applied when the lang packs corresponding to the version being released are available.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under 1 week prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==Releasing==&lt;br /&gt;
===Packaging===&lt;br /&gt;
This should happen immediately before the next integration cycle begins on Monday (i.e., some days after last weekly, 2 days prior to official release).&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Check list:&lt;br /&gt;
* Make sure there are no real blockers introduced in the last weekly (install / upgrade ...).&lt;br /&gt;
* Confirm that the latest [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc en_fix changes]have been generated and integrated.&lt;br /&gt;
* Verify that [https://tracker.moodle.org/issues/?jql=text%20~%20%22%2BPrepare%20%2Bsecurity%20%2Badvisories%20%2Bfriends%22%20ORDER%20BY%20updated%20DESC all security issues] have been integrated and there are not leftovers in the security area (but for delayed majors, where some security issues may have been introduced along the delay and they will be postponed to next minors).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify all unit tests and integration tests have passed (check all current CI servers in use).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Verify QA tests have passed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Timing prerequisites (don&#039;t continue with the process if not within the time window!):&lt;br /&gt;
# Latest weeklies before the minor/major releases must be done (moodle-package-extract-and-postprocess email should confirm this has happened around 09:00 Australia/Perth).&lt;br /&gt;
# Minor and major releases can be packaged at any time within the 96 hours before the automatic releasing time (Monday 09:00 Australia/Perth). And always, at very least, 4 hours before then (to allow the server to prepare all the stuff).&lt;br /&gt;
(in practice, this means that the packaging of minor/major releases must be done, assuming that weeklies were rolled normally on Thursday, between Friday 09:00 and Monday 05:00 (Australia/Perth times). Breaking any of these rules will require manual operation in the server, forcing repackaging and releasing.&lt;br /&gt;
&lt;br /&gt;
Follow the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script to generate the target minor (--type minor) and major (--type major) releases and their corresponding tags. Pay attention to the complete output of the process: permissions, svg, travis changes (only for majors)... Triple verify all changes are correct! (can use the --show option to inspect them). Follow the on-screen instructions. &lt;br /&gt;
* Push changes to integration.git (but tags).&lt;br /&gt;
For major releases, only when a new STABLE branch has been created:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script (--type back-to-dev) to move master to next X.Y+1 development version/branch. &lt;br /&gt;
* Push changes to integration.git - note this will lead to the &amp;quot;versions checker&amp;quot; failing for master, no problem, it will be fixed by the 1st cloned issue at #12 below).&lt;br /&gt;
* Configure &amp;quot;mdlrelease&amp;quot; (config.sh) to know about the new MOODLE_XY stable branch.&lt;br /&gt;
* Update the old CI server(s) by cloning all the &amp;quot;master&amp;quot; jobs to a new &amp;quot;MXY&amp;quot; view (trick: do it down-top, way easier). Don&#039;t forget to re-chain the jobs properly.&lt;br /&gt;
** Adjust &amp;quot;master&amp;quot; compare DB jobs to check for upgrade from MOODLE_XY_STABLE.&lt;br /&gt;
** Configure the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
** Run all them.&lt;br /&gt;
* Update the new CI infrastructure:&lt;br /&gt;
** MR1: Merge pull request for new version in [https://git.in.moodle.com/integration/nightlyjobs CI Jobs Repository]&lt;br /&gt;
** MR2: Merge pull request for symlink in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** MR3: Merge pull request for skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** Clone all the &amp;quot;B - master&amp;quot; jobs to a new &amp;quot;B - XY&amp;quot; view (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Clone%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
Both with minors and majors, continue with the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Once CI servers have ended and all jobs have passed, &#039;&#039;&#039;push tags&#039;&#039;&#039; and run the &#039;&#039;&#039;release.sh&#039;&#039;&#039; script to apply the changes to moodle.git.&lt;br /&gt;
* If needed configure &amp;quot;mdlrelease&amp;quot; (config.sh) to get rid of any unsupported version and adjust stable and security branches. Make a pull request with the changes.&lt;br /&gt;
* Don&#039;t forget the &amp;quot;[https://github.com/moodlehq/mdlrelease/#after-the-release After the release]&amp;quot; tasks.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;git repos updated &amp;amp; tagged&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=810 Partner forum]&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| In the [https://github.com/moodlehq/moodle-performance-comparison performance comparison repository], set the new release commit hash as $basecommit in the master branch and create a new MOODLE_XY_STABLE branch from it. ([https://github.com/moodlehq/moodle-performance-comparison/commit/7c875f03e52641f69674235a8947131d77691299 example]). Also, apply it to the current performance testing infrastructure.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Wait for the automated (every 2 hours) moodle-package to finish building for all versions. Verify the process has ended successfully (email).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
* Create new windows packager script (cloning the current master one and configuring it).&lt;br /&gt;
* Edit the stats.php script (in the moodle-local_downloadmoodleorg repository), adding the new branch to the versions. Push it. Next time the plugin is deployed (normally 1 week after release, aprox.) the stats will start showing the new branch statistics.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
* Visit the versions page and make the release, bumping all remaining open bugs to the next point release. If there is not next (end of support), clean that version from all the issues having it as &amp;quot;Fix for&amp;quot;. This must be done both for the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10011 Moodle Project] and the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10033 Plugins project].&lt;br /&gt;
* Archive all versions but the ones being released, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
* Remove from all screens the custom fields belonging to 100% unsupported branches.&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Release and archive the [https://tracker.moodle.org/issues/?jql=affectedVersion%20~%20%22must%20fix%20for*%22%20OR%20fixVersion%20~%20%22must%20fix%20for*%22 &amp;quot;Must fix for X.Y&amp;quot; versions], it must be empty to do so.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Create the new &amp;quot;Pull X.Y Branch&amp;quot; and &amp;quot;Pull X.Y Diff URL&amp;quot; custom fields and spread them to all the screens needing them (copy from previous ones). Order them properly on each screen. Re-index Tracker.&lt;br /&gt;
* In the CI server edit the [http://integration.moodle.org/view/tracker/job/Tracker%20-%20CI%20-%20Bulk%20precheck%20issues/ &amp;quot;Bulk precheck issues&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(awaiting_integration)/ &amp;quot;Pre-launch DEV jobs (awaiting_integration)&amp;quot;], [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch DEV jobs (list_of_mdsl)&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/STR%20-%20Bulk%20pre-launch%20SDEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch SDEV jobs (list_of_mdsl)&amp;quot;] jobs to make them meet the new &amp;quot;Pull X.Y Branch&amp;quot; field created. At the same time, remove from those jobs any branch belonging to 100% unsupported branches.&lt;br /&gt;
* Edit the &amp;quot;Tracker - CI - Check marked as integrated&amp;quot; job ([https://ci.moodle.org/view/Tracker/job/TR%20-%20Check%20marked%20as%20integrated/ link]) to configure the development branches (devbranches) (39, 310, 311, 400...) actually active. Normally only the branch corresponding to master, but also accepts a comma separated list when under parallel development (&amp;quot;310,400&amp;quot; or &amp;quot;311,400&amp;quot; for example). Ordered by planned release date.&lt;br /&gt;
* Check/configure (again, this may be has been already executed few steps above) the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Create the new &amp;quot;X.Y regressions&amp;quot; version to be applied to every issue found to be a recent problem introduced by the major release. These issues should get priority after release.&lt;br /&gt;
* Adjust the [https://tracker.moodle.org/issues/?filter=17528 Latest regressions] filter (requires login).&lt;br /&gt;
For all releases:&lt;br /&gt;
* Verify how the &amp;quot;X.Y regressions&amp;quot; versions [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20resolution%20%3D%20Unresolved%20AND%20affectedVersion%20in%20(versionMatches(%22.*regressions%22)) are going] (requires login) and ping Development Managers about. Package and archive them once empty.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-74509 and MDL-74510, to be resolved ASAP.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
* Create the new MOODLE_XY_STABLE and lastbased-MOODLE_XY_STABLE branches in the security repo (branching from the just created upstream MOODLE_XY_STABLE branch).&lt;br /&gt;
* Cherry pick any security commit present in the security repository&#039;s master branch to the new MOODLE_XY_STABLE branch (note that normally there should not be any, see point #1 check list above).&lt;br /&gt;
* Verify the new security jobs exist for the new branch and check it&#039;s working in all servers, keeping only enabled the public one.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Protect the MOODLE_XY_STABLE branches in github interface to prevent non-FF accidents ( MDLSITE-4183 )&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
===Release day===&lt;br /&gt;
Usually on Monday&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| The execution of &amp;quot;moodle-package-extract-and-postprocess X&amp;quot; script may be needed if the releases &#039;&#039;&#039;are not going to be published on Monday&#039;&#039;&#039; but another weekday (X is the weekday, (1-7) starting in Monday).&lt;br /&gt;
By default it happens automatically around 09:00 AM Perth/Australia time (check emails then). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify release status, download pages and windows packages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| If needed, modify the downloads cfg script (serverscripts) to decide about branches status, master visibility and windows availability. Push changes, will be autodeployed in a few minutes.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add/update the release date, build number and link on the [[Releases|Releases page]] and date in new version pages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify all registered sys admins, including security notes with CVE identifiers, using the [http://lists.moodle.org/ mailing list server].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Post about the Major release on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post about minor releases on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| New &amp;quot;X.Y+1dev&amp;quot; branch to be created in AMOS, to have master changes performed there. New install_XY_STABLE processing set up. These needs to be done anytime during the on-sync period.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify, 24h after tagging, that https://moodle.org/dev/contributions.php has been updated with new versions. If not, file an urgent mdlsite issue, crons must be running!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| For en and de Moodle Docs, update default redirects and enable email notifications.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under Day of release in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Decide the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot; and &amp;quot;QA begins&amp;quot; dates for the next X.(Y+1) major release and put them in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar]. They will be -7w, -5w and -4w before release date respectively.&lt;br /&gt;
* Update the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot;, &amp;quot;QA begins&amp;quot; and Release dates on the [[Roadmap]] page.&lt;br /&gt;
* Add events to the HQ calendar for next Major release 6-months cycle according to [[Process#Sprints|the cycle plan]]: ~4 weeks planning and regression fixing, 2 sprints, 1 personal project week, 2 sprints, 1 personal project week, 1 sprint (which should lead up to code freeze).&lt;br /&gt;
* Notify the Community Manager of new dates to be added to the moodle.org calendar.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &lt;br /&gt;
| Add calendar events in the [https://moodle.org/calendar moodle.org calendar] for coming Major and Minor releases up to the next Major release.&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update release schedule image on [[Releases#Version_support|Releases page]]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 15.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Important: This must be done &#039;&#039;&#039;once it&#039;s already release day @ UTC&#039;&#039;&#039; (aka, after Australia/Perth 08:00) or the &#039;&#039;&#039;queues manage with hold them again&#039;&#039;&#039; because it&#039;s still &amp;quot;last week before release&amp;quot;.&lt;br /&gt;
The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed &#039;&#039;&#039;only&#039;&#039;&#039; [https://tracker.moodle.org/issues/?jql=filter%3D13669%20AND%20type%20in%20(bug%2C%20task%2C%20Sub-task) from &#039;&#039;&#039;bug issues&#039;&#039;&#039; awaiting integration]; they correspond to last-week bugs that were held because of them being unrelated with the release. Now they can be processed, under on-sync rules. Standard message will be used to explain the un-hold.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==1 week after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Publish the X.Y+ packages for download.moodle.org (should be automatic once weeklies are packaged).&lt;br /&gt;
For major releases, within the on-sync period, master packages will be generated using the prerelease.sh script (--type on-sync). That guarantees XY_STABLE and master versions are kept the same. The last week, when leaving the on-sync period, master package will be generated normally (implicit --type weekly), so versions will diverge and dev can continue separately from that point.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update the version.php in git to be X.Y.Z+ during the next weekly integration process&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create a new release notes page for the next minor versions (using the [[Release notes template|release notes template]].) Add note to top of relevant version page about security support.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add all security advisories to [http://moodle.org/security Security news] and [[:Category:Release notes|release notes]] with links to security advisories&lt;br /&gt;
|| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify about publications of CVE using form: https://cveform.mitre.org/&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Upgrade moodle.org and all other Moodle community sites (next sites first, then production)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &#039;&#039;&#039;Deprecations:&#039;&#039;&#039;&lt;br /&gt;
* Create the next deprecation epic (for X.Y+1+2y) similar to MDL-74579 and add standard issues to it:&lt;br /&gt;
** Final deprecation of lib/deprecatedlib.php (like MDL-74580)&lt;br /&gt;
** Removal of deprecated Behat steps (like MDL-74581)&lt;br /&gt;
** Removal of strings (like MDL-74582) and&lt;br /&gt;
** Removal of renamed classes (MDL-74583).&lt;br /&gt;
The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Libraries:&#039;&#039;&#039;&lt;br /&gt;
* Create the next third party libraries epic for X.Y+1, similar to MDL-73715. The issue should refer to the list of [[Moodle libraries credits]]. The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it. &#039;&#039;&#039;Drag/link opened issues from the previous one&#039;&#039;&#039;, avoiding leaving unfinished stuff.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20(summary%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20OR%20summary%20~%20%22Review%20third-party%20libraries%20for%20upgrade%22)%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Once the &amp;quot;On Sync&amp;quot; period ends:&lt;br /&gt;
* Confirm that versions (XY_STABLE and master) diverged properly the last on-sync week. If not, proceed to it by manually bumping master the version to currentthe date @ integration.git.&lt;br /&gt;
* Disable the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job. It has served us well.&lt;br /&gt;
* The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed from all issues awaiting integration, so they will be, automatically (see next point), be moved to current integration. Send a &amp;quot;unnholding + rebase&amp;quot; message to all those issues.&lt;br /&gt;
* Enable the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job. It will control the queues over coming months, until nextthe  freeze.&lt;br /&gt;
* In the [https://ci.moodle.org/ Jenkins CI server] enable all the jobs corresponding to the new branch (B-XYZ view) that were created on packaging day.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The discussion about environmental requirements for next X.Y+1 major release (MDL-71747) will end and the issue will be resolved &#039;&#039;&#039;immediately&#039;&#039;&#039;. A new issue, about the requirements for nextthe -next X.Y+2 major release wil,l be created at the same time by cloning the previous one and dragging any non-resolved detail (due date = 3w after release).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure [https://download.moodle.org/langpack/X.Y+1/ Language pack for master (X.Y+1)] is available and merge the pull request MR4 for stop skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure release retrospectives are held for each of the LMS teams and results are actioned.&lt;br /&gt;
| Development Manager / Head of LMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==1 month after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Remove, in CI servers, all the jobs and views corresponding to branches which support has ended completely. (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Remove%20all%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Upgrade all the Moodle CI sites to recent major release by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Confirm that there isn&#039;t any remaining [https://tracker.moodle.org/issues/?filter=13669 integration_held] issue from latest release, proceeding to uhhold them immediately. Note that there may exist [https://tracker.moodle.org/issues/?filter=13669&amp;amp;jql=project%20%3D%20MDL%20AND%20labels%20in%20(integration_held)%20ORDER%20BY%20%22Integration%20priority%22%20DESC%2C%20priority%20DESC%2C%20votes%20DESC%2C%20%22Last%20comment%20date%22%20ASC other &amp;quot;held&amp;quot; issues], unrelated with latest release. This process step does not affect them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Deprecation|Deprecation process]]&lt;br /&gt;
[[Category:Processes|Release process]]&lt;br /&gt;
[[Category:Release notes|Release process]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62087</id>
		<title>Release process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Release_process&amp;diff=62087"/>
		<updated>2022-04-27T08:02:36Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: reordering a little bit, so things happen in correct order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8 weeks prior ==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Recurring release epics review:&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20created%20%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure we are running latest/good behat, phpunit and nodejs (npm) versions.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm external testers daily availability from -6w to release (internally with dev manager and then, externally, with contractors). They start in just 2 weeks!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| - Move QA tests for new features in old release with automated tests from MDLQA-1 to MDLQA-5249.&lt;br /&gt;
- Remind devs:&lt;br /&gt;
* To label issues qa_test_required when a new feature/improvement is landing without automated tests. Also add a comment advising exactly what should be covered in the QA test e.g. steps 6-10 in testing instructions.&lt;br /&gt;
* The best possible lang strings land at first attempt. Given the proximity of the major release and to facilitate the work of translators and others... the sooner, the better, instead of relying on (late) en_fixes too much. &lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| - Create a &amp;quot;Must fix for X.Y&amp;quot; version in the Tracker and adjust the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Set%20integration%20priority%20to%20one/ &amp;quot;TR - Set integration priority to one&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20reopened%20out%20from%20current/ &amp;quot;TR - Move reopened out from current&amp;quot;] jobs in &#039;&#039;&#039;all CI servers&#039;&#039;&#039; to point to it.&lt;br /&gt;
- Apply the following changes to filters and dashboards:&lt;br /&gt;
*  Edit the [https://tracker.moodle.org/issues/?filter=21363 All &amp;quot;must fix&amp;quot; issues] filter used both in the release dashboard and to detect wrong uses of must-fix issues. Note that, since 3.7, this filter is fully automated and does not need edition (uses regexp to catch all must fix versions).&lt;br /&gt;
* Comment about its creation within HQ, to get people applying for it. &lt;br /&gt;
* Verify that these filters ([https://tracker.moodle.org/issues/?filter=18596 1], [https://tracker.moodle.org/issues/?filter=18594 2] and [https://tracker.moodle.org/issues/?filter=18861 3]), used in the [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard], are working ok (they should be, automatically based in the filter edited in the previous point). &lt;br /&gt;
* Rename [https://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=16582 Release urgent dashboard] to point to incoming release (QA part of the dashboard will not work yet)&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==7 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Full demo of new code and sign-off for internal HQ projects. Decide which projects will be completed by the code freeze.&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Check [https://tracker.moodle.org/issues/?jql=labels%20%3D%20qa_test_required%20AND%20status%20%3D%20Closed closed qa_test_required-labelled issues] and create new QA tests as required.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==6 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| The [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period Continuous Integration] period begins. Warn about it everywhere (telegram, exposed posts...).&lt;br /&gt;
Rolling (on demand, beta, rc... all them together with stable weeklies) happens often (Tuesday &amp;amp; Friday are the usual days). All the team is on integration 100% since this week and until the end of continuous.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create the next &amp;quot;X.Y+1&amp;quot; (next dev) version in the Tracker (MDL and CONTRIB), so people can move delayed stuff to next major release if needed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Warn external developers about the impending code freeze in a post to the [http://moodle.org/mod/forum/view.php?id=55 General developer forum]. ([https://moodle.org/mod/forum/discuss.php?d=225854 example])&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Let the community know [[QA testing]] starts in two weeks and how they can participate. &lt;br /&gt;
| Community Manager&lt;br /&gt;
|}&lt;br /&gt;
==5 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Confirm the code freeze by replying to the previous warning in the [http://moodle.org/mod/forum/view.php?id=55 General developer forum].&lt;br /&gt;
| Development manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| This week, once the freeze has happened at 11:00 UTC:&lt;br /&gt;
* The [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job has to be disabled.&lt;br /&gt;
* Immediately after that, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Move%20awaiting%20issues%20to%20current%20integration/ Move awaiting issues to current integration] job must be enabled and executed, only once, and all the candidate issues already @ integration will come to the current queue. All them did the freeze.&lt;br /&gt;
* Once run, disable the job again to avoid executing it by mistake.&lt;br /&gt;
* Once the previous job has ended, the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job, in charge of managing the integration queues after freeze, will be enabled (until the end of on-sync). It performs some tasks like moving important (must fix, qa, security...) issues to the current integration queue and also keep if fed by priority when there are few issues remaining. &#039;&#039;&#039;Don&#039;t forget&#039;&#039;&#039; to configure the &amp;quot;releasedate&amp;quot; date to get it automatically holding issues the last week (instead of moving them to current integration) and also processing issues over the on-sync (after release) period.&lt;br /&gt;
Irrespectively from any automation, issues can, also, be manually picked for integration until the post-release &amp;quot;On Sync&amp;quot; period ends, usually 2 weeks after release.&lt;br /&gt;
&lt;br /&gt;
Review all the new features and improvements so, everything &amp;quot;unrelated&amp;quot; with the release, is given the &amp;quot;integration_held&amp;quot; label. That means that will be ignored unless there is an [https://docs.moodle.org/dev/Integration_Review#During_continuous_integration.2FFreeze.2FQA_period unhold request process] started on them.&lt;br /&gt;
&lt;br /&gt;
Dev leaders promptly vote on held issues labelled with unhold_requested label and decide whether they can be allowed to break the freeze.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare a fresh installation of the [http://qa.moodle.net QA site] based on the beta code to make sure the site is not affected by incremental upgrade steps during the development cycle.&lt;br /&gt;
| QA Master Site Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Begin reviewing [https://lang.moodle.org/mod/forum/view.php?id=7 new and changed English language strings] ready for en_fix to be merged 2 weeks prior.&lt;br /&gt;
| English fixes lang pack maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review standards certifications (Open Badges, LTI, etc) and schedule in recertification to be performed.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==4 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Start reviewing fixed issues and add the release_notes label to all issues to be listed in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review requirements for adding user tours for new features in the upcoming release (clone of MDL-72783). Review existing tours and remove very old ones (clone of MDL-72781)&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Beta release (The Moodle release tool - mdlrelease - manages it): Release normal weeklies but with these changes in the master branch being considered all the time, until we are feature complete (can happen @ -4w - ideally - but also later):&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_BETA and $release = &#039;X.Ybeta (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-beta&amp;quot; (and MOODLE_XY_BETA as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Once the beta is available create the &amp;quot;[https://docs.google.com/spreadsheets/d/1TcMJT3o2Cnyq006lmLWrXJeNQQzyNXz2E_Vbc8ff5EE/edit?usp=sharing|Release testing matrix for X.Y.0]&amp;quot; and share it @ HQ &amp;amp; Dev. chat.&lt;br /&gt;
* (Optionally) Announce Beta release in forums (ideally once packages are available).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-72815 for the X.Y release, adding there all the debugging / PHP notices happening in the web server logs while running tests.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Release candidates release (The Moodle release tool - mdlrelease - manages it): At some points (between beta to final release) produce release candidates (Z = 1, 2, 3..), which are normal builds with the following changes:&lt;br /&gt;
* version.php: Move to $maturity = MATURITY_RC and $release = &#039;X.YrcZ (Build:xxxxxxxx)&#039;&lt;br /&gt;
* tag git repo with: &amp;quot;vX.Y.0-rcZ&amp;quot; (and MOODLE_XY_RCZ as description and CVS tag)&lt;br /&gt;
* Automatic: Confirm packages are available under download.moodle.org (and windows).&lt;br /&gt;
* Upgrade all the Moodle CI sites to recent release candidate by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Add a new version in the Plugins Directory with the version&#039;s name and the beta release version build number (https://moodle.org/plugins/admin/softwareversions.php).&lt;br /&gt;
* Any standard plugins being retired from the release can transition to Add-on (that supports this release and/or any previous ones) now.&lt;br /&gt;
* These plugins currently collect at https://moodle.org/plugins/browse.php?list=contributor&amp;amp;id=1532512&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Push any plugins to the plugins database which were previously a part of core.&lt;br /&gt;
| Plugins Liaison&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Tidy up current latest en version of Moodle Docs prior to copying it to create new version wiki as described in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new QA test cycle and post in moodle.org front page news forum about [[QA testing]].&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Invite community volunteers to start [[QA testing]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Modify [https://tracker.moodle.org/issues/?filter=11824 Current QA cycle filter] to link to the new QA test cycle&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor QA fails. Check each fail is real and if so ensure an MDL issue has been created and correctly linked and labelled.&lt;br /&gt;
| Testing Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Monitor MDL issues created for QA fails. Add them to the &amp;quot;Must fix for X.Y&amp;quot; list and get a developer to work on the issue immediately.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the [https://tracker.moodle.org/issues/?filter=17705&amp;amp;jql=filter%20%3D%2011701%20AND%20type%20!%3D%20Bug list of features and improvements submitted before code freeze] which are awaiting integration review and decide on related QA tests to be put on hold.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==3 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ask developers to begin QA tests marked [https://tracker.moodle.org/issues/?filter=22055 external_skipped] then [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20test_server_required%20 test_server_required tests] and [https://tracker.moodle.org/issues/?filter=22055&amp;amp;jql=filter%20%3D%20%22Current%20QA%20cycle%20filter%22%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20credentials_required credentials_required tests].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Create new en and de Moodle Docs version wikis.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Go through all points listed under 3 weeks prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review issues with labelled with [https://tracker.moodle.org/issues/?filter=11824&amp;amp;jql=labels%20in%20%28dev_docs_required%29%20AND%20resolution%20%3D%20fixed%20ORDER%20BY%20assignee%20ASC%2C%20created%20ASC dev_docs_required], prompting assigned developers to create/update this documentation and remove this label when relevant docs are updated.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify how everything is going and, before the end of the week, decide (dev leaders &amp;amp; integrators) if there are real reasons for delaying any release. Whenever a delay is agreed, run the &#039;&#039;&amp;quot;Release delaying process&amp;quot;&#039;&#039; (doc) actions ASAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; ASAP stands for as soon as possible ;-), the delay needs to happen before the last week before release begins (there are flows changing that week requiring the decision and actions to be taken and applied earlier).&lt;br /&gt;
| Development Manager&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Check the number of open QA tests. Depending on the amount of work involved, encourage HQ developers to assist from the start of the week or later in the week in order to achieve the target of 100% pass rate by the end of the week.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
Create MDLSITE issue to ensure all prototype.moodle.net sites which are no longer relevant (part of release) are removed from prototype.moodle.net&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Merge fixes from en_fix pack and then integrate them.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Give Partners complete brandable Marketing pack for release including list and description of major new features.&lt;br /&gt;
| Marketing Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Label (ui_change) in the Tracker all pending issues having &#039;&#039;&#039;noticeable UI modifications&#039;&#039;&#039; and track them in the &amp;quot;[https://docs.google.com/spreadsheets/d/18xZf9OgKrndi7CwSTwjwjF_rzGYCWFuGjNNaaDVZDM4/edit?usp=sharing Late landing UI changes]&amp;quot; sheet, in order to have all the associated docs, screenshots, videos under control. The Integration and Documentation people will try to &#039;&#039;&#039;keep the sheet updated until release&#039;&#039;&#039;.&lt;br /&gt;
|Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
For major releases, use (clone if needed) MDL-72836 to keep the security.txt files in all supported branches updated. For minor releases, also check the security.txt expiry dates in all security supported branches in case known release delays will result in any security.txt expiring before the next release - in that case relevant branches should also be updated.&lt;br /&gt;
| Security Officer&lt;br /&gt;
|}&lt;br /&gt;
==1 week prior==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone as many filters as needed in the Tracker, modifying them to point to the new, upcoming, branch (keeping same perms, title...). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create new minor version X.Y.Z+1 in the Tracker (MDL and CONTRIB). Archive any version &amp;gt; 6 months old, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-71583 and bump all versions, requires and dependencies along all plugins in codebase to planned release dates.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [http://moodle.org/mod/forum/view.php?id=55 General Developer forum] and [https://moodleassociation.org/ MUA website].&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;Heads-up&amp;quot; message on Twitter and other outlets.&lt;br /&gt;
| Marketing Officer&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Identify security issues that need to be integrated using the [https://tracker.moodle.org/issues/?filter=21712 security issues under integration filter] (includes held, being integrated and ready issues).&lt;br /&gt;
* Integrate from provided patches into supported branches (including branches supported only for security issues).&lt;br /&gt;
* Ensure security issues are given priority in weekly integration and testing. Note that the --weekly releases to be performed this week are 100% normal and cover the standard (supported) branches. security branches will come as part of the release process later in the week.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Collect security issues into a clone of the [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20level%20is%20not%20EMPTY%20AND%20summary%20~%20%22security%20advisories%22%20ORDER%20BY%20updated%20DESC last advisory in the list] to prepare for release of Security Advisories.&lt;br /&gt;
* Determine which security issues will be integrated.&lt;br /&gt;
* Request CVE Identifiers by emailing issue descriptions to [mailto:secalert@redhat.com secalert@redhat.com] with a message like... &amp;lt;tt&amp;gt; The following security issues have been discovered in Moodle. We request CVE Identifiers for these issues. We will be releasing the security announcements for these on moodle.org on XXX at 12noon AWST which is 04:00 UTC.&amp;lt;/tt&amp;gt; The email subject should include the characters &amp;lt;tt&amp;gt;[vs]&amp;lt;/tt&amp;gt;. The format needs to be plain text or encrypted. When granted CVE Identifiers, our issues should appear in the [http://cve.mitre.org/cve/cve.html CVE list]. More [http://oss-security.openwall.org/wiki/mailing-lists/distros instructions] are available (since 2015 we request identifiers from redhat and not from distros).&lt;br /&gt;
* Post security issues as a reply to the &amp;quot;Heads-up&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=147 Partners forum].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Release notes tasks:&lt;br /&gt;
* Review and complete the [[Releases|release notes]], making sure that issues have easily understandable summaries. Aim to have the release notes mostly complete on the Wednesday before release, and fully complete on the Friday, to give translators time to translate them.&lt;br /&gt;
* Ensure all issues labelled with &amp;quot;ui_change&amp;quot;, &amp;quot;api_change&amp;quot; and &amp;quot;release_notes&amp;quot; are listed as UI changes, functional changed and fixes/improvements respectively in the release notes.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Review the following issues:&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=21363 &amp;quot;Must fix for X.Y version&amp;quot;]. Filter out unrealistic issues.&lt;br /&gt;
* Check on the [https://tracker.moodle.org/issues/?filter=22350 &amp;quot;Bug issues held last week before release&amp;quot;]. Consider to request the unholding of release related/blocker ones.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|  &lt;br /&gt;
| Upgrade moodle.org to beta release&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Prepare pull requests for CI Repositories:&lt;br /&gt;
* MR1: Create a new version, with unit tests, in Jobs repository ([https://git.in.moodle.com/integration/nightlyjobs/merge_requests/24 see example from 3.11 release])&lt;br /&gt;
* MR2: Create a new symlink for the version in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/41 see example from 3.11 release])&lt;br /&gt;
* MR3: Configure CIs to skip language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository ([https://github.com/moodlehq/moodle-ci-runner/pull/35 see example from 3.10 release])&lt;br /&gt;
* MR4: Configure CIs to stop skipping language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository for after on-sync ([https://github.com/moodlehq/moodle-ci-runner/pull/40 see example from 3.10 release]) -- Note: This change should be based on the previous and only applied when the lang packs corresponding to the version being released are available.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under 1 week prior in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
==Releasing==&lt;br /&gt;
===Packaging===&lt;br /&gt;
This should happen immediately before the next integration cycle begins on Monday (i.e., some days after last weekly, 2 days prior to official release).&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Check list:&lt;br /&gt;
* Make sure there are no real blockers introduced in the last weekly (install / upgrade ...).&lt;br /&gt;
* Confirm that the latest [https://tracker.moodle.org/issues/?jql=summary%20~%20%22en_fix%22%20order%20by%20createdDate%20desc en_fix changes]have been generated and integrated.&lt;br /&gt;
* Verify that [https://tracker.moodle.org/issues/?jql=text%20~%20%22%2BPrepare%20%2Bsecurity%20%2Badvisories%20%2Bfriends%22%20ORDER%20BY%20updated%20DESC all security issues] have been integrated and there are not leftovers in the security area (but for delayed majors, where some security issues may have been introduced along the delay and they will be postponed to next minors).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify all unit tests and integration tests have passed (check all current CI servers in use).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Verify QA tests have passed.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Timing prerequisites (don&#039;t continue with the process if not within the time window!):&lt;br /&gt;
# Latest weeklies before the minor/major releases must be done (moodle-package-extract-and-postprocess email should confirm this has happened around 09:00 Australia/Perth).&lt;br /&gt;
# Minor and major releases can be packaged at any time within the 96 hours before the automatic releasing time (Monday 09:00 Australia/Perth). And always, at very least, 4 hours before then (to allow the server to prepare all the stuff).&lt;br /&gt;
(in practice, this means that the packaging of minor/major releases must be done, assuming that weeklies were rolled normally on Thursday, between Friday 09:00 and Monday 05:00 (Australia/Perth times). Breaking any of these rules will require manual operation in the server, forcing repackaging and releasing.&lt;br /&gt;
&lt;br /&gt;
Follow the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script to generate the target minor (--type minor) and major (--type major) releases and their corresponding tags. Pay attention to the complete output of the process: permissions, svg, travis changes (only for majors)... Triple verify all changes are correct! (can use the --show option to inspect them). Follow the on-screen instructions. &lt;br /&gt;
* Push changes to integration.git (but tags).&lt;br /&gt;
For major releases, only when a new STABLE branch has been created:&lt;br /&gt;
* Run the &#039;&#039;&#039;prerelease.sh&#039;&#039;&#039; script (--type back-to-dev) to move master to next X.Y+1 development version/branch. &lt;br /&gt;
* Push changes to integration.git - note this will lead to the &amp;quot;versions checker&amp;quot; failing for master, no problem, it will be fixed by the 1st cloned issue at #12 below).&lt;br /&gt;
* Configure &amp;quot;mdlrelease&amp;quot; (config.sh) to know about the new MOODLE_XY stable branch.&lt;br /&gt;
* Update the old CI server(s) by cloning all the &amp;quot;master&amp;quot; jobs to a new &amp;quot;MXY&amp;quot; view (trick: do it down-top, way easier). Don&#039;t forget to re-chain the jobs properly.&lt;br /&gt;
** Adjust &amp;quot;master&amp;quot; compare DB jobs to check for upgrade from MOODLE_XY_STABLE.&lt;br /&gt;
** Configure the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
** Run all them.&lt;br /&gt;
* Update the new CI infrastructure:&lt;br /&gt;
** MR1: Merge pull request for new version in [https://git.in.moodle.com/integration/nightlyjobs CI Jobs Repository]&lt;br /&gt;
** MR2: Merge pull request for symlink in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** MR3: Merge pull request for skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
** Clone all the &amp;quot;B - master&amp;quot; jobs to a new &amp;quot;B - XY&amp;quot; view (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Clone%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
Both with minors and majors, continue with the &amp;quot;mdlrelease&amp;quot; steps:&lt;br /&gt;
* Once CI servers have ended and all jobs have passed, &#039;&#039;&#039;push tags&#039;&#039;&#039; and run the &#039;&#039;&#039;release.sh&#039;&#039;&#039; script to apply the changes to moodle.git.&lt;br /&gt;
* If needed configure &amp;quot;mdlrelease&amp;quot; (config.sh) to get rid of any unsupported version and adjust stable and security branches. Make a pull request with the changes.&lt;br /&gt;
* Don&#039;t forget the &amp;quot;[https://github.com/moodlehq/mdlrelease/#after-the-release After the release]&amp;quot; tasks.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post a &amp;quot;git repos updated &amp;amp; tagged&amp;quot; message on the [https://partners.moodle.com/mod/forum/view.php?id=810 Partner forum]&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| In the [https://github.com/moodlehq/moodle-performance-comparison performance comparison repository], set the new release commit hash as $basecommit in the master branch and create a new MOODLE_XY_STABLE branch from it. ([https://github.com/moodlehq/moodle-performance-comparison/commit/7c875f03e52641f69674235a8947131d77691299 example]). Also, apply it to the current performance testing infrastructure.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Wait for the automated (every 2 hours) moodle-package to finish building for all versions. Verify the process has ended successfully (email).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
* Create new windows packager script (cloning the current master one and configuring it).&lt;br /&gt;
* Edit the stats.php script (in the moodle-local_downloadmoodleorg repository), adding the new branch to the versions. Push it. Next time the plugin is deployed (normally 1 week after release, aprox.) the stats will start showing the new branch statistics.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
* Visit the versions page and make the release, bumping all remaining open bugs to the next point release. If there is not next (end of support), clean that version from all the issues having it as &amp;quot;Fix for&amp;quot;. This must be done both for the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10011 Moodle Project] and the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10033 Plugins project].&lt;br /&gt;
* Archive all versions but the ones being released, verifying that [https://tracker.moodle.org/issues/?jql=project%3DMDL%20AND%20status%20!%3D%20Closed%20AND%20fixVersion%20%3D%20VERSION_TO_ARCHIVE there aren&#039;t open issues using that version].&lt;br /&gt;
* Remove from all screens the custom fields belonging to 100% unsupported branches.&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Release and archive the [https://tracker.moodle.org/issues/?jql=affectedVersion%20~%20%22must%20fix%20for*%22%20OR%20fixVersion%20~%20%22must%20fix%20for*%22 &amp;quot;Must fix for X.Y&amp;quot; versions], it must be empty to do so.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Create the new &amp;quot;Pull X.Y Branch&amp;quot; and &amp;quot;Pull X.Y Diff URL&amp;quot; custom fields and spread them to all the screens needing them (copy from previous ones). Order them properly on each screen. Re-index Tracker.&lt;br /&gt;
* In the CI server edit the [http://integration.moodle.org/view/tracker/job/Tracker%20-%20CI%20-%20Bulk%20precheck%20issues/ &amp;quot;Bulk precheck issues&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(awaiting_integration)/ &amp;quot;Pre-launch DEV jobs (awaiting_integration)&amp;quot;], [https://ci.moodle.org/view/Tracker/job/TR%20-%20Bulk%20pre-launch%20DEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch DEV jobs (list_of_mdsl)&amp;quot;] and [https://ci.moodle.org/view/Tracker/job/STR%20-%20Bulk%20pre-launch%20SDEV%20jobs%20(list_of_mdls)/ &amp;quot;Pre-launch SDEV jobs (list_of_mdsl)&amp;quot;] jobs to make them meet the new &amp;quot;Pull X.Y Branch&amp;quot; field created. At the same time, remove from those jobs any branch belonging to 100% unsupported branches.&lt;br /&gt;
* Edit the &amp;quot;Tracker - CI - Check marked as integrated&amp;quot; job ([https://ci.moodle.org/view/Tracker/job/TR%20-%20Check%20marked%20as%20integrated/ link]) to configure the development branches (devbranches) (39, 310, 311, 400...) actually active. Normally only the branch corresponding to master, but also accepts a comma separated list when under parallel development (&amp;quot;310,400&amp;quot; or &amp;quot;311,400&amp;quot; for example). Ordered by planned release date.&lt;br /&gt;
* Check/configure (again, this may be has been already executed few steps above) the &amp;quot;05. Check version.php files&amp;quot; jobs both for the involved branches (XY and master) to define the interval of versions allowed in each.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| In the Tracker...&lt;br /&gt;
For major releases only:&lt;br /&gt;
* Create the new &amp;quot;X.Y regressions&amp;quot; version to be applied to every issue found to be a recent problem introduced by the major release. These issues should get priority after release.&lt;br /&gt;
* Adjust the [https://tracker.moodle.org/issues/?filter=17528 Latest regressions] filter (requires login).&lt;br /&gt;
For all releases:&lt;br /&gt;
* Verify how the &amp;quot;X.Y regressions&amp;quot; versions [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20resolution%20%3D%20Unresolved%20AND%20affectedVersion%20in%20(versionMatches(%22.*regressions%22)) are going] (requires login) and ping Development Managers about. Package and archive them once empty.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Clone MDL-74509 and MDL-74510, to be resolved ASAP.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
* Create the new MOODLE_XY_STABLE and lastbased-MOODLE_XY_STABLE branches in the security repo (branching from the just created upstream MOODLE_XY_STABLE branch).&lt;br /&gt;
* Cherry pick any security commit present in the security repository&#039;s master branch to the new MOODLE_XY_STABLE branch (note that normally there should not be any, see point #1 check list above).&lt;br /&gt;
* Verify the new security jobs exist for the new branch and check it&#039;s working in all servers, keeping only enabled the public one.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Protect the MOODLE_XY_STABLE branches in github interface to prevent non-FF accidents ( MDLSITE-4183 )&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
===Release day===&lt;br /&gt;
Usually on Monday&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| The execution of &amp;quot;moodle-package-extract-and-postprocess X&amp;quot; script may be needed if the releases &#039;&#039;&#039;are not going to be published on Monday&#039;&#039;&#039; but another weekday (X is the weekday, (1-7) starting in Monday).&lt;br /&gt;
By default it happens automatically around 09:00 AM Perth/Australia time (check emails then). &lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify release status, download pages and windows packages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| If needed, modify the downloads cfg script (serverscripts) to decide about branches status, master visibility and windows availability. Push changes, will be autodeployed in a few minutes.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add/update the release date, build number and link on the [[Releases|Releases page]] and date in new version pages.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify all registered sys admins, including security notes with CVE identifiers, using the [http://lists.moodle.org/ mailing list server].&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Post about the Major release on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Head of LMS&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Post about minor releases on the [http://moodle.org/news/ moodle.org News forum]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 8.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| New &amp;quot;X.Y+1dev&amp;quot; branch to be created in AMOS, to have master changes performed there. New install_XY_STABLE processing set up. These needs to be done anytime during the on-sync period.&lt;br /&gt;
| AMOS Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 9.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Verify, 24h after tagging, that https://moodle.org/dev/contributions.php has been updated with new versions. If not, file an urgent mdlsite issue, crons must be running!&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 10.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| For en and de Moodle Docs, update default redirects and enable email notifications.&lt;br /&gt;
| Moodle Docs Maintainer&lt;br /&gt;
|-&lt;br /&gt;
| 11.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Go through all points listed under Day of release in [[New docs version process]].&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 12.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
* Decide the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot; and &amp;quot;QA begins&amp;quot; dates for the next X.(Y+1) major release and put them in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar]. They will be -7w, -5w and -4w before release date respectively.&lt;br /&gt;
* Update the &amp;quot;Full demo&amp;quot;, &amp;quot;Code freeze&amp;quot;, &amp;quot;QA begins&amp;quot; and Release dates on the [[Roadmap]] page.&lt;br /&gt;
* Add events to the HQ calendar for next Major release 6-months cycle according to [[Process#Sprints|the cycle plan]]: ~4 weeks planning and regression fixing, 2 sprints, 1 personal project week, 2 sprints, 1 personal project week, 1 sprint (which should lead up to code freeze).&lt;br /&gt;
* Notify the Community Manager of new dates to be added to the moodle.org calendar.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 13.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &lt;br /&gt;
| Add calendar events in the [https://moodle.org/calendar moodle.org calendar] for coming Major and Minor releases up to the next Major release.&lt;br /&gt;
| Community Manager&lt;br /&gt;
|-&lt;br /&gt;
| 14.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update release schedule image on [[Releases#Version_support|Releases page]]&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 15.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Important: This must be done &#039;&#039;&#039;once it&#039;s already release day @ UTC&#039;&#039;&#039; (aka, after Australia/Perth 08:00) or the &#039;&#039;&#039;queues manage with hold them again&#039;&#039;&#039; because it&#039;s still &amp;quot;last week before release&amp;quot;.&lt;br /&gt;
The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed &#039;&#039;&#039;only&#039;&#039;&#039; [https://tracker.moodle.org/issues/?jql=filter%3D13669%20AND%20type%20in%20(bug%2C%20task%2C%20Sub-task) from &#039;&#039;&#039;bug issues&#039;&#039;&#039; awaiting integration]; they correspond to last-week bugs that were held because of them being unrelated with the release. Now they can be processed, under on-sync rules. Standard message will be used to explain the un-hold.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==1 week after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Publish the X.Y+ packages for download.moodle.org (should be automatic once weeklies are packaged).&lt;br /&gt;
For major releases, within the on-sync period, master packages will be generated using the prerelease.sh script (--type on-sync). That guarantees XY_STABLE and master versions are kept the same. The last week, when leaving the on-sync period, master package will be generated normally (implicit --type weekly), so versions will diverge and dev can continue separately from that point.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Update the version.php in git to be X.Y.Z+ during the next weekly integration process&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Create a new release notes page for the next minor versions (using the [[Release notes template|release notes template]].) Add note to top of relevant version page about security support.&lt;br /&gt;
| Development Manager&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Add all security advisories to [http://moodle.org/security Security news] and [[:Category:Release notes|release notes]] with links to security advisories&lt;br /&gt;
|| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 5.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| Notify about publications of CVE using form: https://cveform.mitre.org/&lt;br /&gt;
| Security Officer&lt;br /&gt;
|-&lt;br /&gt;
| 6.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Upgrade moodle.org and all other Moodle community sites (next sites first, then production)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 7.&lt;br /&gt;
|  style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| &#039;&#039;&#039;Deprecations:&#039;&#039;&#039;&lt;br /&gt;
* Create the next deprecation epic (for X.Y+1+2y) similar to MDL-74579 and add standard issues to it:&lt;br /&gt;
** Final deprecation of lib/deprecatedlib.php (like MDL-74580)&lt;br /&gt;
** Removal of deprecated Behat steps (like MDL-74581)&lt;br /&gt;
** Removal of strings (like MDL-74582) and&lt;br /&gt;
** Removal of renamed classes (MDL-74583).&lt;br /&gt;
The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20text%20~%20%22Collect%20together%20deprecated%20and%20planned%20code%20changes%20for%20Moodle%22%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous deprecation epics are going] and share about them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Libraries:&#039;&#039;&#039;&lt;br /&gt;
* Create the next third party libraries epic for X.Y+1, similar to MDL-73715. The issue should refer to the list of [[Moodle libraries credits]]. The issue can be based/cloned on the previous one and linked (&amp;quot;has to be done after&amp;quot;) with it. &#039;&#039;&#039;Drag/link opened issues from the previous one&#039;&#039;&#039;, avoiding leaving unfinished stuff.&lt;br /&gt;
* Review [https://tracker.moodle.org/issues/?jql=project%20%3D%20MDL%20AND%20(summary%20~%20%22Review%20third%20party%20libraries%20for%20new%20versions%22%20OR%20summary%20~%20%22Review%20third-party%20libraries%20for%20upgrade%22)%20AND%20affectedVersion%20in%20(releasedVersions()%2C%20%22Future%20Dev%22)%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20issuekey%20%20DESC how previous library review epics are going] and share about them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==2 weeks after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Once the &amp;quot;On Sync&amp;quot; period ends:&lt;br /&gt;
* Confirm that versions (XY_STABLE and master) diverged properly the last on-sync week. If not, proceed to it by manually bumping master version to currentdate @ integration.git.&lt;br /&gt;
* Disable the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20continuous/ Manage queues on continuous] job. It has served us well.&lt;br /&gt;
* The &amp;quot;[https://tracker.moodle.org/issues/?filter=13669 integration_held]&amp;quot; label will be removed from all issues awaiting integration, so they will be, automatically (see next point), be moved to current integration. Send a &amp;quot;unholding + rebase&amp;quot; message to all those issues.&lt;br /&gt;
* Enable the [https://ci.moodle.org/view/Tracker/job/TR%20-%20Manage%20queues%20on%20normal/ Manage queues on normal] job. It will control the queues over coming months, until next freeze.&lt;br /&gt;
* The discussion about environmental requirements for next X.Y+1 major release (MDL-70594) will end and the issue will be resolved &#039;&#039;&#039;immediately&#039;&#039;&#039;. A new issue, about the requirements for next-next X.Y+2 major release will be created at the same time by cloning the previous one and dragging any non-resolved detail (due date = 3w after release).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| In https://github.com/moodlehq/moodle-behat-extension project:&lt;br /&gt;
* For the new stable version:&lt;br /&gt;
*# Create a MOODLE_XY_STABLE branch from master&lt;br /&gt;
* For master:&lt;br /&gt;
*# Add a 3.X(Y+1).0 tag for the new release in the master branch (first number is the major behat release, currently 3.x).&lt;br /&gt;
*# Clone MDL-70192, implement, and send it to integration.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure [https://download.moodle.org/langpack/X.Y+1/ Language pack for master (X.Y+1)] is available and merge the pull request MR4 for stop skipping the language upgrade in [https://github.com/moodlehq/moodle-ci-runner moodle-ci-runner] repository.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 4.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Ensure release retrospectives are held for each of the LMS teams and results are actioned.&lt;br /&gt;
| Development Manager / Head of LMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==1 month after==&lt;br /&gt;
{| class=&amp;quot;table table-striped table-bordered&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | #&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Major&lt;br /&gt;
! style=&amp;quot;width:20px&amp;quot; | Minor&lt;br /&gt;
! Task&lt;br /&gt;
! style=&amp;quot;width:12%&amp;quot; | Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| 1.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
| &lt;br /&gt;
| Remove, in CI servers, all the jobs and views corresponding to branches which support has ended completely. (there is a [https://ci.moodle.org/view/maintenance/job/MAINT%20-%20Remove%20all%20jobs%20from%20view/ maintenance job] to perform the operation).&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 2.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Upgrade all the Moodle CI sites to recent major release by configuring the &amp;quot;Moodle CI Auto Upgrade&amp;quot; job in all them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|-&lt;br /&gt;
| 3.&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; | &amp;amp;#10003;&lt;br /&gt;
|&lt;br /&gt;
| Confirm that there isn&#039;t any remaining [https://tracker.moodle.org/issues/?filter=13669 integration_held] issue from latest release, proceeding to uhhold them immediately. Note that there may exist [https://tracker.moodle.org/issues/?filter=13669&amp;amp;jql=project%20%3D%20MDL%20AND%20labels%20in%20(integration_held)%20ORDER%20BY%20%22Integration%20priority%22%20DESC%2C%20priority%20DESC%2C%20votes%20DESC%2C%20%22Last%20comment%20date%22%20ASC other &amp;quot;held&amp;quot; issues], unrelated with latest release. This process step does not affect them.&lt;br /&gt;
| Integration Team&lt;br /&gt;
|}&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Deprecation|Deprecation process]]&lt;br /&gt;
[[Category:Processes|Release process]]&lt;br /&gt;
[[Category:Release notes|Release process]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_4.0_release_notes&amp;diff=61986</id>
		<title>Moodle 4.0 release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_4.0_release_notes&amp;diff=61986"/>
		<updated>2022-04-19T03:11:28Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: Moodle 4.0.0 released&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Migrated|newDocId=/docs/release-notes}}&lt;br /&gt;
[[Releases]] &amp;gt; {{FULLPAGENAME}}&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Release date: 19 April 2022&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is [https://tracker.moodle.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=project+%3D+mdl+AND+resolution+%3D+fixed+AND+fixVersion+in+%28%224.0%22%29+ORDER+BY+priority+DESC&amp;amp;runQuery=true&amp;amp;clear=true the full list of fixed issues in 4.0].&lt;br /&gt;
&lt;br /&gt;
If you are upgrading from a previous version, please see [[:en:Upgrading|Upgrading]] in the user docs.&lt;br /&gt;
==Server requirements==&lt;br /&gt;
These are just the minimum supported versions. We recommend keeping all of your software and operating systems up-to-date.&lt;br /&gt;
* Moodle upgrade: Moodle 3.6 or later&lt;br /&gt;
* PHP version: minimum PHP 7.3.0 &#039;&#039;Note: minimum PHP version has increased since Moodle 3.10&#039;&#039;. PHP 7.4.x is supported too. [[Moodle and PHP|PHP 8.0 support]] is being implemented (see MDL-70745) and &#039;&#039;&#039;not ready for production&#039;&#039;&#039; yet.&lt;br /&gt;
* PHP extension &#039;&#039;&#039;sodium&#039;&#039;&#039; is recommended. It will be required in Moodle 4.2. For further details, see [https://docs.moodle.org/311/en/Environment_-_PHP_extension_sodium Environment - PHP extension sodium].&lt;br /&gt;
* PHP extension &#039;&#039;&#039;exif&#039;&#039;&#039; is recommended.&lt;br /&gt;
* PHP setting &#039;&#039;&#039;max_input_vars&#039;&#039;&#039; is recommended to be &amp;gt;= 5000 for PHP 7.x installations. It&#039;s a requirement for PHP 8.x installations. For further details, see [https://docs.moodle.org/311/en/Environment_-_max_input_vars Environment - max input vars].&lt;br /&gt;
=== Database requirements ===&lt;br /&gt;
Moodle supports the following database servers. Again, version numbers are just the minimum supported version. We recommend running the latest stable version of any software.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Database&lt;br /&gt;
! Minimum version&lt;br /&gt;
! Recommended&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.postgresql.org/ PostgreSQL]&lt;br /&gt;
| 10 (increased since Moodle 3.11)  &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mysql.com/ MySQL]&lt;br /&gt;
| 5.7 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [https://mariadb.org/ MariaDB]&lt;br /&gt;
| 10.2.29 &lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microsoft.com/en-us/server-cloud/products/sql-server/ Microsoft SQL Server]&lt;br /&gt;
| 2017 (increased since Moodle 3.10)&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.oracle.com/us/products/database/overview/index.html Oracle Database]&lt;br /&gt;
| 11.2&lt;br /&gt;
| Latest&lt;br /&gt;
|}&lt;br /&gt;
==Client requirements==&lt;br /&gt;
=== Browser support ===&lt;br /&gt;
Moodle is compatible with any standards compliant web browser. We regularly test Moodle with the following browsers:&lt;br /&gt;
&lt;br /&gt;
Desktop:&lt;br /&gt;
* Chrome&lt;br /&gt;
* Firefox&lt;br /&gt;
* Safari&lt;br /&gt;
* Edge&lt;br /&gt;
&#039;&#039;Note: Moodle 4.0 does NOT support Internet Explorer 11.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Safari 7 and below has known compatibility issues with Moodle 4.0.&lt;br /&gt;
&lt;br /&gt;
Mobile:&lt;br /&gt;
* MobileSafari&lt;br /&gt;
* Google Chrome&lt;br /&gt;
For the best experience and optimum security, we recommend that you keep your browser up to date.&lt;br /&gt;
==Major UX improvements==&lt;br /&gt;
===Navigation improvements===&lt;br /&gt;
* MDL-70208 - Implement frontend functionality for primary navigation&lt;br /&gt;
* MDL-70207 - Implement backend functionality for primary navigation&lt;br /&gt;
* MDL-70202 - Implement frontend functionality for secondary navigation&lt;br /&gt;
* MDL-70198 - Implement backend functionality for secondary navigation&lt;br /&gt;
* MDL-70196 - Create a module based navigation bar&lt;br /&gt;
* MDL-72352 - Ensure that secondary navigation is backwards compatible&lt;br /&gt;
* MDL-73462 - Course and category management secondary and tertiary navigation&lt;br /&gt;
* MDL-71977 - Define the secondary navigation nodes that should be always displayed in the more menu in the module context&lt;br /&gt;
* MDL-71901 - Allow plugins to define their own secondary nav ordering&lt;br /&gt;
* MDL-70844 - Update the secondary navigation view to send site administration information in tab form&lt;br /&gt;
* MDL-72396 - Allow easy setting of the active tab for navigation views&lt;br /&gt;
* MDL-71912 - Implement tertiary navigation for plugins (also see MDL-71913, MDL-71914 and MDL-71914)&lt;br /&gt;
* MDL-73863 - Tertiary navigation in course completion&lt;br /&gt;
* MDL-72875 - Add tertiary navigation to the participants page&lt;br /&gt;
* MDL-72904 - Add tertiary navigation to the badges pages&lt;br /&gt;
* MDL-72873 - Add tertiary navigation to the gradebook&lt;br /&gt;
* MDL-72094 - Update the course reports page styling and functionality&lt;br /&gt;
* MDL-71083 - Move the user menu in the top bar into the primary navigation menu in the mobile view&lt;br /&gt;
* MDL-73393 - Ensure that existing third party themes still work with latest navigation changes&lt;br /&gt;
* MDL-71943 - Dynamic (AJAX) tabs in Moodle LMS&lt;br /&gt;
* MDL-72090 - Convert course admin pages from link farms to dropdowns&lt;br /&gt;
* MDL-72413 - Move the activity modules title, description, and activity completion into a standard module API&lt;br /&gt;
* MDL-72736 - Remove section navigation on one section per page&lt;br /&gt;
* MDL-72834 - Move the calendar link into the user menu&lt;br /&gt;
* MDL-72450 - Remove the next and previous activity links from all activity modules in Boost&lt;br /&gt;
* MDL-71148 - Combine both the custom menu &amp;amp; primary navigation renderers&lt;br /&gt;
* MDL-71683 - Update language menu to move from the top navigation into the user menu when logged in&lt;br /&gt;
* MDL-72005 - Update the context_header in Boost to move the breadcrumb to the top&lt;br /&gt;
===Course index===&lt;br /&gt;
* MDL-71209 - Create the new course index list&lt;br /&gt;
* MDL-72660 - Add activity completion indicators to the course index&lt;br /&gt;
* MDL-71228 - Implement drag and drop option for sections and activities in the course index&lt;br /&gt;
* MDL-71211 - Keep the status of the course index collapsed and expanded sections per user and course&lt;br /&gt;
* MDL-71795 - Course index on activity view page&lt;br /&gt;
* MDL-71828 - Implement section links&#039; behaviour in course index&lt;br /&gt;
* MDL-71664 - Enable drag &amp;amp; drop from course index to course content and vice versa&lt;br /&gt;
* MDL-72463 - Add &#039;highlighted&#039; label to course index&lt;br /&gt;
* MDL-71727 - Sync course index and course content when an element is dragged&lt;br /&gt;
* MDL-72897 - Mark the current section in the course index&lt;br /&gt;
* MDL-73340 - Open course index by default first time a user access the course&lt;br /&gt;
* MDL-73310 - Show the course index on all pages within a course&lt;br /&gt;
===Course experience===&lt;br /&gt;
* MDL-71037 - Sections are now collapsible for Topics and Weekly course formats&lt;br /&gt;
* MDL-71691 - Created a new activity UI component&lt;br /&gt;
* MDL-71689 - Improvements to add activity and add section design&lt;br /&gt;
* MDL-71663 - Created a new &amp;quot;move&amp;quot; option in the sections and activity cog menu in the course editor&lt;br /&gt;
* MDL-71779 - Made &#039;Add a new topic/week&#039; option client side on Topics and Weekly formats&lt;br /&gt;
* MDL-72311 - Proceed straight to course content when creating a new course&lt;br /&gt;
* MDL-71863 - Created core_courseformat subsystem&lt;br /&gt;
* MDL-72578 - Moved activity UI component to output classes and templates&lt;br /&gt;
* MDL-73343 - New quick access to create a new course from My courses page when there is no course available&lt;br /&gt;
===My Courses page and overview block===&lt;br /&gt;
* MDL-70801 - Implement &amp;quot;My courses&amp;quot; page&lt;br /&gt;
* MDL-58579 - Allow searching / filtering of courses in myoverview&lt;br /&gt;
* MDL-73231 - Provide option of having My courses as defaulthomepage&lt;br /&gt;
===Timeline block===&lt;br /&gt;
* MDL-72276 - Update timeline block dropdowns to display current selection&lt;br /&gt;
* MDL-72277 - Improve the layout and usability of the items in the timeline block&lt;br /&gt;
* MDL-73068 - Only display courses in the timeline block if they contain events&lt;br /&gt;
* MDL-72295 - Add text search to the timeline block&lt;br /&gt;
* MDL-72594 - Improve displaying of overdue items in the timeline block&lt;br /&gt;
* MDL-72603 - Replace timeline block pagination with &amp;quot;show more&amp;quot; lazy loading&lt;br /&gt;
* MDL-72543 - Change the display of the event names of the items on the timeline block&lt;br /&gt;
===Calendar usability===&lt;br /&gt;
* MDL-71817 - Render the calendar in the calendar block in month view&lt;br /&gt;
* MDL-72237 - Limit number of events shown per day in calendar month view&lt;br /&gt;
* MDL-71810 - Add a current date indicator and make calendar block responsive when switching between small and large views&lt;br /&gt;
* MDL-71808 - Move the import calendar form to its own page&lt;br /&gt;
* MDL-72045 - Improve help information provided on the calendar export page&lt;br /&gt;
* MDL-71790 - Revamp the manage subscriptions page&lt;br /&gt;
* MDL-71788 - Make it easier to copy the export URL&lt;br /&gt;
* MDL-71775 - Add footer links to the calendar block&lt;br /&gt;
* MDL-72810 - Remove 3-month calendar view&lt;br /&gt;
===Dashboard===&lt;br /&gt;
* MDL-72092 - Arrange blocks between My courses &amp;amp; My dashboard&lt;br /&gt;
* MDL-73114 - Display a title in the dashboard page&lt;br /&gt;
* MDL-71964 - Welcome message for users&lt;br /&gt;
* MDL-73233 - Provide option to disable the Dashboard&lt;br /&gt;
* MDL-72116 - Remove some of the default blocks from the Dashboard&lt;br /&gt;
===User tours===&lt;br /&gt;
* MDL-61674 - Allow user tours to be created using the Atto text editor&lt;br /&gt;
* MDL-72385 - Improve and simplify design of user tours&lt;br /&gt;
* MDL-71938 - Display number of steps in a user tour&lt;br /&gt;
* MDL-72783 - Add new user tours&lt;br /&gt;
* MDL-72781 - Remove previous user tours&lt;br /&gt;
* MDL-72557 - Implement customisable confirmation button for single step user tours&lt;br /&gt;
* MDL-71931 - Update user tours to emit events&lt;br /&gt;
===Other usability and user experience improvements===&lt;br /&gt;
* MDL-69371 - Redesign the Moodle login page (also see MDL-72928)&lt;br /&gt;
* MDL-71457 - Update the Moodle activity icons&lt;br /&gt;
* MDL-71963 - Turn confirmation page into modals&lt;br /&gt;
* MDL-71965 - New footer&lt;br /&gt;
* MDL-71456 - Create page drawers for the block and course index areas&lt;br /&gt;
* MDL-72095 - Set a main container width of Boost pages&lt;br /&gt;
* MDL-71610 - Move the turn editing on button into the navbar&lt;br /&gt;
* MDL-72305 - Show user initials as a placeholder for the user profile picture&lt;br /&gt;
* MDL-72278 - Fake blocks now in drawer are made visible on first visit&lt;br /&gt;
* MDL-72454 - Removal of back to top link&lt;br /&gt;
* MDL-72088 - Update styling across top level pages&lt;br /&gt;
* MDL-70888 - Update the layouts in Boost theme&lt;br /&gt;
* MDL-71292 - Update the page header and include course image / activity icon&lt;br /&gt;
* MDL-73608 - Provide a contact form which sends to the site support email and replace mailto link in footer&lt;br /&gt;
* MDL-73935 - Improved flexibility of site support form and consistency of site support info provided in Moodle&lt;br /&gt;
* MDL-61564 - Allow multiple cohort selection in cohort enrolment&lt;br /&gt;
* MDL-66539 - Better handling of link names and URLs with Atto&lt;br /&gt;
* MDL-73797 - Dialogues now have the action button on the right&lt;br /&gt;
* MDL-60917 - Add highest ranked results section to global search&lt;br /&gt;
* MDL-73917 - Notification preferences page improvements&lt;br /&gt;
* MDL-72500 - Easier to find a specific component in event list report&lt;br /&gt;
* MDL-32103 - Course completion is instant for activity based completion criteria (single user completions only)&lt;br /&gt;
==Other major features==&lt;br /&gt;
===Report builder integration (from Moodle Workplace)===&lt;br /&gt;
* MDL-70795 - Implement functionality for creating custom reports&lt;br /&gt;
* MDL-70794 - Implement functionality for creating system reports&lt;br /&gt;
* MDL-72588 - Implement custom report audiences&lt;br /&gt;
* MDL-72598 - Implement custom report schedules&lt;br /&gt;
* MDL-73598 - Allow Custom Reports to be disabled by site admin&lt;br /&gt;
* MDL-72280 - Create &amp;quot;Courses&amp;quot; custom report source&lt;br /&gt;
* MDL-73069 - Report condition to limit returned data to current user&lt;br /&gt;
* MDL-73180 - Improve definitions of previous/next relative date filters&lt;br /&gt;
* MDL-72662 - Implement relative date options in the Reportbuilder date filter&lt;br /&gt;
* MDL-72172 - Create &amp;quot;Cohort members&amp;quot; custom report source&lt;br /&gt;
* MDL-72962 - Format editable report elements (column, filters, etc)&lt;br /&gt;
* MDL-72826 - Custom report option to display unique row values&lt;br /&gt;
* MDL-71153 - Convert task logs report to a system report&lt;br /&gt;
* MDL-71070 - Convert configuration changes report to a system report&lt;br /&gt;
===BigBlueButton integration===&lt;br /&gt;
* MDL-70658 - Integrate the BigBlueButton plugin into Moodle LMS&lt;br /&gt;
===Quiz and Questions===&lt;br /&gt;
* MDL-71516 - Create new plugin type - Qbank (for the full list of qbank plugins added to core, see MDL-70329)&lt;br /&gt;
* MDL-71679 - Update mod_quiz for new question bank&lt;br /&gt;
* MDL-71636 - Add a columnsortorder settings page &lt;br /&gt;
* MDL-71696 - Add question versions&lt;br /&gt;
* MDL-72076 - Question bank bulk action UI&lt;br /&gt;
* MDL-72553 - Add custom fields to questions&lt;br /&gt;
* MDL-52206 - Move &amp;quot;Require passing grade&amp;quot; completion option to core&lt;br /&gt;
* MDL-52456 - Add notification message for students after questions have been manually graded&lt;br /&gt;
* MDL-71984 - Add logging to quiz auto-save, process_attempt and redo_question&lt;br /&gt;
* MDL-73337 - Log editing quizzes in detail&lt;br /&gt;
* MDL-73699 - Question status UI/UX update&lt;br /&gt;
* MDL-72448 - Add qbank_history to core&lt;br /&gt;
* MDL-71614 - Add qbank_previewquestion to core&lt;br /&gt;
===Update LTI tool provider feature to support 1.3===&lt;br /&gt;
* MDL-69543 - Update tool to support 1.3 OAuth2/OIDC launch flow&lt;br /&gt;
* MDL-71371 - Provide upgrade path for 1.1 preconfigured tools&lt;br /&gt;
* MDL-72745 - Provide account provisioning options for LTI Advantage launches&lt;br /&gt;
* MDL-69547 - Update tool enrolment code so that a user is automatically created and enrolled when launching via 1.3&lt;br /&gt;
* MDL-69545 - Update user sync task to support 1.3 messages&lt;br /&gt;
* MDL-69544 - Update grade sync task to support 1.3 messages&lt;br /&gt;
* MDL-72288 - Update library and model code to support issuer and clientid uniqueness on registrations&lt;br /&gt;
* MDL-69862 - Add dynamic registration support to the tool&lt;br /&gt;
* MDL-70354 - Return line item information during content selection&lt;br /&gt;
===Assignment===&lt;br /&gt;
* MDL-68913 - Per attempt timing now available in assignments&lt;br /&gt;
===Admin configuration presets===&lt;br /&gt;
* MDL-72112 - Integrate admin_presets third-party plugin in Moodle LMS&lt;br /&gt;
* MDL-73145 - Add a $CFG setting to define the preset to be installed&lt;br /&gt;
* MDL-72114 - Include pre-installed admin presets&lt;br /&gt;
* MDL-72113 - Add feature to import/export plugins visibility from Admin presets tool&lt;br /&gt;
* MDL-73394 - Store the latest site admin preset applied&lt;br /&gt;
===Content bank and H5P===&lt;br /&gt;
* MDL-68394 - Integrate mod_h5pactivity with recent activity plugins&lt;br /&gt;
* MDL-72099 - Add navigation by contexts in the content bank&lt;br /&gt;
* MDL-71885 - Inline editing H5P content for mod_h5pactivity&lt;br /&gt;
* MDL-71956 - Inline editing H5P content anywhere&lt;br /&gt;
===Badges===&lt;br /&gt;
* MDL-72141 - Simplifying the external badge page&lt;br /&gt;
===Accessibility improvements===&lt;br /&gt;
* MDL-67853 - Remove online-offline options on notifications&lt;br /&gt;
* MDL-72078 - Give users an indication that they encountered an editor&lt;br /&gt;
* MDL-71604 - Move the screen reader helper button to the first row&lt;br /&gt;
* MDL-72896 - Make html_tables responsive by default&lt;br /&gt;
==Other Highlights==&lt;br /&gt;
===Functional changes===&lt;br /&gt;
* MDL-70456 - Add custom user field support to all places that display user identity [0,Minor] Improvement  &lt;br /&gt;
* MDL-73342 - Disable some blocks by default (such as feedback, RSS and self-completion)&lt;br /&gt;
* MDL-70905 - Updated media default width/height to use 16:9&lt;br /&gt;
* MDL-72118 - Rename &amp;quot;HTML block&amp;quot; to the more easily understood &amp;quot;Text block&amp;quot; &lt;br /&gt;
* MDL-72706 - Change default value of &amp;quot;Hidden sections&amp;quot; course format setting&lt;br /&gt;
* MDL-72115 - Rename &amp;quot;Miscellaneous&amp;quot; category to &amp;quot;Category 1&amp;quot;&lt;br /&gt;
* MDL-72119 - Make “Enable xxxxx” features consistent (hide menus for disabled features)&lt;br /&gt;
===For administrators===&lt;br /&gt;
* MDL-71347 - Add a filter to &amp;quot;browse list of users&amp;quot; for date of user account creation&lt;br /&gt;
* MDL-72031 - Separate out max_time for audio and video files in Atto/RecordRTC&lt;br /&gt;
* MDL-71515 - Improve the test outgoing mail configuration admin page&lt;br /&gt;
* MDL-67686 - Add more filters to task log (/admin/tasklogs.php)&lt;br /&gt;
* MDL-72984 - Ensure support email address is mandatory&lt;br /&gt;
* MDL-73592 - MoodleNet integration now enabled by default&lt;br /&gt;
* MDL-71621 - Parent role cannot edit custom fields in child profile&lt;br /&gt;
* MDL-73918 - Allow admins to change the page width using custom SCSS&lt;br /&gt;
* MDL-71927 - Logs and question attempt history now show time to the second, to help investigate issues&lt;br /&gt;
* MDL-71466 - Custom user field support: Admin role screens (check permissions, assign)&lt;br /&gt;
* MDL-72619 - Provide admin page to view cache size estimates&lt;br /&gt;
* MDL-67822 - New check_database_schema performance check&lt;br /&gt;
* MDL-70271 - Dropbox token and Permission Updates&lt;br /&gt;
* MDL-58395 - LDAP auth sync now skip and report problematic user accounts&lt;br /&gt;
* MDL-72251 - Tasks admin UI now shows time to nearest second&lt;br /&gt;
===Mobile===&lt;br /&gt;
* MDL-67807 - Return concurrent sessions information to apply concurrent login limit in the mobile app&lt;br /&gt;
* MDL-69555 - Make duration of QR login and auto-login time between requests configurable&lt;br /&gt;
* MDL-73794 - Update the footer in the mobile view&lt;br /&gt;
===Performance===&lt;br /&gt;
* MDL-72596 - Caching: Track cache I/O size in perfdebug&lt;br /&gt;
* MDL-69088 - Make file cache store purges instant with a safe and async purge&lt;br /&gt;
* MDL-68164 - Additional caching of pg_field_type postgres field metadata&lt;br /&gt;
* MDL-63983 - Improve the performance of non-contact searches in messaging when site-wide messaging is disabled (default)&lt;br /&gt;
* MDL-71014 - Cache the siteidentifier and site contextid in local cache&lt;br /&gt;
* MDL-72328 - Add TTL support for Redis caches&lt;br /&gt;
* MDL-72837 - Cache API should support versioned data&lt;br /&gt;
==Security improvements==&lt;br /&gt;
* MDL-56873 - Set more secure defaults for the cURL allow/deny lists&lt;br /&gt;
* MDL-66776 - Send notifications when new devices are used to log in into the site&lt;br /&gt;
* MDL-71627 - Add check API for anti virus and optionally remove admin notifications&lt;br /&gt;
* MDL-71806 - Improved the UX of the Moodle security report&lt;br /&gt;
* MDL-71176 - New password and change forms should have autocomplete=&amp;quot;new-password&amp;quot;&lt;br /&gt;
==For developers==&lt;br /&gt;
* MDL-61460 - Introduce the UI components library&lt;br /&gt;
* MDL-74229 - Add navigation node keys to allow themers to hide navigation tabs&lt;br /&gt;
* MDL-74235 - Rename the icons for activities to allow support of multiple icons for multiple versions&lt;br /&gt;
* MDL-74033 - Allow full customisation of the primary navigation&lt;br /&gt;
* MDL-72779 - Set more than one value on a persistent at the same time&lt;br /&gt;
* MDL-70862 - Implement a new callback to extend gradebook plugininfo&lt;br /&gt;
* MDL-72289 - Allow callers to customise the rendered icon of inplace editable elements&lt;br /&gt;
* MDL-73347 - Allow themes to define un-addable blocks&lt;br /&gt;
* MDL-46778 - Allow use a separate DB configuration (not just prefix) for Behat similar to PHPUnit&lt;br /&gt;
* MDL-73270 - Warn where XMLRPC is currently in use&lt;br /&gt;
* MDL-67228 - Tool_replace maturity set&lt;br /&gt;
===Web service additions and updates===&lt;br /&gt;
* MDL-71135 - Create core_course_get_state web service&lt;br /&gt;
* MDL-71165 - Create core_course_update_course web service&lt;br /&gt;
===Core plugins removed===&lt;br /&gt;
* MDL-71473 - Jabber removed as a standard notification plugin&lt;br /&gt;
* MDL-58939 - Picasa repository and portfolio removed from core&lt;br /&gt;
* MDL-72335 - Tool_health removed from core&lt;br /&gt;
* MDL-72615 - Boxnet plugins removed from core&lt;br /&gt;
* MDL-72616 - Quiz results block removed from core&lt;br /&gt;
* MDL-72348 - Microsoft OneDrive (legacy) repository (repository_skydrive) removed from core&lt;br /&gt;
* MDL-72347 - Word censorship filter (filter_censor) removed from core&lt;br /&gt;
* MDL-72407 - VideoJS Flash plugin removed from core&lt;br /&gt;
* MDL-72042 - Flash animation media player removed from core&lt;br /&gt;
* MDL-72041 - WebCT question import format removed from core&lt;br /&gt;
* MDL-72517 - Examview question import format removed from core&lt;br /&gt;
===Deprecations===&lt;br /&gt;
* MDL-53544 - Typo3 library removed&lt;br /&gt;
* MDL-72004 - Quiz 4.0 Class renaming and deprecation&lt;br /&gt;
* MDL-73756 - Deprecate $modinfo param to completion_info::get_data()&lt;br /&gt;
* MDL-65799 - Phase 2 of deprecation of functions in lib/deprecatedlib.php initially deprecated in 3.8&lt;br /&gt;
* MDL-71175 - Deprecate some plagiarism functions that are not used, or have replacements&lt;br /&gt;
* MDL-66266 - Remove deprecated functions in messages/classes/api.php&lt;br /&gt;
* MDL-72098 - deprecate grade_grade::insert method that just calls its parent&lt;br /&gt;
* MDL-72433 - Final deprecation of get_grades() in lib/classes/grades_external.php&lt;br /&gt;
* MDL-71476 - Remove mysql_engine.php&lt;br /&gt;
* MDL-65252 - Final deprecations of forum_count_replies and get_forum_discussion_posts&lt;br /&gt;
* MDL-67412 - Remove deprecated functions in lib/setuplib.php &lt;br /&gt;
* MDL-65801 - Remove strings deprecated in 3.8&lt;br /&gt;
===Component API updates===&lt;br /&gt;
* admin/tool/generator/upgrade.txt&lt;br /&gt;
* admin/tool/log/upgrade.txt&lt;br /&gt;
* admin/tool/mobile/upgrade.txt&lt;br /&gt;
* admin/tool/upgrade.txt&lt;br /&gt;
* admin/tool/usertours/upgrade.txt&lt;br /&gt;
* admin/upgrade.txt&lt;br /&gt;
* analytics/upgrade.txt&lt;br /&gt;
* auth/shibboleth/upgrade.txt&lt;br /&gt;
* availability/upgrade.txt&lt;br /&gt;
* backup/upgrade.txt&lt;br /&gt;
* badges/upgrade.txt&lt;br /&gt;
* blocks/section_links/upgrade.txt&lt;br /&gt;
* blocks/tag_youtube/upgrade.txt&lt;br /&gt;
* blocks/timeline/upgrade.txt&lt;br /&gt;
* blocks/upgrade.txt&lt;br /&gt;
* cache/upgrade.txt&lt;br /&gt;
* calendar/upgrade.txt&lt;br /&gt;
* completion/upgrade.txt&lt;br /&gt;
* contentbank/upgrade.txt&lt;br /&gt;
* course/format/upgrade.txt&lt;br /&gt;
* course/upgrade.txt&lt;br /&gt;
* customfield/upgrade.txt&lt;br /&gt;
* dataformat/upgrade.txt&lt;br /&gt;
* enrol/database/upgrade.txt&lt;br /&gt;
* enrol/upgrade.txt&lt;br /&gt;
* filter/upgrade.txt&lt;br /&gt;
* grade/grading/form/upgrade.txt&lt;br /&gt;
* grade/upgrade.txt&lt;br /&gt;
* group/upgrade.txt&lt;br /&gt;
* h5p/upgrade.txt&lt;br /&gt;
* lib/upgrade.txt&lt;br /&gt;
* media/upgrade.txt&lt;br /&gt;
* message/upgrade.txt&lt;br /&gt;
* mod/assign/upgrade.txt&lt;br /&gt;
* mod/book/upgrade.txt&lt;br /&gt;
* mod/feedback/upgrade.txt&lt;br /&gt;
* mod/forum/upgrade.txt&lt;br /&gt;
* mod/glossary/upgrade.txt&lt;br /&gt;
* mod/h5pactivity/upgrade.txt&lt;br /&gt;
* mod/lesson/upgrade.txt&lt;br /&gt;
* mod/lti/upgrade.txt&lt;br /&gt;
* mod/page/upgrade.txt&lt;br /&gt;
* mod/quiz/upgrade.txt&lt;br /&gt;
* mod/resource/upgrade.txt&lt;br /&gt;
* mod/scorm/upgrade.txt&lt;br /&gt;
* mod/upgrade.txt&lt;br /&gt;
* mod/url/upgrade.txt&lt;br /&gt;
* mod/wiki/upgrade.txt&lt;br /&gt;
* mod/workshop/upgrade.txt&lt;br /&gt;
* my/upgrade.txt&lt;br /&gt;
* payment/upgrade.txt&lt;br /&gt;
* plagiarism/upgrade.txt&lt;br /&gt;
* portfolio/upgrade.txt&lt;br /&gt;
* question/bank/upgrade.txt&lt;br /&gt;
* question/behaviour/upgrade.txt&lt;br /&gt;
* question/engine/upgrade.txt&lt;br /&gt;
* question/format/upgrade.txt&lt;br /&gt;
* question/type/multichoice/upgrade.txt&lt;br /&gt;
* question/type/upgrade.txt&lt;br /&gt;
* question/upgrade.txt&lt;br /&gt;
* report/eventlist/upgrade.txt&lt;br /&gt;
* report/upgrade.txt&lt;br /&gt;
* repository/upgrade.txt&lt;br /&gt;
* search/upgrade.txt&lt;br /&gt;
* theme/upgrade.txt&lt;br /&gt;
* user/upgrade.txt&lt;br /&gt;
* webservice/upgrade.txt&lt;br /&gt;
 &lt;br /&gt;
==See also==&lt;br /&gt;
*[[Moodle 3.11 release notes]]&lt;br /&gt;
 &lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Moodle 4.0]]&lt;br /&gt;
 &lt;br /&gt;
[[fr:Notes de version de Moodle 4.0]]&lt;br /&gt;
[[es:Notas de Moodle 4.0]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=61985</id>
		<title>Releases</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=61985"/>
		<updated>2022-04-19T03:05:10Z</updated>

		<summary type="html">&lt;p&gt;Stronk7: (amend dates to planned release dates)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists all official releases of Moodle, grouped by branch in reverse chronological order.&lt;br /&gt;
==Version support==&lt;br /&gt;
From Moodle 2.6 onwards, the end of support, both general and security, happens the second Monday of May and November, observing the 12, 18... month periods, no matter if the major release date was moved or not.&lt;br /&gt;
&lt;br /&gt;
The most recent [https://en.wikipedia.org/wiki/Long-term_support long-term support release (LTS)] version is Moodle 3.9.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1px solid #dee2e6;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Version&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Release status&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Initial release&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:rgba(0, 0, 0, 0.05);&amp;quot; | General support ends&lt;br /&gt;
! style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; | Security support ends&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 3.9 (LTS)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#239cae; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 15 June 2020&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 10 May 2021&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 13 November 2023 (ext 6M)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 3.10&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#239cae; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 9 November 2020&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 8 November 2021&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 9 May 2022&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 3.11&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current stable&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 17 May 2021&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 14 Nov 2022 (ext 6M)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | 13 Nov 2023 (ext 12M)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |4.0&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; | Current stable&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |19 April 2022&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |8 May 2023&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |13 November 2023&lt;br /&gt;
|-&lt;br /&gt;
|4.1 (LTS)&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#9cbd50; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future stable&lt;br /&gt;
|November 2022&lt;br /&gt;
|November 2023&lt;br /&gt;
|November 2025&lt;br /&gt;
|}&lt;br /&gt;
[[Image:releasescurrent.png|alt=Release graph]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Release graph key:&amp;lt;/b&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1px solid #dee2e6;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#f98012; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Current stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Currently supported stable releases.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#239cae; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Current security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; | Current release of versions still receiving security-only updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#9cbd50; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Future point releases receiving bug fixes, as well as security updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#316d5e; color:white; adding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Future security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |Future point releases receiving security-only updates.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#686566; color:white; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Past stables&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: rgba(0, 0, 0, 0.05);&amp;quot; |Previously released versions containing bug fixes, as well as security updates. Updating to a currently supported version is recommended.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color:#282828; color:white; padding: .3rem 0.5rem 0.3rem 0.5rem;&amp;quot; |Past security&lt;br /&gt;
| style=&amp;quot;vertical-align: top; border-top: 1px solid #dee2e6; background-color: #FFFFFF&amp;quot; |Previously released versions containing security updates only. Updating to a currently supported version is recommended.&lt;br /&gt;
|}&lt;br /&gt;
==General release calendar==&lt;br /&gt;
These are the target dates for releases. These dates may vary slightly due to unforeseen circumstances.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Release type&lt;br /&gt;
!Frequency&lt;br /&gt;
!Months&lt;br /&gt;
|-&lt;br /&gt;
|[[Process#Major_release_cycles|Major]] (eg. 3.x)&lt;br /&gt;
|6 monthly&lt;br /&gt;
|Second Monday of May and November&lt;br /&gt;
|-&lt;br /&gt;
|[[Process#Stable_maintenance_cycles|Minor]] (Point) (eg. 3.x.y)&lt;br /&gt;
| 2 monthly&lt;br /&gt;
|Second Monday of July, September, November, March and May.&lt;br /&gt;
Third Monday of January.&lt;br /&gt;
|}&lt;br /&gt;
All releases are preceded by a one week warning. Upcoming release dates can be found in the [https://www.google.com/calendar/ical/moodle.com_p4c2oe7hsb77ltaro5qtihb5d4%40group.calendar.google.com/public/basic.ics Moodle development calendar] (Note, this is an iCAL link that will try to add the dates to your personal calendar. If you just want to browse the dates online, use [https://calendar.google.com/calendar/embed?src=moodle.com_p4c2oe7hsb77ltaro5qtihb5d4@group.calendar.google.com&amp;amp;pli=1 this link].).&lt;br /&gt;
&lt;br /&gt;
==Moodle 4.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 4.0&lt;br /&gt;
|19 April 2022&lt;br /&gt;
|2022041900&lt;br /&gt;
|[[Moodle 4.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/400/en/Upgrading Upgrading to 4.0]&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).&lt;br /&gt;
&lt;br /&gt;
==Moodle 3.11==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11&lt;br /&gt;
|17 May 2021&lt;br /&gt;
|2021051700&lt;br /&gt;
|[[Moodle 3.11 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/311/en/Upgrading Upgrading to 3.11]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11.1&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2021051701&lt;br /&gt;
|[[Moodle 3.11.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.11.2&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2021051702&lt;br /&gt;
|[[Moodle 3.11.2 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.3&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2021051703&lt;br /&gt;
|[[Moodle 3.11.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.4&lt;br /&gt;
|8 November 2021&lt;br /&gt;
|2021051704&lt;br /&gt;
|[[Moodle 3.11.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.5&lt;br /&gt;
|17 January 2022&lt;br /&gt;
|2021051705&lt;br /&gt;
|[[Moodle 3.11.5 release notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.11.6&lt;br /&gt;
|14 March 2022&lt;br /&gt;
|2021051706&lt;br /&gt;
|[[Moodle 3.11.6 release notes|Release Notes]]&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).&lt;br /&gt;
 Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).&lt;br /&gt;
==Moodle 3.10==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2020110900&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 3.10 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/310/en/Upgrading Upgrading to 3.10]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.1&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2020110901&lt;br /&gt;
| [[Moodle 3.10.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.2&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2020110902&lt;br /&gt;
|[[Moodle 3.10.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10.3&lt;br /&gt;
|25 March 2021&lt;br /&gt;
|2020110903&lt;br /&gt;
|[[Moodle 3.10.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.4&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2020110904&lt;br /&gt;
|[[Moodle 3.10.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.5&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2020110905&lt;br /&gt;
|[[Moodle 3.10.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.6&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2020110906&lt;br /&gt;
|[[Moodle 3.10.6 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.10.7&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2020110907&lt;br /&gt;
|[[Moodle 3.10.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.8&lt;br /&gt;
|8 November 2021&lt;br /&gt;
|2020110908&lt;br /&gt;
|[[Moodle 3.10.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.9&lt;br /&gt;
|17 January 2022&lt;br /&gt;
|2020110909&lt;br /&gt;
|[[Moodle 3.10.9 release notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.10.10&lt;br /&gt;
|14 March 2022&lt;br /&gt;
|2020110910&lt;br /&gt;
|[[Moodle 3.10.10 release notes|Release Notes]]&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.10.x ended 8 November 2021 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).&lt;br /&gt;
==Moodle 3.9 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9&lt;br /&gt;
|15 June 2020&lt;br /&gt;
|2020061500&lt;br /&gt;
|[[Moodle 3.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/39/en/Upgrading Upgrading to 3.9]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.1&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2020061501&lt;br /&gt;
|[[Moodle 3.9.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.2&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2020061502&lt;br /&gt;
| [[Moodle 3.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.3&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2020061503&lt;br /&gt;
| [[Moodle 3.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.4&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2020061504&lt;br /&gt;
|[[Moodle 3.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.5&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2020061505&lt;br /&gt;
|[[Moodle 3.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.6&lt;br /&gt;
|25 March 2021&lt;br /&gt;
|2020061506&lt;br /&gt;
|[[Moodle 3.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.7&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2020061507&lt;br /&gt;
|[[Moodle 3.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9.8&lt;br /&gt;
|12 July 2021&lt;br /&gt;
|2020061508&lt;br /&gt;
|[[Moodle 3.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.9&lt;br /&gt;
|29 July 2021&lt;br /&gt;
|2020061509&lt;br /&gt;
|[[Moodle 3.9.9 release notes|Release Notes]]&lt;br /&gt;
|Emergency minor release&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.9.10&lt;br /&gt;
|13 September 2021&lt;br /&gt;
|2020061510&lt;br /&gt;
|[[Moodle 3.9.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.11&lt;br /&gt;
| 8 November 2021&lt;br /&gt;
|2020061511&lt;br /&gt;
|[[Moodle 3.9.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.12&lt;br /&gt;
| 17 January 2022&lt;br /&gt;
|2020061512&lt;br /&gt;
|[[Moodle 3.9.12 release notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.9.13&lt;br /&gt;
| 14 March 2022&lt;br /&gt;
|2020061513&lt;br /&gt;
|[[Moodle 3.9.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.9.x ended 10 May 2021 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.9.x will end 13 Nov 2023 (36 months plus 6 months extension).&lt;br /&gt;
==Moodle 3.8==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8&lt;br /&gt;
|18 November 2019&lt;br /&gt;
|2019111800&lt;br /&gt;
|[[Moodle 3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/38/en/Upgrading Upgrading to 3.8]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.1&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2019111801&lt;br /&gt;
|[[Moodle 3.8.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.2&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2019111802&lt;br /&gt;
|[[Moodle 3.8.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.3&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2019111803&lt;br /&gt;
|[[Moodle 3.8.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.4&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2019111804&lt;br /&gt;
|[[Moodle 3.8.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.5&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2019111805&lt;br /&gt;
| [[Moodle 3.8.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.6&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2019111806&lt;br /&gt;
| [[Moodle 3.8.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.7&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2019111807&lt;br /&gt;
|[[Moodle 3.8.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.8&lt;br /&gt;
|8 March 2021&lt;br /&gt;
|2019111808&lt;br /&gt;
|[[Moodle 3.8.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.8.9&lt;br /&gt;
|10 May 2021&lt;br /&gt;
|2019111809&lt;br /&gt;
|[[Moodle 3.8.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.8.x ended 9 November 2020 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.8.x ended 10 May 2021 (18 months).&lt;br /&gt;
==Moodle 3.7==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7&lt;br /&gt;
|20 May 2019&lt;br /&gt;
|2019052000&lt;br /&gt;
|[[Moodle 3.7 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/37/en/Upgrading Upgrading to 3.7]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.1&lt;br /&gt;
|8 July 2019&lt;br /&gt;
|2019052001&lt;br /&gt;
|[[Moodle 3.7.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.2&lt;br /&gt;
|9 September 2019&lt;br /&gt;
|2019052002&lt;br /&gt;
|[[Moodle 3.7.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.3&lt;br /&gt;
|11 November 2019&lt;br /&gt;
|2019052003&lt;br /&gt;
| [[Moodle 3.7.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.4&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2019052004&lt;br /&gt;
|[[Moodle 3.7.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.5&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2019052005&lt;br /&gt;
|[[Moodle 3.7.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.6&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2019052006&lt;br /&gt;
|[[Moodle 3.7.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.7&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2019052007&lt;br /&gt;
|[[Moodle 3.7.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.8&lt;br /&gt;
|14 September 2020&lt;br /&gt;
|2019052008&lt;br /&gt;
| [[Moodle 3.7.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.7.9&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2019052009&lt;br /&gt;
|[[Moodle 3.7.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.7.x ended 11 May 2020 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.7.x ended 9 November 2020 (18 months).&lt;br /&gt;
==Moodle 3.6==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6&lt;br /&gt;
| 3 December 2018&lt;br /&gt;
|2018120300&lt;br /&gt;
|[[Moodle 3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/36/en/Upgrading Upgrading to 3.6]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.1&lt;br /&gt;
|5 December 2018&lt;br /&gt;
|2018120301&lt;br /&gt;
| [[Moodle 3.6.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.6.2&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2018120302&lt;br /&gt;
|[[Moodle 3.6.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.3&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2018120303&lt;br /&gt;
|[[Moodle 3.6.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.4&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2018120304&lt;br /&gt;
|[[Moodle 3.6.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.5&lt;br /&gt;
|8th July 2019&lt;br /&gt;
|2018120305&lt;br /&gt;
|[[Moodle 3.6.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.6&lt;br /&gt;
|9th September 2019&lt;br /&gt;
|2018120306&lt;br /&gt;
|[[Moodle 3.6.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.7&lt;br /&gt;
| 11th November 2019&lt;br /&gt;
|2018120307&lt;br /&gt;
|[[Moodle 3.6.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.8&lt;br /&gt;
|13th January 2020&lt;br /&gt;
|2018120308&lt;br /&gt;
|[[Moodle 3.6.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.9&lt;br /&gt;
|9th March 2020&lt;br /&gt;
|2018120309&lt;br /&gt;
| [[Moodle 3.6.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.6.10&lt;br /&gt;
|11th May 2020&lt;br /&gt;
|2018120310&lt;br /&gt;
|[[Moodle 3.6.10 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.6.x ended 11 November 2019 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.6.x ended 11 May 2020 (18 months).&lt;br /&gt;
==Moodle 3.5 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2018051700&lt;br /&gt;
|[[Moodle 3.5 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/35/en/Upgrading Upgrading to 3.5]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.5.1&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2018051701&lt;br /&gt;
|[[Moodle 3.5.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.2&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2018051702&lt;br /&gt;
|[[Moodle 3.5.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.3&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2018051703&lt;br /&gt;
| [[Moodle 3.5.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.5.4&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2018051704&lt;br /&gt;
|[[Moodle 3.5.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.5&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2018051705&lt;br /&gt;
|[[Moodle 3.5.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.6&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2018051706&lt;br /&gt;
|[[Moodle 3.5.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.7&lt;br /&gt;
|8 July 2019&lt;br /&gt;
|2018051707&lt;br /&gt;
|[[Moodle 3.5.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.8&lt;br /&gt;
|9 September 2019&lt;br /&gt;
|2018051708&lt;br /&gt;
|[[Moodle 3.5.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.9&lt;br /&gt;
|11 November 2019&lt;br /&gt;
|2018051709&lt;br /&gt;
|[[Moodle 3.5.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.10&lt;br /&gt;
|13 January 2020&lt;br /&gt;
|2018051710&lt;br /&gt;
| [[Moodle 3.5.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.11&lt;br /&gt;
|9 March 2020&lt;br /&gt;
|2018051711&lt;br /&gt;
|[[Moodle 3.5.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.12&lt;br /&gt;
|11 May 2020&lt;br /&gt;
|2018051712&lt;br /&gt;
| [[Moodle 3.5.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.13&lt;br /&gt;
|13 July 2020&lt;br /&gt;
|2018051713&lt;br /&gt;
|[[Moodle 3.5.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.14&lt;br /&gt;
| 14 September 2020&lt;br /&gt;
|2018051714&lt;br /&gt;
|[[Moodle 3.5.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.15&lt;br /&gt;
|9 November 2020&lt;br /&gt;
|2018051715&lt;br /&gt;
|[[Moodle 3.5.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.16&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2018051716&lt;br /&gt;
| [[Moodle 3.5.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.17&lt;br /&gt;
|8 March 2021&lt;br /&gt;
| 2018051717&lt;br /&gt;
|[[Moodle 3.5.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.5.18&lt;br /&gt;
| 10 May 2021&lt;br /&gt;
| 2018051718&lt;br /&gt;
|[[Moodle 3.5.18 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.5.x ended May 2019 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.5.x ended 10 May 2021 (36 months).&lt;br /&gt;
==Moodle 3.4==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2017111300&lt;br /&gt;
|[[Moodle 3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/34/en/Upgrading Upgrading to 3.4]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.1&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2017111301&lt;br /&gt;
|[[Moodle 3.4.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.2&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2017111302&lt;br /&gt;
|[[Moodle 3.4.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.3&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2017111303&lt;br /&gt;
|[[Moodle 3.4.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.4&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2017111304&lt;br /&gt;
|[[Moodle 3.4.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.5&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2017111305&lt;br /&gt;
|[[Moodle 3.4.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.6&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2017111306&lt;br /&gt;
| [[Moodle 3.4.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.4.7&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2017111307&lt;br /&gt;
|[[Moodle 3.4.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.8&lt;br /&gt;
|11 March 2019&lt;br /&gt;
|2017111308&lt;br /&gt;
|[[Moodle 3.4.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.4.9&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2017111309&lt;br /&gt;
| [[Moodle 3.4.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.4.x ended 12 November 2018 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.4.x ended 13 May 2019 (18 months).&lt;br /&gt;
==Moodle 3.3==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3&lt;br /&gt;
|15 May 2017&lt;br /&gt;
|2017051500&lt;br /&gt;
|[[Moodle 3.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/33/en/Upgrading Upgrading to 3.3]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.1&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2017051501&lt;br /&gt;
|[[Moodle 3.3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.2&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2017051502&lt;br /&gt;
|[[Moodle 3.3.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.3&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2017051503&lt;br /&gt;
| [[Moodle 3.3.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.4&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2017051504&lt;br /&gt;
|[[Moodle 3.3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.5&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2017051505&lt;br /&gt;
|[[Moodle 3.3.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.6&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2017051506&lt;br /&gt;
|[[Moodle 3.3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.7&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2017051507&lt;br /&gt;
|[[Moodle 3.3.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.3.8&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2017051508&lt;br /&gt;
|[[Moodle 3.3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.3.9&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2017051509&lt;br /&gt;
|[[Moodle 3.3.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.3.x ended 17 May 2018 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.3.x ended 12 November 2018 (18 months).&lt;br /&gt;
==Moodle 3.2==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2&lt;br /&gt;
| 5 December 2016&lt;br /&gt;
|2016120500&lt;br /&gt;
|[[Moodle 3.2 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/32/en/Upgrading Upgrading to 3.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.1&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2016120501&lt;br /&gt;
|[[Moodle 3.2.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.2&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2016120502&lt;br /&gt;
|[[Moodle 3.2.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.3&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2016120503&lt;br /&gt;
|[[Moodle 3.2.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.4&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2016120504&lt;br /&gt;
|[[Moodle 3.2.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.5&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2016120505&lt;br /&gt;
|[[Moodle 3.2.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.6&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2016120506&lt;br /&gt;
| [[Moodle 3.2.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.2.7&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2016120507&lt;br /&gt;
|[[Moodle 3.2.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.8&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2016120508&lt;br /&gt;
|[[Moodle 3.2.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.2.9&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2016120509&lt;br /&gt;
| [[Moodle 3.2.9 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.2.x ended 13 November 2017 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.2.x ended 17 May 2018 (18 months).&lt;br /&gt;
==Moodle 3.1 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1&lt;br /&gt;
|23 May 2016&lt;br /&gt;
|2016052300&lt;br /&gt;
|[[Moodle 3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
[https://docs.moodle.org/31/en/Upgrading Upgrading to 3.1]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.1&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2016052301&lt;br /&gt;
|[[Moodle 3.1.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.2&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2016052302&lt;br /&gt;
|[[Moodle 3.1.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.3&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2016052303&lt;br /&gt;
|[[Moodle 3.1.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.4&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2016052304&lt;br /&gt;
|[[Moodle 3.1.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.5&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2016052305&lt;br /&gt;
|[[Moodle 3.1.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.6&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2016052306&lt;br /&gt;
|[[Moodle 3.1.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.7&lt;br /&gt;
|10 July 2017&lt;br /&gt;
|2016052307&lt;br /&gt;
|[[Moodle 3.1.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.8&lt;br /&gt;
|11 September 2017&lt;br /&gt;
|2016052308&lt;br /&gt;
|[[Moodle 3.1.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.9&lt;br /&gt;
|13 November 2017&lt;br /&gt;
|2016052309&lt;br /&gt;
|[[Moodle 3.1.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.10&lt;br /&gt;
|15 January 2018&lt;br /&gt;
|2016052310&lt;br /&gt;
|[[Moodle 3.1.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.11&lt;br /&gt;
|19 March 2018&lt;br /&gt;
|2016052311&lt;br /&gt;
|[[Moodle 3.1.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.12&lt;br /&gt;
|17 May 2018&lt;br /&gt;
|2016052312&lt;br /&gt;
|[[Moodle 3.1.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.13&lt;br /&gt;
|9 July 2018&lt;br /&gt;
|2016052313&lt;br /&gt;
|[[Moodle 3.1.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.14&lt;br /&gt;
|10 September 2018&lt;br /&gt;
|2016052314&lt;br /&gt;
|[[Moodle 3.1.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.15&lt;br /&gt;
|12 November 2018&lt;br /&gt;
|2016052315&lt;br /&gt;
|[[Moodle 3.1.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.16&lt;br /&gt;
|14 January 2019&lt;br /&gt;
|2016052316&lt;br /&gt;
|[[Moodle 3.1.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.1.17&lt;br /&gt;
|11 March 2019&lt;br /&gt;
| 2016052317&lt;br /&gt;
|[[Moodle 3.1.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.1.18&lt;br /&gt;
|13 May 2019&lt;br /&gt;
|2016052318&lt;br /&gt;
|[[Moodle 3.1.18 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.1.x ended 8 May 2017 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.1.x ended 13 May 2019 (36 months).&lt;br /&gt;
==Moodle 3.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0&lt;br /&gt;
|16 November 2015&lt;br /&gt;
|2015111600&lt;br /&gt;
|[[Moodle 3.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/30/en/Upgrading Upgrading to 3.0]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.1&lt;br /&gt;
|21 December 2015&lt;br /&gt;
|2015111601&lt;br /&gt;
| [[Moodle 3.0.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 3.0.2&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2015111602&lt;br /&gt;
|[[Moodle 3.0.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.3&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2015111603&lt;br /&gt;
|[[Moodle 3.0.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.4&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2015111604&lt;br /&gt;
|[[Moodle 3.0.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.5&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2015111605&lt;br /&gt;
|[[Moodle 3.0.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.6&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2015111606&lt;br /&gt;
|[[Moodle 3.0.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.7&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2015111607&lt;br /&gt;
|[[Moodle 3.0.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.8&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2015111608&lt;br /&gt;
|[[Moodle 3.0.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.9&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2015111609&lt;br /&gt;
|[[Moodle 3.0.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 3.0.10&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2015111610&lt;br /&gt;
|[[Moodle 3.0.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 3.0.x ended 14 November 2016 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 3.0.x ended 8 May 2017 (18 months).&lt;br /&gt;
==Moodle 2.9==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9&lt;br /&gt;
| 11 May 2015&lt;br /&gt;
|2015051100&lt;br /&gt;
|[[Moodle 2.9 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/29/en/Upgrading_to_Moodle_2.9 Upgrading to 2.9]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.1&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2015051101&lt;br /&gt;
|[[Moodle 2.9.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.2&lt;br /&gt;
|14 September 2015&lt;br /&gt;
|2015051102&lt;br /&gt;
| [[Moodle 2.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.3&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2015051103&lt;br /&gt;
| [[Moodle 2.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.4&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2015051104&lt;br /&gt;
|[[Moodle 2.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.5&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2015051105&lt;br /&gt;
|[[Moodle 2.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.6&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2015051106&lt;br /&gt;
|[[Moodle 2.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.7&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2015051107&lt;br /&gt;
|[[Moodle 2.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.9.8&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2015051108&lt;br /&gt;
|[[Moodle 2.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.9.9&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2015051109&lt;br /&gt;
|[[Moodle 2.9.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.9.x ended 9 May 2016 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.9.x ended 14 November 2016 (18 months).&lt;br /&gt;
==Moodle 2.8==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2014111000&lt;br /&gt;
| [[Moodle 2.8 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/28/en/Upgrading_to_Moodle_2.8 Upgrading to 2.8]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.1&lt;br /&gt;
|13 November 2014&lt;br /&gt;
|2014111001&lt;br /&gt;
| [[Moodle 2.8.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.2&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2014111002&lt;br /&gt;
| [[Moodle 2.8.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.3&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2014111003&lt;br /&gt;
|[[Moodle 2.8.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.4&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2014111004&lt;br /&gt;
|[[Moodle 2.8.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.5&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2014111005&lt;br /&gt;
|[[Moodle 2.8.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.6&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2014111006&lt;br /&gt;
|[[Moodle 2.8.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.8.7&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2014111007&lt;br /&gt;
|[[Moodle 2.8.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.8&lt;br /&gt;
|14 September 2015&lt;br /&gt;
|2014111008&lt;br /&gt;
| [[Moodle 2.8.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.9&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2014111009&lt;br /&gt;
|[[Moodle 2.8.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.10&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2014111010&lt;br /&gt;
|[[Moodle 2.8.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.11&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2014111011&lt;br /&gt;
|[[Moodle 2.8.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.8.12&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2014111012&lt;br /&gt;
| [[Moodle 2.8.12 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).&lt;br /&gt;
==Moodle 2.7 (LTS)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7&lt;br /&gt;
| 12 May 2014&lt;br /&gt;
|2014051200&lt;br /&gt;
|[[Moodle 2.7 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/27/en/Upgrading_to_Moodle_2.7 Upgrading to 2.7]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.7.1&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2014051201&lt;br /&gt;
|[[Moodle 2.7.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.2&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2014051202&lt;br /&gt;
|[[Moodle 2.7.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.3&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2014051203&lt;br /&gt;
| [[Moodle 2.7.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.4&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2014051204&lt;br /&gt;
| [[Moodle 2.7.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.5&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2014051205&lt;br /&gt;
|[[Moodle 2.7.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.6&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2014051206&lt;br /&gt;
|[[Moodle 2.7.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.7&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2014051207&lt;br /&gt;
|[[Moodle 2.7.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.8&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2014051208&lt;br /&gt;
|[[Moodle 2.7.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.9&lt;br /&gt;
|6 July 2015&lt;br /&gt;
|2014051209&lt;br /&gt;
|[[Moodle 2.7.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.10&lt;br /&gt;
| 14 September 2015&lt;br /&gt;
|2014051210&lt;br /&gt;
|[[Moodle 2.7.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.11&lt;br /&gt;
|9 November 2015&lt;br /&gt;
|2014051211&lt;br /&gt;
|[[Moodle 2.7.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.12&lt;br /&gt;
|11 January 2016&lt;br /&gt;
|2014051212&lt;br /&gt;
|[[Moodle 2.7.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.13&lt;br /&gt;
|14 March 2016&lt;br /&gt;
|2014051213&lt;br /&gt;
|[[Moodle 2.7.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.14&lt;br /&gt;
|9 May 2016&lt;br /&gt;
|2014051214&lt;br /&gt;
| [[Moodle 2.7.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.15&lt;br /&gt;
|11 July 2016&lt;br /&gt;
|2014051215&lt;br /&gt;
|[[Moodle 2.7.15 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.16&lt;br /&gt;
|12 September 2016&lt;br /&gt;
|2014051216&lt;br /&gt;
|[[Moodle 2.7.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.17&lt;br /&gt;
|14 November 2016&lt;br /&gt;
|2014051217&lt;br /&gt;
|[[Moodle 2.7.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.18&lt;br /&gt;
|9 January 2017&lt;br /&gt;
|2014051218&lt;br /&gt;
|[[Moodle 2.7.18 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.19&lt;br /&gt;
|13 March 2017&lt;br /&gt;
|2014051219&lt;br /&gt;
|[[Moodle 2.7.19 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.7.20&lt;br /&gt;
|8 May 2017&lt;br /&gt;
|2014051220&lt;br /&gt;
| [[Moodle 2.7.20 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.7.x ended 11 May 2015 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.7.x ended 8 May 2017 (36 months).&lt;br /&gt;
==Moodle 2.6==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6&lt;br /&gt;
|18 November 2013&lt;br /&gt;
|2013111800&lt;br /&gt;
|[[Moodle 2.6 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/26/en/Upgrading_to_Moodle_2.6 Upgrading to 2.6]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.1&lt;br /&gt;
|13 January 2014&lt;br /&gt;
| 2013111801&lt;br /&gt;
| [[Moodle 2.6.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.2&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2013111802&lt;br /&gt;
|[[Moodle 2.6.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.3&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2013111803&lt;br /&gt;
|[[Moodle 2.6.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.4&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2013111804&lt;br /&gt;
|[[Moodle 2.6.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.5&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2013111805&lt;br /&gt;
|[[Moodle 2.6.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.6&lt;br /&gt;
|10 November 2014&lt;br /&gt;
|2013111806&lt;br /&gt;
|[[Moodle 2.6.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.7&lt;br /&gt;
|12 January 2015&lt;br /&gt;
|2013111807&lt;br /&gt;
|[[Moodle 2.6.7 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.6.8&lt;br /&gt;
|2 February 2015&lt;br /&gt;
|2013111808&lt;br /&gt;
|[[Moodle 2.6.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.6.9&lt;br /&gt;
|9 March 2015&lt;br /&gt;
|2013111809&lt;br /&gt;
|[[Moodle 2.6.9 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.10&lt;br /&gt;
|10 March 2015&lt;br /&gt;
|2013111810&lt;br /&gt;
| [[Moodle 2.6.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.6.11&lt;br /&gt;
|11 May 2015&lt;br /&gt;
|2013111811&lt;br /&gt;
|[[Moodle 2.6.11 release notes|Release Notes]]&lt;br /&gt;
| Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.6.x ended 10 November 2014 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.6.x ended 11 May 2015 (18 months).&lt;br /&gt;
==Moodle 2.5==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5&lt;br /&gt;
| 14 May 2013&lt;br /&gt;
|2013051400&lt;br /&gt;
|[[Moodle 2.5 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/25/en/Upgrading_to_Moodle_2.5 Upgrading to 2.5]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.5.1&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2013051401&lt;br /&gt;
|[[Moodle 2.5.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.2&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2013051402&lt;br /&gt;
|[[Moodle 2.5.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.3&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2013051403&lt;br /&gt;
|[[Moodle 2.5.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.4&lt;br /&gt;
|13 January 2014&lt;br /&gt;
| 2013051404&lt;br /&gt;
| [[Moodle 2.5.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.5&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2013051405&lt;br /&gt;
|[[Moodle 2.5.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.6&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2013051406&lt;br /&gt;
|[[Moodle 2.5.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.7&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2013051407&lt;br /&gt;
|[[Moodle 2.5.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.5.8&lt;br /&gt;
|8 September 2014&lt;br /&gt;
|2013051408&lt;br /&gt;
|[[Moodle 2.5.8 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.5.9&lt;br /&gt;
| 10 November 2014&lt;br /&gt;
|2013051409&lt;br /&gt;
|[[Moodle 2.5.9 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.5.x ended May 2014 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.5.x ended 10 November 2014 (18 months).&lt;br /&gt;
==Moodle 2.4==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4&lt;br /&gt;
|3 December 2012&lt;br /&gt;
|2012120300&lt;br /&gt;
|[[Moodle 2.4 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/24/en/Upgrading_to_Moodle_2.4 Upgrading to 2.4]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4.1&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2012120301&lt;br /&gt;
|[[Moodle 2.4.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.2&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2012120302&lt;br /&gt;
|[[Moodle 2.4.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.3&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2012120303&lt;br /&gt;
|[[Moodle 2.4.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.4&lt;br /&gt;
|14 May 2013&lt;br /&gt;
|2012120304&lt;br /&gt;
|[[Moodle 2.4.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.5&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2012120305&lt;br /&gt;
|[[Moodle 2.4.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.6&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2012120306&lt;br /&gt;
|[[Moodle 2.4.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.7&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2012120307&lt;br /&gt;
| [[Moodle 2.4.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.4.8&lt;br /&gt;
|13 January 2014&lt;br /&gt;
|2012120308&lt;br /&gt;
|[[Moodle 2.4.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.9&lt;br /&gt;
|10 March 2014&lt;br /&gt;
|2012120309&lt;br /&gt;
|[[Moodle 2.4.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.10&lt;br /&gt;
|12 May 2014&lt;br /&gt;
|2012120310&lt;br /&gt;
| [[Moodle 2.4.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.4.11&lt;br /&gt;
|14 July 2014&lt;br /&gt;
|2012120311&lt;br /&gt;
|[[Moodle 2.4.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.4.x ended December 2013 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.4.x ended June 2014 (18 months).&lt;br /&gt;
==Moodle 2.3==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3&lt;br /&gt;
|25 June 2012&lt;br /&gt;
|2012062500&lt;br /&gt;
|[[Moodle 2.3 release notes|Release Notes]]&lt;br /&gt;
| [https://docs.moodle.org/23/en/Upgrading_to_Moodle_2.3 Upgrading to 2.3]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.1&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2012062501&lt;br /&gt;
|[[Moodle 2.3.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.2&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2012062502&lt;br /&gt;
|[[Moodle 2.3.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.3&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2012062503&lt;br /&gt;
|[[Moodle 2.3.3 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.4&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2012062504&lt;br /&gt;
|[[Moodle 2.3.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.5&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2012062505&lt;br /&gt;
|[[Moodle 2.3.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.6&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2012062506&lt;br /&gt;
|[[Moodle 2.3.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.7&lt;br /&gt;
|14 May 2013&lt;br /&gt;
|2012062507&lt;br /&gt;
|[[Moodle 2.3.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.8&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2012062508&lt;br /&gt;
|[[Moodle 2.3.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.9&lt;br /&gt;
|9 September 2013&lt;br /&gt;
|2012062509&lt;br /&gt;
|[[Moodle 2.3.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.3.10&lt;br /&gt;
|11 November 2013&lt;br /&gt;
|2012062510&lt;br /&gt;
|[[Moodle 2.3.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.3.11&lt;br /&gt;
|13 January 2014&lt;br /&gt;
|2012062511&lt;br /&gt;
|[[Moodle 2.3.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.3.x ended June 2013 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.3.x ended December 2013 (18 months).&lt;br /&gt;
==Moodle 2.2==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2&lt;br /&gt;
|5 December 2011&lt;br /&gt;
|2011120500&lt;br /&gt;
|[[Moodle 2.2 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/22/en/Upgrading_to_Moodle_2.2 Upgrading to 2.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.1&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011120501&lt;br /&gt;
|[[Moodle 2.2.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.2&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011120502&lt;br /&gt;
|[[Moodle 2.2.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.3&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011120503&lt;br /&gt;
|[[Moodle 2.2.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2.4&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011120504&lt;br /&gt;
|[[Moodle 2.2.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.5&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2011120505&lt;br /&gt;
|[[Moodle 2.2.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.6&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2011120506&lt;br /&gt;
| [[Moodle 2.2.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.2.7&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2011120507&lt;br /&gt;
|[[Moodle 2.2.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.8&lt;br /&gt;
|11 March 2013&lt;br /&gt;
|2011120508&lt;br /&gt;
|[[Moodle 2.2.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.9&lt;br /&gt;
|18 March 2013&lt;br /&gt;
|2011120509&lt;br /&gt;
|[[Moodle 2.2.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.10&lt;br /&gt;
|14 May 2013&lt;br /&gt;
| 2011120510&lt;br /&gt;
|[[Moodle 2.2.10 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.2.11&lt;br /&gt;
|8 July 2013&lt;br /&gt;
|2011120511&lt;br /&gt;
|[[Moodle 2.2.11 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.2.x ended December 2012 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.2.x ended June 2013 (18 months).&lt;br /&gt;
==Moodle 2.1==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1&lt;br /&gt;
| 1 July 2011&lt;br /&gt;
|2011070100&lt;br /&gt;
|[[Moodle 2.1 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/21/en/Upgrading_to_Moodle_2.1 Upgrading to 2.1]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.1.1&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2011070101&lt;br /&gt;
| [[Moodle 2.1.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.2&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2011070102&lt;br /&gt;
|[[Moodle 2.1.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.3&lt;br /&gt;
|28 November 2011&lt;br /&gt;
|2011070103&lt;br /&gt;
|[[Moodle 2.1.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.4&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011070104&lt;br /&gt;
|[[Moodle 2.1.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.5&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011070105&lt;br /&gt;
|[[Moodle 2.1.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.6&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011070106&lt;br /&gt;
|[[Moodle 2.1.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.1.7&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011070107&lt;br /&gt;
|[[Moodle 2.1.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.8&lt;br /&gt;
|10 September 2012&lt;br /&gt;
|2011070108&lt;br /&gt;
|[[Moodle 2.1.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.9&lt;br /&gt;
|12 November 2012&lt;br /&gt;
|2011070109&lt;br /&gt;
|[[Moodle 2.1.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.1.10&lt;br /&gt;
|14 January 2013&lt;br /&gt;
|2011070110&lt;br /&gt;
|[[Moodle 2.1.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.1.x ended June 2012 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.1.x ended December 2012 (18 months).&lt;br /&gt;
==Moodle 2.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0&lt;br /&gt;
|24 November 2010&lt;br /&gt;
|2010112400&lt;br /&gt;
| [[Moodle 2.0 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/20/en/Upgrading_to_Moodle_2.0 Upgrading to 2.0]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.1&lt;br /&gt;
|25 December 2010&lt;br /&gt;
|2010122500&lt;br /&gt;
|[[Moodle 2.0.1 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.2&lt;br /&gt;
|21 February 2011&lt;br /&gt;
|2011022100&lt;br /&gt;
|[[Moodle 2.0.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.3&lt;br /&gt;
|5 May 2011&lt;br /&gt;
|2011033003&lt;br /&gt;
|[[Moodle 2.0.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 2.0.4&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2011033004&lt;br /&gt;
| [[Moodle 2.0.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.5&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2011033005&lt;br /&gt;
|[[Moodle 2.0.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.6&lt;br /&gt;
|28 November 2011&lt;br /&gt;
|2011033006&lt;br /&gt;
|[[Moodle 2.0.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.7&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2011033007&lt;br /&gt;
|[[Moodle 2.0.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.8&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2011033008&lt;br /&gt;
|[[Moodle 2.0.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.9&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2011033009&lt;br /&gt;
|[[Moodle 2.0.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 2.0.10&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2011033010&lt;br /&gt;
|[[Moodle 2.0.10 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 2.0.x ended December 2011 (12 months).&lt;br /&gt;
 Bug fixes for security issues in 2.0.x ended June 2012 (18 months).&lt;br /&gt;
==Moodle 1.9==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9&lt;br /&gt;
|3 March 2008&lt;br /&gt;
|2007101509&lt;br /&gt;
|[[Moodle 1.9 release notes|Release Notes]]&lt;br /&gt;
|[https://docs.moodle.org/19/en/Upgrading_to_Moodle_1.9 Upgrading to 1.9]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.1&lt;br /&gt;
|15 May 2008&lt;br /&gt;
| 2007101512&lt;br /&gt;
|[[Moodle 1.9.1 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.2&lt;br /&gt;
|11 July 2008&lt;br /&gt;
|2007101520&lt;br /&gt;
|[[Moodle 1.9.2 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.3&lt;br /&gt;
|15 October 2008&lt;br /&gt;
|2007101530&lt;br /&gt;
|[[Moodle 1.9.3 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.4&lt;br /&gt;
|28 January 2009&lt;br /&gt;
|2007101540&lt;br /&gt;
|[[Moodle 1.9.4 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.5&lt;br /&gt;
|13 May 2009&lt;br /&gt;
|2007101550&lt;br /&gt;
|[[Moodle 1.9.5 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.6&lt;br /&gt;
|21 October 2009&lt;br /&gt;
|2007101560&lt;br /&gt;
|[[Moodle 1.9.6 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.7&lt;br /&gt;
|25 November 2009&lt;br /&gt;
|2007101570&lt;br /&gt;
|[[Moodle 1.9.7 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.8&lt;br /&gt;
|25 March 2010&lt;br /&gt;
|2007101580.00&lt;br /&gt;
|[[Moodle 1.9.8 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.9&lt;br /&gt;
| 8 June 2010&lt;br /&gt;
| 2007101590.00&lt;br /&gt;
| [[Moodle 1.9.9 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.10&lt;br /&gt;
|25 October 2010&lt;br /&gt;
|2007101591.00&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 1.9.10 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.11&lt;br /&gt;
|21 February 2011&lt;br /&gt;
|2007101591.02&lt;br /&gt;
|[[Moodle 1.9.11 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.12&lt;br /&gt;
|10 May 2011&lt;br /&gt;
|2007101591.03&lt;br /&gt;
|[[Moodle 1.9.12 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.13&lt;br /&gt;
|1 August 2011&lt;br /&gt;
|2007101591.04&lt;br /&gt;
|[[Moodle 1.9.13 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.14&lt;br /&gt;
|10 October 2011&lt;br /&gt;
|2007101591.06&lt;br /&gt;
|&lt;br /&gt;
[[Moodle 1.9.14 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.15&lt;br /&gt;
|28 November 2011&lt;br /&gt;
| 2007101591.07&lt;br /&gt;
| [[Moodle 1.9.15 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.16&lt;br /&gt;
|9 January 2012&lt;br /&gt;
|2007101591.10&lt;br /&gt;
|[[Moodle 1.9.16 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.17&lt;br /&gt;
|12 March 2012&lt;br /&gt;
|2007101591.12&lt;br /&gt;
|[[Moodle 1.9.17 release notes|Release Notes]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle 1.9.18&lt;br /&gt;
|14 May 2012&lt;br /&gt;
|2007101591.16&lt;br /&gt;
|[[Moodle 1.9.18 release notes|Release Notes]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle 1.9.19&lt;br /&gt;
|9 July 2012&lt;br /&gt;
|2007101592.00&lt;br /&gt;
|[[Moodle 1.9.19 release notes|Release Notes]]&lt;br /&gt;
|Support has ended&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes for general core bugs in 1.9.x has ended June 2011 (3.5 years).&lt;br /&gt;
 Bug fixes for security issues in 1.9.x by Moodle HQ ended June 2012 (4.5 years).&lt;br /&gt;
 Bug fixes for security issues in 1.9.19+ branch by [http://catalyst.net.nz Catalyst IT] ended [http://moodle.org/mod/forum/discuss.php?d=199706 Dec 2013] (6 years).&lt;br /&gt;
==Moodle 1.8 ==&lt;br /&gt;
*[[Moodle 1.8 release notes|Moodle 1.8]] - 30 March 2007&lt;br /&gt;
*[[Moodle 1.8.1 release notes|Moodle 1.8.1]] - 14 June 2007&lt;br /&gt;
*[[Moodle 1.8.2 release notes|Moodle 1.8.2]] - 8 July 2007&lt;br /&gt;
*[[Moodle 1.8.3 release notes|Moodle 1.8.3]] - 11 October 2007&lt;br /&gt;
*[[Moodle 1.8.4 release notes|Moodle 1.8.4]] - 11 January 2008&lt;br /&gt;
*[[Moodle 1.8.5 release notes|Moodle 1.8.5]] - 8 April 2008&lt;br /&gt;
*[[Moodle 1.8.6 release notes|Moodle 1.8.6]] - 11 July 2008&lt;br /&gt;
*[[Moodle 1.8.7 release notes|Moodle 1.8.7]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.8.8 release notes|Moodle 1.8.8]] - 28 January 2009&lt;br /&gt;
*[[Moodle 1.8.9 release notes|Moodle 1.8.9]] - 15 May 2009&lt;br /&gt;
*[[Moodle 1.8.10 release notes|Moodle 1.8.10]] - 26 October 2009&lt;br /&gt;
*[[Moodle 1.8.11 release notes|Moodle 1.8.11]] - 25 November 2009&lt;br /&gt;
*[[Moodle 1.8.12 release notes|Moodle 1.8.12]] - 27 March 2010&lt;br /&gt;
*[[Moodle 1.8.13 release notes|Moodle 1.8.13]] - 8 June 2010&lt;br /&gt;
*[[Moodle 1.8.14 release notes|Moodle 1.8.14]] - 3 December 2010&lt;br /&gt;
*Support has ended&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.7==&lt;br /&gt;
*[[Moodle 1.7 release notes|Moodle 1.7]] - 7 November 2006&lt;br /&gt;
*[[Moodle 1.7.1 release notes|Moodle 1.7.1]] - 17 January 2007&lt;br /&gt;
*[[Moodle 1.7.2 release notes|Moodle 1.7.2]] - 30 March 2007&lt;br /&gt;
*[[Moodle 1.7.3 release notes|Moodle 1.7.3]] - 11 October 2007&lt;br /&gt;
*[[Moodle 1.7.4 release notes|Moodle 1.7.4]] - 11 January 2008&lt;br /&gt;
*[[Moodle 1.7.5 release notes|Moodle 1.7.5]] - 11 July 2008&lt;br /&gt;
*[[Moodle 1.7.6 release notes|Moodle 1.7.6]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.7.7 release notes|Moodle 1.7.7]] - 28 January 2009&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.6==&lt;br /&gt;
*[[Moodle 1.6 release notes|Moodle 1.6]] - 20 June 2006&lt;br /&gt;
*[[Moodle 1.6.1 release notes|Moodle 1.6.1]] - 20 July 2006&lt;br /&gt;
*[[Moodle 1.6.2 release notes|Moodle 1.6.2]] - 12 September 2006&lt;br /&gt;
*[[Moodle 1.6.3 release notes|Moodle 1.6.3]] - 10 October 2006&lt;br /&gt;
*[[Moodle 1.6.4 release notes|Moodle 1.6.4]] - 17 January 2007&lt;br /&gt;
*[[Moodle 1.6.5 release notes|Moodle 1.6.5]] - 30 March 2007&lt;br /&gt;
*Moodle 1.6.6 - 11 January 2008&lt;br /&gt;
*Moodle 1.6.7 - 11 July 2008&lt;br /&gt;
*[[Moodle 1.6.8 release notes|Moodle 1.6.8]] - 15 October 2008&lt;br /&gt;
*[[Moodle 1.6.9 release notes|Moodle 1.6.9]] - 28 January 2009&lt;br /&gt;
* Support has ended&lt;br /&gt;
==Moodle 1.5==&lt;br /&gt;
*[[Moodle 1.5 release notes|Moodle 1.5]] - 5 June 2005&lt;br /&gt;
*[[Moodle 1.5.1 release notes|Moodle 1.5.1]] - 8 July 2005&lt;br /&gt;
*[[Moodle 1.5.2 release notes|Moodle 1.5.2]] - 16 July 2005&lt;br /&gt;
*[[Moodle 1.5.3 release notes|Moodle 1.5.3]] - 11 November 2005&lt;br /&gt;
*[[Moodle 1.5.4 release notes|Moodle 1.5.4]] - 21 May 2006&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.4==&lt;br /&gt;
*Moodle 1.4 - 31 August 2004&lt;br /&gt;
*Moodle 1.4.1 - 12 September 2004&lt;br /&gt;
*Moodle 1.4.2 - 5 November 2004&lt;br /&gt;
*Moodle 1.4.3 - 21 December 2004&lt;br /&gt;
*Moodle 1.4.4 - 7 March 2005&lt;br /&gt;
*[[Moodle 1.4.5 release notes|Moodle 1.4.5]] - 7 May 2005&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.3==&lt;br /&gt;
*Moodle 1.3 - 25 May 2004&lt;br /&gt;
* Moodle 1.3.1 - 4 June 2004&lt;br /&gt;
*Moodle 1.3.2 - 9 July 2004&lt;br /&gt;
*Moodle 1.3.3 - 16 July 2004&lt;br /&gt;
* Moodle 1.3.4 - 11 August 2004&lt;br /&gt;
*Moodle 1.3.5 - 9 September 2004&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.2==&lt;br /&gt;
*Moodle 1.2 - 20 March 2004&lt;br /&gt;
*Moodle 1.2.1 - 25 March 2004&lt;br /&gt;
*Support has ended&lt;br /&gt;
==Moodle 1.1==&lt;br /&gt;
*Moodle 1.1 - 29 August 2003&lt;br /&gt;
*Moodle 1.1.1 - 11 September 2003&lt;br /&gt;
*Support has ended&lt;br /&gt;
== Moodle 1.0==&lt;br /&gt;
*Moodle 1.0 - 20 August 2002&lt;br /&gt;
*Moodle 1.0.1 - 26 August 2002&lt;br /&gt;
*Moodle 1.0.2 - 2 September 2002&lt;br /&gt;
*Moodle 1.0.3 - 5 September 2002&lt;br /&gt;
*Moodle 1.0.4 - 10 September 2002&lt;br /&gt;
*Moodle 1.0.5 - 27 September 2002&lt;br /&gt;
* Moodle 1.0.6 - 26 October 2002&lt;br /&gt;
::1.0.6.1 - 6 November 2002&lt;br /&gt;
::1.0.6.2 - 11 November 2002&lt;br /&gt;
::1.0.6.3 - 14 November 2002&lt;br /&gt;
::1.0.6.4 - 25 November 2002&lt;br /&gt;
*Moodle 1.0.7 - 9 December 2002&lt;br /&gt;
*Moodle 1.0.8 - 7 January 2003&lt;br /&gt;
*Moodle 1.0.9 - 30 May 2003&lt;br /&gt;
*Support has ended&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Roadmap]] - future versions&lt;br /&gt;
*[[Moodle versions]] - an explanation of how our versions work plus version numbers for each release (for $plugin-&amp;gt;requires)&lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Core development]]&lt;br /&gt;
[[fr:Historique des versions]]&lt;br /&gt;
[[es:dev/Historia de las versiones]]&lt;br /&gt;
[[de:Versionshistorie]]&lt;/div&gt;</summary>
		<author><name>Stronk7</name></author>
	</entry>
</feed>