Seize the day

POST : SDP for win32/빌드,배포 자동화

자동 버전 올리기(auto increment build number)

버전 넘버(빌드 넘버)은 잘 관리할 필요가 있다. 버전을 올리는 작업은 자동 업데이트 서버를 위한 version.xml 파일과, 실행화일, 설치폴더에 놓이는 local 버전파일, 셋업파일의 버전, about창에 노출되는 버전 표기 등 여러군데를 수정하여야 한다. 수 작업으로 수정할 경우 실수의 가능성도 있는데 최악의 경우 자동 업데이트 체크가 되지 않는 수도 생긴다. 버전 올리는 작업은 스크립트를 이용해서 자동화하는 것이 중요하다.


*.rc 파일에 버전을 자동으로 증가 시켜주면서

    _version.h : about창에 노출되는 버전 

    _version.nsh : NSIS 셋업에 노출되는 버전

    _version.bat :  빌드 스크립트에서 파일명 생성에 사용

     version.xml  : local설치폴더, 서버 업데이트체크를 위한 파일

파일을 자동으로 생성한다. 


루비를 배우고 있기에 루비를 이용해서 스크립트를 만들었다. 

auto_incre_version.rb :

option = {}


# cmdline option parse

p ARGV.length

ARGV.each { |o|

k,v = o.split('=')

option [k] = v;


#p o

}



# target rc

path = option["/rc"]

synconly = option["/synconly"]


filecontent = File.readlines(path)


new_filecontent = []

new_version = ''


# const

FILEVERSION = " FILEVERSION "

PRODUCTVERSION = " PRODUCTVERSION "

VALUE_FILEVERSION = '            VALUE "FileVersion", '

VALUE_PRODUCTVERSION = '            VALUE "ProductVersion", '


filecontent.each do |line|

if line.start_with?(FILEVERSION) || line.start_with?(PRODUCTVERSION)

#p line

index = line.rindex(' ')

left = line[0..index]

right = line[index+1 .. -1]


version = right.strip.split(',')

if synconly == nil

version[3] = (version.last.to_i + 1) . to_s

end


right  = "%s,%s,%s,%s\n" % version

line = left + right


new_version = "%s.%s.%s.%s" % version

end


if line.start_with?(VALUE_FILEVERSION) || line.start_with?(VALUE_PRODUCTVERSION)

#p line

index = line.rindex(' "')

left = line[0..index]

right = line[index+2 .. -1]

#p right


version = right.split(',')

version.map { |a| a.strip! }

version[3] = (version.last.to_i + 1) . to_s


#p version


right  = "\"%s, %s, %s, %s\"\n" % version

#p right

line = left + right

#p line

end


new_filecontent.push(line)

end


#write new .rc

if synconly == nil

File.write(path+"", new_filecontent.join() );

p "now new version is #{new_version}"

else

p "current version is #{new_version}"

end




url = "http://mdiwebma.com/easyregistry/"


nsh = option["/nsh"]

bat = option["/bat"]

h   = option["/h"]

xml = option["/xml"]


if nsh != nil then 

File.write(nsh, "!define _APP_VERSION \"#{new_version}\"\n") 

p nsh

end


if bat != nil then

File.write(bat, "set PROJ_VERSION=#{new_version}\n")

p bat

end


if h != nil   then

File.write(h, "#pragma once\n#define PROJ_VERSION \"#{new_version}\"\n")

p h

end


if xml != nil then

File.write(xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n<version>#{new_version}</version>\n<url>%s</url>\n</root>" % url)

p xml

end



rb파일을 실행하는 bat 파일

auto_incre_version.cmd:

".\ruby200\bin\ruby.exe"  auto_incre_version.rb "/rc=%cd%\..\src\EasyRegistry\EasyRegistry.rc"  "/nsh=%cd%\_version.nsh"  "/bat=%cd%\_version.bat" "/xml=%cd%\version.xml" "/h=%cd%\..\src\EasyRegistry\_version.h"  "%1%"




실행결과는

D:\NewProject\SDP_for_win32\build>".\ruby200\bin\ruby.exe"  auto_incre_version.r

b "/rc=D:\NewProject\SDP_for_win32\build\..\src\EasyRegistry\EasyRegistry.rc"  "

/nsh=D:\NewProject\SDP_for_win32\build\_version.nsh"  "/bat=D:\NewProject\SDP_fo

r_win32\build\_version.bat" "/xml=D:\NewProject\SDP_for_win32\build\version.xml"

 "/h=D:\NewProject\SDP_for_win32\build\..\src\EasyRegistry\_version.h"  ""

6

"now new version is 1.0.0.2"

"D:\\NewProject\\SDP_for_win32\\build\\_version.nsh"

"D:\\NewProject\\SDP_for_win32\\build\\_version.bat"

"D:\\NewProject\\SDP_for_win32\\build\\..\\src\\EasyRegistry\\_version.h"

"D:\\NewProject\\SDP_for_win32\\build\\version.xml"


생성되는 결과물은 아래와 같다.


_version.bat

set PROJ_VERSION=1.0.0.2

_version.nsh

!define _APP_VERSION "1.0.0.2"

version.xml

<?xml version="1.0" encoding="UTF-8" ?>
   <root>
   <version>1.0.0.2</version>
   <url>http://mdiwebma.com/easyregistry/</url>

</root>

_version.h

#pragma once

#define PROJ_VERSION "1.0.0.2"



xml이 파싱해야 하는 부담이 있어서, 경우에 따라서는  ini 파일을 생성하는 옵션을 간단히 추가하는 것도 가능하다. 


예전에는 이 기능을 exe 파일을 이용하여 직접 구현을 했었고, 파이선을 배울때는 파이선을 이용하여 구현하여 웹마 프로젝트에서 아직도 사용하고 있다. 


incre_build.py

#

# rc파일에서 build를 넘버를 증가시킨다.

#


import os

import sys

import shutil

import time


FILEVERSION = " FILEVERSION "

PRODUCTVERSION = " PRODUCTVERSION "

VALUE_FILEVERSION = '            VALUE "FileVersion", '

VALUE_PRODUCTVERSION = '            VALUE "ProductVersion", '


def touchrc(rcpath, rcout) :

new_version = ''

tlb_found = 0

try :

f = open(rcpath)

lines = f.readlines()

f.close()

f = open(rcout, 'w')

for l in lines :

if l.find('1 TYPELIB "WebMaP.tlb"') == 0 :

tlb_found = 1

if l.find(FILEVERSION) == 0 or l.find(PRODUCTVERSION) == 0 :

tokens = l.split(',')

i = len(tokens)-1

num = int(tokens[i])

num += 1

tokens[i] = str(num)+'\n'

l = ','.join(tokens)

v_list = l.split(' ')

new_version = v_list [ len(v_list)-1]

new_version = new_version.rstrip('\n')

new_version = new_version.replace(',','.')

if l.find(VALUE_FILEVERSION)==0 or l.find(VALUE_PRODUCTVERSION)==0:

tokens = l.split('.')

i = len(tokens)-1

t_list = tokens[i].split('"')

num = int ( t_list[0] )

num += 1

tokens[i] = str(num) + '"\n'

l = '.'.join(tokens)


f.write(l)

f.close()

except Exception, e:

print e

return ''

if tlb_found == 0 :

print 'tlb file not found !! '

sys.exit(1)

return new_version

def main(rc, h, nsh) :

#rc파일의 버전을 올린다.

rcpath = os.path.abspath(rc)

rcout  = rcpath + ".incre"

ver = touchrc( rcpath, rcout )

if ver == '':

print 'build incrment failed !!'

sys.exit(1)

bakdir = os.path.abspath('.rcbak')

if not os.path.exists(bakdir) :

os.mkdir(bakdir)

timestr = str(time.localtime())

timestr = timestr.lstrip('(');

timestr = timestr.rstrip(')');

timestr= timestr.replace(', ','_')

filename = 'WebmaP4(%s).rc.' % timestr

shutil.copy(rcpath, os.path.abspath('.rcbak')+"\\" + filename )

shutil.move(rcout,rcpath)

#헤더파일을 쓴다.

try :

f = open( os.path.abspath(h), 'w')

f.write('#define MY_VERSION _T("%s")\n' % ver)

f.close()

#ver = ver.replace('.', '_')

f = open( os.path.abspath( nsh ), 'w')

f.write ( '!define _VERSION "%s"' % ver)

f.close()

f = open( os.path.abspath( '_version.bat' ), 'w')

f.write ( 'set WMVERSION=%s' % ver)

f.close()

except Exception, e:

print e

sys.exit(1)

print '[ OK ] Buil bumber increment : %s' % ver

if __name__ == "__main__" :

if len(sys.argv) != 4 :

print 'parameter error : rcfile headerfile nshfile'

print 'len(argv) %d' % len(sys.argv)

print sys.argv

sys.exit(1)

main(sys.argv[1], sys.argv[2], sys.argv[3])

sys.exit(0) # Succ!!



프로젝트 소스코드:

http://dev.naver.com/projects/sdp


다음에는 이것을 이용해서 자동 업데이트 체크를 구현해 보겠다. 




top

posted at

2013. 8. 22. 00:33


CONTENTS

Seize the day
BLOG main image
김대정의 앱 개발 노트와 사는 이야기
RSS 2.0Tattertools
공지
아카이브
최근 글 최근 댓글
카테고리 태그 구름사이트 링크