diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..93dfe2d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +RUN apt-get update && apt-get install -y git python3 python3-yaml +RUN apt-get clean +RUN mkdir /repo && chown $APP_UID /repo +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["SS14.Changelog/SS14.Changelog.csproj", "SS14.Changelog/"] +RUN dotnet restore "SS14.Changelog/SS14.Changelog.csproj" +COPY . . +WORKDIR "/src/SS14.Changelog" +RUN dotnet build "SS14.Changelog.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "SS14.Changelog.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "SS14.Changelog.dll"] +VOLUME /repo +ENV Changelog__ChangelogRepo=/repo +ENV Changelog__SshKey=/key +RUN mkdir ~/.ssh && chmod 700 ~/.ssh +COPY "Publish/github_known_hosts" /home/app/.ssh/known_hosts diff --git a/Publish/github_known_hosts b/Publish/github_known_hosts new file mode 100644 index 0000000..1c44994 --- /dev/null +++ b/Publish/github_known_hosts @@ -0,0 +1,3 @@ +github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl +github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= +github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= \ No newline at end of file diff --git a/SS14.Changelog/Configuration/ChangelogConfig.cs b/SS14.Changelog/Configuration/ChangelogConfig.cs index a986a82..f8caf46 100644 --- a/SS14.Changelog/Configuration/ChangelogConfig.cs +++ b/SS14.Changelog/Configuration/ChangelogConfig.cs @@ -3,8 +3,27 @@ public class ChangelogConfig { public string? ChangelogRepo { get; set; } - public string? ChangelogBranchName { get; set; } + public string ChangelogBranchName { get; set; } = ""; public string ChangelogFilename { get; set; } = "Changelog.yml"; + + /// + /// Git remote address (e.g. git@github.com:space-wizards/space-station-14.git). + /// + /// + /// This is used when cloning the repo for the first time. + /// + public string? ChangelogRepoRemote { get; set; } = ""; + + /// + /// Git commit author name used for commits. + /// + public string? CommitAuthorName { get; set; } + + /// + /// Git commit author email used for commits. + /// + public string? CommitAuthorEmail { get; set; } + public string? SshKey { get; set; } public string? GitHubSecret { get; set; } public int DelaySeconds { get; set; } = 60; diff --git a/SS14.Changelog/SS14.Changelog.csproj b/SS14.Changelog/SS14.Changelog.csproj index 8aec2bc..05e2767 100644 --- a/SS14.Changelog/SS14.Changelog.csproj +++ b/SS14.Changelog/SS14.Changelog.csproj @@ -3,6 +3,7 @@ net8.0 enable + Linux diff --git a/SS14.Changelog/Services/ChangelogService.cs b/SS14.Changelog/Services/ChangelogService.cs index cebbcb0..e2e0983 100644 --- a/SS14.Changelog/Services/ChangelogService.cs +++ b/SS14.Changelog/Services/ChangelogService.cs @@ -101,9 +101,21 @@ private void ProcessMessages(CancellationToken stoppingToken) private async Task RunChangelogUpdate() { + var cfg = _cfg.Value; _log.LogInformation("Running changelog update!"); - var repo = _cfg.Value.ChangelogRepo!; + var repo = cfg.ChangelogRepo!; + + await EnsureRepoCloned(); + + _log.LogTrace("Ensuring we're on the correct branch..."); + + await WaitForSuccessAsync(new ProcessStartInfo + { + FileName = "git", + ArgumentList = {"checkout", cfg.ChangelogBranchName}, + WorkingDirectory = repo + }); _log.LogTrace("Pulling repo..."); @@ -133,12 +145,26 @@ await WaitForSuccessAsync(new ProcessStartInfo WorkingDirectory = repo }); - await WaitForSuccessAsync(new ProcessStartInfo + var commitCommand = new ProcessStartInfo { FileName = "git", ArgumentList = {"commit", "-m", "Automatic changelog update"}, WorkingDirectory = repo - }); + }; + + if (cfg.CommitAuthorName is { } authorName) + { + commitCommand.ArgumentList.Insert(0, "-c"); + commitCommand.ArgumentList.Insert(1, "user.name=" + authorName); + } + + if (cfg.CommitAuthorEmail is { } authorEmail) + { + commitCommand.ArgumentList.Insert(0, "-c"); + commitCommand.ArgumentList.Insert(1, "user.email=" + authorEmail); + } + + await WaitForSuccessAsync(commitCommand); // If we merge something *while* the changelog is running then the push would fail. // So if the push fails we pull --rebase again to try to fix that. @@ -192,6 +218,30 @@ await WaitForSuccessAsync(GitNetCommand(new ProcessStartInfo WorkingDirectory = repo }), timeoutSeconds: 30); } + + async Task EnsureRepoCloned() + { + _log.LogTrace("Ensuring repo is cloned..."); + + var dotGitPath = Path.Join(repo, ".git"); + if (Directory.Exists(dotGitPath)) + { + _log.LogTrace("{Path} exists, assuming repo cloned already", dotGitPath); + return; + } + + _log.LogInformation("Repo is not initialized yet, cloning it now."); + + if (cfg.ChangelogRepoRemote is not { } remote) + throw new Exception("Unable to clone new repository, ChangelogRepoRemote is not set!"); + + await WaitForSuccessAsync(GitNetCommand(new ProcessStartInfo + { + FileName = "git", + ArgumentList = {"clone", remote, "."}, + WorkingDirectory = repo + })); + } } private ProcessStartInfo GitNetCommand(ProcessStartInfo info)