Add initial implementation of Microsoft.DotNet.Automation library#2158
Draft
lbussell wants to merge 3 commits into
Draft
Add initial implementation of Microsoft.DotNet.Automation library#2158lbussell wants to merge 3 commits into
Microsoft.DotNet.Automation library#2158lbussell wants to merge 3 commits into
Conversation
Introduce the Microsoft.DotNet.Automation library for automating git commits and pull requests against GitHub. Provides a RepoHostEngine and supporting types for branch/PR automation, replacing the previous ImageBuilder.Automation implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Introduces an initial Microsoft.DotNet.Automation library intended to provide a service-agnostic reconciliation API for automating git commits, branches, and (currently GitHub-only) pull requests, forming the foundation for the broader automation library described in #2152.
Changes:
- Adds a new
Microsoft.DotNet.Automationproject with branch and pull request “ensure desired state” APIs. - Implements git operations via the git CLI (
GitWorkspace/GitCli) and GitHub PR operations via Octokit (GitHubPullRequestApi). - Wires the new project into the repo solution (
Microsoft.DotNet.DockerTools.slnx).
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Automation/RepoHostEngine.cs | Core reconciliation engine for ensuring branch content and PR state; contains create/update logic and foreign-commit policy handling. |
| src/Automation/RemoteRepo.cs | Abstraction for remote repositories, including authenticated clone URL construction. |
| src/Automation/README.md | Usage docs and examples for ensuring PRs/branches and configuring policies. |
| src/Automation/PullRequestUpdateStrategy.cs | Defines append vs replace strategy for PR updates. |
| src/Automation/PullRequestSpec.cs | Defines desired-state contract for an automated PR (key, target branch, apply callback, policies). |
| src/Automation/PullRequestResult.cs | Result object for PR ensure operations (outcome, URL, commits, details). |
| src/Automation/PullRequestOutcome.cs | Enumerates possible PR ensure outcomes (unchanged/created/updated/stopped/dry-run). |
| src/Automation/PullRequestInfo.cs | Internal representation of a PR as seen via IPullRequestApi. |
| src/Automation/Microsoft.DotNet.Automation.csproj | New packable library project with logging abstractions + Octokit dependencies. |
| src/Automation/IRepoHost.cs | Public interface for ensuring PRs and direct branch updates. |
| src/Automation/IPullRequestApi.cs | Internal service-specific PR API surface used by the engine. |
| src/Automation/IGitContext.cs | Public interface for producing commits in a temporary workspace. |
| src/Automation/GitWorkspace.cs | Temporary clone implementation and git operations (clone, fetch, commit, push, diff logging). |
| src/Automation/GitHub/GitHubRepoHost.cs | Public GitHub-backed IRepoHost implementation wiring engine + GitHub API client. |
| src/Automation/GitHub/GitHubRepo.cs | GitHub RemoteRepo implementation and clone/auth URL handling. |
| src/Automation/GitHub/GitHubPullRequestApi.cs | Octokit-backed PR/comment operations used by the engine. |
| src/Automation/GitException.cs | Exception type that masks credentials in command/error text. |
| src/Automation/GitContext.cs | Default IGitContext implementation that commits via GitWorkspace. |
| src/Automation/GitCommit.cs | Commit model plus helper to extract subject line. |
| src/Automation/GitCliResult.cs | Wrapper for git stdout output plus trimming helper. |
| src/Automation/GitCli.cs | Git CLI execution wrapper with secret masking in logs/errors. |
| src/Automation/GitAutomationOptions.cs | Shared options (token, author, dry run). |
| src/Automation/GitAuthor.cs | Commit author identity record. |
| src/Automation/ForeignCommitPolicy.cs | Policy for handling commits not authored by automation. |
| src/Automation/BranchSpec.cs | Desired-state contract for direct branch updates. |
| src/Automation/BranchResult.cs | Result object for branch ensure operations (outcome, commits). |
| src/Automation/BranchOutcome.cs | Enumerates possible branch ensure outcomes. |
| Microsoft.DotNet.DockerTools.slnx | Adds the new Automation project to the solution for CI build/test inclusion. |
| }, | ||
| }; | ||
|
|
||
| AutomationResult result = await host.EnsurePullRequestAsync(spec); |
Comment on lines
+63
to
+65
| AutomationResult result = await host.EnsureBranchContentAsync(spec); | ||
| // result.CommitShas contains the pushed commits, or is empty if nothing needed to change. | ||
| ``` |
|
|
||
| string desiredTreeSha = await workspace.RevParseAsync("HEAD^{tree}"); | ||
| string headTreeSha = await workspace.RevParseAsync($"{headSha}^{{tree}}"); | ||
| bool contentChanged = context.Commits.Count > 0 && desiredTreeSha != headTreeSha; |
Comment on lines
+16
to
+19
| internal override Uri GetAuthenticatedCloneUrl(string token) => | ||
| string.IsNullOrEmpty(token) | ||
| ? CloneUrl | ||
| : new Uri($"https://x-access-token:{Uri.EscapeDataString(token)}@github.com/{Owner}/{Name}"); |
Comment on lines
+61
to
+65
| public async Task<PullRequestResult> EnsurePullRequestAsync( | ||
| PullRequestSpec spec, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| GitCli git = new(logger, options.Token); |
| string rootPath = CreateTempDirectory(); | ||
| try | ||
| { | ||
| string barePath = Path.Combine(rootPath, "remote.git"); |
| try | ||
| { | ||
| string barePath = Path.Combine(rootPath, "remote.git"); | ||
| string workPath = Path.Combine(rootPath, "work"); |
| private static async Task<string> WriteAndCommitAsync( | ||
| string workPath, string relativePath, string content, GitAuthor author, string message) | ||
| { | ||
| string fullPath = Path.Combine(workPath, relativePath); |
|
|
||
| private static string CreateTempDirectory() | ||
| { | ||
| string path = Path.Combine(Path.GetTempPath(), $"automation-test-{Path.GetRandomFileName()}"); |
| async (context, cancellationToken) => | ||
| { | ||
| await File.WriteAllTextAsync( | ||
| Path.Combine(context.Directory, relativePath), content, cancellationToken); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is the start of #2152. It has a small initial scope focusing only on creating pull requests and branches. It also only targets GitHub for now.