Problem/Motivation
- Drupal 8 core introduces the concept of "experimental modules" that are not completely production-ready but that are included in core for testing.
- Since these "experimental modules" are not considered stable and are not recommended for production use, it does not make sense to hold them to the same BC and patch release restrictions as stable code.
- Experimental modules should be able to iterate quickly in core.
- It should be clear to site builders and developers what state the experimental modules are in.
Proposed resolution
- Give experimental modules their own versions, separate from core, so that they can be in unstable, alpha, beta, or RC separately from core.
- Include these version numbers in the module's
info.ymlfile and expose them on the Extend page. - The versions for these modules always begin with
8.y.xin D8 while they are experimental, to make it clear that they are of lower stability than the rest of core and versioned separately from any particular patch or minor release. Examples:8.y.x-alpha8.y.x-beta8.y.x-rc
Optionally, we could designate specific multiple releases for the given stability in the future, e.g.
8.y.x-alpha3, but for now the suffix only indicates the level of stability/allowed changes and not any particular release. migrateis marked alpha.migrate_drupalis marked alpha.inline_form_errorsis marked alpha
Alternate proposal from #64
Use the same version scheme as contrib so that ModuleHandler::parserDependency() and drupal_check_incompatibility() work as expected.
Examples:
8.x-0.x-alpha18.x-0.x-beta18.x-0.x-rc1
This also benefits from the fact that using this version number ModuleHandler::parserDependency() identifies the module's major version as 0. This means we are inline with semver which states the a major version of 0 has no bc promise. Which is the reality we are trying to get across.
Remaining tasks
- (followup) Consider highlighting the version number when it differs from core's and/or automatically extending the details on it.
- #2657062: [policy, no patch] Experimental module policy and handbook page
User interface changes
Experimental modules display a different version number on the Extend page.

API changes
Version numbers for experimental modules change.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #97 | 96-97-interdiff.txt | 981 bytes | effulgentsia |
| #97 | 2656994-2-97.patch | 8.43 KB | effulgentsia |
| #96 | 95-96-interdiff.txt | 1.17 KB | effulgentsia |
| #96 | 2656994-2-96.patch | 8.45 KB | effulgentsia |
| #95 | 92-95-interdiff.txt | 586 bytes | alexpott |
Comments
Comment #2
alexpottI think this looks great and would help satisfy the concern I raised in #2644818-7: Inline Form Errors Module Description
Comment #3
xjmComment #4
xjmComment #5
xjmComment #6
swentel commentedCan't we do something like 'VERSION-unstable' so that we don't necessarily need to reroll this every minor release ? It would need a change in InfoParserDynamic though.
Comment #7
xjmThat's a good idea. Adding something that-like.
Comment #8
xjmAttached does that. Still adding tests.
Note that this results in version numbers like:
8.1.3-betain patch releases. (That's in line with @catch's suggestions.)8.1.0-betain minor releases. That makes sense too.8.1.0-dev-betafor the dev branch. That looks kinda weird, but maybe it makes sense based on the pattern above.Need to confirm whether or not that's a desired format for the version string.
Adding all the tags. We need subsystem maintainer signoff on the versions added for the particular subsystems, and then signoffs from the different committer groups since it affects all three.
Comment #9
benjy commentedFor Migrate, I think beta makes sense for Migrate itself, especially while we're still exploring the plugin implementation. alpha is good for migrate_drupal which has missing D7 upgrade paths and migrate_upgrade which still requires some UX improvements and further testing.
Comment #10
tim.plunkettAs Form system maintainer, unstable for Inline Form Errors makes sense.
Untagging since @benjy covered the other two.
Comment #11
xjmIt occurs to me that this pattern would result in some very funny version numbers when core itself is in beta or RC, e.g.:
8.1.0-beta-betaHmmm. :)
Comment #12
swentel commentedHa, yeah, that's a bit unfortunate, then again, one should never go in production with a alpha/beta core right ? ;)
It doesn't bother me /that/ much, but I'm not against the initial patch either, it was just a thought.
Comment #13
alexpottLooks like we're going to need a new replacement. I was pondering whether we to provide MAJOR, MINOR and PATCH replacements but that seems extremely complex. What we need to is \Drupal::VERSION without the stability modifier. So perhaps "VERSION-" is a good enough way to indicate this.
Comment #14
catchWe could potentially remove the suffix from VERSION before adding the suffix - would just need to strip [a-z] of the end of it.
Comment #15
tstoecklerRe #13: Actually I don't think that's very complex. In fact, we do some string parsing of \Drupal::VERSION to e.g. validate the core: 8.x declaration in moduels, etc. which would be a lot saner with something like \Drupal::MAJOR_VERSION. That doesn't mean that this issue should be the one to introduce that whole logic, but just saying that in general I think that would make a lot of sense.
Comment #16
alexpottUnfortunately it is not possible to do proper testing without adding a method to InfoParserDynamic. But as this is for 8.1.x should be okay.
Comment #17
alexpottSpelling mistake.
Comment #18
alexpottoopsie
Comment #19
alexpottSo I guess with the patch in HEAD we have the issue that an experimental module could be ahead of core it terms of stability. I think in that case we should just change the string to version. Or we could get clever and compare the versions and use the most unstable.
Comment #20
alexpottHere's a patch which makes it impossible for an experimental module to get ahead of core.
Comment #21
alexpottJust a thought shouldn't this be -dev? Adding a test to ensure that unstable is less stable than dev...
Comment #22
swentel commenteds/with/will
Comment #23
alexpottWouldn't it be nice if the test runner told you've added a test that has not run :)
Comment #24
xjmSo here we are missing like a beta-beta example.
If 8.1.0 is in beta, and the experimental module is in its own beta, do we care that those mean different things?
If 8.1.0 is in beta but we've moved the module to RC already, doesn't that imply that the experimental module is more stable than the rest of core? :P Or do we just solve that by not having experimental modules that are RC in a beta?
Edit: Sorry, I was looking at an earlier patch.
Comment #25
xjmSo I actually think the logic in #23 seems okay.
Comment #26
xjmDiscussed with alexpott; I'm going to make a couple of small additions for documentation and readability.
Comment #27
xjmI was adding a few more test cases to document the expected behavior. So here is the scenario where I'm not sure this strategy works:
This also leaves aside the possibility of marking multiple alphas or betas for those experimental modules, or having multiple betas or RCs for a core minor, which we might have occasion to do.
We might be able to solve some of this with policy, but it has the potential to be pretty confusing.
Comment #29
xjmDiscussed with @webchick and @alexpott. We agreed that the magic would probably get too complicated and confusing, and they proposed using
8.x.x-suffixwith the unstable versions. I tested withversion_compare()and this guarantees that the experimental module's version is always considered lower than any core release. And, since the normal course will be for a module to be experimental only once in the 8.x life cycle before it becomes stable, the minor version should not matter, and this way we do not need to worry about updating it.Updated patch reflects that instead. Also updating the screenshot in the summary.

We should double-check in any case that these experimental versions do not do something funky with the version reported with update status. If it works like we expect, they shouldn't, anyway.
Comment #30
xjmOh, right, that issue.
I did confirm that the individual modules' versions do not get picked up or reported by the Update module, so that's enough for this issue, anyway.
Comment #31
xjmOh, and to clarify #29. If Migrate is in RC while the relevant core minor is in beta, then it is still subject to RC rules, because the goal at that point is to stabilize it as quickly as possible. We'd take that into account when we decide to put something into beta or RC.
Comment #32
alexpottAs much as it was fun writing more magic into the extension system I have to agree removing all the magic and making it simple feels like a big win. And it's nice this doesn't break update status.
This approach has a +1 from me as a framework manager and I would also be happy to commit this to 8.0.x as well as 8.1.x.
Leaving at needs review to get release manager and product manager review.
Comment #33
xjmUpdating the summary to reflect that direction.
Comment #36
tim.plunkettCan these all be 8.y.x-whatever instead? the double x is making me twitch :)
Comment #37
xjmxjm agrees because algebra.
Comment #38
xjmComment #39
xjmMy concern with that was it would essentially downgrade the version in a patch release, which seemed prone to be disruptive. So I think it should only go into 8.1.x, along with all the other policy and UI changes related to experimental modules.
Comment #40
xjmWe should probably test this with module dependency checking and potentially add tests for what we expect to happen; see #2641658: Module version dependency in .info.yml is ineffective for patch releases. ModuleHandler::parseDependency() does not use
version_compare(), with this inline comment:Comment #42
dries commentedI like this proposal but recommend that we drop the
-unstableextension. To me,-unstableis ambiguous because-alphaand-betareleases for _experimental_ modules are all "unstable". It will probably not be clear to site builders whether-unstableis more or less stable than-alpha. I recommend we not add experimental modules unless they are at least alpha-quality. This way we can drop the-unstabletag. I believe that will be the easiest and clearest for site builders to understand.Comment #43
xano@alexpott mentioned using
-devin #21. As it's the tag we use everywhere else to indicate a module is unstable and has not entered its release preparation process, it seems fitting we use it here as well.PS: I read through http://semver.org/ again when reviewing this proposal, and realized that I can only find A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers with regards to valid characters in version numbers. Seeing as it says ...normal version number..., I would expect there to be another section that explains what a non-normal number may be, but I cannot find any such thing.
Comment #44
xjmThanks @Xano. We can't use
-dev, because it is too close to (e.g.)8.0.5-devfor stable core. We need to be able to make it obvious to site owners that the version is different from core, even in-devbranches of core.Comment #45
xjmOh, one of the committers should have mentioned this sooner, but we did discuss before Mumbai and everyone agreed that Dries' proposal in #42 would work. So we have the signoffs needed for the attached.
Maybe alpha is a bit of a stretch for inline form errors? :) But it's reasonable.
We also agreed that for modules that were truly unstable that we wanted to have in core experimentally, we could mark them hidden. But we don't have any examples yet that would require that.
This does need tests for dependencies and version comparing since Drupal uses special flower code for it instead of just
version_compare(). I'll look into that next using the test modules that have meanwhile been added in other issues.Comment #46
xjmAlso made this update to the handbook page:
https://www.drupal.org/node/2657056/revisions/view/9367864/9425708
Comment #47
xjmCorrect status given #45.
Comment #48
xanoThat makes sense. I missed that. Thanks!
My only concern is SemVer conformity. I do not expect this change has (m)any practical consequences, but it wouldn't be professional to not document this. If you agree, I'd be happy to do the writing. What would be a good place to document this? I couldn't find an existing handbook page yet.
Comment #49
xjmThe versioning is already documented on the handbook page linked above:
https://www.drupal.org/core/experimental
Did you mean something else? The
-alpha,-beta, etc. qualifiers and our use of them is an existing pattern in Drupal, not something introduced in this issue. See:https://www.drupal.org/documentation/version-info
and its child pages:
https://www.drupal.org/documentation/version-info/numbers
https://www.drupal.org/documentation/version-info/alpha-beta-rc
Edit: Also: https://www.drupal.org/node/1015226
Comment #50
xanoI see I haven't been clear about this. The SemVer docs say A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers, while this patch uses letters for Y and Z. Technically, this seems to be an invalid SemVer version number. I understand we do this for a good reason, and my point is that we should document this deviation from SemVer. I was willing to write this, but I hadn't found a good place to do so yet. https://www.drupal.org/documentation/version-info/numbers looks like the right place though. Thanks for digging that up.
Comment #51
xjmEdit: Never mind, I get it now. You mean the fact that it is
8.y.x-whatever, or that our development versions are8.0.x-dev, rather than8.0.0-whateveretc.Comment #52
xjmA couple other related bugs.
Comment #53
xjmBased on @alexpott's feedback in #2625696: Make migrations themselves plugins instead of config entities, he is not comfortable with Migrate being marked beta without that fixed (and I am not comfortable with it being marked beta without the followups for it being fixed along with it). So need to swap that to alpha.
Also, after reading in
core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php, it looks like we currently do not support-betaetc. with no integer suffix. It's also inconsistent with the tagging requirements for projects, which according to https://www.drupal.org/node/1015226 must have the integer suffix. So we can call all three thingsalpha1for purposes of this issue, and then increment them as we see fit going forward.Comment #54
xjmAlso, need to double-check on the changed stability with the subsystem maintainers.
Comment #55
benjy commented+1 for alpha for migrate
Comment #56
alexpottHere's a patch making migrate alpha and adding a number to everything.
Comment #57
xjmThanks @benjy!
Still needs tests.
Comment #58
alexpott@xjm - what do we need to test exactly? What is wrong with core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php?
Comment #60
xjm@alexpott, nothing is "wrong" with it, but it provides no test coverage for this change in our versioning policy. There are no tests for
8.y.x-anything, with an actualyandx, which has never been an allowed version string before. We also need to test that (e.g.) stable8.1.0-beta1is considered later than8.y.x-rc1, for modules that try to declare dependencies, because (as stated above) we don't actually useversion_compare()everywhere, so our earlier tests of the PHP function were irrelevant.Comment #61
xjmI think we should still consider this change for 8.1.x up to the RC, since it only impacts experimental modules, and since it has important release management implications.
Comment #62
alexpott@xjm we do use
version_compare()everywhere to compare versions to each other - we just manipulate the dependency strings in .info.yml files to satisfy our requirements. But this comment suggests we might need to do something for theyas well... so definitely worth testing.Comment #63
alexpottSomewhat annoyingly there is no explicit test of
drupal_check_incompatibility()Comment #64
alexpottWell this is a can of worms because core dependencies are different from contrib dependencies. Which is leading me to think that experimental modules should look more like contrib than core - ie. have a version string like
8.x-0.x-alpha1. Then we don't need to change any dependency mangling code because this just works... Also the major version of the project would 0 which is totally compatible with semver notions of BC... ie. anything before 1 can be changed.Comment #65
alexpottThe reason for #64 is both ModuleHandler::parseDependency and ModulesListForm and system_requirments all do...
And we need this too... it strips 8.x- from the front of the version string.
Comment #66
dawehnerWhile
8.x-0.x-alpha1makes a lot of sense especially in the context where we so, its for modules we might remove again, because, well this is one of the experimental side of things, I'm a but confused what this would mean for modules, which want to require a specific version of those modules.Let's say, they require
8.x-0.x-alpha2, no the core module is no longer experimental, so its version schema changes to8.2.x. Is this dependency then fullfillled?Comment #67
alexpottHere's a patch based on #64 and with a fix to the dependency parsing to support
-unstable.There no interdiff because it is yet another approach.
Comment #68
alexpottNo it is not but if they require >=8.x-0.x-alpha2 it is. Which is exactly how it works now.
Comment #69
dawehnerOh good point.
Comment #70
alexpottOh I see I've mis-understood... good question @dawehner. I'm not sure. Depending on particular versions of core modules is weird because this is normally handled by the core key in the info.yml file... the whole 8.2.0 is not handled well by ModuleHandlerDependency parser...
Comment #71
alexpott@dawehner we're okay it works as expected but only because we also key the module's core key in the info.yml otherwise one could do some really strange things.
The interdiff is the test only patch - I'm submitting a test only patch to show we've changed nothing about the assumptions around version checking that occur when we move a module into core. It should be green too.
Comment #72
alexpottComment #73
swentel commentedis it = it is ?
Comment #74
alexpottLet's add some tests for the
-unstableidentifier and fix #73.Comment #75
alexpott@xjm mentioned a problem with using the contrib numbering... if bigpipe is in contrib with an 8.x-1.x version... and then it becomes core experimental... so 8.x-0.x-alpha1... it is going back in versioning... which is very very weird.
TBH. I think if a contrib module goes into core we should always choose a different name.
Comment #76
alexpottUpdate on the last comment: I think if a contrib module goes into core we should always choose a different name if it is after the X.0.0 release
Comment #77
xjmDries stated previously that the
unstablewas not clear enough, and we agreed to that when we discussed it previously (and as I belatedly documented in #45). I don't think we should add support for it based on the consensus last month being to drop it. (My mistake for adding that pattern to the test module before this issue was resolved; the test module is what needs to be changed here.)It'd be good to get some wider feedback on this pattern of version string. I can see the advantages but I also am thrown by seeing the contrib pattern for a core module.
Comment #78
xjmSo... do we call it "BiggerPipe"? :P I'm not sure about how feasible this actually is. Of course having the same name also causes hosts of other problems too.
Comment #79
xjmSo this is where I was starting to go with #2677532: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component, but this also does have coverage in a very convoluted way in
\Drupal\system\Tests\Module\VersionTestwithsystem_test_system_info_alter()etc. Maybe a followup to kill that test (or reduce it to just a single UI test) and move any other coverage that's there, here?Edit: There are also whole test modules for checking both core and contrib dependencies as well, which is also related coverage.
Comment #80
xjmMy current work on this issue is now obsolete, so unassigning.
Comment #81
xjmKinda a priority.
Comment #82
xjmFor #77, and also we'd need to roll in
migrate_drupal_uinow. Still could use more feedback on @alexpott's alternate proposal.Comment #83
effulgentsia commentedWhat if instead, when a contrib module goes into core, we bump its major version? So for example, big_pipe in contrib is 8.x-1.0-rc1, but in core, we want it to be alpha, so what if we make it
8.x-2.0-alpha1? That means early adopters of the contrib module move forward in their version number when updating to what's in core, which I think is reflective of the reality in this case (the core code is a forward movement relative to the contrib code).Do we need this? Item #9 on http://semver.org/ says "A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version... A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version." So I'm unclear what the benefit of having 0 for the major version is, in cases where you also have an alpha/beta/rc suffix.
If we do my suggestion, then I think we'd need to make sure that if a hypothetical experimental module went into 8.1 as 8.x-3.0-alpha1, and then became not experimental in 8.2, that in fact 8.2.x is greater than 8.x-3.0-alpha1 (I don't know how the 2 and 3 get compared in that case). And also whether 8.2.x is greater than 8.x-9.0-alpha1 (comparison of 8 and 9), though that might be quite the edge case (not many contrib modules get to major versions that high).
Comment #84
effulgentsia commentedPotentially, we might want to exploit this as a feature rather than a bug. For example, suppose a contrib module wants to hack node.module. How can it indicate to UpdateManager that it's the preferred version to what's in core? Well, if core is on 8.1, then the contrib module can version its hack as 8.x-8.2. If our comparison code strips the "8.x" prefix, then the comparison would yield the contrib version (8.2) as higher than core's (8.1) until core moves to a higher number. We'd need to decide what to do in case of equality (should we prefer core's 8.2 or contrib's 8.x-8.2?), but once we decide that, contrib can accommodate either decision.
Comment #85
xjmThanks @effulgentsia!
Since this issue has these issues and may not land before RC (and it's a stretch for the beta), I added a list of what experimental modules have which stability on the handbook page that is linked from the message when you enable experimental modules:
https://www.drupal.org/core/experimental#alpha
Comment #86
alexpott@effulgentsia - nice idea. What always complicates this is how our modules are versioned... 8.x-2.x means that the module supports Drupal 8 but its major version is 2... and what we want is a minor version of 0. It seems an excellent idea that when contrib comes into core as experimental module we keep the contrib versioning but bump the modules major version. And it follow ups we could then use this to prefer core over contrib if core has the later major version of the module. What really complicates all of this is that modules don't yet have a version that corresponds to semver. I think the solution outlined in #83 is super.
@effulgentsia++
Comment #87
alexpottPatch attached implements and tests @effulgentsia's suggestion and removes support for the unstable modifier.
Comment #88
wim leers+1 for this. Saying that in my role as one of the BigPipe maintainers.
0.0-alpha seems a bit strange. Why not 1.0-alpha?
Comment #89
alexpott@Wim Leers - 0.0 because there has been no major release of these modules for drupal 8.
Comment #90
wim leersOkay. But then why not just start at 1.0? I don't know of contrib modules (or any software ever actually) that have 0.0 as a version number — it'd at least have 0.1.
If we choose to go with 0.0 instead of 1.0 to stress the experimental nature even more, then that's probably fine, though it feels unneeded, almost excessive.
Comment #91
catchI could see using 0.0 versioning for modules that are almost entirely prototypes. i.e. when the code itself has a good chance of being completely ripped out and started over.
migrate_drupal is not in that category, i.e. we expect it to go from alpha to beta to rc mostly as a result of bug fixes and clean-up.
inline_form_errors might be though, in that we don't have a clear path to get the current implementation of it working consistently everywhere, so by the time it gets to beta could be unrecognisable.
Comment #92
alexpottWell reading http://semver.org/ it says
So starting at 0.1 sounds entirely reasonable.
Comment #93
alexpottI;ve opened #2688369: If core provides a more recent version of a module use it instead of contrib to discuss the preferring contrib over core problem
Comment #95
alexpottOopsie... and we have tests...
Comment #96
effulgentsia commented#95 looks great to me. This additionally adds tests for what's discussed in #83 and #84.
Comment #97
effulgentsia commentedThis might be a bit clearer.
Comment #98
xjmWhat about @effulgentsia's proposal for this it to be (e.g.) 8.x-8.0-alpha1?
Is there a reason this is 0.0 rather than 0.1?
I need to read the test coverage more carefully to check for coverage for all the scenarios; will do so when I can.
Comment #99
alexpott#98.2 Nope - it's a leftover from before #92
Comment #100
alexpottre #98.1 I think that @effulgentsia was suggesting using that for a hack i.e.
.
Comment #101
xjmDiscussed with @alexpott and @effulgentsia. We agreed to move this issue to 8.2.x and try to fix it next time around.
Comment #102
wim leersOh, darn, I thought this already went in.
Comment #103
catchSo did I, but someone got caught out by migrate changes and I ended up pointing them here. Tagging again.
Comment #104
xjmSo the workaround for this for 8.1.x is that they are listed on the handbook page (which is linked from the warning displayed when installing an experimental module):
https://www.drupal.org/core/experimental#versions
Discussed also with @catch that I think this isn't going to be as helpful for developers who don't expect API changes for experimental modules, since core will still be one package. I think what would help developers more with that is the meta part of #2550249: [meta] Document @internal APIs both explicitly in phpdoc and implicitly in d.o documentation for explicitly marking internal APIs (including experimental module APIs) as such.
I'm still hesitant about this as an RC target because I feel there could be unknown repercussions, especially with all the outstanding bugs in this area, so using the 8.2.x cycle to fix this would seem the safest bet to me. To some extent, people need to pay attention to the yellow warning and read the handbook page because this is not a magic bullet for the confusion, just one more incremental improvement.
Comment #105
MixologicOne possibility that having the composer façade enables is keeping the experimental modules in the contrib space, and adding them to core via a composer require in core's composer.json and composer.lock.
The advantages would be that the experimental module could maintain its own versioning until such time as it reached a stable level of maturity, and it would be possible to have additional maintainers for that module until it was ready to be fully rolled into core.
A disadvantage would be split issue queues (where does one go to file issues for expermental modules?).
Comment #106
webchickNo, let's not complicate things. We already give experimental modules their own versions (alpha/beta/rc).
Comment #107
xjmThis issue accidentally did not get moved to 8.2.x after the 8.1.x beta phase. Moving to 8.3.x at this point.
Comment #112
tim.plunkettBlocks #2877066: Provide a standard way for tests to find core modules without loading experimental modules, probably
Comment #114
wim leersIs this still relevant? I doubt it is.
Comment #118
xjmYes, it's still relevant. We never did make a decision about how to handle this. Having to go to a secret handbook page on d.o to understand what level of support a module has is pretty ridiculous, even if that's what we've been relying on for years. See also: #2943707: Consider renaming "Experimental" core modules to "Beta" (policy, no patch)
"Postponed (maintainer needs more info)" when a release manager filed this release management issue does not seem the right status. :P
Comment #119
xjmAlso, Field Layout is alpha but ships in tagged releases because it predates the "alphas are not shipped in tagged releases" policy and so
rm -rfnow would be a very disruptive BC break for sites that do use it.Comment #124
quietone commentedThis issue was discussed by the release managers. We no longer ship alphas in a tagged release which make this unnecessary. Therefor, we agreed that this can be closed as won't fix. I am doing that now.
Cheers