Collaborative Software Development Model By Git Repository

Distribution feature of git repository gives leverage to scrum team to work in collaborative manner. Additionally, git with agile can give continuous development, testing and delivery.

Further more, we could separate out work by public-private repository based on developer role/responsibilities which aids to mitigate dispute among developers

Last but not the least, team could have their own unique work flow for development, testing and delivery

Here we go with an example, we have scrum team having below members for an example

  • UI/UX developer – (DEV1)
    • Responsibility to develop only front-end and integrate API
    • Can only pull API developer’s public repository in his/her private repository
  • API developer – (DEV2)
    • Responsibility to develop REST API based on UI/UX requirement
    • Can only pull UI/UX developer’s public repository in his/her private repository
  • Lead
    • Lead can only read both API and UI/UX developer public repository in his/her private repository
    • Push his/her separate work (e.g. configuration, static pages, etc..)
    • Does unit testing, engage API and UI/UX developers for fixes or change before giving it to QA
    • Lead can only push things on central server repository
  • QA / Tester
    • Only read Lead’s public repository in his/her private repository and do 360 degree testing

High level picture for this work flow 


 

git_dist_workflow

Auto Build & Prepare Release

If team use Agile (Scrum) sprint for development and use git as repository then team can easily make strategy of auto build and release

# Strategy
1 keep master and sprint related branches on separate line
2 keep sql changes separate in sprint specific folder under DBChanges


# Solution
Pretty simple logic,  first get changed list of files by executing diff command of git between master and any sprint specific branch. After getting this files we are going to create release folder and after that copy-paste files changed in sprint. Moreover, we explicitly copy-paste content of bin folder and DBChanges folder mentioned in setting file


# Core command is git command which gives list of changed files in development branch

git checkout sprint1
git diff --name-only master 

# First, we are going to create setting file that has file ignore pattern, folder to get content of bin and last but not lease DBChange folder to get database related changes
>>> See Settings.xml

<Settings>
    <!-- Ignore file types while making release -->
    <ignore>.vb|.config|.vbproj|aspnet_client</ignore>    
    <!-- NOTE: Build should have project folders having bin sub-folder and need to be given in release -->
    <build>
        <folders>
            <folder>XYZRootWebApp</folder>
            <folder>XYZApp</folder>
        </folders>
    </build>    
    <!-- Location Of SQL Folder & Keep SQL Folder At The Same Level Of Solution -->
    <sql>        
        <folder>DBChanges</folder>        
    </sql>
</Settings>

# Second we start with powershell file which covers below code
1. Checkout and pull master branches
2. Load setting file
3. Checkout and pull development branch
4. Build solution
5. git diff command to get change file list
6. copy-paste change file list
7. copy-paste content of bin folder mentioned in setting file
8. copy-paste sql files

>>> See repareRelease.ps1

#---
# 1. Checkout and pull masters
#---
$cmdOutput=""
$cmdOutput = git checkout master -f 2>&1
if($cmdOutput -match 'error|conflict') {
    $cmdOutput
    exit
}

$cmdOutput=""
$cmdOutput = git pull 2>&1
if($cmdOutput -match 'error|conflict') {
    $cmdOutput
    exit
}

#---
# Terminate Script If There is no arg
#---
if(!$args) {
    write-host "Please enter branch name" -foreground "red" 
    exit
}

#---
# SET Branch
#---
$branch = $args[0]

#---
# Terminate Script If branch is not existsls
#---
$cmdOutput=""
$cmdOutput = git checkout $args[0]  -f 2>&1
if($cmdOutput -match 'error|conflict') {
    $cmdOutput
    exit
}

#---
# 2. load setting file and ignore folder
#---
#$build_folders = ('XYZRootWebApp','XYZWebApp')
#$ignore_pattern = '.vb|.config|.vbproj|aspnet_client'

[xml]$ConfigFile = Get-Content ".\Settings.xml"

#NOTE: Build should have project folders having bin sub-folder and need to be given in release
$build_folders = @()  # NOTE: list of folder 
$build_folders = $build_folders + $ConfigFile.Settings.build.folders.folder | Foreach-Object { $_}
if([int]$build_folders.length -eq 0) 
{
    write-host "Enter Valid Build Folders"  -foreground "red" 
    exit
}

# Ignore file types while making release
$ignore_pattern = $ConfigFile.Settings.ignore
if($ignore_pattern -eq '') 
{
    write-host "Enter Valid Ignore File Pattern"  -foreground "red" 
    exit
}

$sql_folder = $ConfigFile.Settings.sql.folder
if($sql_folder -eq '') 
{
    write-host "Enter Valid SQL Folder Path"  -foreground "red" 
    exit
}

#---
# sprint name 
#---
$sprint = $branch

#---
# 3 checkout and pull development branch
#---
git checkout -f $sprint
#git pull
$cmdOutput=""
$cmdOutput = git pull 2>&1

if($cmdOutput -match 'error|conflict|fatal') {
    $cmdOutput
    exit
}

#---
# collection projects that affected
# Purpose: move bin after build
#---
$projects = @()
$flag = 0
git diff --name-only master |  % {
    if($_.split('/')) {
       $_.split('/')[0]
    }
} | Sort-Object -Unique | %{     
    $file_path = $_        
    $flag=0
    $build_folders | Foreach-Object {
        if($file_path -match  $_) {
            $flag=1
        }
    } 
    if($flag -eq 1 ) {
        $projects = $projects + $_ 
    }    
}

#---
# 4. Build Projects and Solution
#---
msbuild ..\XYZSln.sln /t:Clean

$cmdOutput=""
$cmdOutput = msbuild ..\XYZSln.sln /t:Rebuild /p:WarningLevel=0 /p:Configuration=Release /clp:ErrorsOnly  2>&1
if($cmdOutput -match 'error') {    
    write-host $cmdOutput -foreground "red"     
    exit
}

#---
# build path
#---
$build_path = ".\" + $sprint

#---
# remove build folder if exists
#---
if(Test-Path -Path $build_path ) {
    Remove-Item $build_path -Force -Recurse
}

#---
# 5. git diff command to get change file list
# 6. copy paste change file list
#---
$flag = 0
git diff --name-only master | Foreach-Object {
    if($_ -notmatch $ignore_pattern) {       
        $file_path = $_
        $flag=0
        $build_folders | Foreach-Object {
            if($file_path -match  $_) {                
                $flag=1
            }
        }                
        if($flag -eq 1 ) {            
           $newfile=$build_path + "\" +  $_.replace("/","\") # OLD
           New-Item -ItemType File -Path  $newfile  -Force  # OLD           
        }        
    }
}

$flag = 0
git diff --name-only master | Foreach-Object { 
    if($_ -notmatch $ignore_pattern) {        
        $file_path = $_        
        $flag=0
        $build_folders | Foreach-Object {
            if($file_path -match  $_) {
                $flag=1
            }
        }          
        if($flag -eq 1 ) {        
            $source =  "..\" + $_.replace("/","\") # OLD
            $destination =   $build_path + "\" +  $_.replace("/","\")   # OLD  
            Copy-Item $source $destination -Force  # OLD            
        }        
    }
}

#---
# 7. copy paste content of bin folder mentioned in setting file
#---
$projects | % {
    $destination =   $build_path + "\" +  $_.replace("/","\")   + "\bin"    
    if(Test-Path -Path $destination ) {
        Remove-Item $destination -Force -Recurse
    }
}

$projects | % {        
    $source =  "..\" + $_.replace("/","\") + "\bin\*"
    $destination =   $build_path + "\" +  $_.replace("/","\")   + "\bin"    
    if(Test-Path -Path $destination ) {
        Remove-Item $destination -Force -Recurse
    }    
    if (!(Test-Path -Path $destination)) {
        New-Item $destination -Type Directory
    }
    Copy-Item $source -Destination $destination                
}

#---
# 8.copy paste sql files
#---
# Source Location /SQL/sprint{N}/*.sql
$source =  "..\" + $sql_folder + "\$sprint\*"
$destination =   $build_path
if(Test-Path -Path $source) {
    Copy-Item $source -Destination $destination
}

write-host "`n`n--------------------------------------" -foreground "magenta" 
write-host ">> " $args[0] "is ready !!!" -foreground "magenta" 
write-host "--------------------------------------" -foreground "magenta" 

#---
# TODO ZIP of build
#---

# Third, we make batch file for user facing
Ask which sprint to build and release
>>> See AutoRelease.bat

:: Enter Branch Name
set /p branch="Enter Branch Name: "

:: Execute ps1 file and pass parameters
Powershell.exe -executionpolicy remotesigned -File prepareRelease.ps1 %branch%

:: To keep console open
PAUSE

🙂 Here is entire code and can be scalped further as need of different team !!!
Git Hub AutoBuildRelease