/* * This command does the necessary preparations for releasing an rc-branch: * 1. Re-pointing all <RepoName>Version.txt files */ public int Run() { Common.VerifySemanticVersioningFormat(options.Version); var(repoName, pullRequestId) = Common.ExtractPullRequestInfo(options.PullRequestUrl); var remoteUrl = string.Format(Common.RepoUrlTemplate, options.GithubOrgName, repoName); try { // 1. Clones the source repo. using (var gitClient = GitClient.FromRemote(remoteUrl)) { // 2. Checks out the candidate branch, which defaults to 4.xx-SpatialOSUnrealGDK-x.y.z-rc in UnrealEngine and x.y.z-rc in all other repos. gitClient.CheckoutRemoteBranch(options.CandidateBranch); bool madeChanges = false; // 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). switch (repoName) { case "UnrealEngine": madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKVersionFile, Logger); madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKExampleProjectVersionFile, Logger); break; case "UnrealGDK": Logger.Info("Updating {0}...", ChangeLogFilename); madeChanges |= Common.UpdateChangeLog(ChangeLogFilename, options.Version, gitClient, ChangeLogReleaseHeadingTemplate); if (!madeChanges) { Logger.Info("{0} was already up-to-date.", ChangeLogFilename); } break; case "UnrealGDKExampleProject": madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKVersionFile, Logger); break; case "UnrealGDKTestGyms": madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKVersionFile, Logger); break; case "UnrealGDKEngineNetTest": madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKVersionFile, Logger); break; case "TestGymBuildKite": madeChanges |= Common.UpdateVersionFile(gitClient, options.Version, UnrealGDKVersionFile, Logger); break; } if (madeChanges) { // 4. Commit changes and push them to a remote candidate branch. gitClient.Commit(string.Format(CandidateCommitMessageTemplate, options.Version)); gitClient.ForcePush(options.CandidateBranch); Logger.Info($"Updated branch '${options.CandidateBranch}' in preparation for the full release."); } else { Logger.Info($"Tried to update branch '${options.CandidateBranch}' in preparation for the full release, but it was already up-to-date."); } } } catch (Exception e) { Logger.Error(e, $"ERROR: Unable to update {options.CandidateBranch}. Error: {0}", e.Message); return(1); } return(0); }
/* * This tool is designed to be used with a robot Github account. When we prep a release: * 1. Clones the source repo. * 2. Checks out the source branch, which defaults to 4.xx-SpatialOSUnrealGDK in UnrealEngine and master in all other repos. * 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). * 4. Commit changes and push them to a remote candidate branch. * 5. IF the release branch does not exist, creates it from the source branch and pushes it to the remote. * 6. Opens a PR for merging the RC branch into the release branch. */ public int Run() { Common.VerifySemanticVersioningFormat(options.Version); var remoteUrl = string.Format(Common.RepoUrlTemplate, options.GithubOrgName, options.GitRepoName); try { var gitHubClient = new GitHubClient(options); // 1. Clones the source repo. using (var gitClient = GitClient.FromRemote(remoteUrl)) { // 2. Checks out the source branch, which defaults to 4.xx-SpatialOSUnrealGDK in UnrealEngine and master in all other repos. gitClient.CheckoutRemoteBranch(options.SourceBranch); if (!gitClient.LocalBranchExists($"origin/{options.CandidateBranch}")) { // 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). switch (options.GitRepoName) { case "UnrealGDK": UpdateChangeLog(ChangeLogFilename, options, gitClient); UpdatePluginFile(pluginFileName, gitClient); var engineCandidateBranches = options.EngineVersions.Split(" ") .Select(engineVersion => $"HEAD {engineVersion.Trim()}-{options.Version}-rc") .ToList(); UpdateUnrealEngineVersionFile(engineCandidateBranches, gitClient); break; case "UnrealEngine": UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKVersionFile); UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKExampleProjectVersionFile); break; case "UnrealGDKExampleProject": UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKVersionFile); break; case "UnrealGDKTestGyms": UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKVersionFile); break; case "UnrealGDKEngineNetTest": UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKVersionFile); break; case "TestGymBuildKite": UpdateVersionFile(gitClient, $"{options.Version}-rc", UnrealGDKVersionFile); break; } // 4. Commit changes and push them to a remote candidate branch. gitClient.Commit(string.Format(CandidateCommitMessageTemplate, options.Version)); gitClient.ForcePush(options.CandidateBranch); } // 5. IF the release branch does not exist, creates it from the source branch and pushes it to the remote. if (!gitClient.LocalBranchExists($"origin/{options.ReleaseBranch}")) { gitClient.Fetch(); gitClient.CheckoutRemoteBranch(options.CandidateBranch); gitClient.Commit(string.Format(ReleaseBranchCreationCommitMessageTemplate, options.Version)); gitClient.ForcePush(options.ReleaseBranch); } // 6. Opens a PR for merging the RC branch into the release branch. var gitHubRepo = gitHubClient.GetRepositoryFromUrl(remoteUrl); var githubOrg = options.GithubOrgName; var branchFrom = options.CandidateBranch; var branchTo = options.ReleaseBranch; // Only open a PR if one does not exist yet. if (!gitHubClient.TryGetPullRequest(gitHubRepo, githubOrg, branchFrom, branchTo, out var pullRequest)) { Logger.Info("No PR exists. Attempting to open a new PR"); pullRequest = gitHubClient.CreatePullRequest(gitHubRepo, branchFrom, branchTo, string.Format(PullRequestTemplate, options.Version), GetPullRequestBody(options.GitRepoName, options.CandidateBranch, options.ReleaseBranch)); } BuildkiteAgent.SetMetaData($"{options.GitRepoName}-{options.SourceBranch}-pr-url", pullRequest.HtmlUrl); var prAnnotation = string.Format(prAnnotationTemplate, pullRequest.HtmlUrl, options.GitRepoName, options.CandidateBranch, options.ReleaseBranch); BuildkiteAgent.Annotate(AnnotationLevel.Info, "candidate-into-release-prs", prAnnotation, true); Logger.Info("Pull request available: {0}", pullRequest.HtmlUrl); Logger.Info("Successfully created release!"); Logger.Info("Release hash: {0}", gitClient.GetHeadCommit().Sha); } } catch (Exception e) { Logger.Error(e, "ERROR: Unable to prep release candidate branch. Error: {0}", e); return(1); } return(0); }
internal static void UpdateChangeLog(string ChangeLogFilePath, Options options, GitClient gitClient) { using (new WorkingDirectoryScope(gitClient.RepositoryPath)) { if (File.Exists(ChangeLogFilePath)) { Logger.Info("Updating {0}...", ChangeLogFilePath); var changelog = File.ReadAllLines(ChangeLogFilePath).ToList(); // If we already have a changelog entry for this release. Skip this step. if (changelog.Any(line => IsMarkdownHeading(line, 2, $"[`{options.Version}`] - "))) { Logger.Info($"Changelog already has release version {options.Version}. Skipping..", ChangeLogFilePath); return; } // First add the new release heading under the "## Unreleased" one. // Assuming that this is the first heading. var unreleasedIndex = changelog.FindIndex(line => IsMarkdownHeading(line, 2)); var releaseHeading = string.Format(ChangeLogReleaseHeadingTemplate, options.Version, DateTime.Now); changelog.InsertRange(unreleasedIndex + 1, new[] { string.Empty, releaseHeading }); File.WriteAllLines(ChangeLogFilePath, changelog); gitClient.StageFile(ChangeLogFilePath); } } }
/* * This tool is designed to be used with a robot Github account. When we prep a release: * 1. Clones the source repo. * 2. Checks out the source branch, which defaults to 4.xx-SpatialOSUnrealGDK in UnrealEngine and master in all other repos. * 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). * 4. Commit changes and push them to a remote candidate branch. * 5. IF the release branch does not exist, creates it from the source branch and pushes it to the remote. * 6. Opens a PR for merging the RC branch into the release branch. */ public int Run() { Common.VerifySemanticVersioningFormat(options.Version); var gitRepoName = options.GitRepoName; var remoteUrl = Common.makeRepoUrl(options.GithubOrgName, gitRepoName); try { // 1. Clones the source repo. using (var gitClient = GitClient.FromRemote(remoteUrl)) { if (!gitClient.LocalBranchExists($"origin/{options.CandidateBranch}")) { // 2. Checks out the source branch, which defaults to 4.xx-SpatialOSUnrealGDK in UnrealEngine and master in all other repos. gitClient.CheckoutRemoteBranch(options.SourceBranch); // 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). // UpdateVersionFilesWithEngine returns a bool to indicate if anything has changed, we could use this to only push when // version files etc have changed which may be reasonable but might have side-effects as our github ci interactions are fragile Common.UpdateVersionFilesWithEngine(gitClient, gitRepoName, options.Version, options.EngineVersions, Logger, "-rc"); // 4. Commit changes and push them to a remote candidate branch. gitClient.Commit(string.Format(CandidateCommitMessageTemplate, options.Version)); gitClient.ForcePush(options.CandidateBranch); Logger.Info($"Updated branch '{options.CandidateBranch}' for the release candidate release."); } // 5. IF the release branch does not exist, creates it from the source branch and pushes it to the remote. if (!gitClient.LocalBranchExists($"origin/{options.ReleaseBranch}")) { Logger.Info("The release branch {0} does not exist! Going ahead with the PR-less release process.", options.ReleaseBranch); Logger.Info("Release candidate head hash: {0}", gitClient.GetHeadCommit().Sha); var branchAnnotation = string.Format(branchAnnotationTemplate, $"https://github.com/{options.GithubOrgName}/{options.GitRepoName}/tree/{options.CandidateBranch}", options.GitRepoName, options.ReleaseBranch); BuildkiteAgent.Annotate(AnnotationLevel.Info, "candidate-into-release-prs", branchAnnotation, true); return(0); } // 6. Opens a PR for merging the RC branch into the release branch. var gitHubClient = new GitHubClient(options); var gitHubRepo = gitHubClient.GetRepositoryFromUrl(remoteUrl); var githubOrg = options.GithubOrgName; var branchFrom = options.CandidateBranch; var branchTo = options.ReleaseBranch; // Only open a PR if one does not exist yet. if (!gitHubClient.TryGetPullRequest(gitHubRepo, githubOrg, branchFrom, branchTo, out var pullRequest)) { Logger.Info("No PR exists. Attempting to open a new PR"); pullRequest = gitHubClient.CreatePullRequest(gitHubRepo, branchFrom, branchTo, string.Format(PullRequestTemplate, options.Version), GetPullRequestBody(options.GitRepoName, options.CandidateBranch, options.ReleaseBranch)); } BuildkiteAgent.SetMetaData($"{options.GitRepoName}-{options.SourceBranch}-pr-url", pullRequest.HtmlUrl); var prAnnotation = string.Format(prAnnotationTemplate, pullRequest.HtmlUrl, options.GitRepoName, options.CandidateBranch, options.ReleaseBranch); BuildkiteAgent.Annotate(AnnotationLevel.Info, "candidate-into-release-prs", prAnnotation, true); Logger.Info("Pull request available: {0}", pullRequest.HtmlUrl); Logger.Info("Successfully created pull request for the release!"); Logger.Info("PR head hash: {0}", gitClient.GetHeadCommit().Sha); } } catch (Exception e) { Logger.Error(e, "ERROR: Unable to prep release candidate branch. Error: {0}", e); return(1); } return(0); }
private void CreatePRFromReleaseToSource(GitHubClient gitHubClient, Repository gitHubRepo, string repoUrl, string repoName, GitClient gitClient) { // Check if a PR has already been opened from release branch into source branch. // If it has, log the PR URL and move on. // This ensures the idempotence of the pipeline. var githubOrg = options.GithubOrgName; var branchFrom = $"{options.CandidateBranch}-cleanup"; var branchTo = options.SourceBranch; if (!gitHubClient.TryGetPullRequest(gitHubRepo, githubOrg, branchFrom, branchTo, out var pullRequest)) { try { if (gitClient == null) { using (gitClient = GitClient.FromRemote(repoUrl)) { gitClient.CheckoutRemoteBranch(options.ReleaseBranch); gitClient.ForcePush(branchFrom); } } else { gitClient.CheckoutRemoteBranch(options.ReleaseBranch); gitClient.ForcePush(branchFrom); } pullRequest = gitHubClient.CreatePullRequest(gitHubRepo, branchFrom, branchTo, string.Format(PullRequestNameTemplate, options.Version, options.ReleaseBranch, options.SourceBranch), string.Format(pullRequestBody, options.ReleaseBranch, options.SourceBranch)); } catch (Octokit.ApiValidationException e) { // Handles the case where source-branch (default master) and release-branch (default release) are identical, so there is no need to merge source-branch back into release-branch. if (e.ApiError.Errors.Count > 0 && e.ApiError.Errors[0].Message.Contains("No commits between")) { Logger.Info(e.ApiError.Errors[0].Message); Logger.Info("No PR will be created."); return; } throw; } } else { Logger.Info("A PR has already been opened from release branch into source branch: {0}", pullRequest.HtmlUrl); } var prAnnotation = string.Format(prAnnotationTemplate, pullRequest.HtmlUrl, repoName, options.ReleaseBranch, options.SourceBranch); BuildkiteAgent.Annotate(AnnotationLevel.Info, "release-into-source-prs", prAnnotation, true); Logger.Info("Pull request available: {0}", pullRequest.HtmlUrl); Logger.Info($"Successfully created PR for merging {options.ReleaseBranch} into {options.SourceBranch}."); }
private Release CreateRelease(GitHubClient gitHubClient, Repository gitHubRepo, GitClient gitClient, string repoName) { var headCommit = gitClient.GetHeadCommit().Sha; var engineVersion = options.SourceBranch.Trim(); string tag = options.Version; // Default tag, only changed for Engine versions currently string name; string releaseBody; switch (repoName) { case "UnrealGDK": string changelog; using (new WorkingDirectoryScope(gitClient.RepositoryPath)) { changelog = GetReleaseNotesFromChangeLog(); } name = $"GDK for Unreal Release {options.Version}"; releaseBody = $@"The release notes are published in both English and Chinese. To view the Chinese version, scroll down a bit for details. Thanks! Release notes 将同时提供中英文。要浏览中文版本,向下滚动页面查看详情。感谢! # English version **Unreal GDK version {options.Version} has been released!** ## Release Notes * **Release sheriff:** Your human labour is required to populate this section with the headline new features and breaking changes from the CHANGELOG. ## Upgrading * You can find the corresponding UnrealEngine version(s) [here](https://github.com/improbableio/UnrealEngine/releases). * You can find the corresponding UnrealGDKExampleProject version [here](https://github.com/spatialos/UnrealGDKExampleProject/releases/tag/{options.Version}). Follow **[these](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date)** steps to upgrade your GDK, Engine fork and Example Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md) or below. Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing, *The GDK team* --- {changelog} # 中文版本 **[虚幻引擎开发套件 (GDK) {options.Version} 版本已发布!** ## Release Notes * **Tech writer:** Your human labour is required to translate the above and include it here. "; break; case "UnrealEngine": tag = $"{engineVersion}-{options.Version}"; name = $"{engineVersion}-{options.Version}"; releaseBody = $@"Unreal GDK version {options.Version} has been released! * This Engine version corresponds to GDK version: [{options.Version}](https://github.com/spatialos/UnrealGDK/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKExampleProject version [here](https://github.com/spatialos/UnrealGDKExampleProject/releases/tag/{options.Version}). Follow [these steps](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date) to upgrade your GDK, Unreal Engine fork and your Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md). Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing!<br> GDK team"; break; case "UnrealGDKTestGyms": name = $"Unreal GDK Test Gyms {options.Version}"; releaseBody = $@"Unreal GDK version {options.Version} has been released! * This UnrealGDKTestGyms version corresponds to GDK version: [{options.Version}](https://github.com/spatialos/UnrealGDK/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKExampleProject version [here](https://github.com/spatialos/UnrealGDKExampleProject/releases/tag/{options.Version}). * You can find the corresponding UnrealEngine version(s) [here](https://github.com/improbableio/UnrealEngine/releases). Follow [these steps](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date) to upgrade your GDK, Unreal Engine fork and your Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md). Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing!<br> GDK team"; break; case "UnrealGDKEngineNetTest": name = $"Unreal GDK EngineNetTest {options.Version}"; releaseBody = $@"Unreal GDK version {options.Version} has been released! * This UnrealGDKEngineNetTest version corresponds to GDK version: [{options.Version}](https://github.com/spatialos/UnrealGDK/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKTestGyms version [here](https://github.com/improbable/UnrealGDKTestGyms/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKExampleProject version [here](https://github.com/spatialos/UnrealGDKExampleProject/releases/tag/{options.Version}). * You can find the corresponding UnrealEngine version(s) [here](https://github.com/improbableio/UnrealEngine/releases). Follow [these steps](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date) to upgrade your GDK, Unreal Engine fork and your Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md). Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing!<br> GDK team"; break; case "TestGymBuildKite": name = $"Unreal GDK TestGymBuildKite {options.Version}"; releaseBody = $@"Unreal GDK version {options.Version} has been released! * This TestGymBuildKite version corresponds to GDK version: [{options.Version}](https://github.com/spatialos/UnrealGDK/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKTestGyms version [here](https://github.com/improbable/UnrealGDKTestGyms/releases/tag/{options.Version}). * You can find the corresponding UnrealGDKExampleProject version [here](https://github.com/spatialos/UnrealGDKExampleProject/releases/tag/{options.Version}). * You can find the corresponding UnrealEngine version(s) [here](https://github.com/improbableio/UnrealEngine/releases). Follow [these steps](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date) to upgrade your GDK, Unreal Engine fork and your Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md). Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing!<br> GDK team"; break; case "UnrealGDKExampleProject": name = $"Unreal GDK Example Project {options.Version}"; releaseBody = $@"Unreal GDK version {options.Version} has been released! * This UnrealGDKExampleProject version corresponds to GDK version: [{options.Version}](https://github.com/spatialos/UnrealGDK/releases/tag/{options.Version}). * You can find the corresponding UnrealEngine version(s) [here](https://github.com/improbableio/UnrealEngine/releases). Follow [these steps](https://documentation.improbable.io/gdk-for-unreal/docs/keep-your-gdk-up-to-date) to upgrade your GDK, Unreal Engine fork and your Project to the latest release. You can read the full release notes [here](https://github.com/spatialos/UnrealGDK/blob/release/CHANGELOG.md). Join the community on our [forums](https://forums.improbable.io/), or on [Discord](https://discordapp.com/invite/vAT7RSU). Happy developing!<br> GDK team"; break; default: throw new ArgumentException("Unsupported repository.", nameof(repoName)); } return(gitHubClient.CreateDraftRelease(gitHubRepo, tag, releaseBody, name, headCommit)); }
/* * This tool is designed to execute most of the git operations required when releasing: * 1. Merge the RC PR into the release branch. * 2. Draft a GitHub release using the changelog notes. * 3. Open a PR from the release-branch into source-branch. */ public int Run() { Common.VerifySemanticVersioningFormat(options.Version); var(repoName, pullRequestId) = Common.ExtractPullRequestInfo(options.PullRequestUrl); var gitHubClient = new GitHubClient(options); var repoUrl = string.Format(Common.RepoUrlTemplate, options.GithubOrgName, repoName); var gitHubRepo = gitHubClient.GetRepositoryFromUrl(repoUrl); // Check if the PR has been merged already. // If it has, log the PR URL and move on. // This ensures the idempotence of the pipeline. if (gitHubClient.GetMergeState(gitHubRepo, pullRequestId) == GitHubClient.MergeState.AlreadyMerged) { Logger.Info("Candidate branch has already merged into release branch. No merge operation will be attempted."); // null for GitClient will let it create one if necessary CreatePRFromReleaseToSource(gitHubClient, gitHubRepo, repoUrl, repoName, null); return(0); } var remoteUrl = string.Format(Common.RepoUrlTemplate, options.GithubOrgName, repoName); try { // Only do something for the UnrealGDK, since the other repos should have been prepped by the PrepFullReleaseCommand. if (repoName == "UnrealGDK") { // 1. Clones the source repo. using (var gitClient = GitClient.FromRemote(remoteUrl)) { // 2. Checks out the candidate branch, which defaults to 4.xx-SpatialOSUnrealGDK-x.y.z-rc in UnrealEngine and x.y.z-rc in all other repos. gitClient.CheckoutRemoteBranch(options.CandidateBranch); // 3. Makes repo-specific changes for prepping the release (e.g. updating version files, formatting the CHANGELOG). Common.UpdateChangeLog(ChangeLogFilename, options.Version, gitClient, ChangeLogReleaseHeadingTemplate); var releaseHashes = options.EngineVersions.Split(" ") .Select(version => $"{version.Trim()}-release") .Select(BuildkiteAgent.GetMetadata) .Select(hash => $"UnrealEngine-{hash}") .ToList(); UpdateUnrealEngineVersionFile(releaseHashes, gitClient); // 4. Commit changes and push them to a remote candidate branch. gitClient.Commit(string.Format(CandidateCommitMessageTemplate, options.Version)); gitClient.ForcePush(options.CandidateBranch); } } // Since we've (maybe) pushed changes, we need to wait for all checks to pass before attempting to merge it. var startTime = DateTime.Now; while (true) { if (DateTime.Now.Subtract(startTime) > TimeSpan.FromHours(12)) { throw new Exception($"Exceeded timeout waiting for PR to be mergeable: {options.PullRequestUrl}"); } if (gitHubClient.GetMergeState(gitHubRepo, pullRequestId) == GitHubClient.MergeState.ReadyToMerge) { Logger.Info($"{options.PullRequestUrl} is mergeable. Attempting to merge."); break; } Logger.Info($"{options.PullRequestUrl} is not in a mergeable state, will query mergeability again in one minute."); Thread.Sleep(TimeSpan.FromMinutes(1)); } PullRequestMerge mergeResult = null; while (true) { // Merge into release try { mergeResult = gitHubClient.MergePullRequest(gitHubRepo, pullRequestId, PullRequestMergeMethod.Merge, $"Merging final GDK for Unreal {options.Version} release"); } catch (Octokit.PullRequestNotMergeableException e) { Logger.Info($"Was unable to merge pull request at: {options.PullRequestUrl}. Received error: {e.Message}"); } if (DateTime.Now.Subtract(startTime) > TimeSpan.FromHours(12)) { throw new Exception($"Exceeded timeout waiting for PR to be mergeable: {options.PullRequestUrl}"); } if (!mergeResult.Merged) { Logger.Info($"{options.PullRequestUrl} is not in a mergeable state, will query mergeability again in one minute."); Thread.Sleep(TimeSpan.FromMinutes(1)); } else { break; } } Logger.Info($"{options.PullRequestUrl} had been merged."); // This uploads the commit hashes of the merge into release. // When run against UnrealGDK, the UnrealEngine hashes are used to update the unreal-engine.version file to include the UnrealEngine release commits. BuildkiteAgent.SetMetaData(options.ReleaseBranch, mergeResult.Sha); // TODO: UNR-3615 - Fix this so it does not throw Octokit.ApiValidationException: Reference does not exist. // Delete candidate branch. //gitHubClient.DeleteBranch(gitHubClient.GetRepositoryFromUrl(repoUrl), options.CandidateBranch); using (var gitClient = GitClient.FromRemote(repoUrl)) { // Create GitHub release in the repo gitClient.Fetch(); gitClient.CheckoutRemoteBranch(options.ReleaseBranch); var release = CreateRelease(gitHubClient, gitHubRepo, gitClient, repoName); BuildkiteAgent.Annotate(AnnotationLevel.Info, "draft-releases", string.Format(releaseAnnotationTemplate, release.HtmlUrl, repoName), true); Logger.Info("Release Successful!"); Logger.Info("Release hash: {0}", gitClient.GetHeadCommit().Sha); Logger.Info("Draft release: {0}", release.HtmlUrl); CreatePRFromReleaseToSource(gitHubClient, gitHubRepo, repoUrl, repoName, gitClient); } } catch (Exception e) { Logger.Error(e, $"ERROR: Unable to merge {options.CandidateBranch} into {options.ReleaseBranch} and/or clean up by merging {options.ReleaseBranch} into {options.SourceBranch}. Error: {0}", e.Message); return(1); } return(0); }
public static bool UpdateVersionFilesButNotEngine(GitClient gitClient, string gitRepoName, string versionRaw, NLog.Logger logger, string versionSuffix = "") { return(UpdateVersionFiles_Internal(gitClient, gitRepoName, versionRaw, logger, versionSuffix)); }