| package org.apache.maven.continuum.buildcontroller; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.continuum.dao.BuildDefinitionDao; |
| import org.apache.continuum.dao.BuildResultDao; |
| import org.apache.continuum.dao.ProjectDao; |
| import org.apache.continuum.dao.ProjectGroupDao; |
| import org.apache.continuum.dao.ProjectScmRootDao; |
| import org.apache.continuum.model.project.ProjectScmRoot; |
| import org.apache.continuum.utils.ContinuumUtils; |
| import org.apache.continuum.utils.build.BuildTrigger; |
| import org.apache.maven.continuum.core.action.AbstractContinuumAction; |
| import org.apache.maven.continuum.core.action.ExecuteBuilderContinuumAction; |
| import org.apache.maven.continuum.execution.ContinuumBuildExecutor; |
| import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants; |
| import org.apache.maven.continuum.execution.manager.BuildExecutorManager; |
| import org.apache.maven.continuum.model.project.BuildDefinition; |
| import org.apache.maven.continuum.model.project.BuildResult; |
| import org.apache.maven.continuum.model.project.Project; |
| import org.apache.maven.continuum.model.project.ProjectDependency; |
| import org.apache.maven.continuum.model.project.ProjectGroup; |
| import org.apache.maven.continuum.model.scm.ChangeFile; |
| import org.apache.maven.continuum.model.scm.ChangeSet; |
| import org.apache.maven.continuum.model.scm.ScmResult; |
| import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher; |
| import org.apache.maven.continuum.project.ContinuumProjectState; |
| import org.apache.maven.continuum.store.ContinuumObjectNotFoundException; |
| import org.apache.maven.continuum.store.ContinuumStoreException; |
| import org.apache.maven.continuum.utils.WorkingDirectoryService; |
| import org.apache.maven.scm.ScmException; |
| import org.apache.maven.scm.repository.ScmRepositoryException; |
| import org.codehaus.plexus.action.ActionManager; |
| import org.codehaus.plexus.action.ActionNotFoundException; |
| import org.codehaus.plexus.taskqueue.execution.TaskExecutionException; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a> |
| * @version $Id$ |
| * @plexus.component role="org.apache.maven.continuum.buildcontroller.BuildController" role-hint="default" |
| */ |
| public class DefaultBuildController |
| implements BuildController |
| { |
| private static final Logger log = LoggerFactory.getLogger( DefaultBuildController.class ); |
| |
| /** |
| * @plexus.requirement |
| */ |
| private BuildDefinitionDao buildDefinitionDao; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private BuildResultDao buildResultDao; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private ProjectDao projectDao; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private ProjectGroupDao projectGroupDao; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private ProjectScmRootDao projectScmRootDao; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private ContinuumNotificationDispatcher notifierDispatcher; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private ActionManager actionManager; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private WorkingDirectoryService workingDirectoryService; |
| |
| /** |
| * @plexus.requirement |
| */ |
| private BuildExecutorManager buildExecutorManager; |
| |
| // ---------------------------------------------------------------------- |
| // BuildController Implementation |
| // ---------------------------------------------------------------------- |
| |
| /** |
| * @param projectId |
| * @param buildDefinitionId |
| * @param buildTrigger |
| * @param scmResult |
| * @throws TaskExecutionException |
| */ |
| public void build( int projectId, int buildDefinitionId, BuildTrigger buildTrigger, ScmResult scmResult ) |
| throws TaskExecutionException |
| { |
| log.info( "Initializing build" ); |
| BuildContext context = initializeBuildContext( projectId, buildDefinitionId, buildTrigger, scmResult ); |
| |
| // ignore this if AlwaysBuild ? |
| if ( !checkScmResult( context ) ) |
| { |
| log.info( "Error updating from SCM, not building" ); |
| return; |
| } |
| |
| log.info( "Starting build of " + context.getProject().getName() ); |
| startBuild( context ); |
| |
| try |
| { |
| checkProjectDependencies( context ); |
| |
| if ( !shouldBuild( context ) ) |
| { |
| return; |
| } |
| |
| Map<String, Object> actionContext = context.getActionContext(); |
| |
| try |
| { |
| performAction( "update-project-from-working-directory", context ); |
| } |
| catch ( TaskExecutionException e ) |
| { |
| updateBuildResult( context, ContinuumUtils.throwableToString( e ) ); |
| |
| //just log the error but don't stop the build from progressing in order not to suppress any build result messages there |
| log.error( "Error executing action update-project-from-working-directory '", e ); |
| } |
| |
| performAction( "execute-builder", context ); |
| |
| performAction( "deploy-artifact", context ); |
| |
| context.setCancelled( ExecuteBuilderContinuumAction.isCancelled( actionContext ) ); |
| |
| String s = AbstractContinuumAction.getBuildId( actionContext, null ); |
| |
| if ( s != null && !context.isCancelled() ) |
| { |
| try |
| { |
| context.setBuildResult( buildResultDao.getBuildResult( Integer.valueOf( s ) ) ); |
| } |
| catch ( NumberFormatException e ) |
| { |
| throw new TaskExecutionException( "Internal error: build id not an integer", e ); |
| } |
| catch ( ContinuumObjectNotFoundException e ) |
| { |
| throw new TaskExecutionException( "Internal error: Cannot find build result", e ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error loading build result", e ); |
| } |
| } |
| } |
| finally |
| { |
| endBuild( context ); |
| } |
| } |
| |
| /** |
| * Checks if the build should be marked as ERROR and notifies the end of the build. |
| * |
| * @param context |
| * @throws TaskExecutionException |
| */ |
| private void endBuild( BuildContext context ) |
| throws TaskExecutionException |
| { |
| Project project = context.getProject(); |
| |
| try |
| { |
| if ( project.getState() != ContinuumProjectState.NEW && |
| project.getState() != ContinuumProjectState.CHECKEDOUT && |
| project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED && |
| project.getState() != ContinuumProjectState.ERROR && !context.isCancelled() ) |
| { |
| try |
| { |
| String s = AbstractContinuumAction.getBuildId( context.getActionContext(), null ); |
| |
| if ( s != null ) |
| { |
| BuildResult buildResult = buildResultDao.getBuildResult( Integer.valueOf( s ) ); |
| project.setState( buildResult.getState() ); |
| projectDao.updateProject( project ); |
| } |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error storing the project", e ); |
| } |
| } |
| } |
| finally |
| { |
| if ( !context.isCancelled() ) |
| { |
| notifierDispatcher.buildComplete( project, context.getBuildDefinition(), context.getBuildResult() ); |
| } |
| } |
| } |
| |
| private void updateBuildResult( BuildContext context, String error ) |
| throws TaskExecutionException |
| { |
| BuildResult build = context.getBuildResult(); |
| |
| if ( build == null ) |
| { |
| build = makeAndStoreBuildResult( context, error ); |
| } |
| else |
| { |
| updateBuildResult( build, context ); |
| |
| build.setError( error ); |
| |
| try |
| { |
| buildResultDao.updateBuildResult( build ); |
| |
| build = buildResultDao.getBuildResult( build.getId() ); |
| |
| context.setBuildResult( build ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error updating build result", e ); |
| } |
| } |
| |
| context.getProject().setState( build.getState() ); |
| |
| try |
| { |
| projectDao.updateProject( context.getProject() ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error updating project", e ); |
| } |
| } |
| |
| private void updateBuildResult( BuildResult build, BuildContext context ) |
| { |
| if ( build.getScmResult() == null && context.getScmResult() != null ) |
| { |
| build.setScmResult( context.getScmResult() ); |
| } |
| |
| if ( build.getModifiedDependencies() == null && context.getModifiedDependencies() != null ) |
| { |
| build.setModifiedDependencies( context.getModifiedDependencies() ); |
| } |
| } |
| |
| private void startBuild( BuildContext context ) |
| throws TaskExecutionException |
| { |
| |
| Project project = context.getProject(); |
| |
| project.setOldState( project.getState() ); |
| |
| project.setState( ContinuumProjectState.BUILDING ); |
| |
| try |
| { |
| projectDao.updateProject( project ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error persisting project", e ); |
| } |
| |
| notifierDispatcher.buildStarted( project, context.getBuildDefinition() ); |
| |
| } |
| |
| /** |
| * Initializes a BuildContext for the build. |
| * |
| * @param projectId |
| * @param buildDefinitionId |
| * @param buildTrigger |
| * @param scmResult |
| * @return |
| * @throws TaskExecutionException |
| */ |
| @SuppressWarnings( "unchecked" ) |
| protected BuildContext initializeBuildContext( int projectId, int buildDefinitionId, BuildTrigger buildTrigger, |
| ScmResult scmResult ) |
| throws TaskExecutionException |
| { |
| BuildContext context = new BuildContext(); |
| |
| context.setStartTime( System.currentTimeMillis() ); |
| |
| Map actionContext = context.getActionContext(); |
| |
| try |
| { |
| Project project = projectDao.getProject( projectId ); |
| |
| context.setProject( project ); |
| |
| BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId ); |
| |
| BuildTrigger newBuildTrigger = buildTrigger; |
| |
| if ( newBuildTrigger.getTrigger() == ContinuumProjectState.TRIGGER_SCHEDULED ) |
| { |
| newBuildTrigger.setTriggeredBy( buildDefinition.getSchedule().getName() ); |
| } |
| |
| context.setBuildTrigger( newBuildTrigger ); |
| |
| context.setBuildDefinition( buildDefinition ); |
| |
| BuildResult oldBuildResult = buildResultDao.getLatestBuildResultForBuildDefinition( projectId, |
| buildDefinitionId ); |
| |
| context.setOldBuildResult( oldBuildResult ); |
| |
| context.setScmResult( scmResult ); |
| |
| // CONTINUUM-2193 |
| ProjectGroup projectGroup = project.getProjectGroup(); |
| List<ProjectScmRoot> scmRoots = projectScmRootDao.getProjectScmRootByProjectGroup( projectGroup.getId() ); |
| String projectScmUrl = project.getScmUrl(); |
| String projectScmRootAddress = ""; |
| |
| for ( ProjectScmRoot projectScmRoot : scmRoots ) |
| { |
| projectScmRootAddress = projectScmRoot.getScmRootAddress(); |
| if ( projectScmUrl.startsWith( projectScmRoot.getScmRootAddress() ) ) |
| { |
| AbstractContinuumAction.setProjectScmRootUrl( actionContext, projectScmRoot.getScmRootAddress() ); |
| break; |
| } |
| } |
| |
| if ( project.isCheckedOutInSingleDirectory() ) |
| { |
| List<Project> projectsInGroup = projectGroupDao.getProjectGroupWithProjects( |
| projectGroup.getId() ).getProjects(); |
| List<Project> projectsWithCommonScmRoot = new ArrayList<Project>(); |
| for ( Project projectInGroup : projectsInGroup ) |
| { |
| if ( projectInGroup.getScmUrl().startsWith( projectScmRootAddress ) ) |
| { |
| projectsWithCommonScmRoot.add( projectInGroup ); |
| } |
| } |
| AbstractContinuumAction.setListOfProjectsInGroupWithCommonScmRoot( actionContext, |
| projectsWithCommonScmRoot ); |
| } |
| |
| // CONTINUUM-1871 olamy if continuum is killed during building oldBuildResult will have a endTime 0 |
| // this means all changes since the project has been loaded in continuum will be in memory |
| // now we will load all BuildResult with an Id bigger or equals than the oldBuildResult one |
| //if ( oldBuildResult != null ) |
| //{ |
| // context.setOldScmResult( |
| // getOldScmResults( projectId, oldBuildResult.getBuildNumber(), oldBuildResult.getEndTime() ) ); |
| //} |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error initializing the build context", e ); |
| } |
| |
| // Map<String, Object> actionContext = context.getActionContext(); |
| |
| AbstractContinuumAction.setProjectId( actionContext, projectId ); |
| |
| AbstractContinuumAction.setProject( actionContext, context.getProject() ); |
| |
| AbstractContinuumAction.setBuildDefinitionId( actionContext, buildDefinitionId ); |
| |
| AbstractContinuumAction.setBuildDefinition( actionContext, context.getBuildDefinition() ); |
| |
| AbstractContinuumAction.setBuildTrigger( actionContext, buildTrigger ); |
| |
| AbstractContinuumAction.setScmResult( actionContext, context.getScmResult() ); |
| |
| if ( context.getOldBuildResult() != null ) |
| { |
| AbstractContinuumAction.setOldBuildId( actionContext, context.getOldBuildResult().getId() ); |
| } |
| |
| return context; |
| } |
| |
| private void performAction( String actionName, BuildContext context ) |
| throws TaskExecutionException |
| { |
| String error; |
| TaskExecutionException exception; |
| |
| try |
| { |
| log.info( "Performing action " + actionName ); |
| actionManager.lookup( actionName ).execute( context.getActionContext() ); |
| return; |
| } |
| catch ( ActionNotFoundException e ) |
| { |
| error = ContinuumUtils.throwableToString( e ); |
| exception = new TaskExecutionException( "Error looking up action '" + actionName + "'", e ); |
| } |
| catch ( ScmRepositoryException e ) |
| { |
| error = getValidationMessages( e ) + "\n" + ContinuumUtils.throwableToString( e ); |
| |
| exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e ); |
| } |
| catch ( ScmException e ) |
| { |
| error = ContinuumUtils.throwableToString( e ); |
| |
| exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e ); |
| } |
| catch ( Exception e ) |
| { |
| exception = new TaskExecutionException( "Error executing action '" + actionName + "'", e ); |
| error = ContinuumUtils.throwableToString( exception ); |
| } |
| |
| // TODO: clean this up. We catch the original exception from the action, and then update the buildresult |
| // for it - we need to because of the specialized error message for SCM. |
| // If updating the buildresult fails, log the previous error and throw the new one. |
| // If updating the buildresult succeeds, throw the original exception. The build result should NOT |
| // be updated again - a TaskExecutionException is final, no further action should be taken upon it. |
| |
| try |
| { |
| updateBuildResult( context, error ); |
| } |
| catch ( TaskExecutionException e ) |
| { |
| log.error( "Error updating build result after receiving the following exception: ", exception ); |
| throw e; |
| } |
| |
| throw exception; |
| } |
| |
| protected boolean shouldBuild( BuildContext context ) |
| throws TaskExecutionException |
| { |
| BuildDefinition buildDefinition = context.getBuildDefinition(); |
| if ( buildDefinition.isAlwaysBuild() ) |
| { |
| log.info( "AlwaysBuild configured, building" ); |
| return true; |
| } |
| if ( context.getOldBuildResult() == null ) |
| { |
| log.info( "The project has never been built with the current build definition, building" ); |
| return true; |
| } |
| |
| Project project = context.getProject(); |
| |
| //CONTINUUM-1428 |
| if ( project.getOldState() == ContinuumProjectState.ERROR || |
| context.getOldBuildResult().getState() == ContinuumProjectState.ERROR ) |
| { |
| log.info( "Latest state was 'ERROR', building" ); |
| return true; |
| } |
| |
| if ( context.getBuildTrigger().getTrigger() == ContinuumProjectState.TRIGGER_FORCED ) |
| { |
| log.info( "The project build is forced, building" ); |
| return true; |
| } |
| |
| boolean shouldBuild = false; |
| |
| boolean allChangesUnknown = true; |
| |
| if ( project.getOldState() != ContinuumProjectState.NEW && |
| project.getOldState() != ContinuumProjectState.CHECKEDOUT && |
| context.getBuildTrigger().getTrigger() != ContinuumProjectState.TRIGGER_FORCED && |
| project.getState() != ContinuumProjectState.NEW && project.getState() != ContinuumProjectState.CHECKEDOUT ) |
| { |
| // Check SCM changes |
| if ( context.getScmResult() != null ) |
| { |
| allChangesUnknown = checkAllChangesUnknown( context.getScmResult().getChanges() ); |
| } |
| |
| if ( allChangesUnknown ) |
| { |
| if ( context.getScmResult() != null && !context.getScmResult().getChanges().isEmpty() ) |
| { |
| log.info( |
| "The project was not built because all changes are unknown (maybe local modifications or ignored files not defined in your SCM tool." ); |
| } |
| else |
| { |
| log.info( |
| "The project was not built because no changes were detected in sources since the last build." ); |
| } |
| } |
| |
| // Check dependencies changes |
| if ( context.getModifiedDependencies() != null && !context.getModifiedDependencies().isEmpty() ) |
| { |
| log.info( "Found dependencies changes, building" ); |
| shouldBuild = true; |
| } |
| } |
| |
| // Check changes |
| if ( !shouldBuild && ( ( !allChangesUnknown && context.getScmResult() != null && |
| !context.getScmResult().getChanges().isEmpty() ) || project.getExecutorId().equals( |
| ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR ) ) ) |
| { |
| try |
| { |
| ContinuumBuildExecutor executor = buildExecutorManager.getBuildExecutor( project.getExecutorId() ); |
| |
| Map<String, Object> actionContext = context.getActionContext(); |
| List<Project> projectsWithCommonScmRoot = |
| AbstractContinuumAction.getListOfProjectsInGroupWithCommonScmRoot( actionContext ); |
| String projectScmRootUrl = AbstractContinuumAction.getProjectScmRootUrl( actionContext, |
| project.getScmUrl() ); |
| |
| if ( executor == null ) |
| { |
| log.warn( "No continuum build executor found for project " + project.getId() + |
| " with executor '" + project.getExecutorId() + "'" ); |
| } |
| else if ( context.getScmResult() != null ) |
| { |
| shouldBuild = executor.shouldBuild( context.getScmResult().getChanges(), project, |
| workingDirectoryService.getWorkingDirectory( project, |
| projectScmRootUrl, |
| projectsWithCommonScmRoot ), |
| context.getBuildDefinition() ); |
| } |
| } |
| catch ( Exception e ) |
| { |
| updateBuildResult( context, ContinuumUtils.throwableToString( e ) ); |
| throw new TaskExecutionException( "Can't determine if the project should build or not", e ); |
| } |
| } |
| |
| if ( shouldBuild ) |
| { |
| log.info( "Changes found in the current project, building" ); |
| } |
| else |
| { |
| project.setState( project.getOldState() ); |
| |
| project.setOldState( 0 ); |
| |
| try |
| { |
| projectDao.updateProject( project ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error storing project", e ); |
| } |
| log.info( "No changes in the current project, not building" ); |
| |
| } |
| |
| return shouldBuild; |
| } |
| |
| private boolean checkAllChangesUnknown( List<ChangeSet> changes ) |
| { |
| for ( ChangeSet changeSet : changes ) |
| { |
| List<ChangeFile> changeFiles = changeSet.getFiles(); |
| |
| for ( ChangeFile changeFile : changeFiles ) |
| { |
| if ( !"unknown".equalsIgnoreCase( changeFile.getStatus() ) ) |
| { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| private String getValidationMessages( ScmRepositoryException ex ) |
| { |
| List<String> messages = ex.getValidationMessages(); |
| |
| StringBuffer message = new StringBuffer(); |
| |
| if ( messages != null && !messages.isEmpty() ) |
| { |
| for ( Iterator<String> i = messages.iterator(); i.hasNext(); ) |
| { |
| message.append( i.next() ); |
| |
| if ( i.hasNext() ) |
| { |
| message.append( System.getProperty( "line.separator" ) ); |
| } |
| } |
| } |
| return message.toString(); |
| } |
| |
| protected void checkProjectDependencies( BuildContext context ) |
| { |
| if ( context.getOldBuildResult() == null ) |
| { |
| return; |
| } |
| |
| try |
| { |
| Project project = projectDao.getProjectWithDependencies( context.getProject().getId() ); |
| List<ProjectDependency> dependencies = project.getDependencies(); |
| |
| if ( dependencies == null ) |
| { |
| dependencies = new ArrayList<ProjectDependency>(); |
| } |
| |
| if ( project.getParent() != null ) |
| { |
| dependencies.add( project.getParent() ); |
| } |
| |
| if ( dependencies.isEmpty() ) |
| { |
| return; |
| } |
| |
| List<ProjectDependency> modifiedDependencies = new ArrayList<ProjectDependency>(); |
| |
| for ( ProjectDependency dep : dependencies ) |
| { |
| Project dependencyProject = projectDao.getProject( dep.getGroupId(), dep.getArtifactId(), |
| dep.getVersion() ); |
| |
| if ( dependencyProject != null ) |
| { |
| long nbBuild = buildResultDao.getNbBuildResultsInSuccessForProject( dependencyProject.getId(), |
| context.getOldBuildResult().getEndTime() ); |
| if ( nbBuild > 0 ) |
| { |
| log.debug( "Dependency changed: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" + |
| dep.getVersion() ); |
| modifiedDependencies.add( dep ); |
| } |
| else |
| { |
| log.debug( "Dependency not changed: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" + |
| dep.getVersion() ); |
| } |
| } |
| else |
| { |
| log.debug( "Skip non Continuum project: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" + |
| dep.getVersion() ); |
| } |
| } |
| |
| context.setModifiedDependencies( modifiedDependencies ); |
| AbstractContinuumAction.setUpdatedDependencies( context.getActionContext(), modifiedDependencies ); |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| log.warn( "Can't get the project dependencies", e ); |
| } |
| } |
| |
| // ---------------------------------------------------------------------- |
| // |
| // ---------------------------------------------------------------------- |
| |
| private BuildResult makeAndStoreBuildResult( BuildContext context, String error ) |
| throws TaskExecutionException |
| { |
| // Project project, ScmResult scmResult, long startTime, int trigger ) |
| // project, scmResult, startTime, trigger ); |
| |
| BuildResult build = new BuildResult(); |
| |
| build.setState( ContinuumProjectState.ERROR ); |
| |
| build.setTrigger( context.getBuildTrigger().getTrigger() ); |
| |
| build.setUsername( context.getBuildTrigger().getTriggeredBy() ); |
| |
| build.setStartTime( context.getStartTime() ); |
| |
| build.setEndTime( System.currentTimeMillis() ); |
| |
| updateBuildResult( build, context ); |
| |
| build.setScmResult( context.getScmResult() ); |
| |
| build.setBuildDefinition( context.getBuildDefinition() ); |
| |
| if ( error != null ) |
| { |
| build.setError( error ); |
| } |
| |
| try |
| { |
| buildResultDao.addBuildResult( context.getProject(), build ); |
| |
| build = buildResultDao.getBuildResult( build.getId() ); |
| |
| context.setBuildResult( build ); |
| |
| return build; |
| } |
| catch ( ContinuumStoreException e ) |
| { |
| throw new TaskExecutionException( "Error storing build result", e ); |
| } |
| } |
| |
| /** |
| * Check to see if there was a error while checking out/updating the project |
| * |
| * @param context The build context |
| * @return true if scm result is ok |
| * @throws TaskExecutionException |
| */ |
| private boolean checkScmResult( BuildContext context ) |
| throws TaskExecutionException |
| { |
| Project project = context.getProject(); |
| |
| int projectGroupId = project.getProjectGroup().getId(); |
| |
| List<ProjectScmRoot> scmRoots = projectScmRootDao.getProjectScmRootByProjectGroup( projectGroupId ); |
| |
| for ( ProjectScmRoot projectScmRoot : scmRoots ) |
| { |
| if ( project.getScmUrl().startsWith( projectScmRoot.getScmRootAddress() ) ) |
| { |
| if ( projectScmRoot.getState() == ContinuumProjectState.UPDATED ) |
| { |
| return true; |
| } |
| |
| break; |
| } |
| } |
| |
| return false; |
| } |
| } |