diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6a865c8a28..64b8c85c28 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,6 @@ name: build -on: - pull_request: - paths-ignore: - - docs/** - push: - paths-ignore: - - docs/** +on: [push, pull_request] jobs: build: @@ -35,6 +29,7 @@ jobs: env: BranchSpec: ${{ github.ref }} BuildNumber: ${{ github.run_number }} + PullRequestBase: ${{ github.event.pull_request.base.ref }} ApiKey: ${{ secrets.NUGETAPIKEY }} - name: coveralls @@ -71,3 +66,5 @@ jobs: - name: Run NUKE run: ./build.sh UnitTests + env: + BaseRef: ${{ github.event.pull_request.base.ref }} diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml deleted file mode 100644 index 18fc1a93b7..0000000000 --- a/.github/workflows/spellcheck.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Documentation Checks - -on: - push: - branches: - - develop - paths: - # This ensures the check will only be run when something changes in the docs content - - "docs/**/*" # or whatever the path to the markdown / docs files happens to be - pull_request: - branches: - - develop - paths: - - "docs/**/*" -jobs: - spellcheck: - name: "Docs: Spellcheck" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Check out the code - - name: Run NUKE spell check - run: ./build.sh --target SpellCheck diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index a917c108cb..37dcfce118 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -66,6 +66,10 @@ "type": "string" } }, + "PullRequestBase": { + "type": "string", + "description": "The target branch for the pull request" + }, "Root": { "type": "string", "description": "Root directory during build execution" diff --git a/Build/Build.cs b/Build/Build.cs index a5f76d2205..41980e1044 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using LibGit2Sharp; using Nuke.Common; using Nuke.Common.Execution; +using Nuke.Common.Git; using Nuke.Common.IO; using Nuke.Common.ProjectModel; using Nuke.Common.Tooling; @@ -28,7 +30,7 @@ class Build : NukeBuild - Microsoft VSCode https://nuke.build/vscode */ - public static int Main() => Execute(x => x.Push); + public static int Main() => Execute(x => x.SpellCheck, x => x.Push); [Parameter("A branch specification such as develop or refs/pull/1775/merge")] readonly string BranchSpec; @@ -36,6 +38,9 @@ class Build : NukeBuild [Parameter("An incrementing build number as provided by the build engine")] readonly string BuildNumber; + [Parameter("The target branch for the pull request")] + readonly string PullRequestBase; + [Parameter("The key to push to Nuget")] readonly string ApiKey; @@ -45,6 +50,9 @@ class Build : NukeBuild [GitVersion(Framework = "net6.0")] readonly GitVersion GitVersion; + [GitRepository] + readonly GitRepository GitRepository; + [PackageExecutable("nspec", "NSpecRunner.exe", Version = "3.1.0")] Tool NSpec3; @@ -65,6 +73,7 @@ class Build : NukeBuild string YarnCli => ToolPathResolver.GetPackageExecutable("Yarn.MSBuild", "yarn.js", "1.22.19"); Target Clean => _ => _ + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { EnsureCleanDirectory(ArtifactsDirectory); @@ -72,25 +81,27 @@ class Build : NukeBuild }); Target CalculateNugetVersion => _ => _ + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { SemVer = GitVersion.SemVer; if (IsPullRequest) { - Serilog.Log.Information( + Information( "Branch spec {branchspec} is a pull request. Adding build number {buildnumber}", BranchSpec, BuildNumber); SemVer = string.Join('.', GitVersion.SemVer.Split('.').Take(3).Union(new[] { BuildNumber })); } - Serilog.Log.Information("SemVer = {semver}", SemVer); + Information("SemVer = {semver}", SemVer); }); bool IsPullRequest => BranchSpec != null && BranchSpec.Contains("pull", StringComparison.InvariantCultureIgnoreCase); Target Restore => _ => _ .DependsOn(Clean) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { DotNetRestore(s => s @@ -101,6 +112,7 @@ class Build : NukeBuild Target Compile => _ => _ .DependsOn(Restore) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { DotNetBuild(s => s @@ -115,6 +127,7 @@ class Build : NukeBuild Target ApiChecks => _ => _ .DependsOn(Compile) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { DotNetTest(s => s @@ -126,6 +139,7 @@ class Build : NukeBuild Target UnitTests => _ => _ .DependsOn(Compile) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { Project[] projects = new[] @@ -172,6 +186,7 @@ class Build : NukeBuild Target CodeCoverage => _ => _ .DependsOn(TestFrameworks) .DependsOn(UnitTests) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { ReportGenerator(s => s @@ -183,11 +198,12 @@ class Build : NukeBuild .SetAssemblyFilters("+FluentAssertions")); string link = TestResultsDirectory / "reports" / "index.html"; - Serilog.Log.Information($"Code coverage report: \x1b]8;;file://{link.Replace('\\', '/')}\x1b\\{link}\x1b]8;;\x1b\\"); + Information($"Code coverage report: \x1b]8;;file://{link.Replace('\\', '/')}\x1b\\{link}\x1b]8;;\x1b\\"); }); Target TestFrameworks => _ => _ .DependsOn(Compile) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { var testCombinations = @@ -227,6 +243,7 @@ class Build : NukeBuild .DependsOn(UnitTests) .DependsOn(CodeCoverage) .DependsOn(CalculateNugetVersion) + .OnlyWhenDynamic(() => RunAllTargets || HasSourceChanges) .Executes(() => { DotNetPack(s => s @@ -258,11 +275,31 @@ class Build : NukeBuild }); Target SpellCheck => _ => _ + .OnlyWhenDynamic(() => RunAllTargets || HasDocumentationChanges) .Executes(() => { Node($"{YarnCli} install --silent", workingDirectory: RootDirectory); Node($"{YarnCli} --silent run cspell --no-summary", workingDirectory: RootDirectory, customLogger: (_, msg) => Error(msg)); }); + + bool HasDocumentationChanges => + Changes.Any(x => x.StartsWith("docs")); + + bool HasSourceChanges => + Changes.Any(x => !x.StartsWith("docs")); + + string[] Changes => + Repository.Diff + .Compare(TargetBranch, SourceBranch) + .Where(x => x.Exists) + .Select(x => x.Path) + .ToArray(); + + Repository Repository => new Repository(GitRepository.LocalDirectory); + Tree TargetBranch => Repository.Branches[PullRequestBase].Tip.Tree; + Tree SourceBranch => Repository.Branches[Repository.Head.FriendlyName].Tip.Tree; + bool RunAllTargets => PullRequestBase == default; + bool IsTag => BranchSpec != null && BranchSpec.Contains("refs/tags", StringComparison.InvariantCultureIgnoreCase); } diff --git a/Build/_build.csproj b/Build/_build.csproj index b73d4f73d0..e60e653e3a 100644 --- a/Build/_build.csproj +++ b/Build/_build.csproj @@ -22,6 +22,7 @@ + diff --git a/package.json b/package.json index 4c21a44ce7..6d8b3d61b5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "version": "1.0.0", "scripts": { - "cspell": "cspell --config ./cSpell.json ./**/*.md --no-progress" + "cspell": "cspell --config ./cSpell.json ./docs/**/*.md --no-progress" }, "dependencies": { "cspell": "^6.18.1"