docs: @Override
      public void execute() throws MojoExecutionException, MojoFailureException {
          validateConfiguration(preReleaseGoals, postReleaseGoals);
  
          try {
              // set git flow configuration
              initGitFlowConfig();
  
              // check uncommitted changes
              checkUncommittedChanges();
  
              // git for-each-ref --count=1 refs/heads/release/*
              final String releaseBranch = gitFindBranches(
                      gitFlowConfig.getReleaseBranchPrefix(), true);
  
              if (StringUtils.isNotBlank(releaseBranch)) {
                  throw new MojoFailureException(
                          "Release branch already exists. Cannot start release.");
              }
  
              if (fetchRemote) {
                  // checkout from remote if doesn't exist
                  gitFetchRemoteAndCreate(gitFlowConfig.getDevelopmentBranch());
  
                  // fetch and check remote
                  gitFetchRemoteAndCompare(gitFlowConfig.getDevelopmentBranch());
  
                  if (notSameProdDevName()) {
                      // checkout from remote if doesn't exist
                      gitFetchRemoteAndCreate(gitFlowConfig.getProductionBranch());
  
                      // fetch and check remote
                      gitFetchRemoteAndCompare(gitFlowConfig
                              .getProductionBranch());
                  }
              }
  
              // need to be in develop to check snapshots and to get correct
              // project version
              // git checkout develop
              gitCheckout(gitFlowConfig.getDevelopmentBranch());
  
              // check snapshots dependencies
              if (!allowSnapshots) {
                  checkSnapshotDependencies();
              }
  
              if (!skipTestProject) {
                  // mvn clean test
                  mvnCleanTest();
              }
  
              // get current project version from pom
              final String currentVersion = getCurrentProjectVersion();
  
              String defaultVersion = null;
              if (tychoBuild) {
                  defaultVersion = currentVersion;
              } else {
                  // get default release version
                  defaultVersion = new GitFlowVersionInfo(currentVersion)
                          .getReleaseVersionString();
              }
  
              if (defaultVersion == null) {
                  throw new MojoFailureException(
                          "Cannot get default project version.");
              }
  
              String version = null;
              if (settings.isInteractiveMode()) {
                  try {
                      while (version == null) {
                          version = prompter.prompt("What is release version? ["
                                  + defaultVersion + "]");
  
                          if (!"".equals(version)
                                  && (!GitFlowVersionInfo.isValidVersion(version) || !validBranchName(version))) {
                              getLog().info("The version is not valid.");
                              version = null;
                          }
                      }
                  } catch (PrompterException e) {
                      throw new MojoFailureException("release", e);
                  }
              } else {
                  version = releaseVersion;
              }
  
              if (StringUtils.isBlank(version)) {
                  getLog().info("Version is blank. Using default version.");
                  version = defaultVersion;
              }
  
              // maven goals before release
              if (StringUtils.isNotBlank(preReleaseGoals)) {
                  mvnRun(preReleaseGoals);
              }
  
              Map<String, String> messageProperties = new HashMap<String, String>();
              messageProperties.put("version", version);
  
              // execute if version changed
              if (!version.equals(currentVersion)) {
                  // mvn set version
                  mvnSetVersions(version);
  
                  // git commit -a -m updating versions for release
                  gitCommit(commitMessages.getReleaseStartMessage(), messageProperties);
              }
  
              if (notSameProdDevName()) {
                  // git checkout master
                  gitCheckout(gitFlowConfig.getProductionBranch());
  
                  gitMerge(gitFlowConfig.getDevelopmentBranch(), releaseRebase,
                          releaseMergeNoFF, releaseMergeFFOnly, commitMessages.getReleaseFinishMergeMessage(),
                          messageProperties);
              }
  
              if (!skipTag) {
                  if (tychoBuild && ArtifactUtils.isSnapshot(version)) {
                      version = version.replace("-" + Artifact.SNAPSHOT_VERSION, "");
                  }
  
                  messageProperties.put("version", version);
  
                  // git tag -a ...
                  gitTag(gitFlowConfig.getVersionTagPrefix() + version,
                          commitMessages.getTagReleaseMessage(), gpgSignTag, messageProperties);
              }
  
              // maven goals after release
              if (StringUtils.isNotBlank(postReleaseGoals)) {
                  mvnRun(postReleaseGoals);
              }
  
              if (notSameProdDevName()) {
                  // git checkout develop
                  gitCheckout(gitFlowConfig.getDevelopmentBranch());
              }
  
              // get next snapshot version
              final String nextSnapshotVersion;
              if (!settings.isInteractiveMode()
                      && StringUtils.isNotBlank(developmentVersion)) {
                  nextSnapshotVersion = developmentVersion;
              } else {
                  GitFlowVersionInfo versionInfo = new GitFlowVersionInfo(version);
                  if (digitsOnlyDevVersion) {
                      versionInfo = versionInfo.digitsVersionInfo();
                  }
  
                  nextSnapshotVersion = versionInfo
                          .nextSnapshotVersion(versionDigitToIncrement);
              }
  
              if (StringUtils.isBlank(nextSnapshotVersion)) {
                  throw new MojoFailureException(
                          "Next snapshot version is blank.");
              }
  
              // mvn set version
              mvnSetVersions(nextSnapshotVersion);
  
              messageProperties.put("version", nextSnapshotVersion);
  
              // git commit -a -m updating for next development version
              gitCommit(commitMessages.getReleaseFinishMessage(), messageProperties);
  
              if (installProject) {
                  // mvn clean install
                  mvnCleanInstall();
              }
  
              if (pushRemote) {
                  gitPush(gitFlowConfig.getProductionBranch(), !skipTag);
                  if (notSameProdDevName()) {
                      gitPush(gitFlowConfig.getDevelopmentBranch(), !skipTag);
                  }
              }
          } catch (Exception e) {
              throw new MojoFailureException("release", e);
          }
      }