Changes between Initial Version and Version 1 of IndependentLibraryVersioning


Ignore:
Timestamp:
Jun 7, 2007, 6:10:46 AM (15 years ago)
Author:
Gennadiy Rozental
Comment:

Initial version

Legend:

Unmodified
Added
Removed
Modified
  • IndependentLibraryVersioning

    v1 v1  
     1    {{{
     2#!html
     3<h1 style="font-size: 180%; text-align: center;">Independent libraries versioning proposal for boost development environment, testing and release procedures</h1>
     4}}}
     5
     6== Introduction ==
     7
     8This document presents the proposal for [#snv_structure restructuring] boost development environment along with new [#test_procedures testing] and [#release_procedures release] procedures. The primary idea of this proposal is to "bite the bullet" and completely separate boost into multiple independent components and use [#independent_versioning independent versioning] for each one.
     9
     10== Objectives ==
     11
     12The objectives of this proposal include:
     13
     14* Independent development of all the components that constitute boost libraries set (accepted and proposed), so that each developer may work on his own pace and boost can scale up to an ever-larger number of libraries, and so do without the incremental weight of each new library having a negative impact on other libraries or on release management
     15
     16* Explicit support for libraries dependencies
     17
     18* Decoupling individual library testing and release [#individual_lib_release procedures] from [#boost_umbrella_release boost umbrella releases]
     19
     20* Minimizing requirements for the test environment while making it flexible to support all the necessary tests
     21
     22* Boost releases that are professional and reliable, and suitable for users ranging from simple projects by individuals on up to very large multi-developer projects in large organizations.
     23
     24* Timely releases of Boost are available on a predictable schedule, with no possibility that problems with a few libraries can delay a release of Boost as a whole.
     25
     26* Release preparation does not require super-human effort by the release manager and does not involve neither testers nor developers.
     27
     28* It is easy to release of subsets of Boost
     29
     30== SNV repository structure == #snv_structure
     31
     32The repository structure have to be changed to reflect an "independent nature" of this proposal. Essentially the change convert existing boost tree that look like this:
     33
     34{{{
     35boost/
     36   lib1/
     37   lib2/
     38   lib3/
     39....
     40   some_header1.hpp
     41   some_header2.hpp
     42....
     43
     44libs/
     45   lib1/
     46   lib2/
     47   lib3/
     48....
     49}}}
     50
     51to
     52
     53{{{
     54lib1/
     55   boost/lib1/
     56   boost/lib1.hpp
     57   libs/lib1/
     58lib2/
     59   boost/lib2/
     60   boost/lib2.hpp
     61   libs/lib3/
     62...
     63}}}
     64
     65The SNV repository directory structure for every library should look like this:
     66
     67{{{
     68libX/
     69  trunk/
     70    boost/
     71      libX/
     72      libX.hpp
     73    libs/
     74      libX/
     75        src/
     76        test/
     77            Jamfile
     78        example/
     79            Jamfile
     80        build/
     81            Jamfile
     82        doc/
     83  releases/
     84     1.0.0/
     85     1.0.1/
     86     1.0      -> 1.0.1
     87     1.1.0/
     88     1.1      -> 1.1.0
     89  branches/
     90     dev_branch
     91}}}
     92
     93Releases directory should only be populated by automated [#individual_lib_release script] during libX release. Branches are created by developer when needed.
     94
     95=== Boost web site content === #web_content
     96
     97The content of the boost web site should be made a first class citizen library that has it's own [##independent_versioning version] and [#lib_dependency dependency] on all others accepted boost libraries.
     98
     99=== Boost tools === #boost_tools
     100
     101The tools developed by boost (if any) should be made a first class citizen libraries that has it's own [##independent_versioning version]. This includes boost.build and boost.doc.
     102
     103=== Optional extensions ===
     104
     105{{{
     106#!html
     107<h4 style="font-style: italic; font-size: 100%">New library script</h4>
     108}}}
     109
     110To automate the procedure of new library creation it might be convenient to create a script that create above directory structure in a single command.
     111
     112{{{
     113#!html
     114<h4 style="font-style: italic; font-size: 100%">Combined tree as a reflection</h4>
     115}}}
     116
     117To support the need for a single command update of several (all) boost libraries it might be convenient to create combined boost tree (similar to our current tree) using snv externals based reflections.
     118
     119{{{
     120boost/
     121   lib1      -> lib1/trunk/boost/lib1
     122   lib1.hpp  -> lib1/trunk/boost/lib1.hpp
     123   lib2      -> lib2/trunk/boost/lib2
     124   lib2.hpp  -> lib2/trunk/boost/lib2.hpp
     125   lib3      -> lib3/trunk/boost/lib3
     126   lib3.hpp  -> lib3/trunk/boost/lib3.hpp
     127   ...
     128}}}
     129
     130Note that this tree will reflect the trunk versions of all the components
     131
     132{{{
     133#!html
     134<h4 style="font-style: italic; font-size: 100%">Sandbox/proposed libraries support</h4>
     135}}}
     136
     137The proposed directory structure allows us to avoid introduction of independent notion of sandbox. The same structure that is used for accepted libraries have to be used for any other component. This should make library incorporation into accepted libraries set especially easy.
     138
     139{{{
     140#!html
     141<h4 style="font-style: italic; font-size: 100%"><A name="boost_release_view">Boost release view</A></h4>
     142}}}
     143
     144It might be convenient (especially from [#build_procedures build procedures] standpoint) to create [#boost_umbrella_release boost umbrella release] reflections that combines all released libraries with their versions:
     145
     146{{{
     147boost_release/
     148   1.35.0/
     149     lib1      -> lib1/<lib1-version>/boost
     150     lib2      -> lib2/<lib2-version>/boost
     151     lib3      -> lib3/<lib3-version>/boost
     152   ...
     153   1.35.1/
     154}}}
     155
     156For example, above tree allows make system to refer to the version of library lib1 released as part of 1.35.0 as $(BOOST_DEV_ENV_HOME)/1.35.0/lib1.
     157
     158Alternatively boost release reflection can be made to match the deployment structure.
     159
     160{{{
     161boost_release/
     162   1.35.0/
     163     boost/
     164       lib1      -> lib1/<lib1-version>/boost/lib1
     165       lib1.hpp  -> lib1/<lib1-version>/boost/lib1.hpp
     166       lib2      -> lib2/<lib2-version>/boost/lib2
     167       lib3.hpp  -> lib2/<lib1-version>/boost/lib2.hpp
     168       lib3      -> lib3/<lib3-version>/boost/lib3
     169       lib3.hpp  -> lib3/<lib1-version>/boost/lib3.hpp
     170   ...
     171   1.35.1/
     172}}}
     173
     174== Independent versioning == #independent_versioning
     175
     176Each library is independently versioned and [#individual_lib_release released]. The [#boost_umbrella_release boost release] is just a thin packaging layer on top of set of already releases components. Concrete versions naming scheme is up for discussion.
     177
     178Each library may [#lib_dependency depend] not only on truck version of other library, but also on any other released versions. Optionally we may consider support for depending on development braches.
     179
     180== Explicit dependencies support == #lib_dependency
     181
     182There several ways to maintain the library dependencies. Concrete implementation may depend on tools we use/develop. For the sake if this proposal let's make them part of the library Jamfile (It may require further revision, for we need to access this information from outside make system).
     183
     184Each library build/Jamfile file should include dependency statement in a form like this:
     185
     186{{{libX.dependant_libs = lib1:<version of lib1> lib2:<version of lib2> lib3:<version of lib3>}}}
     187
     188For example:
     189
     190{{{A.dependant_libs = B:1.2.1 C:1.5.0 D:1.4.3}}}
     191
     192The Jamfile have to be created even if library is header only. All the targets in test and example directories have to include similar dependency statements. The dependency for a test/example of library X have to include the host library X version as well.
     193
     194For example:
     195
     196{{{A_test_1.dependant_libs = A:TRUNK B:1.2.1 C:1.5.0 D:1.4.3}}}
     197
     198For offline libraries and test/examples the dependencies list generation is straightforward and enforced during [#build_procedures compilation]. For the header only libraries it is library developer responsibility to maintain it (usually it should be easily deducible from the dependency list in the library tests).
     199
     200=== Strong dependency === #strong_dependency
     201
     202If library A required library B for all the configurations in which it can be used, B is called a strong dependency of library A. For example all boost libraries have strong dependency on Boost.Config.
     203
     204=== Weak dependency === #weak_dependency
     205
     206If library B is required by library A only for particular configuration or if particular feature is used, B is called a weak dependency of library A. This is also the case if library B is only required by library A tests/examples.
     207
     208=== Supported version formats ===
     209
     210* <major>.<minor>.<patch>
     211
     212Refers to the specific version of library X.
     213
     214* <major>.<minor>
     215
     216Refers to the latest patch release of library X in <major>.<minor> version
     217
     218* LATEST
     219
     220Refers to the LATEST released version of library X
     221
     222* Boost:<version of boost>
     223
     224Refers to the version of library X that was released as part of referred version of Boost
     225
     226* Boost:LATEST
     227
     228Refers to the version of library X that was released as part of latest released version of Boost
     229
     230* TRUNK
     231
     232Points to the library X trunk. To be used to test against development version of another component. Is not recommended and would prevent releasing of your library.
     233
     234== Development/testing environment == #dev_tree
     235
     236The environment used by developers and testers can represent a subset of SNV repository and only refer to the libraries/versions actually used:
     237
     238{{{
     239my_lib_under_development/
     240  trunk/
     241lib1/
     242  releases/
     243     1.1.0/
     244lib5/
     245  releases/
     246     1.5.1/
     247...
     248}}}
     249
     250In addition the environment may include [#boost_release_view boost umbrella release reflections].
     251
     252Boost make system [#auto_fetch automatically fetch] any dependency that is not present in the environment.
     253
     254== Build procedures == #build_procedures
     255
     256Boost make system have to recognize different locations of boost libraries and their independent versioning.
     257
     258=== Automated dependency fetch === #auto_fetch
     259
     260If build target depends on the libX:Nx and the version Nx of the library libX is not present in development environment
     261boost make system pulls it automatically from the snv and place in an appropriate location.
     262
     263For the header only library there should be a way to define the target in build/Jamfile that does only that dependencies fetching.
     264
     265=== Automated include/lib population  === #include_lib_population
     266
     267Boost make system shouldn't add $(BOOST_ROOT) to the list of includes. Instead if build target depends on the libX:Nx then $(BOOST_DEV_ENV_HOME)/libX/releases/Nx should be added to the list of includes. Similarly appropriate library have to be added to the list of ling objects and link path have to be added to the library search dirs list.
     268
     269This procedure should allows us to easily identify all necessary dependant libraries for all the targets.
     270
     271== Development procedure ==
     272
     273Let's say you are a developer of library X. Your development tree can include only your own library (at least this is the only thing you need to pull from svn manually, the rest is done by make system automatically). There are several modes you can work in using new development environment
     274
     275=== Active development mode ===
     276
     277If you are doing active development you have to change build/Jamfile to depend on stable versions of dependant component. Easiest choice is the versions used in last boost leases:
     278
     279{{{libX.dependant_libs = A:Boost:LATEST B:Boost:LATEST C:Boost:LATEST D:Boost:LATEST }}}
     280
     281Now you can do your own development with no regards to other developers activity. Your tests are validated against stable version of boost and any failures are introduces exclusively by your changes.
     282
     283If let say you found a problem in library A and after discussion library A developer releases new version of his library you may change dependency list to
     284
     285{{{libX.dependant_libs = A:<new version of A> B:Boost:LATEST C:Boost:LATEST D:Boost:LATEST }}}
     286
     287Note that by this time new version of A is already tested and released. And yet again you are testing against stable version of boost.
     288
     289If you are in a hurry, you can change dependency list to
     290
     291{{{libX.dependant_libs = A:TRUNK B:Boost:LATEST C:Boost:LATEST D:Boost:LATEST }}}
     292
     293But in this case you are on your own to figure whose fault is new failure, so in general this is not recommended.
     294
     295Once all your tests are green you proceed with library [#individual_lib_release release] and switch to maintenance mode (or another round of development).
     296
     297=== Maintenance mode ===
     298
     299If you are not doing any active development you have to change build/Jamfile to
     300
     301{{{libX.dependant_libs = A:LATEST B:LATEST C:LATEST D:LATEST }}}
     302
     303Now you are testing against latest released version of all dependant libraries. This mode allows you to [#auto_test_restart immediately] see any regressions caused by other libraries changes, allows [#auto_promotion automated promotion releases] and is required to prevent library [#lib_deprecation deprecation].
     304
     305If regression is detected and your library require changes, you switch to the development mode. If one of the dependencies is at fault you may switch to the last stable version of that library and wait for the update release announcement or just ignore it for now. Once dependency is fixed you can do your own patch version release. But this is optional since it going to be taken care of by [#auto_promotion automated promotion release] feature of the [#boost_umbrella_release boost umbrella release] procedure.
     306
     307=== Deprecation mode === #lib_deprecation
     308
     309If you are interested in maintaining library anymore you have to change build/Jamfile to
     310
     311{{{libX.dependant_libs = A:<last tested against> B:<last tested against> C:<last tested against> D:<last tested against> }}}
     312
     313The [#boost_umbrella_release boost umbrella release] will remove your library from the supported boost libraries set.
     314
     315== Individual library release == #individual_lib_release
     316
     317As soon as regression test for your library is green, you are free to make
     318release. You don't have to synchronize with/wait for anyone. It's done by
     319single script that does following tasks:
     320
     3211. Checks that all unit tests are green
     322
     3232. Checks that you don't depend on development version of other components (version TRUNK)
     324
     3253. Create release tag in libX/releases directory
     326
     3274. Save version of all dependant component. Even it you point on the LATEST, this will save actual version at the time of release. This is done by modifying libX.dependant_libs to refer to concrete version at the time of release
     328
     3295. Post announcements "Library A version N is released" on dev list.
     330
     331No binaries are released at this time unless we invent another procedure for independent component packaging. Ideally this should be server side script to prevent manual "hack" releases.
     332
     333== Boost umbrella release == #boost_umbrella_release
     334
     335The boost release is done automatically every predefined period of time (my preference would be three month). It requires NO testing, NO branching and NO merging/reverting. It's done by single script (a bit oversimplification, but
     336close) that expect at least one optional argument: list of libraries to be released. By default all accepted boost libraries are released. But the same script can be used to release any subset of boost.
     337
     338The script performs following tasks:
     339
     3401. For every library to be released it checks that all libraries it depends on are part of released libs set and if not adds it.
     341
     3422. Does [#auto_promotion automated promotion release] for all the released libraries that requires it.
     343
     3443. For every library to be released it finds last version that can be included in the release based on [#version_selection version selection algorithm]
     345
     3464. Deduces next version of boost (unless specified explicitly, which is what you should be doing for subset releases)
     347If, in comparison with last boost release, any library was released with <minor> version update this will be <minor> version update of the Boost. If all libraries released with <patch> version updates, it's going to be <patch> release of boost.
     348
     3495. Merge appropriate versions of all released libraries into single deployment tree:
     350
     351{{{
     352boost/
     353   lib1/
     354   lib1.hpp
     355   lib2/
     356   lib2.hpp
     357   lib3/
     358   lib3.hpp
     359....
     360libs/
     361   lib1/
     362   lib2/
     363   lib3/
     364....
     365}}}
     366
     3676. Produce deployment package and post dev list notification.
     368
     369=== Automatic promotion releases === #auto_promotion
     370
     371Let's say S is the set of libraries to be released
     372
     373for each library X in S we can do a "auto-promotion release" in case if following conditions are satisfied:
     374
     3751. For the latest version of library X - Nx - there is dependant library Y, so that release Nx depends on version Ny1, but latest version of library Y is Ny2 > Ny1. This essentially means that one of the dependencies was released after X is released.
     376
     3772. Trunk version of library X depends on LATEST version of library X and all the tests for the trunk version of library X are green. This essentially means that library X still works with new version of library Y.
     378
     379In this case we can make an automatic "promotion" and release patch version update for library X without any changes that depends on latest version of library Y Ny2.
     380
     381In practice for at the beginning we may have to do this manually. In a long run it have to be automated.
     382
     383=== Version selection algorithm === #version_selection
     384
     385Let's say S is the set of libraries to be released. Following algorithm is used to select the versions of all the libraries in S that can be safely released together.
     386
     387TODO
     388
     389== Testing procedures == #testing_procedures
     390
     391This proposal doesn't require significant modification in testing procedures. Test driver script have to be changed to:
     392
     393* Accommodate different [#dev_tree testing environment] structure
     394
     395* Accommodate to the fact that test environment may include only subset of all the boost libraries
     396
     397In addition the test results have to be accessible programmatically from the single location for scripts managing releases. The ideal solution would be to have some external DB based server that hosts interfaces for tests reporting and querying.
     398
     399=== Optional extensions ===
     400
     401In addition we may consider in long term implementing following extensions:
     402
     403* On-demand test requests.[[BR]]Exact scope of this feature is up to discussion
     404
     405* Proposed library testing.[[BR]]It might be helpful to allow some not-yet-accepted libraries to be tested in the same environment as regular libs. It shouldn't be difficult to support, since they are going to be no different in directory structure.
     406
     407* "Non-incremental testing" mode.[[BR]]For the test hosts running under limited disc space resources test system configuration have support option to clear all the results (including built binaries) after testing is completed. Exact scope of this feature is up for discussion.
     408
     409
     410