AEM - Source Code, Code Reviews, Build and Release Management

Goal


Every other's SCM is icky. So you may find the following process lengthy, confusing and lead to the decision, let's continue with the way it is - and that is fine given the nature of project.

Here is a process (not fork based) on setting up the project source code GIT repo in Bit Bucket (free for 5 users), Source Tree GIT Client, Git Flow for Branch Management and creating Releases, Hotfixes, in a collaborative environment. Configuring Jenkins for Continuous Integration is discussed here

The process discussed below is based on GIT Flow and suggests creating 5 type of branches

                         Development branch -  develop
                         Production branch - master
                         Feature branches - prefixed with feature/
                         Release branches - prefixed with release/
                         Hotfix branches - prefixed with hotfix/

Solution


Create Repository in BitBucket

1) Sign up for creating a Repository. The admin, for example, experience.aem@gmail.com (username: eaem) signs up and creates a repo by clicking Create -> Create repository

2) Enter project name - experience-aem-intranet and other necessary details





Clone Repository

1) Create a local clone by accessing https://bitbucket.org/eaem/experience-aem-intranet/overview clicking on Clone in Source Tree




2) In Source Tree, enter local directory path, click Clone



3) Master branch clone gets created on the file system and bookmarked in source tree



4) If you are using multiple bitbucket accounts in source tree, add the credentials in experience-aem-intranet repo settings




Initialize Repo with GITFlow

1) Create an empty file, eg. readme.txt in local repo - C:\dev\code\projects\cq6-extensions\experience-aem-intranet\readme.txt; commit and push, to create local & remote (origin) master branch



2) Using GIT Flow gives a neat, standardized approach; streamlines the entire release process and works well in collaborative environments. The next step is to initialize repo experience-aem-intranet with GIT Flow



      Branch develop gets created



      Push the created masterdevelop branches to origin




3) The significance of master branch is, it contains released/deployed codebase (the one installed on production). develop branch contains feature code, bug fixes. Quality Assurance team should generally get their deployments built out of develop branch, for feature testing.

So its good to have some write access control on master and develop branches to avoid accidental checkins, make it a policy to review any code ready for QA or Production. In this example, the project admin eaem acts as reviewer. The job of a reviewer is to make sure feature/bugfix code submitted for review is clean, conventions followed, proper commenting added, any best practices internally are followed etc...

4) For code review process, set access restrictions on master and develop branches by accessing bitbucket https://bitbucket.org/eaem/experience-aem-intranet/admin



5) This being a private repository, only team members should be allowed to access source code for feature development. For this example, lets add user nalabotu - https://bitbucket.org/eaem/experience-aem-intranet/admin/access




Create New AEM Bundle

1) Admin of experience-aem-intranet eaem creates new module intranet-portal (remove line breaks in the below command) using archetype https://github.com/Adobe-Marketing-Cloud/aem-project-archetype

C:\dev\code\projects\cq6-extensions\experience-aem-intranet>"C:\Program Files\Java\jdk1.7.0_25\bin\java" -Dmaven.home=C:\dev\code\install\apache-maven-3.1.0 -Dclassworlds.conf=C:\dev\code\install\apache-maven-3.1.0\bin\m2.conf -Dfile.encoding=UTF-8 -classpath C:\dev\code\install\apache-maven-3.1.0\boot\plexus-classworlds-2.4.2.jar org.codehaus.classworlds.Launcher --fail-fast --lax-checksums -DinteractiveMode=false 
-DgroupId=com.experienceaem.intranet 
-DartifactId=intranet-portal 
-Dversion=1.0-SNAPSHOT 
-DarchetypeGroupId=com.adobe.granite.archetypes 
-DarchetypeArtifactId=aem-project-archetype 
-DarchetypeVersion=10 
-Dpackage=com.experienceaem 
-DappsFolderName=experienceaem-intranet 
"-DartifactName=Experience AEM Intranet Portal" 
"-DcomponentGroupName=Experience AEM" 
-DcontentFolderName=experience-aem-intranet 
-DcssId=experience-aem 
"-DpackageGroup=Experience AEM" 
"-DsiteName=Experience AEM Intranet" org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate


2) The project module experience-aem-intranet\intranet-portal in IDE



3) Install module package using mvn -PautoInstallPackage clean install and a sample page http://localhost:4502/content/experience-aem-intranet/en.html should become available



4)  Add target (folder name) to C:\dev\code\projects\cq6-extensions\experience-aem-intranet\.gitignore, as folders generated via build are not needed in repository

5) The current branch is develop (if it isn't double click to switch to develop ), commit and push the code to origin develop branch



6) At this point the module Intranet Portal is available for feature development


Feature Development (Bug Fixing)

1) Say a new feature story is assigned to user nalabotu (developing on MAC). User starts development by creating a feature branch feature/EAEM-users-json-servlet-sreek  (<Project-Name>-<Brief-Description>-<Username>)





2) Code the servlet com.experienceaem.core.servlets.GetUsersJSON, test it by accessing http://localhost:4502/bin/experience-aem/users.json, commit and push from local feature branch to origin (select create pull request)



   Before creating the pull request make sure you pull changes from remote develop and merge the latest develop changes into feature branch. It's a good practice to merge latest code into feature branches daily or should do it atleast before creating a pull to develop request, test and make sure feature changes are working ok, with latest develop code

3) The remote branch should have been created - feature/EAEM-users-json-servlet-sreek

4) In Step 2, user has selected Create pull request while committing; a browser tab with create pull request opens, make sure the feature to be merged is on left and destination develop on right, select the reviewer eaem, click Create pull request (pull request gets created and email sent to reviewers)



5) In regular GIT Flow, developer clicks Finish feature in source tree and the feature branch gets merged to local develop, which can then be pushed to origin develop. For review process, admin eaem has push restrictions enabled on develop and master, so Finish feature is not going to work here, as the developer nalabotu with no write access to remote develop, cannot push the local develop changes. Doing so will result in following error; so when the developer is done with coding a feature, he/she can simply delete the branch (instead of clicking Finish feature), after creating the pull request and it gets merged to develop branch by reviewer.






Review Process - admin eaem

1) User eaem, clicks on the review link in email notification, adds a comment (developer nalabotu is notified by email)



Incorporate Review Comments - dev nalabotu

1) Developer implements review comments, commits, pushes & creates a pull request as explained above; the pull request created earlier gets updated with latest changes





Reviewer merges the changes - eaem

1) Reviewer eaem is happy with the implementation, clicks Merge to pull in the feature changes into develop. At this point the feature is ready for testing by quality team



2) Hooks can be configured in bitbucket on branches (develop, master etc.) to kickoff build and deploy packages to test CQ servers, when any changes are pulled into develop branch (For Continuous Integration check this post)


Creating Release

1) When feature development/testing is done and code is all set to move to production, the project admin (or any user with necessary permissions on develop, master and release branches) uses GIT Flow -> Create release to create a release, say v1.1.0 (based on develop)





2) Make the necessary version changes in pom.xml, 1.1.0 (following the <Major>.<Minor>.<Patch> convention) test on local CQ, commit and push the changes to origin. Some use even/odd convention, even number in minor for release and odd number for development, but for pre-release or development, -SNAPSHOT can be used in version; so 1.2.3-snapshot would be a lower version number than 1.2.3, for more information check this post)



3) The release branch release/v1.1.0, created in origin (remote)...



4) Click Finish Release to create the release and tag it with some message





5) The release changes (versions in pom.xml) are merged to master and develop branches. Push to origin...




6) Switch to master branch, build and do some smoke testing on local CQ. Upload the deployment package to a centralized location for Production deployment. Develop branch has latest code and Master branch has code deployed to Production. 


Prepare Develop for Next Iteration

1) Release 1.1.0 was created, code was promoted to master, its time to prepare develop for next set of features

2) Project admin eaem, switches to develop branch and makes changes to version number in pom.xml , 1.2.0-SNAPSHOT (So the next release is 1.2.0). Commit and Push to Origin



3) Send an email to developers to merge the latest develop changes into their feature branches to update them with latest version numbers


Production Bugs HotFixes

1) If you need to patch the latest release without picking up new features from the development branch, you can create a hotfix branch from the latest deployed code in master. Once you’ve made your changes, the hotfix branch is then merged back into both the master branch (to update the released version) and the development branch (to make sure the fixes go into the next release too)

2) Say the servlet GetUsersJSON coded by developer nalabotu, has a bug. It was supposed to return userids and not user node paths; the bug was assigned to developer(admin) eaem.

3) Project admin eaem setups a hotfix branch by using GIT Flow -> Start New HotFix



4) Say every end of month, bug fixes are promoted to production via hot fix branch. Name the hotfix may-bug-fixes. Hotfix branches are always based on master (production code)



5) Developers working on production bugfixes do not create feature branches. Fetch hotfix branch and bug fixes from all developers are pushed to one hotfix branch, here it's may-bug-fixes. Quality team creates a build out of hotfix branch, verifies fixes for sign-off.

6) Developer eaem fixes the servlet and pushes code to origin hotfix branch (similarly over the next few days, developers working on production bugs, sync hotfix branch, fix bugs and push the code to remote hotfix branch)



7) When the fixes are tested and ready to move to production, project admin, here eaem, or any developer having write permissions on master and develop branches, finishes the hotfix by clicking Git Flow -> Finish Hotfix





8) The hotfix branch gets merged back into master and develop branches. Push the changes, if there are any merge conflicts (say the same lines of code were modified in develop as well), resolve the conflicts...



9) Switch to master, generate the deployment packages, smoke test and upload the packages to a centralized location for deployment team

10) When the hotfix is finished, the bug fixes for production are automatically pulled (merged) into develop branch and available in next feature releases as well.



2 comments:

  1. Github is a new source repository. Do code management, code review, host private projects all at one place

    ReplyDelete
  2. Nice post... I am using open source code review tools and this tool is beneficial to all developers, managers and architects. Thanks for sharing

    ReplyDelete