public ReleaseInfo(ReleaseBranchInfo currentBranch, ReleaseBranchInfo newBranch) { Requires.NotNull(currentBranch, nameof(currentBranch)); // skip null check for newBranch, it is allowed to be null. this.CurrentBranch = currentBranch; this.NewBranch = newBranch; }
/// <summary> /// Prepares a release for the specified directory by creating a release branch and incrementing the version in the current branch. /// </summary> /// <exception cref="ReleasePreparationException">Thrown when the release could not be created.</exception> /// <param name="projectDirectory"> /// The path to the directory which may (or its ancestors may) define the version file. /// </param> /// <param name="releaseUnstableTag"> /// The prerelease tag to add to the version on the release branch. Pass <c>null</c> to omit/remove the prerelease tag. /// The leading hyphen may be specified or omitted. /// </param> /// <param name="nextVersion"> /// The next version to save to the version file on the current branch. Pass <c>null</c> to automatically determine the next /// version based on the current version and the <c>versionIncrement</c> setting in <c>version.json</c>. /// Parameter will be ignored if the current branch is a release branch. /// </param> /// <param name="versionIncrement"> /// The increment to apply in order to determine the next version on the current branch. /// If specified, value will be used instead of the increment specified in <c>version.json</c>. /// Parameter will be ignored if the current branch is a release branch. /// </param> /// <param name="outputMode"> /// The output format to use for writing to stdout. /// </param> public void PrepareRelease(string projectDirectory, string releaseUnstableTag = null, Version nextVersion = null, VersionOptions.ReleaseVersionIncrement?versionIncrement = null, ReleaseManagerOutputMode outputMode = default) { Requires.NotNull(projectDirectory, nameof(projectDirectory)); // open the git repository var repository = this.GetRepository(projectDirectory); if (repository.Info.IsHeadDetached) { this.stderr.WriteLine("Detached head. Check out a branch first."); throw new ReleasePreparationException(ReleasePreparationError.DetachedHead); } // get the current version var versionOptions = VersionFile.GetVersion(projectDirectory); if (versionOptions == null) { this.stderr.WriteLine($"Failed to load version file for directory '{projectDirectory}'."); throw new ReleasePreparationException(ReleasePreparationError.NoVersionFile); } var releaseBranchName = this.GetReleaseBranchName(versionOptions); var originalBranchName = repository.Head.FriendlyName; var releaseVersion = string.IsNullOrEmpty(releaseUnstableTag) ? versionOptions.Version.WithoutPrepreleaseTags() : versionOptions.Version.SetFirstPrereleaseTag(releaseUnstableTag); // check if the current branch is the release branch if (string.Equals(originalBranchName, releaseBranchName, StringComparison.OrdinalIgnoreCase)) { if (outputMode == ReleaseManagerOutputMode.Text) { this.stdout.WriteLine($"{releaseBranchName} branch advanced from {versionOptions.Version} to {releaseVersion}."); } else { var releaseInfo = new ReleaseInfo(new ReleaseBranchInfo(releaseBranchName, repository.Head.Tip.Id.ToString(), releaseVersion)); this.WriteToOutput(releaseInfo); } this.UpdateVersion(projectDirectory, repository, versionOptions.Version, releaseVersion); return; } var nextDevVersion = this.GetNextDevVersion(versionOptions, nextVersion, versionIncrement); // check if the release branch already exists if (repository.Branches[releaseBranchName] != null) { this.stderr.WriteLine($"Cannot create branch '{releaseBranchName}' because it already exists."); throw new ReleasePreparationException(ReleasePreparationError.BranchAlreadyExists); } // create release branch and update version var releaseBranch = repository.CreateBranch(releaseBranchName); Commands.Checkout(repository, releaseBranch); this.UpdateVersion(projectDirectory, repository, versionOptions.Version, releaseVersion); if (outputMode == ReleaseManagerOutputMode.Text) { this.stdout.WriteLine($"{releaseBranchName} branch now tracks v{releaseVersion} stabilization and release."); } // update version on main branch Commands.Checkout(repository, originalBranchName); this.UpdateVersion(projectDirectory, repository, versionOptions.Version, nextDevVersion); if (outputMode == ReleaseManagerOutputMode.Text) { this.stdout.WriteLine($"{originalBranchName} branch now tracks v{nextDevVersion} development."); } // Merge release branch back to main branch var mergeOptions = new MergeOptions() { CommitOnSuccess = true, MergeFileFavor = MergeFileFavor.Ours, }; repository.Merge(releaseBranch, this.GetSignature(repository), mergeOptions); if (outputMode == ReleaseManagerOutputMode.Json) { var originalBranchInfo = new ReleaseBranchInfo(originalBranchName, repository.Head.Tip.Sha, nextDevVersion); var releaseBranchInfo = new ReleaseBranchInfo(releaseBranchName, repository.Branches[releaseBranchName].Tip.Id.ToString(), releaseVersion); var releaseInfo = new ReleaseInfo(originalBranchInfo, releaseBranchInfo); this.WriteToOutput(releaseInfo); } }
/// <summary> /// Initializes a new instance of <see cref="ReleaseInfo"/>. /// </summary> /// <param name="currentBranch">Information on the branch the release was created from.</param> public ReleaseInfo(ReleaseBranchInfo currentBranch) : this(currentBranch, null) { }