Wiki source code of Development Practices
Last modified by Eleni Cojocariu on 2026/05/12 12:29
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | XWiki development follows several rules listed below. If you're a Committer or if you simply wish to contribute please take the time to read them as you're expected to follow these rules. | ||
| 2 | |||
| 3 | {{toc/}} | ||
| 4 | |||
| 5 | = General Development Flow = | ||
| 6 | |||
| 7 | == Servers == | ||
| 8 | |||
| 9 | Here's the big picture, listing all servers making up the xwiki.org ecosystem and showing all interactions between servers. | ||
| 10 | |||
| 11 | (% class="centered" %) | ||
| 12 | [[image:xwiki:[email protected]||style="max-width:1024px" title="Tools used in XWiki's development process and their relationship"]] | ||
| 13 | |||
| 14 | List of servers (alphabetical order): | ||
| 15 | |||
| 16 | * [[ci.xwiki.org>>https://ci.xwiki.org]]: Builds all the XWiki and XWiki Contrib GitHub repositories whenever there are source changes. | ||
| 17 | * [[elk.xwiki.org>>https://elk.xwiki.org]]: Stores anonymous data from XWiki instances in the world. Measures progress of the XWiki market share. | ||
| 18 | * [[extensions.xwiki.org>>https://extensions.xwiki.org]]: Sub wiki of xwiki.org listing and documenting all free extensions of XWiki. Uses the XWiki Repository Application and is used by all XWiki instances to install and upgrade extensions inside of XWiki. | ||
| 19 | * [[forum.xwiki.org>>https://forum.xwiki.org]]: Forum to discuss about anything related to XWiki. | ||
| 20 | * [[github.com>>https://github.com/xwiki]]: Stores all the sources for the XWiki and XWiki Contrib project sources. | ||
| 21 | * [[ge.xwiki.org>>https://ge.xwiki.org]]: Store CI build results + provide build caching for both CI builds and local developer's builds. | ||
| 22 | * [[jira.xwiki.org>>https://jira.xwiki.org]]: Issue tracker used to develop XWiki and XWiki Contrib projects. | ||
| 23 | * [[l10n.xwiki.org>>https://l10n.xwiki.org]]: Used to contribute translations of XWiki. | ||
| 24 | * [[lists.xwiki.org>>https://lists.xwiki.org]]: Mailing lists that were originally used to discuss anything related to XWiki. The forum was then added to replace that usage but some lists are kept to receive notifications from the various servers and for Committers-private discussions (+ infra and security too). | ||
| 25 | * [[nexus.xwiki.org>>https://nexus.xwiki.org]]: Stores artifacts produced by the CI (snapshots) and by official releases. Accessed by the XWiki Extension Manager feature. | ||
| 26 | * [[sonar.xwiki.org>>https://sonar.xwiki.org]]: Provides quality data on the XWiki and XWiki Contrib GitHub repositories. Triggered by the CI to run quality checks on the source code. Fails the CI build when the Quality Gate doesn't pass. | ||
| 27 | * [[xwiki.org>>https://xwiki.org]]: Documentation web site for XWiki. | ||
| 28 | * [[#xwiki:matrix.xwiki.com>>https://riot.im/app/#/room/#xwiki:matrix.xwiki.com]]: Chat that can be used by anyone to have conversations about XWiki. Used by the XWiki developers to develop the software too. | ||
| 29 | |||
| 30 | == Roadmap == | ||
| 31 | |||
| 32 | * A roadmap proposal thread is started regularly on the forum, proposing high level topics to work on in the coming XWiki releases. | ||
| 33 | ** Any committer could do this work but at the moment it's Vincent Massol who's sending the roadmap proposal topic. See the info box below to learn more. | ||
| 34 | * The idea is to discuss with the XWiki community and especially the XWiki committers what everyone is interested to work on, but also to verify that in the proposed list, there's nothing that the committers think are not going in the good interest of the project. At this point, committers can also propose new items they'd like to work on. | ||
| 35 | * Once the roadmap is agreed, or if there are no comments, its content is updated on the [[Roadmap page>>xwiki:Roadmaps.WebHome]] | ||
| 36 | * Then, each committers having accepted to implement tasks from the roadmap should analyse their tasks, discuss (to cover all topics including functional needs but also cross-topics such as security, risk, performance, accessibility, and more) with others about them (especially with the person who's proposed the topic), and quickly create a list of JIRA issues, representing the different elements to implement the high level topics. | ||
| 37 | * Note that there can be more JIRA issues than what the committer can take for the release (we currently do monthly releases so committers must take work that take less than a month!) | ||
| 38 | * Committers must update the [[Roadmap page>>xwiki:Roadmaps.WebHome]] and list the JIRA issue they've decided to implement for the coming release. Thus leaving out for other releases the other JIRAs that they cannot implement for this release. | ||
| 39 | * Committers must then assign themselves on the JIRAs + set the ##fixVersion## field. | ||
| 40 | * For complex topics or if they wish to get an agreement from other committers, whenever a committers starts working on a topic, he/she should post a proposal topic to the forum (Development category) to explain what he/she's going to work on, to gather feedback and to get agreement. Usually he/she will also create a [[Design page>>design:Main.WebHome]] and link it in the topic. | ||
| 41 | * Commits should be done regularly and more than once per week (the more the better, ideally several times per day). | ||
| 42 | * Committers are free to create Pull Requests if they want to get some review before pushing the code. | ||
| 43 | |||
| 44 | The goals of this process are several: | ||
| 45 | |||
| 46 | * Provide visibility to the community at large and especially other developers and users | ||
| 47 | * Ensure agreement on the work being done (it's too stupid to do a lot of work and only find when it's finished that it wasn't the right way to do it and it has to be all redone again) | ||
| 48 | * Allow us to have product roadmaps | ||
| 49 | * Provide the ability to help someone if he's lagging behind or has issues | ||
| 50 | |||
| 51 | {{info}} | ||
| 52 | **A peek into XWiki SAS** | ||
| 53 | |||
| 54 | * Vincent works for the [[XWiki SAS company>>https://xwiki.com]] as its CTO but also as the person responsible for the Product Development Team of XWiki SAS, working on several products, including the XWiki open source product. | ||
| 55 | * If you're curious, you can check the [[relationship between XWiki SAS & xwiki.org>>xwiki:FAQ.What is the relationship between XWiki SAS and the XWiki open source project]]. | ||
| 56 | * XWiki SAS has an internal roadmap process which comes up with a list of roadmap items that XWiki SAS think are interesting for the XWiki open source product to work on and that it's willing to sponsor by paying developers to work on them. | ||
| 57 | * Vincent discusses with the XWiki SAS Product team members to assign roadmap items to XWiki SAS developers. | ||
| 58 | * Vincent then sends the roadmap proposal topic on the forum, listing the items discussed by XWiki SAS with the defined assignees from XWiki SAS. | ||
| 59 | {{/info}} | ||
| 60 | |||
| 61 | == Development Flow == | ||
| 62 | |||
| 63 | When you work on some XWiki code here's the typical workflow depending on what you're working on: | ||
| 64 | |||
| 65 | * If you're working on Java classes, you develop in your IDE and [[unit tests>>Testing]] there. Then you build your module with Maven and this generates some JAR file in ##target/##. Then to test the functionality you write some [[functional tests>>Testing]]. For some minor updates, sometimes the tests will already be here. Running the functional tests generates a ##target/xwiki## instance containing an XWiki instance that you can start manually if you wish to perform some additional manual tests. If you don't have any functional tests, you can use a standard XWiki standalone instance and copy the generated JAR file to that it replaces the original one in ##WEB-INF/lib## (if you're changing an installed Extension, you need to replace the JAR in the ##/data/extension/repository## folder). | ||
| 66 | * If you're working on ##vm##/##js##/##css## files, then you create/modify them directly in your XWiki standalone instance in the ##template/##, ##resource/## or ##skin/## folders and just refresh the page using them (you may also need to clear browser cache for ##js##/##css##). When it works you copy paste your modifications in the source tree. Note that you can also write functional tests as for the Java use case above. | ||
| 67 | * If you're working on wiki pages, you also modify them directly in your running XWiki instance, and when you are happy with the result you export the pages as a XAR which you then unzip in the source tree (and you run ##mvn xar:format## on them, see [[XAR plugin>>XARPlugin]]). | ||
| 68 | |||
| 69 | = Automated Builds = | ||
| 70 | |||
| 71 | XWiki has an automated build system and developers are asked to use it on their local machines to prove that their changes work before committing them to the [[Source Repository>>SourceRepository]]. See the [[Building page>>Building]] for more details. | ||
| 72 | |||
| 73 | = Continuous Integration = | ||
| 74 | |||
| 75 | See the [[Continuous Build page>>ContinuousBuild]]. | ||
| 76 | |||
| 77 | = Special Project Roles = | ||
| 78 | |||
| 79 | == Committer Role == | ||
| 80 | |||
| 81 | See [[Committership>>Community.Committership]] | ||
| 82 | |||
| 83 | == Release Manager Role == | ||
| 84 | |||
| 85 | Role definition: | ||
| 86 | |||
| 87 | * In charge of performing a Release of XWiki (usually XWiki Commons/Rendering/Platform). | ||
| 88 | * Is responsible to ensure that the dates defined in the Roadmap are achieved | ||
| 89 | * Needs to coordinate with developers so that they are ready on the release day, this means warning several days ahead and shepherding them to finish their stuff on time or push stuff to the next release | ||
| 90 | * Needs to follow the [[Release Plan Process>>ReleasePlans.WebHome]]. This app creates a release plan for releasing a version, listing all steps to be executed. It also keeps track of past Release Managers (and future ones) and of all past releases. | ||
| 91 | |||
| 92 | Process: | ||
| 93 | |||
| 94 | * We have a [[list of declared Release Managers>>ReleasePlans.WebHome#HNextReleaseManagers]]. Any committer willing to help the project is free to ask to perform a release! | ||
| 95 | * We take turns, following the order (from top to bottom). When a newcomer is added he's inserted at the bottom of the list. | ||
| 96 | * If a committer cannot do the release for a reason or another (sick, holiday, workload, etc) he’s still responsible for the release and he/she needs to find a replacement. He also has the option to propose changing the release date but that needs to be accepted by the project. If he/she finds a replacement, it’s up to them to decide together who will do the release the next time that replacement’s time comes. | ||
| 97 | * All releases are included in this process: milestones, RCs, final, bugfix releases. | ||
| 98 | * We switch Release Manager at each release (be it a milestone, RC, final or bugfix release). | ||
| 99 | * Once a Release is done, the Release Manager updates the [[Release Manager order>>ReleasePlans.WebHome#HNextReleaseManagers]] by moving himself/herself at the bottom of the pile. | ||
| 100 | |||
| 101 | == Build Manager Role == | ||
| 102 | |||
| 103 | {{info}} | ||
| 104 | This is not a role we have all the time. We do it from time to time when our build quality starts to deteriorate and we want to get it back on track | ||
| 105 | {{/info}} | ||
| 106 | |||
| 107 | Role definition: | ||
| 108 | |||
| 109 | * Every week we have a different Build Manager chosen amongst the Committers | ||
| 110 | * The Build Manager has the **responsibility** to get the build fixed ASAP whenever it's failing. His priority #1 during the week becomes monitoring and having the Build in working order (i.e. no failure) | ||
| 111 | * By "Build" we mean the CI Build on https://ci.xwiki.org and by "failing" we mean anything that makes the build fail: tests, compilation, backward-compatibility checks, etc. | ||
| 112 | * In order to fix build issues the Build Manager has several possibilities: | ||
| 113 | ** find out who caused the build to break and ask that person to fix it. That person cannot refuse that and must consider it his/her priority to fix it (or rollback the change that caused the build to fail) | ||
| 114 | ** rollback the issue that caused the build to fail | ||
| 115 | ** fix it himself/herself | ||
| 116 | ** find someone knowledgable in the failing domain and get him/her to fix the build. | ||
| 117 | * The #2 priority of the Build Manager is to improve the XWiki build. Examples: | ||
| 118 | ** Fix more flickering tests | ||
| 119 | ** Improve the PO objects where needed, make sure that tests don’t use getDriver() (that should be only in POs). | ||
| 120 | ** Convert old func tests to docker-based tests | ||
| 121 | ** [[Add missing tests>>https://jira.xwiki.org/issues/?jql=labels%20%3D%20testneeded%20and%20resolution%20%3D%20Unresolved%20]] | ||
| 122 | ** Review/Analyze/Fix CI environment issues | ||
| 123 | ** Upgrade Jenkins and Jenkins plugins | ||
| 124 | * There's a [[Build Manager Roster>>BuildManagerRoster]] to log past Build Managers (and possibly future ones if some have expressed the wish to be the Build Manager for a specific week). | ||
| 125 | * At the end of the Week the Build Manager must find the next Build Manager and hand over his duty. If he doesn't find anyone else, he remains the Build Manager. Note that for fairness the oldest Build Managers on the [[Roster>>BuildManagerRoster]] need to accept to be the next Build Manager. | ||
| 126 | * All committers must perform this duty and take turns | ||
| 127 | |||
| 128 | == Roadmap Manager Role == | ||
| 129 | |||
| 130 | Role definition: | ||
| 131 | |||
| 132 | * Proposes new roadmap and ensure that there's always a roadmap ready before work is started for new XWiki versions | ||
| 133 | |||
| 134 | Process: | ||
| 135 | |||
| 136 | * Once the [[RC version has been released and before the final version is released>>Community.VersioningAndReleasePractices]], send a [[Forum>>Community.Discuss]] post proposal (tag: ##proposal##, subjet: ##Roadmap for XS X.Y.Z##) | ||
| 137 | * Do this by discussing with the various commmitters to gather what everyone is interested in implementing for the upcoming release | ||
| 138 | * Review leftovers from previous releases and consider them as candidates for the new release | ||
| 139 | * Also update the [[Roadmap page>>xwiki:Roadmaps.WebHome]] with the proposal | ||
| 140 | * Ask everyone with tasks in this roadmap to create JIRA issues and to mention them on the [[Roadmap page>>xwiki:Roadmaps.WebHome]] (using the ##jira## macro) | ||
| 141 | |||
| 142 | Current manager: | ||
| 143 | |||
| 144 | * [[vmassol>>xwiki:XWiki.VincentMassol]] | ||
| 145 | |||
| 146 | == Security Manager Role == | ||
| 147 | |||
| 148 | Role definition: | ||
| 149 | |||
| 150 | * Ensures that the XWiki project has a [[security policy>>Community.SecurityPolicy.WebHome]] and maintains it/improves it | ||
| 151 | * Ensures that the security policy is enforced, e.g. make sure that confidential JIRA issues as categorized, and push for "high" severity ones (i.e. blocker ones) are put on the roadmap | ||
| 152 | * Globally making sure that the XWiki project progresses on the topic of security. | ||
| 153 | |||
| 154 | Process: | ||
| 155 | |||
| 156 | * Review weekly (at maximum, can be done more frequently) that there are [[no security issues not categorized>>https://jira.xwiki.org/issues/?jql=(labels%20in%20(securityreview)%20OR%20level%20%3D%20Confidential)%20AND%20resolution%20%3D%20Unresolved%20AND%20%22Development%20Priority%22%20is%20EMPTY]]. | ||
| 157 | |||
| 158 | Current manager: | ||
| 159 | |||
| 160 | * [[surli>>xwiki:XWiki.surli]] (helped with [[MichaelHamann>>xwiki:XWiki.MichaelHamann]]) | ||
| 161 | |||
| 162 | == Infrastructure Manager Role == | ||
| 163 | |||
| 164 | Role definition: | ||
| 165 | |||
| 166 | * Ensures that the servers used to develop XWiki are using latest versions and working fast and properly. | ||
| 167 | |||
| 168 | Process: | ||
| 169 | |||
| 170 | * Review regularly the servers for problems and required upgrades, ideally once a month. | ||
| 171 | |||
| 172 | Current managers: | ||
| 173 | |||
| 174 | * Weblate (l10n.xwiki.org): [[surli>>xwiki:XWiki.surli]] | ||
| 175 | * xwiki.org and myxwiki.org: [[tmortagne>>xwiki:XWiki.ThomasMortagne]] | ||
| 176 | * ci.xwiki.org: all committers | ||
| 177 | * lists.xwiki.org: all committers | ||
| 178 | * nexus.xwiki.org & nexus-snapshots.xwiki.org: all committers | ||
| 179 | * forum.xwiki.org: [[vmassol>>xwiki:XWiki.VincentMassol]] | ||
| 180 | |||
| 181 | == Accessibility Manager Role == | ||
| 182 | |||
| 183 | Role definition: | ||
| 184 | |||
| 185 | * Update the XWiki accessibility statement to keep it in line with the current state of accessibility in XWiki | ||
| 186 | * Ensure that the accessibility of XWiki is improved regularly and does not regress. | ||
| 187 | * Keep an up to date accessibility status of XWiki | ||
| 188 | |||
| 189 | Process: | ||
| 190 | |||
| 191 | * Once per cycle, review the content of the XWiki accessibility statement and: make sure all the items mentionned in the statement have been fulfilled. Then update the statement to fit the current accessibility status in XWiki. | ||
| 192 | * Once per cycle, organize an accessibility audit or a user testing session focused on accessibility for XWiki. This allows to make sure that the accessibility status is up to date. | ||
| 193 | * At least once per master release, check the results of the automatic accessibility tests. This allows a close monitoring of the accessibility status. | ||
| 194 | |||
| 195 | Current manager: | ||
| 196 | |||
| 197 | * [[lcharpentier>>xwiki:XWiki.CharpentierLucas]] | ||
| 198 | |||
| 199 | == Dependency Manager Role == | ||
| 200 | |||
| 201 | Role definition: | ||
| 202 | |||
| 203 | * Ensure that XWiki dependencies are up to date, as much as possible | ||
| 204 | ** There can be valid cases where upgrading takes more time as it requires some complex tasks to be performed. These cases need to be documented and known. The Dependency Manager should ensure that a jira issue with an explanation is created in this case. | ||
| 205 | |||
| 206 | Process: | ||
| 207 | |||
| 208 | * See [[Dependency upgrade pull requests>>#HDependencyupgradepullrequests]]. | ||
| 209 | |||
| 210 | == Performance Manager Role == | ||
| 211 | |||
| 212 | Role definition: | ||
| 213 | |||
| 214 | * Have a good view on performance-related issues with XWiki (large instances: lots of users, lots of sub wikis, lots of accesses, lots of xobjects, lots of pages, etc). | ||
| 215 | * Help maintain the ##performance## label in JIRA issues. | ||
| 216 | * Regularly propose performance-related topics for the Roadmap. | ||
| 217 | * Get some time from the Roadmap to work on performance-related topics. | ||
| 218 | * Help maintain dev pages on xwiki.org related to performance best practices. | ||
| 219 | |||
| 220 | Process: | ||
| 221 | |||
| 222 | * When the Roadmap process starts, discuss taking some performance-related topics. | ||
| 223 | |||
| 224 | Current manager: | ||
| 225 | |||
| 226 | * [[tmortagne>>xwiki:XWiki.ThomasMortagne]] | ||
| 227 | |||
| 228 | == Documentation Manager Role == | ||
| 229 | |||
| 230 | Role definition: | ||
| 231 | |||
| 232 | * Globally responsible for the quality of the xwiki.org documentation. | ||
| 233 | * In charge of proposing rules to improve the quality of the documentation. | ||
| 234 | * In charge of monitoring changes on xwiki.org to fight spam + ensure that the agreed rules are implemented correctly. | ||
| 235 | * In charge and responsible of the [[Documentation Guide>>https://dev.xwiki.org/xwiki/bin/view/Community/DocGuide]]. | ||
| 236 | * Monitor Change Requests and ensure that they're handled. | ||
| 237 | |||
| 238 | === Process === | ||
| 239 | |||
| 240 | To ensure that errors do not proliferate, spam is kept under control, and tasks are handled consistently, it is best to solve issues as soon as notifications are received. However, having a defined weekly process helps maintain regular checks and ensures nothing is overlooked. The following strategy organizes tasks to be performed each day: | ||
| 241 | |||
| 242 | * Monday (Change Request day): Check for Change Requests on each sub-wiki, ask for reviews on CRs in the #xwiki chat. | ||
| 243 | * Tuesday (Spam day): Check for spam, use the AntiSpam Tool to delete unwanted content. | ||
| 244 | * Wednesday (Doc Review day): Review newly created documentation pages to comply to the Documentation Guide. | ||
| 245 | * Thursday (Violation Fix day): Check [[Documentation Violations>>xwiki:DocApp.WebHome]]. | ||
| 246 | * Friday (Reviews day): Review existing documents and request reviews and feedback from the team. | ||
| 247 | |||
| 248 | Current Manager | ||
| 249 | |||
| 250 | * [[Eleni Cojocariu>>xwiki:XWiki.elenicojocariu]] (with help from Vincent Massol) | ||
| 251 | |||
| 252 | = Versioning & Release Practices = | ||
| 253 | |||
| 254 | Check the [[Versioning and Release Practices page>>VersioningAndReleasePractices]]. | ||
| 255 | |||
| 256 | = Copyright header in source files = | ||
| 257 | |||
| 258 | All files (including configuration files) must have the following copyright statement. | ||
| 259 | |||
| 260 | == For Java & Javascript files == | ||
| 261 | |||
| 262 | {{code language="none"}} | ||
| 263 | /* | ||
| 264 | * See the NOTICE file distributed with this work for additional | ||
| 265 | * information regarding copyright ownership. | ||
| 266 | * | ||
| 267 | * This is free software; you can redistribute it and/or modify it | ||
| 268 | * under the terms of the GNU Lesser General Public License as | ||
| 269 | * published by the Free Software Foundation; either version 2.1 of | ||
| 270 | * the License, or (at your option) any later version. | ||
| 271 | * | ||
| 272 | * This software is distributed in the hope that it will be useful, | ||
| 273 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 274 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 275 | * Lesser General Public License for more details. | ||
| 276 | * | ||
| 277 | * You should have received a copy of the GNU Lesser General Public | ||
| 278 | * License along with this software; if not, write to the Free | ||
| 279 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 280 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 281 | */ | ||
| 282 | {{/code}} | ||
| 283 | |||
| 284 | == For XML & Vue files == | ||
| 285 | |||
| 286 | {{code language="none"}} | ||
| 287 | <!-- | ||
| 288 | * See the NOTICE file distributed with this work for additional | ||
| 289 | * information regarding copyright ownership. | ||
| 290 | * | ||
| 291 | * This is free software; you can redistribute it and/or modify it | ||
| 292 | * under the terms of the GNU Lesser General Public License as | ||
| 293 | * published by the Free Software Foundation; either version 2.1 of | ||
| 294 | * the License, or (at your option) any later version. | ||
| 295 | * | ||
| 296 | * This software is distributed in the hope that it will be useful, | ||
| 297 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 298 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 299 | * Lesser General Public License for more details. | ||
| 300 | * | ||
| 301 | * You should have received a copy of the GNU Lesser General Public | ||
| 302 | * License along with this software; if not, write to the Free | ||
| 303 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 304 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 305 | --> | ||
| 306 | {{/code}} | ||
| 307 | |||
| 308 | == For Shell scripts, Properties & YAML files == | ||
| 309 | |||
| 310 | {{code language="none"}} | ||
| 311 | # --------------------------------------------------------------------------- | ||
| 312 | # See the NOTICE file distributed with this work for additional | ||
| 313 | # information regarding copyright ownership. | ||
| 314 | # | ||
| 315 | # This is free software; you can redistribute it and/or modify it | ||
| 316 | # under the terms of the GNU Lesser General Public License as | ||
| 317 | # published by the Free Software Foundation; either version 2.1 of | ||
| 318 | # the License, or (at your option) any later version. | ||
| 319 | # | ||
| 320 | # This software is distributed in the hope that it will be useful, | ||
| 321 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 322 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 323 | # Lesser General Public License for more details. | ||
| 324 | # | ||
| 325 | # You should have received a copy of the GNU Lesser General Public | ||
| 326 | # License along with this software; if not, write to the Free | ||
| 327 | # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 328 | # 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 329 | # --------------------------------------------------------------------------- | ||
| 330 | {{/code}} | ||
| 331 | |||
| 332 | == For Bat files == | ||
| 333 | |||
| 334 | {{code language="none"}} | ||
| 335 | REM ------------------------------------------------------------------------- | ||
| 336 | REM See the NOTICE file distributed with this work for additional | ||
| 337 | REM information regarding copyright ownership. | ||
| 338 | REM | ||
| 339 | REM This is free software; you can redistribute it and/or modify it | ||
| 340 | REM under the terms of the GNU Lesser General Public License as | ||
| 341 | REM published by the Free Software Foundation; either version 2.1 of | ||
| 342 | REM the License, or (at your option) any later version. | ||
| 343 | REM | ||
| 344 | REM This software is distributed in the hope that it will be useful, | ||
| 345 | REM but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 346 | REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 347 | REM Lesser General Public License for more details. | ||
| 348 | REM | ||
| 349 | REM You should have received a copy of the GNU Lesser General Public | ||
| 350 | REM License along with this software; if not, write to the Free | ||
| 351 | REM Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 352 | REM 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 353 | REM ------------------------------------------------------------------------- | ||
| 354 | {{/code}} | ||
| 355 | |||
| 356 | == For Velocity files == | ||
| 357 | |||
| 358 | {{code language="velocity"}} | ||
| 359 | ## --------------------------------------------------------------------------- | ||
| 360 | ## See the NOTICE file distributed with this work for additional | ||
| 361 | ## information regarding copyright ownership. | ||
| 362 | ## | ||
| 363 | ## This is free software; you can redistribute it and/or modify it | ||
| 364 | ## under the terms of the GNU Lesser General Public License as | ||
| 365 | ## published by the Free Software Foundation; either version 2.1 of | ||
| 366 | ## the License, or (at your option) any later version. | ||
| 367 | ## | ||
| 368 | ## This software is distributed in the hope that it will be useful, | ||
| 369 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 370 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 371 | ## Lesser General Public License for more details. | ||
| 372 | ## | ||
| 373 | ## You should have received a copy of the GNU Lesser General Public | ||
| 374 | ## License along with this software; if not, write to the Free | ||
| 375 | ## Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 376 | ## 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| 377 | ## --------------------------------------------------------------------------- | ||
| 378 | {{/code}} | ||
| 379 | |||
| 380 | = Coding Conventions = | ||
| 381 | |||
| 382 | See the [[Code Style page>>CodeStyle]]. | ||
| 383 | |||
| 384 | = File encoding = | ||
| 385 | |||
| 386 | The following rules must be taken into account when the need for writing non-ASCII content in the XWiki sources arises: | ||
| 387 | |||
| 388 | * All Java source files must contain only ASCII chars, Unicode escapes inside strings when needed, and XML entities in javadocs. Since we don't use @author tags, this should not be a problem. | ||
| 389 | * All translation files must contain only ASCII chars and Unicode escapes (stronger than the Java properties specification). | ||
| 390 | * All wiki documents sources must be stored in UTF-8. | ||
| 391 | * Other XML files should always specify their encoding in the **{{{<?xml>}}}** header, and it should be UTF-8 as often as possible. | ||
| 392 | * All other textual resources must be stored in UTF-8, minimizing the use of non-ASCII chars. | ||
| 393 | |||
| 394 | Currently, only the XML rules are broken, but this is not a serious problem since the XML reader can detect and use the charset/encoding specified in the XML header. | ||
| 395 | |||
| 396 | = Isssue Tracker = | ||
| 397 | |||
| 398 | See [[Issue Tracker>>Community.IssueTracker.WebHome]]. | ||
| 399 | |||
| 400 | = Git/GitHub practices = | ||
| 401 | |||
| 402 | == Branches == | ||
| 403 | |||
| 404 | Some branch names are reserved: | ||
| 405 | |||
| 406 | * ##master## (or ##main## in new repositories) | ||
| 407 | * ##stable-xxx## (where ##xxx## is a version) | ||
| 408 | |||
| 409 | Those branch names are used for specific purposes and shouldn't be used for working on changes. | ||
| 410 | |||
| 411 | Any branch could trigger a build on the CI, however it might be problematic to trigger a build with changes coming from the different repositories (e.g. a change in platform needed custom changes in commons too). For that purpose, a special branch name scheme can be used: ##feature-deploy-xxx##. During the build of that branch, this will deploy on https://nexus-snapshots.xwiki.org/ artifacts with a version corresponding to the branch, to avoid collision with the more standard branches. | ||
| 412 | If you are working on a change which involves several repositories, you should create a branch in each one with the same name (so for example if you have changes in both ##xwiki-commons## and ##xwiki-platform##, you should create a branche ##feature-deploy-mychange## in ##xwiki-commons##, ##xwiki-rendering## and ##xwiki-platform##, because the ##xwiki-commons## build is triggering the ##xwiki-rendering## build, which in turn triggers the ##xwiki-platform## build). | ||
| 413 | |||
| 414 | == Pull requests == | ||
| 415 | |||
| 416 | === Use assignees === | ||
| 417 | |||
| 418 | The committer who is planning to be the one doing the final merge should be assigned to the pull request. This also involves making sure to ping others to gather accurate review for the pull request if parts of the changes are not the assignee’s strong suit (which currently tend to often cause a “yeah someone will need to take responsibility for this PR as I’m not the right person for this part” reaction). | ||
| 419 | |||
| 420 | === Dependency upgrade pull requests === | ||
| 421 | |||
| 422 | The default assignees for dependencies pull request should be: | ||
| 423 | |||
| 424 | * for webjar Maven dependencies: ##@mflorea## on GitHub | ||
| 425 | * for non-webjar Maven dependencies: ##@tmortagne## on GitHub | ||
| 426 | * for npm dependencies: ##@manuelleduc## on GitHub | ||
| 427 | |||
| 428 | This is just a default assignee and any of those issues could be assigned to someone else in a case by case basis. Either by the assignee itself, because he/she knows that some upgrade requires someone with more experience with that specific dependency because something changed (like an API breakage), or by discussing quickly with the current assignee if somone else wants to take care of a specific upgrade. | ||
| 429 | |||
| 430 | Renovate pull requests are currently supposed to be automatically assigned, but if for some reason it's not the case, don't hesitate to set one of those assignees. | ||
| 431 | |||
| 432 | === Labels === | ||
| 433 | |||
| 434 | The following labels can be used in Github Pull Requests: | ||
| 435 | |||
| 436 | * ##backport stable-xxx## (where ##stable-xxx## is a branch): those labels are used along with [[an automation tool>>https://github.com/xwiki/xwiki-platform/blob/master/.github/workflows/backport.yml]] to automatically perform cherry-picks once the pull request is merged. The cherry-pick is not immediately applied to the branch, but another PR is created targeting the appropriate branch if the cherry-pick can be performed. If it cannot due to conflicts, a comment is added to the original PR. Note that right now, the automation tool only work properly when there's a single commit to apply: it doesn't work properly with multiple commits, so it's better for it to squash commits when merging. | ||
| 437 | |||
| 438 | == Extracting out a module == | ||
| 439 | |||
| 440 | When a module is moved to XWiki Contrib or to the XWiki Attic, it needs to be done without loosing the git history. For example for extracting out ##xwiki-platform-blog## to ##xwiki-contrib##: | ||
| 441 | |||
| 442 | * Create the new target repo in https://github.com/xwiki-contrib/, e.g. https://github.com/xwiki-contrib/application-blog | ||
| 443 | * Inside ##xwiki-platform## (you need to be at the root), run: {{code language="bash"}}git subtree split -P xwiki-platform-core/xwiki-platform-blog -b split{{/code}} | ||
| 444 | * Push the ##split## branch into the new repo: {{code language="bash"}}git push [email protected]:xwiki-contrib/application-blog.git split:master{{/code}} | ||
| 445 | * Remove the ##split## branch: {{code language="bash"}}git branch -D split{{/code}} | ||
| 446 | * Remove the code from ##xwiki-platform## and commit | ||
| 447 | |||
| 448 | When moving to XWiki Contrib you'll need to do the following: | ||
| 449 | |||
| 450 | * Change the groupId/artifactIds and directory names | ||
| 451 | * Use the ##org.xwiki.contrib:parent-*## as the parent, using the LTS version (e.g. ##13.10## if 13.10.x is the "LTS branch") | ||
| 452 | * Use the ##xwiki.extension.features## EM property in the POMs to provide retro-compatibility | ||
| 453 | * Continue using the same version to signify it's not a new extension. E.g. if the version in XWiki Platform was ##14.7-SNAPSHOT## when moving it out, keep using that. Then, once the extension has been released, it'll decide how often to release and how to increase the version (but the version must be increased from that number). | ||
| 454 | * Update the extension id on the e.x.o page for the extension and mention the move there in the compatibility section. | ||
| 455 | * More generally follow the [[best practices for a Contrib project>>contrib:Main.WebHome]] (new JIRA project, changes to the top level POM, README file, etc). | ||
| 456 | |||
| 457 | == Merging in a module == | ||
| 458 | |||
| 459 | When a module is moved from XWiki Contrib to XWiki Platform, it needs to be done without loosing the git history. For example, for merging in ##application-ckeditor## to ##xwiki-platform##: | ||
| 460 | |||
| 461 | * Call ##git subtree add ~-~-prefix xwiki-platform-core/xwiki-platform-ckeditor [email protected]:xwiki-contrib/application-ckeditor.git master## where the prefix is the new location of the merged in extension in XWiki Platform hierarchy | ||
| 462 | * Adapt the code to conform to XWiki Standard coding style, integrate the new module to the hierarchy, etc. | ||
| 463 | * Push the branch | ||
| 464 | |||
| 465 | {{warning}} | ||
| 466 | It is also important to test the build on an environment similar to the ##release## machine to detect problems early (e.g., missing command line tools). | ||
| 467 | {{/warning}} | ||
| 468 | |||
| 469 | == Merging a security pull request == | ||
| 470 | |||
| 471 | Sometimes a contributor without committer right will create pull requests to fix a security issue which a committer will need to merge. | ||
| 472 | |||
| 473 | Contrary to other types of pull requests we don't merge them through the GitHub UI because we don't have enough control over the merge message. So you will need to do that manually. | ||
| 474 | |||
| 475 | * add the remote security advisory git repository to your workspace | ||
| 476 | {{code language="sh"}}git remote add ghsa-rr6p-3pfg-562j [email protected]:xwiki/xwiki-platform-ghsa-rr6p-3pfg-562j.git{{/code}} | ||
| 477 | * fetch the remote repository | ||
| 478 | {{code language="sh"}}git fetch ghsa-rr6p-3pfg-562j{{/code}} | ||
| 479 | * squash the pull request locally | ||
| 480 | {{code language="sh"}}git merge --squash ghsa-rr6p-3pfg-562j/XWIKI-22149{{/code}} | ||
| 481 | * [optional] modify what you need to modify (for example, some @since annotations) | ||
| 482 | * commit but indicate the contributor as author{{code language="sh"}}git commit --author="Pierre Jeanjean <[email protected]>"{{/code}} | ||
| 483 | ** you are asked to set a clean commit comment for the whole thing (by default you get each commit comment one after the other) | ||
| 484 | ** save & quit the editor | ||
| 485 | * push | ||
| 486 | {{code language="sh"}}git push{{/code}} | ||
| 487 | * get rid of the remote repository | ||
| 488 | {{code language="sh"}}git remote remove ghsa-rr6p-3pfg-562j{{/code}} | ||
| 489 | * "Delete temporary private fork" from the GitHub advisory | ||
| 490 | |||
| 491 | = Documentation Best Practices = | ||
| 492 | |||
| 493 | The strategy is that when closing an issue in JIRA we make sure that there's documentation for it on xwiki.org (reference documentation) and on the Release Notes for the version corresponding to the JIRA ##Fix Version(s)## field. This is done by filling the 2 corresponding fields in JIRA on the issue that is being closed. This allows several things: | ||
| 494 | |||
| 495 | * Have up to date documentation on xwiki.org | ||
| 496 | * Build Release Notes progressively so that when we perform the Release we don't have to wait a few more days to have everyone try to remember all the stuff they've done for the release... | ||
| 497 | * Sometimes developers go on holidays (yep that happens ;)) and if they don't document the jira issues just after they're done, they forget to document them and it blocks the release or forces the Release Managers and other devs to document the jiras for them, which is painful and hard to do. | ||
| 498 | |||
| 499 | If an issue is a bug fix or contains changes that do not impact users or developers, then the string ##N/A## should be used in the corresponding documentation fields in JIRA. This allows doing JQL queries and finding issues missing documentation. {{warning}}If an issue is a bugfix with an impact on user experience, release note documentation should still be provided.{{/warning}} | ||
| 500 | |||
| 501 | = Using bird names for Skins = | ||
| 502 | |||
| 503 | We have decided to name XWiki official skins using bird names. We are currently renaming the existing skins. Any new skin must use a bird name. It's recommended to send a proposal to the list whenever a new skin has to be named. | ||
| 504 | |||
| 505 | Here are some potential ideas for future names: | ||
| 506 | |||
| 507 | * Dove | ||
| 508 | * Emu | ||
| 509 | * Kiwi | ||
| 510 | * Grasswren | ||
| 511 | * Condor | ||
| 512 | * Warbler | ||
| 513 | * Kestrel | ||
| 514 | * Redtail | ||
| 515 | * Pigeon | ||
| 516 | * Booby | ||
| 517 | * Sparrow | ||
| 518 | * Blackbird | ||
| 519 | * Parrot | ||
| 520 | * Peacock | ||
| 521 | * Finch | ||
| 522 | * Wren | ||
| 523 | * Crow | ||
| 524 | * Turkey | ||
| 525 | * Thunderbird | ||
| 526 | * Piasa (a local phenomenon, from a primitive painting on the cliffs on the eastern shore of the Mississippi, attributed to the Piasa tribe, which looks rather like a griffin) | ||
| 527 | * Thunder Chicken | ||
| 528 | * Kingfisher | ||
| 529 | * Swallow | ||
| 530 | * Hummingbird | ||
| 531 | |||
| 532 | = Back-end Development Practices = | ||
| 533 | |||
| 534 | == Component Development == | ||
| 535 | |||
| 536 | Read the [[Component Module documentation>>extensions:Extension.Component Module]] for details on how to write components. | ||
| 537 | |||
| 538 | == Backward Compatibility == | ||
| 539 | |||
| 540 | We pay a lot of attention to backward compatibility. This is why we're using the [[Revapi Maven plugin>>https://revapi.org/revapi-maven-plugin/index.html]] in our builds to ensure we don't break public APIs. | ||
| 541 | |||
| 542 | Specifically we check for the following type of backward compatibility issues ([[See full list provided by Revapi>>https://revapi.org/revapi-java/0.26.0/differences.html]]): | ||
| 543 | |||
| 544 | * Binary incompatibilities | ||
| 545 | * Semantic incompatibilities | ||
| 546 | |||
| 547 | Note that we don't check for source incompatibilities since it's too strict and we want to be able to change code (like add missing generics to return types) without breaking the build and having to put ignores in the Revapi configuration of the build. | ||
| 548 | |||
| 549 | Since it takes time to stabilize an API we've introduced an annotation named ##@Unstable## (see below). | ||
| 550 | |||
| 551 | {{warning}} | ||
| 552 | When you need to add a new method to an interface there are 2 solutions to preserve backward compatibility: | ||
| 553 | |||
| 554 | * Create a new interface with the new method and deprecate the old one. This means that code using the old interface must be modified to support the 2 interfaces, and that's not easy. | ||
| 555 | * (Recommended) Use [[Default Methods>>https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html]] (introduced in Java 8). | ||
| 556 | ** Note that the default method should not throw an exception in general (like ##throw new UnsupportedOperationException("Not supported");##), since that would mean that the code calling the default method will fail. As such, it cannot be considered as backward compatibility. | ||
| 557 | ** However there's an exception: if the new method throws a checked exception in its signature then it's fine to throw it in the default method's implementation. Similarly, if the new method is not throwing a checked exception but it's documented to throw some runtime exeption that is supposed to be handled in the call chain, then it's also fine. | ||
| 558 | {{/warning}} | ||
| 559 | |||
| 560 | === Deprecating Code === | ||
| 561 | |||
| 562 | We follow 2 steps when it comes to deprecating code: | ||
| 563 | |||
| 564 | * **First step**: We start by deprecating it [[using the ##@deprecate## and ##@Deprecated## Javadoc and java annotations>>Community.CodeStyle.JavaCodeStyle.WebHome#HDeprecation]]. The code remains where it was before the deprecation happens. | ||
| 565 | * **Second step**: When our own code doesn't use any of the deprecated APIs anymore then move the code to a **legacy** module. This can be done as soon as the deprecation is added. | ||
| 566 | |||
| 567 | This has the following advantages: | ||
| 568 | |||
| 569 | * Our code remains clean of old deprecated APIs | ||
| 570 | * Deprecated code is cleanly separated from new ways of doing things | ||
| 571 | * When new users download our code they see the new ways (same for javadoc generation) | ||
| 572 | * Users wanting to use the old APIs can still do so | ||
| 573 | * We never remove APIs from the legacy modules by default. However if we really need to do so (for some technical reason for example), we do it on a case by case basis with a VOTE. | ||
| 574 | |||
| 575 | {{info}} | ||
| 576 | In the future, our distribution may not package legacy JARs by default and users wanting to use older APIs may need to install the legacy modules. This is an effort to move users to the newest API as soon as possible while still allowing them to use the old API if they're not ready to move yet (but at least they'll be aware of the changes and about what they have to fix). However in order to provide a good user experience, before doing this we need to add support for Legacy jars in the Extension Manager. | ||
| 577 | {{/info}} | ||
| 578 | |||
| 579 | === Revapi Ignores === | ||
| 580 | |||
| 581 | At build time, Revapi tells us when we break backward compatibility, by marking the Maven build in error. We then need to review the error and decide if it's legitimate or not. If we decide it's legitimate, we then add an ignore in a ##pom.xml## in each repository (commons, rendering and platform. To know the location search for ##<revapi.differences>##). | ||
| 582 | |||
| 583 | There are 4 types of cases: | ||
| 584 | |||
| 585 | * Real breakages that we still want to do but the users need to be warned since existing code using these APIs will or may fail at runtime. | ||
| 586 | ** Mark the ignore with ##<criticality>highlight</criticality>##, e.g.((( | ||
| 587 | {{code language="none"}} | ||
| 588 | <item> | ||
| 589 | <code>java.method.removed</code> | ||
| 590 | <old>method void org.xwiki.diff.xml.XMLDiff::xxx()</old> | ||
| 591 | <justification>Not really usable API added by mistake.</justification> | ||
| 592 | <criticality>highlight</criticality> | ||
| 593 | </item> | ||
| 594 | {{/code}} | ||
| 595 | ))) | ||
| 596 | * Real breakages but happening on @Unstable code. | ||
| 597 | ** Mark the ignore with ##<criticality>documented</criticality>## | ||
| 598 | * Semantic changes that are potentially breaking in severity(like adding an annotation) but that, after analyzing we consider to not be a breakage. | ||
| 599 | ** Mark the ignore with ##<criticality>allowed</criticality>## | ||
| 600 | * Revapi bugs or limitations, that are not breakages in our opinion (could also be APIs moved into another Maven module) | ||
| 601 | ** Mark the ignore with ##<criticality>allowed</criticality>## | ||
| 602 | |||
| 603 | Note that the ##criticality## information is then used when producing our release notes (e.g. we don't list ##allowed## items in the Release Notes). | ||
| 604 | |||
| 605 | === Deprecation Rules === | ||
| 606 | |||
| 607 | For details and rationale about those rules below see [[this thread>>http://markmail.org/thread/cljbqwbrrmunlmar]]. | ||
| 608 | |||
| 609 | * Rule: **Location of Legacy modules** | ||
| 610 | ** Each Git repository needing legacy modules provides a ##*-legacy## module for holding legacy modules. For example: | ||
| 611 | *** For Commons, ##xwiki-commons-core/xwiki-commons-legacy/## | ||
| 612 | *** For Platform, ##xwiki-platform-core/xwiki-platform-legacy/## | ||
| 613 | *** For Rendering, ##xwiki-rendering-legacy/## | ||
| 614 | * Rule: **Use AspectJ to move deprecated APIs to Legacy modules** | ||
| 615 | ** This idea was found in this [[blog post>>http://www.sonatype.com/people/2007/11/two-fantastic-uses-for-aspectj-part-one-backward-compatibility/]]. | ||
| 616 | ** Here's an {{scm path="xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj"}}example of such an Aspect{{/scm}}. | ||
| 617 | * Rule: **Legacy modules replace modules from where they come from** | ||
| 618 | ** Each Legacy module replace the non-legacy module it corresponds to. This means that the user must have only 1 JAR for a given module: either its legacy version or it's non-legacy version but should never have both. | ||
| 619 | * Rule: **Annotate code with version to show deprecations** | ||
| 620 | ** Use both ##@Deprecated## annotation and the ##@deprecated## javadoc tag **and** specify the version when the deprecation was added. For example:((( | ||
| 621 | {{code language="java"}} | ||
| 622 | /** | ||
| 623 | * @param time the time in milliseconds | ||
| 624 | * @return the time delta in milliseconds between the current date and the time passed as parameter | ||
| 625 | * @deprecated replaced by {@link com.xpn.xwiki.api.Util#getTimeDelta(long)} since 1.3M2 | ||
| 626 | */ | ||
| 627 | @Deprecated | ||
| 628 | public int XWiki.getTimeDelta(long time) | ||
| 629 | { | ||
| 630 | return this.util.getTimeDelta(time); | ||
| 631 | } | ||
| 632 | {{/code}} | ||
| 633 | ))) | ||
| 634 | |||
| 635 | === ##@Unstable## Annotation === | ||
| 636 | |||
| 637 | This annotation can (and should) be used by developers whenever new public API is introduced (in addition to also adding a ##@since## annotation). This annotation means that the code is subject to change at any time (in which case it'll appear in the backward-compatibility reports but with the explanation that it's an Unstable API). From a user point of view, it means they should use classes or methods annotated with the ##@Unstable## annotation with caution. It means they need to be prepared to modify their code. Alternatively they can decide to not use classes/methods annotated with ##@Unstable## and wait for them to come out of unstability. | ||
| 638 | |||
| 639 | In order to prevent code to remain annotated with ##@Unstable## forever, we've defined some rule; | ||
| 640 | |||
| 641 | * Any code annotated with ##@Unstable## can only remain in this state for a maximum of 1 full [[cycle>>VersioningAndReleasePractices]]. For example if a unstable API is introduced in 4.4, it'll have to come out of unstability before 6.0M1 is released (thus having 1 full cycle, i.e. the 5.x cycle). This means that the worse that can happen is for an unstable API added in N.1 which will have to be removed before N+2 Milestone 1 is released. | ||
| 642 | * However, the previous rule is only a maximum and developers are encouraged to remove the unstable annotation whenever they feel that the API should come out of unstability. When this happens the standard deprecation mechanism then kicks in. | ||
| 643 | |||
| 644 | The following automated checks related to the ##@Unstable## annotation are performed in the [[build>>Building]]: | ||
| 645 | |||
| 646 | * {{scm project="xwiki-commons" path="xwiki-commons-tools/xwiki-commons-tool-verification-resources/src/main/java/org/xwiki/tool/checkstyle/UnstableAnnotationCheck.java"}}Automatically enforce the removal of the @Unstable annotation{{/scm}}. Also verifies that a ##@since## annotation is present. | ||
| 647 | * {{scm project="xwiki-commons" path="xwiki-commons-tools/xwiki-commons-tool-verification-resources/src/main/java/org/xwiki/tool/checkstyle/SinceFormatCheck.java"}}Automatically verify the format of the ##@since## annotation{{/scm}} (used in the previous check to verify the age of the ##@Unstable## annotation. | ||
| 648 | |||
| 649 | == Configuration Property Naming == | ||
| 650 | |||
| 651 | XWiki uses 2 configuration files at the moment: | ||
| 652 | |||
| 653 | * An old one, named ##xwiki.cfg## for old core code and which eventually will go away when all code will have been rewritten using component and extracted as separate modules | ||
| 654 | * A more recent one that must be used for new configuration properties required by new code, named ##xwiki.properties## | ||
| 655 | |||
| 656 | The naming rule for ##xwiki.properties## is: | ||
| 657 | |||
| 658 | * Use ##<module>.<propertyName>##. Ex: ##rendering.linkLabelFormat## | ||
| 659 | * For submodules use ##<module>.<submodule>.<propertyName>##. Ex: ##rendering.macro.velocity.filter## | ||
| 660 | ** Note: Unfortunately you'll find some properties not following this rule in ##xwiki.properties##. This is because we've been bad in following this rule and doing code review to ensure it was followed. It was also voted on the mailing list but not documented here in the past. | ||
| 661 | * Use camelcase for the property name itself. ex: ##linkLabelFormat## | ||
| 662 | |||
| 663 | == Translation Best Practices == | ||
| 664 | |||
| 665 | === General === | ||
| 666 | |||
| 667 | * The XWiki Core committers maintain one version, the English one and more precisely the ##en_US## one. This means: | ||
| 668 | ** The ##ApplicationResources.properties## file (without any language suffix) represents the ##en_US## version | ||
| 669 | ** We should use "customize" instead of "customise" or "color" instead of "colour" ;) | ||
| 670 | * Other translations are maintained by the community at large on [[l10n>>http://l10n.xwiki.org]]. | ||
| 671 | |||
| 672 | === Translation Property Naming === | ||
| 673 | |||
| 674 | When content requires localization you should use the following rules: | ||
| 675 | |||
| 676 | * If the content is inside a wiki page, then create a wiki page named ##Translations## (or ##*Translations## if there's a need to have several translation pages) in the space of the application containing the content to translate. This page must be registered using a ##XWiki.TranslationDocumentClass## xobject. | ||
| 677 | * If the content is inside some ##.vm## files or in Java, then create an ##ApplicationResources.properties## file in the ##src/main/resources## directory of the module using the translation (so that it's packaged at the root of the JAR). | ||
| 678 | * Generally speaking the translations must be part of the extension containing the content to translate. | ||
| 679 | * New translation resources must be added on [[http://l10n.xwiki.org]] and also in the Weblate synchronization scripts. | ||
| 680 | * Special case for extensions containing only wiki Macros which go in the ##Macros## space: the ##Translations## file should be located in the same space as the macro. | ||
| 681 | * Follow the [[Community.L10N.Conventions.WebHome]] for naming the translation keys | ||
| 682 | |||
| 683 | === Translation Property Deprecations === | ||
| 684 | |||
| 685 | * When deleting a key, it should be moved to the deprecated section at the end of the file, linked to the first version in which it started to be deprecated. If there's no such section in your translation file you must add one, using the following syntax:((( | ||
| 686 | {{code language="properties"}} | ||
| 687 | #@deprecatedstart | ||
| 688 | ... | ||
| 689 | ################################################## | ||
| 690 | ## until <version that deprecated the keys below> | ||
| 691 | ################################################## | ||
| 692 | ... | ||
| 693 | {{/code}} | ||
| 694 | ))) | ||
| 695 | |||
| 696 | {{warning}} | ||
| 697 | Not supported by the new Weblate based l10n platform. | ||
| 698 | |||
| 699 | * When renaming a key, in addition to move the deprecated key to the deprecation section, you should also add a ###@deprecated## comment pointing to the new key, using the following syntax: | ||
| 700 | |||
| 701 | Example: | ||
| 702 | |||
| 703 | {{code language="properties"}} | ||
| 704 | ############################################################################### | ||
| 705 | ## Deprecated | ||
| 706 | ## Note: each element should be removed when the last branch using it is no longer supported | ||
| 707 | ############################################################################### | ||
| 708 | |||
| 709 | ## Used to indicate where deprecated keys start | ||
| 710 | #@deprecatedstart | ||
| 711 | |||
| 712 | ####################################### | ||
| 713 | ## until 10.1 | ||
| 714 | ####################################### | ||
| 715 | |||
| 716 | job.log.label.refactoring/rename=Rename log | ||
| 717 | job.log.label.refactoring/copyAs=Copy log | ||
| 718 | |||
| 719 | ... | ||
| 720 | |||
| 721 | ####################################### | ||
| 722 | ## until 3.5 | ||
| 723 | ####################################### | ||
| 724 | |||
| 725 | #@deprecated platform.livetable.results | ||
| 726 | xe.livetable.results=Livetable Results | ||
| 727 | ... | ||
| 728 | {{/code}} | ||
| 729 | {{/warning}} | ||
| 730 | |||
| 731 | === Moving Translations === | ||
| 732 | |||
| 733 | In general translations should not be moved as this could cause backward compatibility problems with existing extensions, and thus it's better to deprecate and create new keys. However it's a good idea to copy all existing translations to the new key whenever possible. This should be done on the source files and committed in Git (it's automatically synced on l10n.xwiki.org with a commit hook). A script is available to help performing such migration: [[https://github.com/xwiki/xwiki-dev-tools/blob/master/weblate-scripts/migrate_keys.py]]. | ||
| 734 | |||
| 735 | == Migrating away from the Old Core == | ||
| 736 | |||
| 737 | Starting in 2006 we've started to work on splitting the code that's currently located in the ##xwiki-platform-oldcore## module into various modules, each one specific to a given domain. Before 2006 the whole of XWiki was located in that ##oldcore##. The work isn't over and the current strategy is the following: | ||
| 738 | |||
| 739 | * Continue extracting code from ##oldcore## and put it in its own domain modules | ||
| 740 | * We allow new modules to depend on ##oldcore## provided that ##oldcore## itself doesn't depend on these new modules obviously (as otherwise it would create a cyclic dependency). When that happen it usually means we need to move the code in ##oldcore## that uses thee new module outside of ##oldcore## in an existing module or in a new one. | ||
| 741 | * At some point all that should remain in ##oldcore## is the old Model itself. | ||
| 742 | * We need to continue the work we started about writing the [[New Model>>Design.XWikiModel20]] and put it in some new module, at which point we'll need to migrate our code to use the new Model progressively and then the last step will be to remove ##oldcore## altogether. | ||
| 743 | |||
| 744 | {{warning}} | ||
| 745 | It's important that we stop adding new stuff to ##oldcore## and instead always try to extract stuff outside of it as otherwise this means accruing even more our technical debt and making it harder to completely remove ##oldcore##. | ||
| 746 | {{/warning}} | ||
| 747 | |||
| 748 | == User Interface Extension Point Naming == | ||
| 749 | |||
| 750 | User Interface Extension Point (UIXP) must follow the following pattern: | ||
| 751 | |||
| 752 | ##<groupId>.<moduleName>.<uixpQualifier>## where: | ||
| 753 | |||
| 754 | * ##<groupId>##: reuse maven’s groupId in which the UIXP is declared. Lower case, dot separated. | ||
| 755 | * ##<moduleName>##: reuse maven’s module in which the UIXP is declared. Lower case, dot separated. | ||
| 756 | * ##<uixpQualifier>##: descriptive name of the UIXP. Single camel case identifier. | ||
| 757 | |||
| 758 | Example: ##org.xwiki.platform.user.profile.menu## | ||
| 759 | |||
| 760 | The User Interface Extensions (UIXs) contributing to an UIXP must follow the following pattern: | ||
| 761 | |||
| 762 | ##<groupId>.<moduleName>.<uixpQualifier>(.<uixQualifier>)## where: | ||
| 763 | |||
| 764 | * ##<groupId>##: reuse maven’s groupId in which the UIX is declared. Lower case, dot separated. | ||
| 765 | * ##<moduleName>##: reuse maven’s module in which the UIX is declared. Lower case, dot separated. | ||
| 766 | * ##<uixpQualifier>##: reuse the uixpQualifier of the UIXP where the UIX contributes. | ||
| 767 | * ##<uixQualifier>##: optional, used only in case of ambiguity, for instance if the UIX is declared in the same module as the UIXP, or if several UIX are declared in the same module. Single camel case identifier. | ||
| 768 | |||
| 769 | Examples of UIX contributing to the ##org.xwiki.platform.user.profile.menu## UIXP: | ||
| 770 | ##org.xwiki.platform.notifications.menu## | ||
| 771 | ##org.xwiki.platform.user.profile.menu.userMembership## | ||
| 772 | ##org.xwiki.platform.user.profile.menu.userNetwork## | ||
| 773 | |||
| 774 | |||
| 775 | = Front-end Development Practices = | ||
| 776 | |||
| 777 | == HTML & CSS Best Practices == | ||
| 778 | |||
| 779 | See our [[HTML & CSS code style>>.CodeStyle.XhtmlCssCodeStyle.WebHome]]. | ||
| 780 | |||
| 781 | === Icons === | ||
| 782 | |||
| 783 | When using icons in content, they must rely on [[the XWiki icon set>>https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/FrontendResources/Icons/]]. | ||
| 784 | |||
| 785 | When adding new icons to the XWiki icon set, their names must follow our [[icon naming conventions>>https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/FrontendResources/Icons/#HIconnamingconvention]]. | ||
| 786 | |||
| 787 | == JavaScript Best Practices == | ||
| 788 | |||
| 789 | * JavaScript code should be organized in **modules** following the [[Asynchronous module definition>>https://en.wikipedia.org/wiki/Asynchronous_module_definition]] (AMD) specification. At the moment we're using [[RequireJS>>https://requirejs.org/]] for this:((( | ||
| 790 | {{code language="js"}} | ||
| 791 | require(['jquery', 'xwiki-suggestPages', 'xwiki-events-bridge'], function($) { | ||
| 792 | ... | ||
| 793 | }); | ||
| 794 | {{/code}} | ||
| 795 | ))) | ||
| 796 | * XWiki JavaScript modules should have their name prefixed with 'xwiki-' in order to avoid conflicts with external modules. E.g.:((( | ||
| 797 | {{code language="js"}} | ||
| 798 | define('xwiki-diff', ['jquery', 'xwiki-events-bridge'], function($) { | ||
| 799 | ... | ||
| 800 | }); | ||
| 801 | {{/code}} | ||
| 802 | ))) | ||
| 803 | * The recommeded places to store and load JavaScript modules (dependencies) from are: | ||
| 804 | ** [[WebJars>>extensions:Extension.WebJars Integration]] that can be installed through the [[Extension Manager>>extensions:Extension.Extension Manager Application]] | ||
| 805 | ** [[JavaScript Skin Extensions>>extensions:Extension.Skin Extension Plugin]] (JSX), usually provided / packaged by XAR extensions | ||
| 806 | ** the [[Skin>>extensions:Extension.Skin Application]], using ##$xwiki.getSkinFile(...)## | ||
| 807 | * [[Integrating external JavaScript libraries>>xwiki:Documentation.DevGuide.FrontendResources.IntegratingJavaScriptLibraries.WebHome]] should be done only through WebJars. | ||
| 808 | * Avoid using inline script tags or inline JavaScript through HTML attributes (like ##onclick##). Doing this can cause problems with event handlers and is sometimes [[WCAG>>Community.Testing.WCAGTesting.WebHome]] invalid. | ||
| 809 | * The recommended way to inject a JavaScript module into the current web page is: | ||
| 810 | ** either by using the JSX plugin (e.g. ##$xwiki.jsx.use(...)##) from a server-side script (e.g. to load the JavaScript module that serves as your entry point) | ||
| 811 | ** or by declaring the module as a dependency of another JavaScript module | ||
| 812 | * We recommend loading JSX using "On demand only". That is: load your JavaScript code only where / when it is needed. Avoid using "On this wiki". | ||
| 813 | * Localizations in Javascript should use [[a dedicated module and the specific loader>>extensions:Extension.Localization#HFromJavaScript]]. | ||
| 814 | * Avoid mixing JavaScript with server-side scripting (e.g. Velocity), especially for JavaScript code packaged as WebJar, because in this case the scripts are evaluated long after the JavaScript code is **minified** and the minifier can rewrite the JavaScript code in a way that breaks the embedded server-side scripts. If this is not possible then use this pattern to separate the JavaScript-only code from the embedded scripts:((( | ||
| 815 | {{code language="js"}} | ||
| 816 | /*! | ||
| 817 | ## Velocity code here. | ||
| 818 | #set ($paths = ...) | ||
| 819 | #set ($l10n = ...) | ||
| 820 | ... | ||
| 821 | #[[*/ | ||
| 822 | // Start JavaScript-only code. | ||
| 823 | (function(paths, l10n) { | ||
| 824 | "use strict"; | ||
| 825 | |||
| 826 | require(...); | ||
| 827 | |||
| 828 | // End JavaScript-only code. | ||
| 829 | }).apply(']]#', $jsontool.serialize([$paths, $l10n])); | ||
| 830 | {{/code}} | ||
| 831 | ))) | ||
| 832 | * Check the list of [[supported browsers>>dev:Community.SupportStrategy.BrowserSupportStrategy]] and [[MDN>>https://developer.mozilla.org/en-US/]] or websites like [[caniuse.com>>https://caniuse.com/]] before using newer JavaScript APIs or syntax sugar. Note that the minifier might be able to rewrite your code in order to support older browsers, but you need to check. | ||
| 833 | * When updating existing non-AMD code (e.g. when fixing bugs) try to rewrite the code (or parts of it) as AMD. Avoid in-line mixing of non-AMD code with AMD code because it makes the code harder to read and maintain. | ||
| 834 | * Rewrite old code based on Prototype.js by using jQuery or plain JavaScript when possible | ||
| 835 | * We recommend enabling the [[Strict mode>>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode]] | ||
| 836 | * The JavaScript code should pass the following rules to ensure good quality and common code style:((( | ||
| 837 | {{code language="js"}} | ||
| 838 | // jsHint rules, see https://github.com/jshint/jshint/blob/master/examples/.jshintrc | ||
| 839 | { | ||
| 840 | "camelcase": true, | ||
| 841 | "maxparams": 5, | ||
| 842 | "maxdepth": 3, | ||
| 843 | "maxstatements": 20, | ||
| 844 | "maxcomplexity": 10, | ||
| 845 | "maxlen": 120 | ||
| 846 | } | ||
| 847 | |||
| 848 | // ESLint rules, see https://eslint.org/docs/rules/ | ||
| 849 | { | ||
| 850 | "camelcase": "error", | ||
| 851 | "max-params": ["error", 5], | ||
| 852 | "max-depth": ["error", 3], | ||
| 853 | "max-statements": ["error", 20], | ||
| 854 | "complexity": ["error", 10], | ||
| 855 | "max-len": ["error", 120] | ||
| 856 | } | ||
| 857 | {{/code}} | ||
| 858 | ))) | ||
| 859 | * JavaScript modules should have [[automated unit-like tests>>Community.Testing.WebHome#HJavaScriptUnitTesting]]. | ||
| 860 | |||
| 861 | Check [[xwiki:Documentation.DevGuide.FrontendResources.WebHome]] for more JavaScript-related documentation. | ||
| 862 | |||
| 863 | |||
| 864 | === Backward compatibility and deprecation === | ||
| 865 | |||
| 866 | As for back-end development, we should take care of backward compatibility. There are applications developed on top of XWiki that use their own JavaScript APIs. The rule for deprecating a JavaScript API (be it an object or a method of an object) is to move or write code to maintain compatibility in the compatibility.js file under the xwiki folder. We should always wrap deprecated code to log its usages. This will make the life of applications developers much easier. | ||
| 867 | |||
| 868 | Example of deprecation code: | ||
| 869 | |||
| 870 | {{code language="javascript"}} | ||
| 871 | /** | ||
| 872 | * Deprecated since 1.9M2 | ||
| 873 | */ | ||
| 874 | window.displayDocExtra = XWiki.displayDocExtra; | ||
| 875 | window.displayDocExtra = window.displayDocExtra.wrap( | ||
| 876 | function(){ | ||
| 877 | warn("window.displayDocExtra is deprecated since XWiki 1.9M2. Use XWiki.displayDocExtra instead."); | ||
| 878 | var args = $A(arguments), proceed = args.shift(); | ||
| 879 | return proceed.apply(window, args); | ||
| 880 | } | ||
| 881 | ); | ||
| 882 | {{/code}} | ||
| 883 | |||
| 884 | {{warning}} | ||
| 885 | XWiki Standard should **always** work fine when running without the compatibility file. Before deprecating a method or object, we should ensure it is not used anywhere any longer in XWiki Standard distribution. | ||
| 886 | {{/warning}} | ||
| 887 | |||
| 888 | == Accessibility == | ||
| 889 | |||
| 890 | XWiki has committed to support [[Web Content Accessibility Guidelines 2.2>>https://www.w3.org/TR/WCAG22/]] at the AA level. All features (and especially new ones) must comply with this set of rules. Refer to our [[Accessibility Statement>>xwiki:Documentation.UserGuide.Features.Accessibility.WebHome]] for more information. | ||
| 891 | |||
| 892 | = Bug Reporting = | ||
| 893 | |||
| 894 | The bug reporting system resides at https://jira.xwiki.org/ | ||
| 895 | |||
| 896 | = XWiki.org Rules = | ||
| 897 | |||
| 898 | Some rules to follow when making modifications on xwiki.org. | ||
| 899 | |||
| 900 | == Don't remove important pages when they are moved == | ||
| 901 | |||
| 902 | Rationale: Users will save links and when they navigate to them later on these links will be broken. | ||
| 903 | Solution: Add a redirect script to redirect to the new page | ||
| 904 | Implementation: Use this script: | ||
| 905 | |||
| 906 | {{code language="none"}} | ||
| 907 | {{velocity}} | ||
| 908 | $response.sendRedirect($xwiki.getURL("newSpace.newPage")) | ||
| 909 | {{/velocity}} | ||
| 910 | {{/code}} | ||
| 911 | |||
| 912 | == Don't use URLs for links to *.xwiki.org == | ||
| 913 | |||
| 914 | Rationale: If we change the URL format or the domain the links will be broken | ||
| 915 | Solution: Use the ##wiki:Space.Name## notation | ||
| 916 | |||
| 917 | = XWiki Days = | ||
| 918 | |||
| 919 | See [[XWiki Days>>XWikiDays]]. | ||
| 920 | |||
| 921 | = Developer Meetings = | ||
| 922 | |||
| 923 | See [[Developer Meetings>>DeveloperMeetings]]. | ||
| 924 | |||
| 925 | = Application Development = | ||
| 926 | |||
| 927 | See [[Application Development Best Practices>>ApplicationDevelopmentBestPractices]]. | ||
| 928 | |||
| 929 | = Build Best Practices = | ||
| 930 | |||
| 931 | * For the general directory structure, see [[dev:Community.SourceRepository]]. | ||
| 932 | * **Directory names**: | ||
| 933 | ** We're currently using the directory name corresponding to the Maven ##artifactId##. For example: ##xwiki-platform-watchlist-ui## for a ##pom.xml## having ##<artifactId>xwiki-platform-watchlist-ui</artifactId>##((( | ||
| 934 | {{warning}} | ||
| 935 | Note that this scheme is causing some issues on Windows since it generates long path names and Windows usually supports only 255 characters. It's possible that we'll change this in the future... or not, since you can use Cygwin on Windows to have longer path names. | ||
| 936 | {{/warning}} | ||
| 937 | ))) | ||
| 938 | ** Use the singular form in artifactId and maven module names/directories, e.g. ##xwiki-platform-flamingo-theme## and NOT xwiki-platform-flamingo-themes##. And use the same prefix for children modules, e.g. ##xwiki-platform-flamingo-theme-test##.## | ||
| 939 | * Maven **groupId**s: ##org.xwiki.<short name of top level project>##. For example ##org.xwiki.commons## for XWiki Commons, ##org.xwiki.rendering## for XWiki Rendering and ##org.xwiki.platform## for XWiki Platform | ||
| 940 | * Maven **artifactId**s: ##xwiki-<short name of top level project this module belongs to>-<module name>-<qualifiers>##. For example:##xwiki-platform-watchlist-ui##. There are some conventions used: | ||
| 941 | ** ##-api## for modules providing APIs | ||
| 942 | ** ##-ui## for modules generating XARs | ||
| 943 | ** ##-webjar## for packages providing final JavaScript bundling of code for a business domain (i.e., not meant to be imported by other modules) (e.g., ##xwiki-platform-livedata-webjar##, or ##xwiki-platform-notifications-webjar##). | ||
| 944 | ** ##-node-*## for modules providing bundles of code coming from the ##xwiki-platform-node## module. They are meant to distribute packages built to be reusable and published publicly as npm packages in a form that is easy to reuse in a XWiki application. Their goal is primarily to avoid the same code being loaded twice by the browser. | ||
| 945 | ** ##-test## for functional test parent POM | ||
| 946 | ** ##-test-pageobjects## for functional test Page Objects modules | ||
| 947 | ** ##-test-tests## for modules containing and executing the functional tests (non-docker tests) | ||
| 948 | ** ##-test-docker## for modules containing and executing the functional tests (docker-based tests) | ||
| 949 | * Npm **package names**: | ||
| 950 | ** For ##private## packages: | ||
| 951 | *** The name must be the same as the parent module | ||
| 952 | *** The version must be ##0.0.0## | ||
| 953 | *** The ##private## field must be set to ##true.## | ||
| 954 | ** For public packages (i.e., located in the ##xwiki-platform-node## module): | ||
| 955 | *** The name must be ##@xwiki/platform-<business domain>-<qualifiers> following the same logic as for the **artifactIds**.## | ||
| 956 | *** ##The version must be the same as the parent module (the version is updated automatically at release time).## | ||
| 957 | *** ##The private field must not be set.## | ||
| 958 | |||
| 959 | = Top Level Extensions = | ||
| 960 | |||
| 961 | Rationale/Need: | ||
| 962 | |||
| 963 | * Be able to extract some apps from ##xwiki-contrib## that the XWiki Dev Team would like to maintain. Example: File Manager app developed by Marius when it’ll have had some releases and tests (if it doesn’t have some already!), GitHub Stats app used on xwiki.org, Meeting Manager App, Forum App, etc | ||
| 964 | * Be able to extract some extensions currently located in ##xwiki-platform## but not released with XWiki Standard so that they can have a different release cycle (examples: FAQ app, IRCBot extension, JIRA macro, etc). Having different release cycle allow to release new versions quicker to our users (bug fixes, new features). | ||
| 965 | |||
| 966 | Governance: | ||
| 967 | |||
| 968 | * Extensions are VOTEd in on a case by case basis. | ||
| 969 | * Each voted extension has its own Git Repository in the “xwiki” organization (so that each extension can be released independently of each other). | ||
| 970 | * When moving an extension either from ##xwiki-contrib## or from ##xwiki-platform##, keep its Git history as much as possible or simply donate the repo to the ##xwiki## organization. | ||
| 971 | * FTM extensions bundled by default with XWiki Standard still remain in XWiki Commons/Rendering/Platform. | ||
| 972 | * The Git repository name must be of the form ##xwiki-<short project name>##. ##<short project name>## must be part of the VOTE. | ||
| 973 | * All [[XWiki Development rules>>dev:Main.WebHome]] apply | ||
| 974 | * Each extension has a Release Manager defined and he’s responsible for defining its own Roadmap/Release notes (if need be), on the extension page on e.x.o and perform the releases or ensure the extension is released regularly when there are changes. | ||
| 975 | * Each extension must follow these criteria for being VOTEd: | ||
| 976 | ** A Release Manager needs to be defined in the proposal | ||
| 977 | ** The extension must have had several releases already (i.e. someone wanting to propose a new extensions that doesn’t exist would start in ##xwiki-contrib## for ex and prove that his extension works and is useful by doing several releases and creating the pages on e.x.o) | ||
| 978 | ** It must follow [[our best practices>>dev:Main.WebHome]] (coding practices, tests, etc) and follow the [[apps best practices (for apps)>>dev:Community.ApplicationDevelopmentBestPractices]]. | ||
| 979 | ** It must have one or several integration or functional tests (for apps) to prove that it works. This allows to prove the app continues working when XWiki progresses | ||
| 980 | ** The main contributors of the extensions must agree about the move. If they have the “level" to be an xwiki dev [[committer>>dev:Community.Committership]] then they should be voted in. If not then either they’re ok to send Pull Requests or the extension should not be moved. | ||
| 981 | * If an extension ceases to work or if its quality becomes too low, it can be moved to ##xwiki-contrib## with a VOTE | ||
| 982 | * We create one JIRA project per extension | ||
| 983 | * We create a new JIRA Category called “XWiki Extensions” | ||
| 984 | * We put the extensions in our CI at http://ci.xwiki.org | ||
| 985 | * The Java package must follow the same rule as for XWiki Platform, i.e. ##org.xwiki.<short project name>##. Exceptions would need to be discussed. | ||
| 986 | * The group id for extensions having their own repo must be ##org.xwiki.<short project name>##. The ##<short project name>## needs to be part of the VOTE when proposing a new extensions. | ||
| 987 | |||
| 988 | = Retiring a module = | ||
| 989 | |||
| 990 | When a module needs to be moved to the XWiki Attic, the following process must be followed: | ||
| 991 | |||
| 992 | * Send a VOTE propose on the Forum | ||
| 993 | * Once agreed: | ||
| 994 | ** If you're retiring the whole GitHub repo, then simply move it on GitHub and if you're only retiring a part of the repo then [[Extract out the module>>#HExtractingoutamodule]]. | ||
| 995 | ** [[Retire the JIRA project>>#HRetiringaJIRAproject]] | ||
| 996 | ** Update the page on e.x.o to indicate this with a warning and information in the Compatibility section. | ||
| 997 | |||
| 998 | {{info}} | ||
| 999 | Any module moved to the XWiki Attic is not supported anymore. | ||
| 1000 | {{/info}} | ||
| 1001 | |||
| 1002 | = JMX Monitoring = | ||
| 1003 | |||
| 1004 | All XWiki monitoring APIs must be implemented and exposed as [[JMX>>http://en.wikipedia.org/wiki/Java_Management_Extensions]] MBeans. See also how to [[Monitor an XWiki instance>>xwiki:Documentation.AdminGuide.Monitoring]]. | ||
| 1005 | |||
| 1006 | Best practices: | ||
| 1007 | |||
| 1008 | * Always use XWiki's {{scm project="xwiki-commons" path="xwiki-commons-core/xwiki-commons-management/src/main/java/org/xwiki/management/JMXBeanRegistration.java"}}JMXBeanRegistration{{/scm}} component to register a MBean. | ||
| 1009 | * Make sure you don't forget to unregister your MBean when needed. Usually registration is done in component's ##Initializable#initialize()## methods and unregistration in ##Disposable#dispose()## one. | ||
| 1010 | |||
| 1011 | Example: | ||
| 1012 | |||
| 1013 | {{code language="java"}} | ||
| 1014 | public interface JMXVelocityEngineMBean | ||
| 1015 | { | ||
| 1016 | TabularData getTemplates(); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | public class JMXVelocityEngine implements JMXVelocityEngineMBean | ||
| 1020 | { | ||
| 1021 | /** | ||
| 1022 | * The Velocity Engine for which to return management data. | ||
| 1023 | */ | ||
| 1024 | private VelocityEngine engine; | ||
| 1025 | |||
| 1026 | /** | ||
| 1027 | * @param engine the Velocity Engine for which to return management data | ||
| 1028 | */ | ||
| 1029 | public JMXVelocityEngine(VelocityEngine engine) | ||
| 1030 | { | ||
| 1031 | this.engine = engine; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | /** | ||
| 1035 | * {@inheritDoc} | ||
| 1036 | * @see JMXVelocityEngineMBean#getTemplates() | ||
| 1037 | */ | ||
| 1038 | public TabularData getTemplates() | ||
| 1039 | { | ||
| 1040 | ... | ||
| 1041 | } | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | @Inject | ||
| 1045 | private JMXBeanRegistration jmxRegistration; | ||
| 1046 | ... | ||
| 1047 | JMXVelocityEngineMBean mbean = new MyBean(engine); | ||
| 1048 | this.jmxRegistration.registerMBean(mbean, "type=Velocity,domain=Engines,name=" + key); | ||
| 1049 | {{/code}} | ||
| 1050 | |||
| 1051 | = Add a new committer = | ||
| 1052 | |||
| 1053 | See [[Community.Committership#HChecklisttoaddanewcommitter]]. | ||
| 1054 | |||
| 1055 | = Security = | ||
| 1056 | |||
| 1057 | * We follow the [[Security Policy>>Community.SecurityPolicy.WebHome]]. This documents contains both the policy and also development topics (such as how to handle security issues by developers, how to add a new member to the security sites, etc) | ||
| 1058 | * All developers must also follow the [[best practices regarding security>>Community.Security.WebHome]]. | ||
| 1059 | |||
| 1060 | = Performances = | ||
| 1061 | |||
| 1062 | * [[Performance best practices>>xwiki:Documentation.DevGuide.Performances.WebHome]] | ||
| 1063 | |||
| 1064 | = Rendering Macros = | ||
| 1065 | |||
| 1066 | Macros written for XWiki Platform should be written in Java (by opposition to wiki pages) for the reasons mentioned in the [[comparison table>>xwiki:Documentation.DevGuide.Tutorials.WritingMacros.WebHome]]. | ||
| 1067 | |||
| 1068 | = Dependencies = | ||
| 1069 | |||
| 1070 | == Adding a new Dependency == | ||
| 1071 | |||
| 1072 | If a developer needs to add a new dependency to an XWiki distribution, the following checks must be performed: | ||
| 1073 | |||
| 1074 | * Longevity of the project (> 2 years) | ||
| 1075 | * Frequency of releases (several times per year and a minimum of once per year if there’s a track record of it happening for more than 3 years) | ||
| 1076 | * Speed of support and whether questions are answered at all (a question should usually be answered within 1 month at most) | ||
| 1077 | * Number of active contributors, to avoid single man efforts which is not a sign of stability as the developer can move to something else | ||
| 1078 | ** For a dependency providing important features to XWiki: minimum of 3 active developers, and even more ideally, not all from the same company | ||
| 1079 | ** For a dependency providing secondary features to XWiki: minimum of 1 active developer | ||
| 1080 | * Quality of documentation (existence of documentation) | ||
| 1081 | * License compatibility with XWiki’s LGPL 2.1 license, and OSI-approved | ||
| 1082 | * No known important and unhandled security issues | ||
| 1083 | * Releases are versioned properly | ||
| 1084 | |||
| 1085 | If one or several of these criteria is not achieved or if there's a doubt (except for the license criteria which is non-negotiable), and we don’t have the choice because there’s no alternative, then a VOTE can be sent to make an exception for a given dependency. |