Show last authors
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 == Roadmap ==
15
16 * A roadmap proposal email is sent regularly on the devs mailing list, proposing high level topics to work on in the coming XWiki releases.
17 ** Any committer could do this work but at the moment it's Vincent Massol who's sending the roadmap proposal email. See the info box below to learn more.
18 * 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.
19 * Once the roadmap is agreed, or if there are no comments, its content is updated on the [[Roadmap page>>xwiki:Roadmaps.WebHome]]
20 * Then, each committers having accepted to implement tasks from the roadmap should analyse their tasks, discuss 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.
21 * 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!)
22 * 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.
23 * Committers must then assign themselves on the JIRAs + set the ##fixVersion## field.
24 * 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 send a proposal email to the list 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 mail.
25 * Commits should be done regularly and more than once per week (the more the better, ideally several times per day).
26 * Committers are free to create Pull Requests if they want to get some review before pushing the code.
27
28 The goals of this process are several:
29
30 * Provide visibility to the community at large and especially other developers and users
31 * 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)
32 * Allow us to have product roadmaps
33 * Provide the ability to help someone if he's lagging behind or has issues
34
35 {{info}}
36 **A peek into XWiki SAS**
37
38 * 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.
39 * 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]].
40 * 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.
41 * Vincent discusses with the XWiki SAS Product team members to assign roadmap items to XWiki SAS developers.
42 * Vincent then sends the roadmap proposal mail on the devs mailing list, listing the items discussed by XWiki SAS with the defined assignees from XWiki SAS.
43 {{/info}}
44
45 == Development Flow ==
46
47 When you work on some XWiki code here's the typical workflow depending on what you're working on:
48
49 * 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 functionally you write some [[functional tests>>Testing]]. 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).
50 * 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.
51 * 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]]).
52
53 = Automated Builds =
54
55 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.
56
57 = Continuous Integration =
58
59 See the [[Continuous Build page>>ContinuousBuild]].
60
61 = Release Manager Role =
62
63 Role definition:
64
65 * In charge of performing a Release of XWiki (usually XWiki Commons/Rendering/Platform).
66 * Is responsible to ensure that the dates defined in the Roadmap are achieved
67 * 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
68 * 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.
69
70 Process:
71
72 * 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!
73 * We take turns, following the order (from top to bottom). When a newcomer is added he's inserted at the bottom of the list.
74 * 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.
75 * All releases are included in this process: milestones, RCs, final, bugfix releases.
76 * We switch Release Manager at each release (be it a milestone, RC, final or bugfix release).
77 * 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.
78
79 = Build Manager Role =
80
81 {{info}}
82 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
83 {{/info}}
84
85 Role definition:
86
87 * Every week we have a different Build Manager chosen amongst the Committers
88 * 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)
89 * By "Build" we mean the CI Build on http://ci.xwiki.org and by "failing" we mean anything that makes the build fail: tests, compilation, backward-compatibility checks, etc.
90 * In order to fix build issues the Build Manager has several possibilities:
91 ** 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)
92 ** rollback the issue that caused the build to fail
93 ** fix it himself/herself
94 ** find someone knowledgable in the failing domain and get him/her to fix the build.
95 * 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).
96 * 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.
97 * All committers must perform this duty and take turns
98
99 Some examples of things that break the build and for which we need someone "owning" the build to fix them:
100
101 * Agents stop working. For ex some morning there were 2 jobs stuck because of a failure to start Firefox. This happens from time to time. Someone needs to investigate and at the very least kill the job to free the agent.
102 * New versions of Jenkins fixing bugs. Someone needs to check and upgrade the build when a new version has interesting stuff for us and when it fixes some of our issues.
103 * The most important ones: flickering tests. Of course we always test locally before committing and we even check that it works on Jenkins. But flickering don't fail immediately, they might run fine for 50 or 100 iterations and suddenly start to fail. It's not always easy to find who's the culprit on flickering tests.
104 * Various issues with filesystem locks, permissions on agents, memory settings, number of allowed open files, etc that make the build fail
105
106 = Versioning & Release Practices =
107
108 Check the [[Versioning and Release Practices page>>VersioningAndReleasePractices]].
109
110 = Copyright header in source files =
111
112 All files (including configuration files) must have the following copyright statement.
113
114 == For Java & Javascript files ==
115
116 {{code language="none"}}
117 /*
118 * See the NOTICE file distributed with this work for additional
119 * information regarding copyright ownership.
120 *
121 * This is free software; you can redistribute it and/or modify it
122 * under the terms of the GNU Lesser General Public License as
123 * published by the Free Software Foundation; either version 2.1 of
124 * the License, or (at your option) any later version.
125 *
126 * This software is distributed in the hope that it will be useful,
127 * but WITHOUT ANY WARRANTY; without even the implied warranty of
128 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
129 * Lesser General Public License for more details.
130 *
131 * You should have received a copy of the GNU Lesser General Public
132 * License along with this software; if not, write to the Free
133 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
134 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
135 */
136 {{/code}}
137
138 == For XML files ==
139
140 {{code language="none"}}
141 <!--
142 * See the NOTICE file distributed with this work for additional
143 * information regarding copyright ownership.
144 *
145 * This is free software; you can redistribute it and/or modify it
146 * under the terms of the GNU Lesser General Public License as
147 * published by the Free Software Foundation; either version 2.1 of
148 * the License, or (at your option) any later version.
149 *
150 * This software is distributed in the hope that it will be useful,
151 * but WITHOUT ANY WARRANTY; without even the implied warranty of
152 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
153 * Lesser General Public License for more details.
154 *
155 * You should have received a copy of the GNU Lesser General Public
156 * License along with this software; if not, write to the Free
157 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
158 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
159 -->
160 {{/code}}
161
162 == For Shell scripts, Properties & YAML files ==
163
164 {{code language="none"}}
165 # ---------------------------------------------------------------------------
166 # See the NOTICE file distributed with this work for additional
167 # information regarding copyright ownership.
168 #
169 # This is free software; you can redistribute it and/or modify it
170 # under the terms of the GNU Lesser General Public License as
171 # published by the Free Software Foundation; either version 2.1 of
172 # the License, or (at your option) any later version.
173 #
174 # This software is distributed in the hope that it will be useful,
175 # but WITHOUT ANY WARRANTY; without even the implied warranty of
176 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
177 # Lesser General Public License for more details.
178 #
179 # You should have received a copy of the GNU Lesser General Public
180 # License along with this software; if not, write to the Free
181 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
182 # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
183 # ---------------------------------------------------------------------------
184 {{/code}}
185
186 == For Bat files ==
187
188 {{code language="none"}}
189 REM -------------------------------------------------------------------------
190 REM See the NOTICE file distributed with this work for additional
191 REM information regarding copyright ownership.
192 REM
193 REM This is free software; you can redistribute it and/or modify it
194 REM under the terms of the GNU Lesser General Public License as
195 REM published by the Free Software Foundation; either version 2.1 of
196 REM the License, or (at your option) any later version.
197 REM
198 REM This software is distributed in the hope that it will be useful,
199 REM but WITHOUT ANY WARRANTY; without even the implied warranty of
200 REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
201 REM Lesser General Public License for more details.
202 REM
203 REM You should have received a copy of the GNU Lesser General Public
204 REM License along with this software; if not, write to the Free
205 REM Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
206 REM 02110-1301 USA, or see the FSF site: http://www.fsf.org.
207 REM -------------------------------------------------------------------------
208 {{/code}}
209
210 == For Velocity files ==
211
212 {{code language="velocity"}}
213 ## ---------------------------------------------------------------------------
214 ## See the NOTICE file distributed with this work for additional
215 ## information regarding copyright ownership.
216 ##
217 ## This is free software; you can redistribute it and/or modify it
218 ## under the terms of the GNU Lesser General Public License as
219 ## published by the Free Software Foundation; either version 2.1 of
220 ## the License, or (at your option) any later version.
221 ##
222 ## This software is distributed in the hope that it will be useful,
223 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
224 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
225 ## Lesser General Public License for more details.
226 ##
227 ## You should have received a copy of the GNU Lesser General Public
228 ## License along with this software; if not, write to the Free
229 ## Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
230 ## 02110-1301 USA, or see the FSF site: http://www.fsf.org.
231 ## ---------------------------------------------------------------------------
232 {{/code}}
233
234 = Coding Conventions =
235
236 See the [[Code Style page>>CodeStyle]].
237
238 = File encoding =
239
240 The following rules must be taken into account when the need for writing non-ASCII content in the XWiki sources arises:
241
242 * 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.
243 * All translation files must contain only ASCII chars and Unicode escapes (stronger than the Java properties specification).
244 * All wiki documents sources must be stored in UTF-8.
245 * Other XML files should always specify their encoding in the **{{{<?xml>}}}** header, and it should be UTF-8 as often as possible.
246 * All other textual resources must be stored in UTF-8, minimizing the use of non-ASCII chars.
247
248 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.
249
250 = Creating a JIRA project =
251
252 When creating a new Contrib JIRA project on https://jira.xwiki.org make sure to use the XWiki Contrib template ({{scm project="xwiki-dev-tools" path="xwiki-jira-template-plugin"}}source code here{{/scm}}):
253
254 {{image reference="jira-contrib-template.png"/}}
255
256 In addition perform the following steps:
257
258 * Put as Project Lead the person requesting the project
259 * Make sure to fill the URL part. Ideally it should point to documentation on extensions.xwiki.org. Failing that it should point to the GitHub project's page.
260 * Create the appropriate versions. If the project has already had releases, recreate the versions and release them in JIRA with the correct release dates
261
262 For information this is what this template automates:
263
264 * Creating a "JIRA Classic" project type
265 * Selecting the proper "Category". For Contrib projects, it's "XWiki Contributed Projects".
266 * Setting Workflows to use the "XWiki Workflow Scheme"
267 * Setting Screens to use the "Basic Issue Creation Scheme"
268 * Setting Fields to use the "XWiki Open Field Configuration Scheme"
269 * Making sure that the default assignee is "Unassigned" and that it's not the Project Lead by default
270 * Setting Permissions to use the "XWiki Open" scheme
271 * Setting Issue Security to use the "XWiki" scheme
272 * Setting Notifications to use the "XWiki Notification Scheme"
273
274 = JIRA Best Practices =
275
276 Here are some rules on how to use JIRA for XWiki projects.
277
278 == Rule: Always put a JIRA issue reference in commit messages ==
279
280 The rationale behind this:
281
282 * One consistent way to manage all the work to be done on the XWiki project. It also means there's no unaccounted work, meaning anyone can go to JIRA and query it and see what everyone has been working on.
283 * Automated release notes/change logs. When we release a version we can simply do a JIRA extract and it'll give the full change log of what happened. This is really important for our users to see what has been done when in XWiki.
284 * Traceability. When you use the JIRA issue number in your commit, the JIRA DVCS Connector Plugin can show the modified files directly from JIRA. This is quite useful later on, when someone is looking at a JIRA issue and wants to see what was modified. In addition Fisheye is also integrated with JIRA and when you browse the source repository you can see the JIRA issue associated with files.
285
286 Of course this shouldn't be done for any trivial things like adding a small javadoc, renaming a single variable, cosmetic changes, ignore files, etc.
287
288 JIRA issues can be marked "confidential", e.g. to hide the details of a security issue until it is fixed. Such issues should also be referenced in the commit message. However, avoid exposing the details of the issue in the commit message (some time will pass until the code is released) by choosing a more neutral description.
289
290 The general strategy goes like this:
291
292 * When you plan to work on something, create a JIRA issue and assign it to yourself or simply assign an existing JIRA issue to yourself if one already exists
293 * Implement it
294 * Commit it with the JIRA issue number in the commit message. The format we follow is:(((
295 {{code language="none"}}
296 <JIRA ID, e.g. XWIKI-1000>: <JIRA issue description>
297 * <details>
298 ...
299 * <details>
300 {{/code}}
301 )))
302 * Close the JIRA issue
303
304 * Another acceptable variation is:
305 ** Implement something
306 ** When you want to commit it you realize you don't have any JIRA issue to put in the commit message so don't commit.
307 ** Create the JIRA issue
308 ** Commit with the JIRA number in the commit message
309
310 == Rule: Don't create unnecessary issues ==
311
312 * If you want to know whether you should create a JIRA issue or not, ask yourself the question: "is my change going to affect any user or any extension developer in any way"? If the answer is yes then you must create a JIRA issue
313 * If you're fixing something related to build then it's not mandatory to create an issue. However if you do, make sure you use the special component usually labeled "Development Issues only" in our JIRA projects. We're excluding issues in this category from our release notes.
314 * Note that if you're upgrading a third-party dependency used by XWiki at runtime then you must create a JIRA issue using the special component usually labeled "Dependency Upgrades" and this needs to make it in the Release notes since it impacts XWiki users. If you're upgrading a third-party dependency only used at build time (for example the Selenium dependency) then you should use the "Development Issues only" component.
315 * If you're fixing or reporting an issue related to code that's been introduced in the current version being developed, you shouldn't create a JIRA issue. Actually, if you did, you'd be hard-pressed to find the correct "Affects version" to use! :). Instead, use (or reopen) the existing JIRA that affects the current version being developed. If you're fixing it yourself, just use the same issue key. If you're reporting a problem, just reopen the issue and add a comment for the developer to see and fix before releasing.
316 * If you're adding some translations on l10n.xwiki.org it's not necessary to create an issue in the [[l10n Project's JIRA>>https://jira.xwiki.org/browse/XINFRA/component/12646]]. It would cause too much overhead.
317
318 == Rule: Don't reopen issues closed for a released version ==
319
320 If you spot an incorrectly or incompletely fixed issue that was closed but the version it was closed for is already released (i.e. no more development can be done for that version), then you must never reopen such an issue. Instead, you should create a new issue that describes the work left to be done or the fact that the problem still exists after the attempted fix and link the new issue to the old one.
321
322 The main reason is that a fix for an issue must never span commits across multiple versions and we need to be able to clearly indicate what is the version where the issue was fixed in.
323
324 The only case where reopening such an issue is allowed is when the closed issue has no commits associated to it (i.e. closed as ##Won't Fix##, ##Duplicate##, etc.).
325
326 == Rule: Use nice user-friendly titles ==
327
328 When you create a JIRA issue always take the time to put a nice title for the issue. The title must be understandable by a user so don't describe the issue technically but rather in what way it affects users. For example don't say "Fix the addXXX API to return an Array List" but rather "Allow creating several pages at once".
329
330 == Rule: Don't set a "Fix For" field for invalid issues ==
331
332 Issues that are closed with "Won't fix", "Duplicate", "Cannot reproduce", 'Solved By" or "Incomplete" must have a "Fix For" field set to "unknown" so that they don't appear in the Release Notes, as JIRA doesn't make the distinction visible and this causes confusion.
333
334 == Rule: Close issues that XWiki committers don't plan to implement ==
335
336 * We close issues that we know we won't fix (using a "Fix For" value of "Duplicate", "Incomplete", "Cannot Reproduce" or "Won't Fix"). We might not want to fix them for several reasons but one reason is that the issue is for an old XWiki project version.
337 ** This is especially true since [[XWiki committers are only officially supporting a few branches>>xwiki:Main.Support]]. Of course, any committer wanting to
338 fix any old issue is free to do it.
339 * Leaving these issues open is not a good idea since:
340 ** It sends the wrong signals that we're going to fix the issue
341 ** The issue can still be found with a search even if closed
342 ** When we close it then the reporter can explain why it's so important for him/her, or not. Which we wouldn't know if we hadn't closed it
343 ** Contributors can reopen issues and attach a patch or just create a new issue
344 ** It means that for all other issues we plan to fix them at some point
345
346 == Rule: Assign contributor when there's a Pull Request ==
347
348 * If a contributor opens a PR, [[assign the corresponding JIRA issue to the contributor>>https://markmail.org/message/6vgagzsrkxij3k3l]]
349 * If the contributor doesn't have a JIRA account then ask the contributor to create an account to assign him/her and in the mean time assign the committer merging the PR (so that if no account is ever created the committer stays assigned)
350 * If you have to make substantial modifications to the PR, then you decide who gets assigneed (contributor or you), on a case by case basis.
351
352 == Rule: create lowercase labels and without versions ==
353
354 The idea is consistency:
355
356 * We use lowercase labels
357 * Don't put specific versions in labels, instead use the Environment field to add more details about versions.
358 ** For example don't create a ##tomcat9## label, instead use the ##tomcat## one and put "Tomcat 9.x" in the Environment field.
359
360 = Retiring a JIRA project =
361
362 Eventually, some XWiki projects will reach their end-of-life. This is often a good thing as new approaches or technologies have developed which reduce the need for the project. When a project retires, it is best to clean up loose ends to make sure outstanding users still have access to the code and the valuable project history is captured for future researchers.
363
364 Retiring steps:
365
366 * Make the project 'Read-Only' by using the "XWiki Retired Project Scheme" permission scheme.
367 * Change the name of the project by prepending it with the ##{Retired}## label (e.g. ##Forum Application## -> ##{Retired} Forum Application##).
368 * Move the project to the [["XWiki Retired Projects" category>>https://jira.xwiki.org/secure/BrowseProjects.jspa#10060]]. Edit the project and set its new category.
369 * Update the project's description accordingly, informing the users that the project is no longer active.
370
371 = Documentation Best Practices =
372
373 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 two things:
374
375 * Have up to date documentation on xwiki.org
376 * 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...
377
378 == Documentation of young API modifications ==
379
380 When an API is considered as "young" (it has the ##@Unstable## annotation), some changes can be made to its methods declarations. In order for those changes to not be considered as breakages, please mention clearly that the API you just modified is still considered as unstable when you report an API change in the {{scm path="xwiki-platform-core/pom.xml"}}##xwiki-platform-core## POM file{{/scm}} (something like "##Young API, FooBarClass#getSomething() now takes … argument.##" will perfectly do the work).
381
382 This is important mostly because changes that concerns young APIs are not especially differentiated from standard API breakages in the [[release notes>>xwiki:ReleaseNotes.WebHome]].
383
384 = Using bird names for Skins =
385
386 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.
387
388 Here are some potential ideas for future names:
389
390 * Dove
391 * Emu
392 * Kiwi
393 * Grasswren
394 * Condor
395 * Warbler
396 * Kestrel
397 * Redtail
398 * Pigeon
399 * Booby
400 * Sparrow
401 * Blackbird
402 * Parrot
403 * Peacock
404 * Finch
405 * Wren
406 * Crow
407 * Turkey
408 * Thunderbird
409 * 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)
410 * Thunder Chicken
411 * Kingfisher
412 * Swallow
413
414 = Back-end Development Practices =
415
416 == Component Development ==
417
418 Read the [[Component Module documentation>>extensions:Extension.Component Module]] for details on how to write components.
419
420 == Backward Compatibility ==
421
422 We pay a lot of attention to backward compatibility. This is why we're using the [[Revapi Maven plugin>>http://revapi.org/modules/revapi-maven-plugin/index.html]] in our builds to ensure we don't break public APIs.
423
424 Specifically we check for the following type of backward compatibility issues ([[See full list provided by Revapi>>https://revapi.org/modules/revapi-java/index.html]]:
425 * Binary incompatibilities
426 * Semantic incompatibilities
427
428 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.
429
430 Since it takes time to stabilize an API we've introduced an annotation named ##@Unstable## (see below).
431
432 We follow 2 steps when it comes to deprecating code:
433
434 * **First step**: We start by deprecating it using the ##@deprecate## and ##@Deprecated## Javadoc and java annotations. The code remains where it was before the deprecation happens.
435 * **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.
436
437 This has the following advantages:
438
439 * Our code remains clean of old deprecated APIs
440 * Deprecated code is cleanly separated from new ways of doing things
441 * When new users download the our code they see the new ways (same for javadoc generation)
442 * Users wanting to use the old APIs can still do so
443 * 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.
444
445 {{info}}
446 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 it 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.
447 {{/info}}
448
449 {{warning}}
450 When you need to add a new method to an interface there are 2 solutions to preserve backward compatibility:
451
452 * 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.
453 * (Recommended) Use [[Default Methods>>https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html]] (introduced in Java 8).
454 {{/warning}}
455
456 === Deprecation Rules ===
457
458 For details and rationale about those rules below see [[this thread>>http://markmail.org/thread/cljbqwbrrmunlmar]].
459
460 * Rule: **Location of Legacy modules**
461 ** Each Git repository needing legacy modules provides a ##*-legacy## module for holding legacy modules. For example:
462 *** For Commons, ##xwiki-commons-core/xwiki-commons-legacy/##
463 *** For Platform, ##xwiki-platform-core/xwiki-platform-legacy/##
464 *** For Rendering, ##xwiki-rendering-legacy/##
465 * Rule: **Use AspectJ to move deprecated APIs to Legacy modules**
466 ** This idea was found in this [[blog post>>http://www.sonatype.com/people/2007/11/two-fantastic-uses-for-aspectj-part-one-backward-compatibility/]].
467 ** 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}}.
468 * Rule: **Legacy modules replace modules from where they come from**
469 ** 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.
470 * Rule: **Annotate code with version to show deprecations**
471 ** Use both ##@Deprecated## annotation and the ##@deprecated## javadoc tag **and** specify the version when the deprecation was added. For example:(((
472 {{code language="java"}}
473 /**
474 * @param time the time in milliseconds
475 * @return the time delta in milliseconds between the current date and the time passed as parameter
476 * @deprecated replaced by {@link com.xpn.xwiki.api.Util#getTimeDelta(long)} since 1.3M2
477 */
478 @Deprecated
479 public int XWiki.getTimeDelta(long time)
480 {
481 return this.util.getTimeDelta(time);
482 }
483 {{/code}}
484 )))
485
486 === ##@Unstable## Annotation ===
487
488 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.
489
490 In order to prevent code to remain annotated with ##@Unstable## forever, we've defined some rule;
491
492 * 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.
493 * 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.
494
495 The following automated checks related to the ##@Unstable## annotation are performed in the [[build>>Building]]:
496
497 * {{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.
498 * {{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.
499
500 == Configuration Property Naming ==
501
502 XWiki uses 2 configuration files at the moment:
503
504 * 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
505 * A more recent one that must be used for new configuration properties required by new code, named ##xwiki.properties##
506
507 The naming rule for ##xwiki.properties## is:
508
509 * Use ##<module>.<propertyName>##. Ex: ##rendering.linkLabelFormat##
510 * For submodules use ##<module>.<submodule>.<propertyName>##. Ex: ##rendering.macro.velocity.filter##
511 ** 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.
512 * Use camelcase for the property name itself. ex: ##linkLabelFormat##
513
514 == Translation Best Practices ==
515
516 === General ===
517
518 * The XWiki Core committers maintain one version, the English one and more precisely the ##en_US## one. This means:
519 ** The ##ApplicationResources.properties## file (without any language suffix) represents the ##en_US## version
520 ** We should use "customize" instead of "customise" or "color" instead of "colour" ;)
521 * Other translations are maintained by the community at large on [[l10n>>http://l10n.xwiki.org]].
522
523 === Translation Property Naming ===
524
525 When content requires localization you should use the following rules:
526
527 * 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.
528 * 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).
529 * Generally speaking the translations must be part of the extension containing the content to translate.
530 * New translation resources must be added on [[http://l10n.xwiki.org]] and also in the Weblate synchronization scripts.
531 * 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.
532 * Follow the [[L10N Conventions]] for naming the translation keys
533
534 === Translation Property Deprecations ===
535
536 * 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:(((
537 {{code language="properties"}}
538 #@deprecatedstart
539 ...
540 ##################################################
541 ## until <version that deprecated the keys below>
542 ##################################################
543 ...
544 {{/code}}
545 )))
546
547 {{warning}}
548 Not supported by the new Weblate based l10n platform.
549
550 * 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:
551
552 Example:
553
554 {{code language="properties"}}
555 ###############################################################################
556 ## Deprecated
557 ## Note: each element should be removed when the last branch using it is no longer supported
558 ###############################################################################
559
560 ## Used to indicate where deprecated keys start
561 #@deprecatedstart
562
563 #######################################
564 ## until 10.1
565 #######################################
566
567 job.log.label.refactoring/rename=Rename log
568 job.log.label.refactoring/copyAs=Copy log
569
570 ...
571
572 #######################################
573 ## until 3.5
574 #######################################
575
576 #@deprecated platform.livetable.results
577 xe.livetable.results=Livetable Results
578 ...
579 {{/code}}
580 {{/warning}}
581
582 === Moving Translations ===
583
584 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.
585
586 == Migrating away from the Old Core ==
587
588 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:
589
590 * Continue extracting code from ##oldcore## and put it in its own domain modules
591 * 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.
592 * At some point all that should remain in ##oldcore## is the old Model itself.
593 * 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.
594
595 {{warning}}
596 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##.
597 {{/warning}}
598
599 == User Interface Extension Point Naming ==
600
601 User Interface Extension Point (UIXP) must follow the following pattern:
602
603 ##<groupId>.<moduleName>.<uixpQualifier>## where:
604
605 * ##<groupId>##: reuse maven’s groupId in which the UIXP is declared. Lower case, dot separated.
606 * ##<moduleName>##: reuse maven’s module in which the UIXP is declared. Lower case, dot separated.
607 * ##<uixpQualifier>##: descriptive name of the UIXP. Single camel case identifier.
608
609 Example: ##org.xwiki.platform.user.profile.menu##
610
611 The User Interface Extensions (UIXs) contributing to an UIXP must follow the following pattern:
612
613 ##<groupId>.<moduleName>.<uixpQualifier>(.<uixQualifier>)## where:
614
615 * ##<groupId>##: reuse maven’s groupId in which the UIX is declared. Lower case, dot separated.
616 * ##<moduleName>##: reuse maven’s module in which the UIX is declared. Lower case, dot separated.
617 * ##<uixpQualifier>##: reuse the uixpQualifier of the UIXP where the UIX contributes.
618 * ##<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.
619
620 Examples of UIX contributing to the ##org.xwiki.platform.user.profile.menu## UIXP:
621 ##org.xwiki.platform.notifications.menu##
622 ##org.xwiki.platform.user.profile.menu.userMembership##
623 ##org.xwiki.platform.user.profile.menu.userNetwork##
624
625
626 = Front-end Development Practices =
627
628 == JavaScript Best Practices ==
629
630 * [[All javascript should be in the HTML ##<head>## of the document>>http://xwiki.markmail.org/message/7bgqcfx5hgnxqtjm]] (as much as possible).
631 ** Reason 1: Moving all script into the head makes it easier to find and makes impossible bad (and often non WCAG-compliant) practices such as attaching script to xml attributes. It makes it less of a jungle.
632 ** Reason 2: If we have no script in the body of any documents then users can implement filters which remove any script after the ##</head>## tag. This makes script injection certifiably impossible.
633 See [[this email thread>>http://xwiki.markmail.org/message/7bgqcfx5hgnxqtjm]]
634 * Avoid using javascript in attributes such as ##onload##, ##onmouseover##, etc. Doing this can cause problems with event handlers and is sometimes [[WCAG>>http://en.wikipedia.org/wiki/Web_Content_Accessibility_Guidelines]] invalid.
635 * Whether features should work or not when Javascript is turned off is a [[discussion in progress>>http://markmail.org/message/emzpfs6bdyu5f2e5]].
636
637 === External libraries ===
638
639 XWiki bundles several libraries to ease the development of front-end components. Amongst them are:
640
641 * [[Prototype.js>>http://prototypejs.org/]] (DOM manipulation, AJAX library, OOP-style classes)
642 * [[Smartclient>>http://www.smartclient.com/]] (Rich AJAX widgets)
643 * [[Scriptaculous>>http://script.aculo.us/]] (Drag and drop, animation framework, AJAX controls, DOM utilities and unit testing. Add-on for the Prototype library.)
644
645 For an exhaustive list, including XWiki internal libraries, see [[platform:DevGuide.FrontendResources]]
646
647 Front-end components should rely on components provided by those libraries as much as possible.
648
649 The introduction of new libraries should go through a vote on XWiki devs list. Only libraries which bring functionalities that none of the already provided external or internal libraries do are likely to be considered.
650
651 === XWiki Namespacing ===
652
653 All XWiki's JavaScript code should be under the **XWiki** namespace. The preferred way to namespace a module's code is to use the [[Module Pattern>>http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html]], in particular loose augmentation and sub-modules.
654
655 Methods, classes and properties that have sense only in one module should be created under a module object of the XWiki object.
656
657 Example:
658
659 {{code}}
660 var XWiki = (function(XWiki) {
661
662 // sub-module object lazy creation
663 var dataEditors = XWiki.dataEditors = XWiki.dataEditors || {};
664
665 // sub-module augmentation
666 dataEditors.XPropertyOrdering = Class.create({
667 // [snip]
668 });
669
670 return XWiki;
671
672 })(XWiki || {});
673 {{/code}}
674
675 Methods, classes and properties that have sense in all XWiki pages can be considered generic and be create directly under the XWiki object.
676
677 Example:
678
679 {{code}}
680 var XWiki = (function(XWiki){
681 /**
682 * Build a resource object from a wiki resource descriptor (aka fullName).
683 */
684 XWiki.getResource = function(fullName) {
685 // [snip]
686 }
687
688 return XWiki;
689
690 })(XWiki || {});
691 {{/code}}
692
693 === Backward compatibility and deprecation ===
694
695 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.
696
697 Example of deprecation code:
698
699 {{code language="javascript"}}
700 /**
701 * Deprecated since 1.9M2
702 */
703 window.displayDocExtra = XWiki.displayDocExtra;
704 window.displayDocExtra = window.displayDocExtra.wrap(
705 function(){
706 warn("window.displayDocExtra is deprecated since XWiki 1.9M2. Use XWiki.displayDocExtra instead.");
707 var args = $A(arguments), proceed = args.shift();
708 return proceed.apply(window, args);
709 }
710 );
711 {{/code}}
712
713 {{warning}}
714 XE 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 XE standard distribution.
715 {{/warning}}
716
717 = Bug Reporting =
718
719 The bug reporting system resides at https://jira.xwiki.org/
720
721 = XWiki.org Rules =
722
723 Some rules to follow when making modifications on xwiki.org.
724
725 == Don't remove important pages when they are moved ==
726
727 Rationale: Users will save links and when they navigate to them later on these links will be broken.
728 Solution: Add a redirect script to redirect to the new page
729 Implementation: Use this script:
730
731 {{code language="none"}}
732 {{velocity}}
733 $response.sendRedirect($xwiki.getURL("newSpace.newPage"))
734 {{/velocity}}
735 {{/code}}
736
737 == Don't use URLs for links to *.xwiki.org ==
738
739 Rationale: If we change the URL format or the domain the links will be broken
740 Solution: Use the ##wiki:Space.Name## notation
741
742 = XWiki Days =
743
744 See [[XWiki Days>>XWikiDays]].
745
746 = Application Development =
747
748 See [[Application Development Best Practices>>ApplicationDevelopmentBestPractices]].
749
750 = Build Best Practices =
751
752 * For the general directory structure, see [[dev:Community.SourceRepository]].
753 * **Directory names**: We're currently using the a directory name corresponding to the Maven ##artifactId##. For example: ##xwiki-platform-watchlist-ui## for a ##pom.xml## having(((
754 <artifactId>xwiki-platform-watchlist-ui</artifactId>
755 {{warning}}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.{{/warning}}
756 )))
757 * 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, ##org.xwiki.platform## for XWiki Platform and ##org.xwiki.enterprise## for XWiki Enterprise
758 * 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: ##-api## for modules providing APIs, ##-ui## for modules generating XARs, ##-test## for functional test parent POM, ##-test-pageobjects## for functional test Page Objects modules, ##-test-tests## and ##-test-docker## for modules containing and executing the functional tests (with and without Docker).
759
760 = Top Level Extensions =
761
762 Rationale/Need:
763
764 * 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
765 * 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).
766
767 Governance:
768
769 * Extensions are VOTEd in on a case by case basis.
770 * Each voted extension has its own Git Repository in the “xwiki” organization (so that each extension can be released independently of each other).
771 * 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.
772 * FTM extensions bundled by default with XWiki Standard still remain in XWiki Commons/Rendering/Platform/Enterprise.
773 * The Git repository name must be of the form ##xwiki-<short project name>##. ##<short project name>## must be part of the VOTE.
774 * All [[XWiki Development rules>>dev:Main.WebHome]] apply
775 * 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.
776 * Each extension must follow these criteria for being VOTEd:
777 ** A Release Manager needs to be defined in the proposal
778 ** 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)
779 ** It must follow [[our best practices>>dev:Main.WebHome]] (coding practices, tests, etc) and follow the [[apps best practices (for apps)>>dev:Community.ApplicationDevelopmentBestPractices]].
780 ** 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
781 ** 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.
782 * If an extension ceases to work or if its quality becomes too low, it can be moved to ##xwiki-contrib## with a VOTE
783 * We create one JIRA project per extension
784 * We create a new JIRA Category called “XWiki Extensions”
785 * We put the extensions in our CI at http://ci.xwiki.org
786 * 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.
787 * 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.
788
789 = Extracting out a module =
790
791 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##:
792
793 * Create the new target repo in https://github.com/xwiki-contrib/, e.g. https://github.com/xwiki-contrib/application-blog
794 * 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}}
795 * Push the ##split## branch into the new repo: {{code language="bash"}}git push https://github.com/xwiki-contrib/application-blog.git split:master{{/code}}
796 * Remove the ##split## branch: {{code language="bash"}}git branch -D split{{/code}}
797 * Remove the code from ##xwiki-platform## and commit

Get Connected