I have configured the build for liquibase deployment and release publish to artifact.
Deployment is success but release is failing in teamcity whilest release is success from my local machine.
this is ths build.gradle file:
group = 'com.db.calico'
apply plugin: 'net.researchgate.release'
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'liquibase'
apply plugin: 'org.liquibase.gradle'
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'com.jfrog.artifactory'
import groovy.util.XmlSlurper
import groovy.xml.XmlUtil
import groovy.sql.Sql
def newVersion
def deploymentID
buildscript {
repositories {
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_libs_release_url}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_libs_snapshot_url}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
//url "${repo_mvn_public_local}"
url "${repo_mvn_external}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_plugin_relase}"
}
}
dependencies {
classpath("net.researchgate:gradle-release:2.4.1")
classpath("org.liquibase:liquibase-gradle-plugin:2.0.1")
}
}
release {
buildTasks = []
tagTemplate = '$version'
versionPropertyFile = 'gradle.properties'
git {
requireBranch = 'feature/TAPP-3171-Liquibase-DB_Deploy'
pushToRemote = 'origin'
pushToCurrentBranch = true
}
failOnCommitNeeded = false
failOnPublishNeeded = false
preCommitText = 'Calico DB: Commiting Release version - $tagTemplate'
preTagCommitMessage = 'Calico DB: Pre Tagging for release'
tagCommitMessage = 'Calico DB: Tagging for release'
newVersionCommitMessage = 'Calico DB: Upgrading the version'
}
// afterReleaseBuild.dependsOn(':packageDistribution')
beforeReleaseBuild.dependsOn(':publish')
allprojects {
repositories {
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_libs_release_url}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_libs_snapshot_url}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
//url "${repo_mvn_public_local}"
url "${repo_mvn_external}"
}
maven {
credentials {
username "${repo_username}"
password "${repo_password}"
}
url "${repo_mvn_plugin_relase}"
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
dependencies {
liquibaseRuntime 'org.liquibase:liquibase-gradle-plugin:2.0.1'
liquibaseRuntime 'org.liquibase:liquibase-groovy-dsl:2.0.2'
liquibaseRuntime 'org.liquibase:liquibase-core:3.6.1'
liquibaseRuntime 'com.oracle:ojdbc8:12.2.0.1'
// liquibaseRuntime 'mysql:mysql-connector-java:5.1.45'
// liquibaseRuntime 'org.mariadb.jdbc:mariadb-java-client:2.2.5'
}
liquibase {
mainClassName 'org.liquibase.gradle.OutputEnablingLiquibaseRunner'
activities {
DEV {
changeLogFile 'liquibase/changelog.xml'
url 'jdbc:oracle:thin:@nycal3d.us.db.com:1825/nycal3d_app.us.db.com'
username "${DB_USERNAME}"
password "${DB_PASSWORD}"
}
UAT {
changeLogFile 'liquibase/changelog.xml'
url 'jdbc:oracle:thin:@nycal4u.us.db.com:1700/nycal4u_app.us.db.com'
username "${DB_USERNAME}"
password "${DB_PASSWORD}"
}
PROD {
changeLogFile 'liquibase/changelog.xml'
url 'jdbc:oracle:thin:@nycal4p.US.DB.COM:1600/nycal4p_app.us.db.com'
username "${DB_USERNAME}"
password "${DB_PASSWORD}"
}
}
runList = project.ext.runList
}
publishing {
repositories {
maven {
credentials {
username "${project.version.endsWith('-SNAPSHOT') ? repo_username : repo_releaser}"
password "${project.version.endsWith('-SNAPSHOT') ? repo_password : repo_releaser_password}"
}
url "${project.version.endsWith('-SNAPSHOT') ? repo_mvn_libs_snapshot_url : repo_mvn_libs_release_url}"
}
publications {
mavenJava(MavenPublication) {
groupId 'com.db.calico'
version "${version}"
from components.java
artifact("$buildDir/dist/${version}.7z")
}
}
}
}
// default gradle publish task depends on packageFistribution task
publish.dependsOn(':packageDistribution')
/**
* packageDistribution task is for coping all files and folders from root directory and
* version name folder which already specified in gradle.properties and will create .7z
* zip file will all contents will place it in build directory of dist folder
*
**/
task packageDistribution(type: Zip) {
description 'package distribution task to take folder as input with version prefixed by release- and make its zip and will place it into build directory'
doFirst {
println 'packaging task started'
}
from "$rootDir/src/release/${version}"
include '*'
include '*/*' // to incude contents of a folder present inside given directory
archiveName "${version}.7z"
destinationDir(file("$buildDir/dist"))
doLast {
println 'package distribution task exection end'
}
}
/**
* here we marking dependency of versionFolderCheck on packageDistribution task
* before execution of packageDistribution taks versionFolderCheck task will execute
**/
packageDistribution.dependsOn(':versionFolderCheck')
/**
* versionFolderCheck Task to check version folder should exists in root directory for application
* and if version folder which contents compile scripts which would be deployed on production if not exists then
* this task will throw exception and build will be failed
**/
task versionFolderCheck {
doFirst {
println "********** ${newVersion} **********"
println "Looking for ${version} folder in $rootDir directory"
}
doLast {
def folder = new File("$rootDir/src/release/${version}");
def isExists = folder.exists();
// checking for directory not exists
if(!isExists) {
// and if not exists throwing exception and build will fail
def errorMessage = "Folder not exists ${version} in $rootDir directory";
println errorMessage;
throw new Exception(errorMessage);
}
if(isExists) {
println "Folder exists ${version} in $rootDir directory"
}
println 'version folder check task end'
}
}
// versionFolderCheck.dependsOn(':input')
// task input {
// def console = System.in.newReader()
// if(console) {
// println "Last version is ${version} please input latest version"
// newVersion = console.readLine()
// println "Latest version is ${newVersion}"
// } else {
// logger.error "Can not get console"
// }
// }
// Task to copy files into test folder and replace their extension with .sql
// **********************************************************************************************
task toSql(type: Copy) {
description = 'Copies and renames file to .sql after reading from changelog'
def getChangesetsFromChangeLogs = {changelogPath ->
def xmlSource = new File(changelogPath)
def xml = new XmlParser().parse(xmlSource)
def names = [], sqlFileName, sqlRollbackFileName
xml.changeSet.each {
if(!it.sqlFile.isEmpty()){
sqlFileName =it.sqlFile[0].'@path'
println sqlFileName
}
names.add(sqlFileName)
if(!it.rollback.sqlFile.isEmpty()){
sqlRollbackFileName =it.rollback.sqlFile[0].'@path'
println sqlRollbackFileName
}
names.add(sqlRollbackFileName)
}
println names
return names
}
def fileExist = { fileName ->
def file = new File("$rootDir/"+fileName);
def isExists = file.exists();
// checkingif file does not exists
if(!isExists) {
// and if it does not exists throwing exception and build will fail
def errorMessage = "Provided sql file $fileName does not exist";
println errorMessage;
throw new Exception(errorMessage);
}
}
def copyFiles = {changelogPath->
def sourceFile = getChangesetsFromChangeLogs(changelogPath)
sourceFile.each {
if(it != null){
fileExist(it)
from "$it"
into "test/"
def path = "$it".tokenize('/')
def file = path[path.size()-1]
def (name,extension) = file.tokenize(".")
rename(file, name + '.sql')
}
}
}
println "Inside toSql"
def changeLogFiles = [
'calico_ddl_changelog.xml',
'calico_dml_changelog.xml',
'calico_functions_changelog.xml',
'calico_package_body_changelog.xml',
'calico_package_spec_changelog.xml',
'calico_procedures_changelog.xml',
'calico_sequences_changelog.xml',
'calico_tables_changelog.xml',
'calico_triggers_changelog.xml',
'calico_types_changelog.xml',
'calico_views_changelog.xml',
'calico_grants_changelog.xml'
]
changeLogFiles.each {
copyFiles("OracleSourceCode/liquibase/changelog_directory/" + "$it")
}
}
// Task to update changelog file extensions to .sql in changesets
// ******************************************************************************************
task modifyXml {
def changeFileAttributeInChangesets = { changeLogFile->
def xmlSource = new File(changeLogFile)
def xml = new XmlParser().parse(xmlSource)
def sqlFileName, sqlRollbackFileName
xml.changeSet.each {
if(!it.sqlFile.isEmpty()){
sqlFileName =it.sqlFile[0].'@path'
println sqlFileName
def (path, extension) = sqlFileName.tokenize('.')
def fileLocation = path.tokenize("/")
def fileName = fileLocation[fileLocation.size()-1]
def sqlFile = 'test/' + fileName + '.sql'
it.sqlFile[0].'@path' = sqlFile
}
if(!it.rollback.sqlFile.isEmpty()){
sqlRollbackFileName =it.rollback.sqlFile[0].'@path'
println sqlRollbackFileName
def (rpath, rextension) = sqlRollbackFileName.tokenize('.')
def rfileLocation = rpath.tokenize("/")
def rfileName = rfileLocation[rfileLocation.size()-1]
def rsqlFile = 'test/' + rfileName + '.sql'
it.rollback.sqlFile[0].'@path' = rsqlFile
}
xmlSource.text = XmlUtil.serialize(xml)
}
}
doLast{
println ("Inside modify xml")
def changeLogFiles = [
'calico_ddl_changelog.xml',
'calico_dml_changelog.xml',
'calico_functions_changelog.xml',
'calico_package_body_changelog.xml',
'calico_package_spec_changelog.xml',
'calico_procedures_changelog.xml',
'calico_sequences_changelog.xml',
'calico_tables_changelog.xml',
'calico_triggers_changelog.xml',
'calico_types_changelog.xml',
'calico_views_changelog.xml',
'calico_grants_changelog.xml'
]
changeLogFiles.each {
changeFileAttributeInChangesets("OracleSourceCode/liquibase/changelog_directory/" + "$it")
}
}
}
modifyXml.dependsOn(':toSql')
liquibaseUpdate.dependsOn(':modifyXml')
// Task to insert database changelog into changelog audit table
// ******************************************************************************************
task insertChangelogInAuditAfterLiquibaseDeploy{
def createSqlInstance = {
GroovyObject.class.classLoader.addURL(new File("$rootDir//libs//ojdbc8-12.2.0.1.jar").toURL())
def sql = Sql.newInstance("${JDBC_URL}", "${DB_USERNAME}", "${DB_PASSWORD}", 'oracle.jdbc.OracleDriver')
return sql;
}
def insertInAuditLog = {
def sql = createSqlInstance();
def fileName, author, exectype, tag, orderExecuted, changesetId;
sql.eachRow("SELECT * FROM DATABASECHANGELOG WHERE DEPLOYMENT_ID = (SELECT DEPLOYMENT_ID FROM DATABASECHANGELOG WHERE orderexecuted= (SELECT max(orderexecuted) FROM DATABASECHANGELOG ))ORDER BY ORDEREXECUTED") { resultSet ->
changesetId = resultSet[0]
author = resultSet[1]
fileName = resultSet[2]
orderExecuted = resultSet[4]
exectype = resultSet[5]
tag = resultSet[9]
deploymentID = resultSet[13]
sql.execute("INSERT INTO DATABASECHANGELOG_AUDIT (ID, FILENAME, AUTHOR, DATEEXECUTED,EXECTYPE,TAG,DEPLOYMENT_ID, CHANGESET_ID) VALUES(DBAD_SEQ.NEXTVAL,$fileName, $author, CURRENT_TIMESTAMP, $exectype,$tag,$deploymentID, $changesetId)")
}
sql.close()
}
doLast{
insertInAuditLog();
}
}
insertChangelogInAuditAfterLiquibaseDeploy.dependsOn(liquibaseUpdate)
liquibaseUpdate.finalizedBy(insertChangelogInAuditAfterLiquibaseDeploy)
// Task to fetch previous tag of database before running rollback and get changelogs before rollback
// ******************************************************************************************
task preLiquibaseRollback{
def createSqlInstance = {
GroovyObject.class.classLoader.addURL(new File("$rootDir//libs//ojdbc8-12.2.0.1.jar").toURL())
def sql = Sql.newInstance("${JDBC_URL}", "${DB_USERNAME}", "${DB_PASSWORD}", 'oracle.jdbc.OracleDriver')
return sql;
}
def getTagFromChangeLogTable = {
def versionTag;
def sql = createSqlInstance()
sql.query("select * from(select TAG , DENSE_RANK() OVER (order by ORDEREXECUTED DESC) RNK from DATABASECHANGELOG where DESCRIPTION = 'tagDatabase' ) where RNK=2") { resultSet ->
while (resultSet.next()) {
versionTag = resultSet.getString(1)
}
}
sql.close()
return versionTag;
}
def getChangeLogFromTableBeforeRollback = {
def sql = createSqlInstance();
def fileName, author, tag, orderExecuted, changesetId;
sql.eachRow("SELECT * FROM DATABASECHANGELOG WHERE DEPLOYMENT_ID = (SELECT DEPLOYMENT_ID FROM DATABASECHANGELOG WHERE orderexecuted= (SELECT max(orderexecuted) FROM DATABASECHANGELOG )) ORDER BY ORDEREXECUTED") { resultSet ->
changesetId = resultSet[0]
author = resultSet[1]
fileName = resultSet[2]
orderExecuted = resultSet[4]
tag = resultSet[9]
deploymentID = resultSet[13]
sql.execute("INSERT INTO DATABASECHANGELOG_AUDIT (ID, FILENAME, AUTHOR, DATEEXECUTED,EXECTYPE,TAG,DEPLOYMENT_ID, CHANGESET_ID) VALUES(DBAD_SEQ.NEXTVAL,$fileName, $author, CURRENT_TIMESTAMP, 'ROLLBACKED',$tag,$deploymentID, $changesetId)")
}
sql.close()
}
doLast{
def tagValue = getTagFromChangeLogTable();
if(tagValue == null){
def errorMessage = "Tagged state not available for rollback";
println errorMessage;
throw new Exception(errorMessage);
}
else{
project.setProperty("liquibaseCommandValue", tagValue)
}
getChangeLogFromTableBeforeRollback()
}
}
preLiquibaseRollback.finalizedBy(liquibaseRollback)
liquibaseRollback.dependsOn(preLiquibaseRollback)
// Task to delete database changelog record in audit table after unsuccessful rollback
// ******************************************************************************************
task postLiquibaseRollback{
def createSqlInstance = {
GroovyObject.class.classLoader.addURL(new File("$rootDir//libs//ojdbc8-12.2.0.1.jar").toURL())
def sql = Sql.newInstance("${JDBC_URL}", "${DB_USERNAME}", "${DB_PASSWORD}", 'oracle.jdbc.OracleDriver')
return sql;
}
def commitRollBackRecord = {
def sql = createSqlInstance()
def rows = sql.rows("SELECT * FROM DATABASECHANGELOG where DEPLOYMENT_ID = $deploymentID")
if( rows.size() != 0){
sql.execute("DELETE FROM DATABASECHANGELOG_AUDIT WHERE DEPLOYMENT_ID = $deploymentID and EXECTYPE = 'ROLLBACKED'")
}
sql.close()
}
doLast{
commitRollBackRecord()
}
}
liquibaseRollback.finalizedBy(postLiquibaseRollback)
}
task wrapper(type: Wrapper) {
}