Project

General

Profile

Developers' Best Practices » History » Version 20

Andrea Dell'Amico, 19/07/2021 02:52 PM

1 1 Alessia Bardi
h1. Developers' Best Practices
2
3 3 Claudio Atzori
It is time for D-Net development teams to find a strategy to improve our developement work!
4 1 Alessia Bardi
5
The introduction of Jenkins and Nexus helped a lot in terms of code management, but now it is time to establish a set of guidelines to better co-ordinate our teams.
6
The following best practices are inspired by CNR developers' common sense, so we do not assume they are written in stones and applies as they are also in your cases.
7
8
So, you are strongly invited to comment/update this wiki page, so that we can reach a consensus. 
9 3 Claudio Atzori
10 20 Andrea Dell'Amico
*Important:* a migration from subversion to git is in progress. A guide, provided by the gCube people, can be used for the D-Net projects too. 
11
Here a link to the main page: https://wiki.gcube-system.org/gcube/Source_Code_Management:_Gitea, here a page about managing and operating a repository, https://wiki.gcube-system.org/gcube/Git_Repositories, here a migration guide: https://wiki.gcube-system.org/gcube/Import_from_SVN
12
13 3 Claudio Atzori
h2. Coding
14
15 19 Claudio Atzori
Most of the D-Net modules have been migrated to from the old build system ant to maven. This implies some changes to the module directories and files. The starting point is the maven settings file describing the maven repository used when resolving module dependencies
16 1 Alessia Bardi
17 19 Claudio Atzori
<pre>
18
<?xml version="1.0" encoding="utf-8"?>
19
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
20
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
22
    http://maven.apache.org/xsd/settings-1.0.0.xsd">
23
    <servers>
24
        
25
        <server>
26
            <id>dnet45-releases</id>
27
            <username>{}</username>
28
            <password>{}</password>
29
        </server>
30
        <server>
31
            <id>dnet45-bootstrap-release</id>
32
            <username>{}</username>
33
            <password>{}</password>
34
        </server>
35
        
36
    </servers>
37
    
38
    <profiles>
39
        <profile>
40
            <id>dnet-bootstrap-profile</id>
41
            <activation>
42
                <activeByDefault>true</activeByDefault>
43
            </activation>
44
            <repositories>
45
                
46
                <repository>
47
                    <id>dnet45-bootstrap-snapshot</id>
48
                    <name>D-Net 45 Bootstrap Snapshot</name>
49
                    <url>http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-bootstrap-snapshot/</url>
50
                    <releases>
51
                        <enabled>false</enabled>
52
                    </releases>
53
                    <snapshots>
54
                        <enabled>true</enabled>
55
                    </snapshots>
56
                    <layout>default</layout>
57
                </repository>
58
                
59
                <repository>
60
                    <id>dnet45-bootstrap-release</id>
61
                    <name>D-Net 45 Bootstrap Release</name>
62
                    <url>http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-bootstrap-release/</url>
63
                    <releases>
64
                        <enabled>true</enabled>
65
                    </releases>
66
                    <snapshots>
67
                        <enabled>false</enabled>
68
                    </snapshots>
69
                    <layout>default</layout>
70
                </repository>
71
                
72
                <repository>
73
                    <id>dfm-releases</id>
74
                    <name>dfm-releases</name>
75
                    <url>http://maven.research-infrastructures.eu/nexus/content/repositories/dfm-releases/</url>
76
                    <releases>
77
                        <enabled>true</enabled>
78
                    </releases>
79
                    <snapshots>
80
                        <enabled>false</enabled>
81
                    </snapshots>
82
                    <layout>default</layout>
83
                </repository>
84
                
85
            </repositories>
86
        </profile>
87
    </profiles>
88
    <pluginGroups>
89
        <pluginGroup>org.apache.tomcat.maven</pluginGroup>
90
    </pluginGroups>
91
</settings>
92
93
</pre>
94
95 3 Claudio Atzori
Maven compliant D-Net module structure:
96
97
<pre>
98
.
99
├── pom.xml
100
├── src
101
│   ├── main
102
│   │   ├── java
103
│   │   │   └── eu
104
│   │   │       └── dnetlib
105
│   │   └── resources
106
│   │       └── eu
107
│   │           └── dnetlib
108
│   └── test
109
│       ├── java
110
│       │   └── eu
111
│       │       └── dnetlib
112
│       └── resources
113
│           └── eu
114
│               └── dnetlib
115
└── target
116
    └── classes
117
</pre>
118
119
Hint: consider to define the svn:ignore property, set on the module root
120
121
<pre>
122
cd <MODULE_NAME>
123
svn pe svn:ignore .
124
125
.classpath
126
.project
127
.settings
128
target 
129 1 Alessia Bardi
</pre>
130
131
h2. Branching
132
133 16 Alessia Bardi
It is always recommended to create a new branch when performing heavy changes to a module, rather than directly into trunk.
134 1 Alessia Bardi
Since branching and merging is usually a lot of pain, we can use this section to keep track useful commands:
135 16 Alessia Bardi
136 1 Alessia Bardi
* To merge the branch into trunk, you can follow this step by step tutorial: http://www.sepcot.com/blog/2007/04/SVN-Merge-Branch-Trunk
137 16 Alessia Bardi
* If you want to merge changes committed in one or more specific revisions of your branch into trunk, you can use the command:
138
@cd trunk@
139 19 Claudio Atzori
@svn merge -c revNumber -c anotherRevNumber https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/yourBranch@
140 14 Alessia Bardi
141 17 Alessia Bardi
h2. Revert to previous version
142
143
Because sometimes devs commit things that should not have been committed....
144
@svn merge -r HEAD:<goodRevision> <pathToFileTorevert>@
145
where @<goodRevision>@ is the revision number prior to the wrong commit of @<pathToFileTorevert>@
146
147 2 Claudio Atzori
h2. Use CI: trust Jenkins!
148 1 Alessia Bardi
149
The developer should clean the @.m2/repository/eu@ local repository from time to time to be sure that there are no modules installed locally. 
150
151
Modules should be downloaded from Nexus in order to properly resolve dependencies.
152
153 5 Alessia Bardi
h2. Maven dependencies
154
155
For information about version conflict resolution with Maven3:
156
* http://docs.codehaus.org/display/MAVEN/Versioning
157
* https://cwiki.apache.org/confluence/display/MAVEN/Maven+3.x+Compatibility+Notes
158
159
Generally speaking, we suggest to use the keyword @LATEST@ to refer to the last available artifact (snapshot or release) for a module.
160
Keep in mind that Maven3 considers:
161
@1.0-alpha-1 < 1.0-beta-1 < 1.0-SNAPSHOT < 1.0 < 1.1-SNAPSHOT@
162
163 6 Alessia Bardi
h3. How to change the version number of a snapshot?
164 1 Alessia Bardi
165
Depending on the kind of changes you can decide to increase the artifact version according to the following guidelines:
166
* BIG CHANGES impact the MAJOR version number. Ex. @0.0.1 --> 1.0.0@
167
** Examples of big changes are: updates to service interfaces, shared libraries, new functionalities.
168
* MINOR CHANGES impact the MINOR version number. Ex. @1.2.5 --> 1.3.0@
169
** Examples of minor changes are: service internals, non-shared code and libraries, important bug fixes.
170
* BUG FIXES impact the BUILD version number. Ex. @1.4.2 --> 1.4.3@
171
** Examples are small bug fixes that do not affect other components 
172
173 6 Alessia Bardi
h2. Release Best Practices
174
175
h3. When/Why releasing a module?
176
177
* Generally speaking a developer should release a module when the code is mature enough to be used by others. 
178
* An early release should be available in case others are relying on a module that is currently under heavy development (i.e., frequent commits that imply frequent snapshot updates), in order to avoid blocking other development activities.
179 7 Alessia Bardi
* Before updating an interface (e.g., service interfaces) or library (e.g., common and utilities modules) a developer MUST ENSURE there is a release of the current version.
180 6 Alessia Bardi
181 1 Alessia Bardi
h3. How to release?
182
183 13 Alessia Bardi
Note that the maven release plugin works fine with *Apache Maven 3.0.5* and that is the version that we suggest you to use.
184
To know which maven version you are using run: <pre>mvn -version</pre>
185
If you have a newer version (e.g. 3.2.3), then you'll get the error @Return code is: 400, ReasonPhrase: Bad Request@ when running @mvn release:perform@.
186
However +the jar should have been correctly deployed+: we strongly suggest you to check this is true by logging into our "Nexus":http://maven.research-infrastructures.eu/nexus.
187
188 1 Alessia Bardi
These are the steps for the release of a module, given that developer has a fresh checkout of the module to be released.
189 13 Alessia Bardi
190 11 Alessia Bardi
# Add the following at the beginning of your @~/.m2/settings.xml@:
191 8 Alessia Bardi
<pre>
192
<servers>
193
 <server>
194 18 Claudio Atzori
      <id>dnet45-releases</id>
195 8 Alessia Bardi
      <username>your LDAP username</username>
196
      <password>your LDAP password</password>
197
   </server>
198
</servers>
199
</pre>
200 7 Alessia Bardi
# Add the SCM info (change @{project.name}@ with the actual name of the project):
201 6 Alessia Bardi
<pre>
202
<scm>
203 18 Claudio Atzori
   <developerConnection>scm:svn:https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/{project.name}/trunk</developerConnection>
204 6 Alessia Bardi
</scm>
205
</pre>
206
# Set the parent to a released parent. Example:
207
<pre>
208
<parent>
209
   <groupId>eu.dnetlib</groupId>
210
   <artifactId>dnet-parent</artifactId>
211
   <version>1.0.0</version>
212
</parent>
213
</pre>
214 18 Claudio Atzori
# Ensure there are no snapshots included as dependencies. Snapshot dependencies won't be resolved anymore by maven because released parents have visibility only on the released repository (@dnet45-releases@). For example, if your module currently depends on 
215 6 Alessia Bardi
<pre>
216
<dependency>
217
	<groupId>eu.dnetlib</groupId>
218
	<artifactId>cnr-misc-utils</artifactId>
219
	<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
220
</dependency>
221
</pre>
222
You should change the dependency as follows:
223
<pre>
224
<dependency>
225
	<groupId>eu.dnetlib</groupId>
226
	<artifactId>cnr-misc-utils</artifactId>
227
	<version>[1.0.0,2.0.0)</version>
228
</dependency>
229
</pre>
230
Note that this implies that the dependency module (e.g. @cnr-misc-utils@) must have been released.
231 15 Alessia Bardi
# Commit the changes you made in the pom.xml 
232 6 Alessia Bardi
# Run @mvn release:prepare@ and answer the questions. Default answers are usually fine. This will:
233
#* copy your trunk into another svn folder (@tags@) 
234
#* update the versions in trunk and tags
235 18 Claudio Atzori
# Run @mvn release:perform@. This will deploy the artifact on Nexus in the release repository @dnet45-releases@.
236 8 Alessia Bardi
237 12 Alessia Bardi
If you experience any issue, open a ticket to CNR.