diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3ab02cd..e3eae9e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,12 +29,14 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: 'recursive' # Install the .NET Core workload - name: Install .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x.x + dotnet-version: 9.x.x # Execute the build - name: Execute Release Build @@ -49,12 +51,14 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: 'recursive' # Install the .NET Core workload - name: Install .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x.x + dotnet-version: 9.x.x # Execute the tests - name: Execute Tests @@ -92,6 +96,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: 'recursive' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -114,7 +120,7 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x.x + dotnet-version: 9.x.x # Execute the build - name: Execute Build diff --git a/Dockerfile b/Dockerfile index 14f1171..5b6784d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,13 @@ -FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base +FROM mcr.microsoft.com/dotnet/runtime:9.0 AS base USER $APP_UID WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src -RUN ls -a + COPY ["src/Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj", "Nullinside.Cicd.GitHub/"] RUN dotnet restore "Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj" COPY . . diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b234b84 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +name: nullinside-cicd-github +services: + nullinside-cicd-github: + build: + context: . + tags: + - "nullinside-cicd-github:latest" + logging: + driver: loki + options: + loki-url: 'http://192.168.1.4:3100/loki/api/v1/push' + container_name: nullinside-cicd-github + environment: + - GITHUB_PAT + ports: + - 8081:8080 + - 8082:8081 + restart: unless-stopped + image: nullinside-cicd-github:latest diff --git a/go.sh b/go.sh index 814e787..3985c52 100644 --- a/go.sh +++ b/go.sh @@ -1,4 +1,3 @@ -docker build -t nullinside-cicd-github:latest . -docker container stop nullinside-cicd-github -docker container prune -f -docker run -d --name=nullinside-cicd-github -e GITHUB_PAT=$GITHUB_PAT --restart unless-stopped nullinside-cicd-github:latest +docker compose build +docker compose down +docker compose up -d \ No newline at end of file diff --git a/src/Nullinside.Cicd.GitHub/Constants.cs b/src/Nullinside.Cicd.GitHub/Constants.cs index ffdbe8c..f3d82cc 100644 --- a/src/Nullinside.Cicd.GitHub/Constants.cs +++ b/src/Nullinside.Cicd.GitHub/Constants.cs @@ -1,6 +1,16 @@ namespace Nullinside.Cicd.GitHub; +/// +/// Constants used throughout the appliction. +/// public static class Constants { + /// + /// The github project name + /// public const string GITHUB_ORG = "nullinside-development-group"; + + /// + /// The github project's unique identifier on github. + /// public const int GITHUB_PROJECT_NUM = 1; } \ No newline at end of file diff --git a/src/Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj b/src/Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj index 50f4e1f..f0b7cd4 100644 --- a/src/Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj +++ b/src/Nullinside.Cicd.GitHub/Nullinside.Cicd.GitHub.csproj @@ -2,10 +2,11 @@ Exe - net8.0 + net9.0 enable enable Linux + default @@ -18,12 +19,12 @@ - - + + - + diff --git a/src/Nullinside.Cicd.GitHub/Program.cs b/src/Nullinside.Cicd.GitHub/Program.cs index 7eec26d..afb9fca 100644 --- a/src/Nullinside.Cicd.GitHub/Program.cs +++ b/src/Nullinside.Cicd.GitHub/Program.cs @@ -18,25 +18,30 @@ .Where(o => null != o) .ToArray(); -var client = new GitHubClient(new ProductHeaderValue("nullinside")) { - Credentials = new Credentials(Environment.GetEnvironmentVariable("GITHUB_PAT")) -}; - -var graphQl = new Connection(new Octokit.GraphQL.ProductHeaderValue("nullinside"), - Environment.GetEnvironmentVariable("GITHUB_PAT")); - -ID projectId = await graphQl.Run(new Query() - .Organization(Constants.GITHUB_ORG) - .ProjectV2(Constants.GITHUB_PROJECT_NUM) - .Select(p => p.Id)); - -IReadOnlyList? repository = await client.Repository.GetAllForOrg(Constants.GITHUB_ORG); -foreach (Repository repo in repository) { - if (repo.Private) { - continue; - } - - foreach (IRepoRule? rule in rules) { - await rule.Handle(client, graphQl, projectId, repo); +while (true) { + var client = new GitHubClient(new ProductHeaderValue("nullinside")) { + Credentials = new Credentials(Environment.GetEnvironmentVariable("GITHUB_PAT")) + }; + + var graphQl = new Connection(new Octokit.GraphQL.ProductHeaderValue("nullinside"), + Environment.GetEnvironmentVariable("GITHUB_PAT")); + + ID projectId = await graphQl.Run(new Query() + .Organization(Constants.GITHUB_ORG) + .ProjectV2(Constants.GITHUB_PROJECT_NUM) + .Select(p => p.Id)); + + IReadOnlyList? repository = await client.Repository.GetAllForOrg(Constants.GITHUB_ORG); + foreach (Repository repo in repository) { + if (repo.Private) { + continue; + } + + foreach (IRepoRule? rule in rules) { + await rule!.Handle(client, graphQl, projectId, repo); + } } + + Console.WriteLine("Waiting for next execution time..."); + Task.WaitAll(Task.Delay(TimeSpan.FromMinutes(5))); } \ No newline at end of file diff --git a/src/Nullinside.Cicd.GitHub/Rule/AssociateIssuesWithProject.cs b/src/Nullinside.Cicd.GitHub/Rule/AssociateIssuesWithProject.cs index c32da3c..b7185ae 100644 --- a/src/Nullinside.Cicd.GitHub/Rule/AssociateIssuesWithProject.cs +++ b/src/Nullinside.Cicd.GitHub/Rule/AssociateIssuesWithProject.cs @@ -8,7 +8,11 @@ namespace Nullinside.Cicd.GitHub.Rule; +/// +/// Handles associating issues with the project automatically. +/// public class AssociateIssuesWithProject : IRepoRule { + /// public async Task Handle(GitHubClient client, Connection graphQl, ID projectId, Repository repo) { if (!repo.HasIssues) { return; diff --git a/src/Nullinside.Cicd.GitHub/Rule/CreateRulesets.cs b/src/Nullinside.Cicd.GitHub/Rule/CreateRulesets.cs index c2c6c7d..f7e488a 100644 --- a/src/Nullinside.Cicd.GitHub/Rule/CreateRulesets.cs +++ b/src/Nullinside.Cicd.GitHub/Rule/CreateRulesets.cs @@ -8,7 +8,11 @@ namespace Nullinside.Cicd.GitHub.Rule; +/// +/// Creates the branch merging rules based on the code bases' language. +/// public class CreateRulesets : IRepoRule { + /// public async Task Handle(GitHubClient client, Connection graphQl, ID projectId, Repository repo) { // This currently doesn't run properly. You get an error about not specifying multiple Parameters on the status // checks. Waiting on an update from the source library to not include nulls in the compiled query. @@ -18,19 +22,19 @@ public async Task Handle(GitHubClient client, Connection graphQl, ID projectId, .Rulesets() .AllPages() .Select(i => i.Name)); - + string? expectedRuleset = rulesets.FirstOrDefault(r => "main".Equals(r, StringComparison.InvariantCultureIgnoreCase)); if (null != expectedRuleset) { return; } - + ID id = await graphQl.Run(new Query() .Repository(repo.Name, Constants.GITHUB_ORG) .Select(i => i.Id)); - + Console.WriteLine($"{repo.Name}: Creating default ruleset"); - StatusCheckConfigurationInput[] statusChecks = null; + StatusCheckConfigurationInput[]? statusChecks = null; if ("Typescript".Equals(repo.Language, StringComparison.InvariantCultureIgnoreCase)) { statusChecks = new[] { new StatusCheckConfigurationInput { @@ -90,7 +94,7 @@ public async Task Handle(GitHubClient client, Connection graphQl, ID projectId, } }); } - + await graphQl.Run(new Mutation() .CreateRepositoryRuleset(new Arg(new CreateRepositoryRulesetInput { SourceId = id, diff --git a/src/Nullinside.Cicd.GitHub/Rule/IRepoRule.cs b/src/Nullinside.Cicd.GitHub/Rule/IRepoRule.cs index dbd3e59..b9ee988 100644 --- a/src/Nullinside.Cicd.GitHub/Rule/IRepoRule.cs +++ b/src/Nullinside.Cicd.GitHub/Rule/IRepoRule.cs @@ -5,6 +5,17 @@ namespace Nullinside.Cicd.GitHub.Rule; +/// +/// Contracts for executing code against a project. +/// public interface IRepoRule { + /// + /// Handles performing the rule updates. + /// + /// The github rest api client. + /// The github graphql client. + /// The unique identifier of the project. + /// The git repo being updated. + /// Task Handle(GitHubClient client, Connection graphQl, ID projectId, Repository repo); } \ No newline at end of file